]> code.delx.au - gnu-emacs/blob - src/xdisp.c
Simplify last change.
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code. (Or,
35 let's say almost---see the description of direct update
36 operations, below.)
37
38 The following diagram shows how redisplay code is invoked. As you
39 can see, Lisp calls redisplay and vice versa. Under window systems
40 like X, some portions of the redisplay code are also called
41 asynchronously during mouse movement or expose events. It is very
42 important that these code parts do NOT use the C library (malloc,
43 free) because many C libraries under Unix are not reentrant. They
44 may also NOT call functions of the Lisp interpreter which could
45 change the interpreter's state. If you don't follow these rules,
46 you will encounter bugs which are very hard to explain.
47
48 (Direct functions, see below)
49 direct_output_for_insert,
50 direct_forward_char (dispnew.c)
51 +---------------------------------+
52 | |
53 | V
54 +--------------+ redisplay +----------------+
55 | Lisp machine |---------------->| Redisplay code |<--+
56 +--------------+ (xdisp.c) +----------------+ |
57 ^ | |
58 +----------------------------------+ |
59 Don't use this path when called |
60 asynchronously! |
61 |
62 expose_window (asynchronous) |
63 |
64 X expose events -----+
65
66 What does redisplay do? Obviously, it has to figure out somehow what
67 has been changed since the last time the display has been updated,
68 and to make these changes visible. Preferably it would do that in
69 a moderately intelligent way, i.e. fast.
70
71 Changes in buffer text can be deduced from window and buffer
72 structures, and from some global variables like `beg_unchanged' and
73 `end_unchanged'. The contents of the display are additionally
74 recorded in a `glyph matrix', a two-dimensional matrix of glyph
75 structures. Each row in such a matrix corresponds to a line on the
76 display, and each glyph in a row corresponds to a column displaying
77 a character, an image, or what else. This matrix is called the
78 `current glyph matrix' or `current matrix' in redisplay
79 terminology.
80
81 For buffer parts that have been changed since the last update, a
82 second glyph matrix is constructed, the so called `desired glyph
83 matrix' or short `desired matrix'. Current and desired matrix are
84 then compared to find a cheap way to update the display, e.g. by
85 reusing part of the display by scrolling lines.
86
87
88 Direct operations.
89
90 You will find a lot of redisplay optimizations when you start
91 looking at the innards of redisplay. The overall goal of all these
92 optimizations is to make redisplay fast because it is done
93 frequently.
94
95 Two optimizations are not found in xdisp.c. These are the direct
96 operations mentioned above. As the name suggests they follow a
97 different principle than the rest of redisplay. Instead of
98 building a desired matrix and then comparing it with the current
99 display, they perform their actions directly on the display and on
100 the current matrix.
101
102 One direct operation updates the display after one character has
103 been entered. The other one moves the cursor by one position
104 forward or backward. You find these functions under the names
105 `direct_output_for_insert' and `direct_output_forward_char' in
106 dispnew.c.
107
108
109 Desired matrices.
110
111 Desired matrices are always built per Emacs window. The function
112 `display_line' is the central function to look at if you are
113 interested. It constructs one row in a desired matrix given an
114 iterator structure containing both a buffer position and a
115 description of the environment in which the text is to be
116 displayed. But this is too early, read on.
117
118 Characters and pixmaps displayed for a range of buffer text depend
119 on various settings of buffers and windows, on overlays and text
120 properties, on display tables, on selective display. The good news
121 is that all this hairy stuff is hidden behind a small set of
122 interface functions taking an iterator structure (struct it)
123 argument.
124
125 Iteration over things to be displayed is then simple. It is
126 started by initializing an iterator with a call to init_iterator.
127 Calls to get_next_display_element fill the iterator structure with
128 relevant information about the next thing to display. Calls to
129 set_iterator_to_next move the iterator to the next thing.
130
131 Besides this, an iterator also contains information about the
132 display environment in which glyphs for display elements are to be
133 produced. It has fields for the width and height of the display,
134 the information whether long lines are truncated or continued, a
135 current X and Y position, and lots of other stuff you can better
136 see in dispextern.h.
137
138 Glyphs in a desired matrix are normally constructed in a loop
139 calling get_next_display_element and then produce_glyphs. The call
140 to produce_glyphs will fill the iterator structure with pixel
141 information about the element being displayed and at the same time
142 produce glyphs for it. If the display element fits on the line
143 being displayed, set_iterator_to_next is called next, otherwise the
144 glyphs produced are discarded.
145
146
147 Frame matrices.
148
149 That just couldn't be all, could it? What about terminal types not
150 supporting operations on sub-windows of the screen? To update the
151 display on such a terminal, window-based glyph matrices are not
152 well suited. To be able to reuse part of the display (scrolling
153 lines up and down), we must instead have a view of the whole
154 screen. This is what `frame matrices' are for. They are a trick.
155
156 Frames on terminals like above have a glyph pool. Windows on such
157 a frame sub-allocate their glyph memory from their frame's glyph
158 pool. The frame itself is given its own glyph matrices. By
159 coincidence---or maybe something else---rows in window glyph
160 matrices are slices of corresponding rows in frame matrices. Thus
161 writing to window matrices implicitly updates a frame matrix which
162 provides us with the view of the whole screen that we originally
163 wanted to have without having to move many bytes around. To be
164 honest, there is a little bit more done, but not much more. If you
165 plan to extend that code, take a look at dispnew.c. The function
166 build_frame_matrix is a good starting point. */
167
168 #include <config.h>
169 #include <stdio.h>
170 #include <limits.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 "character.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "font.h"
192 #include "fontset.h"
193 #include "blockinput.h"
194
195 #ifdef HAVE_X_WINDOWS
196 #include "xterm.h"
197 #endif
198 #ifdef WINDOWSNT
199 #include "w32term.h"
200 #endif
201 #ifdef HAVE_NS
202 #include "nsterm.h"
203 #endif
204 #ifdef USE_GTK
205 #include "gtkutil.h"
206 #endif
207
208 #include "font.h"
209
210 #ifndef FRAME_X_OUTPUT
211 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
212 #endif
213
214 #define INFINITY 10000000
215
216 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
217 || defined(HAVE_NS) || defined (USE_GTK)
218 extern void set_frame_menubar P_ ((struct frame *f, int, int));
219 extern int pending_menu_activation;
220 #endif
221
222 extern int interrupt_input;
223 extern int command_loop_level;
224
225 extern Lisp_Object do_mouse_tracking;
226
227 extern int minibuffer_auto_raise;
228 extern Lisp_Object Vminibuffer_list;
229
230 extern Lisp_Object Qface;
231 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
232
233 extern Lisp_Object Voverriding_local_map;
234 extern Lisp_Object Voverriding_local_map_menu_flag;
235 extern Lisp_Object Qmenu_item;
236 extern Lisp_Object Qwhen;
237 extern Lisp_Object Qhelp_echo;
238 extern Lisp_Object Qbefore_string, Qafter_string;
239
240 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
241 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
242 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
243 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
244 Lisp_Object Qinhibit_point_motion_hooks;
245 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
246 Lisp_Object Qfontified;
247 Lisp_Object Qgrow_only;
248 Lisp_Object Qinhibit_eval_during_redisplay;
249 Lisp_Object Qbuffer_position, Qposition, Qobject;
250
251 /* Cursor shapes */
252 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
253
254 /* Pointer shapes */
255 Lisp_Object Qarrow, Qhand, Qtext;
256
257 Lisp_Object Qrisky_local_variable;
258
259 /* Holds the list (error). */
260 Lisp_Object list_of_error;
261
262 /* Functions called to fontify regions of text. */
263
264 Lisp_Object Vfontification_functions;
265 Lisp_Object Qfontification_functions;
266
267 /* Non-nil means automatically select any window when the mouse
268 cursor moves into it. */
269 Lisp_Object Vmouse_autoselect_window;
270
271 Lisp_Object Vwrap_prefix, Qwrap_prefix;
272 Lisp_Object Vline_prefix, Qline_prefix;
273
274 /* Non-zero means draw tool bar buttons raised when the mouse moves
275 over them. */
276
277 int auto_raise_tool_bar_buttons_p;
278
279 /* Non-zero means to reposition window if cursor line is only partially visible. */
280
281 int make_cursor_line_fully_visible_p;
282
283 /* Margin below tool bar in pixels. 0 or nil means no margin.
284 If value is `internal-border-width' or `border-width',
285 the corresponding frame parameter is used. */
286
287 Lisp_Object Vtool_bar_border;
288
289 /* Margin around tool bar buttons in pixels. */
290
291 Lisp_Object Vtool_bar_button_margin;
292
293 /* Thickness of shadow to draw around tool bar buttons. */
294
295 EMACS_INT tool_bar_button_relief;
296
297 /* Non-nil means automatically resize tool-bars so that all tool-bar
298 items are visible, and no blank lines remain.
299
300 If value is `grow-only', only make tool-bar bigger. */
301
302 Lisp_Object Vauto_resize_tool_bars;
303
304 /* Non-zero means draw block and hollow cursor as wide as the glyph
305 under it. For example, if a block cursor is over a tab, it will be
306 drawn as wide as that tab on the display. */
307
308 int x_stretch_cursor_p;
309
310 /* Non-nil means don't actually do any redisplay. */
311
312 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
313
314 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
315
316 int inhibit_eval_during_redisplay;
317
318 /* Names of text properties relevant for redisplay. */
319
320 Lisp_Object Qdisplay;
321 extern Lisp_Object Qface, Qinvisible, Qwidth;
322
323 /* Symbols used in text property values. */
324
325 Lisp_Object Vdisplay_pixels_per_inch;
326 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
327 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
328 Lisp_Object Qslice;
329 Lisp_Object Qcenter;
330 Lisp_Object Qmargin, Qpointer;
331 Lisp_Object Qline_height;
332 extern Lisp_Object Qheight;
333 extern Lisp_Object QCwidth, QCheight, QCascent;
334 extern Lisp_Object Qscroll_bar;
335 extern Lisp_Object Qcursor;
336
337 /* Non-nil means highlight trailing whitespace. */
338
339 Lisp_Object Vshow_trailing_whitespace;
340
341 /* Non-nil means escape non-break space and hyphens. */
342
343 Lisp_Object Vnobreak_char_display;
344
345 #ifdef HAVE_WINDOW_SYSTEM
346 extern Lisp_Object Voverflow_newline_into_fringe;
347
348 /* Test if overflow newline into fringe. Called with iterator IT
349 at or past right window margin, and with IT->current_x set. */
350
351 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
352 (!NILP (Voverflow_newline_into_fringe) \
353 && FRAME_WINDOW_P (it->f) \
354 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
355 && it->current_x == it->last_visible_x \
356 && it->line_wrap != WORD_WRAP)
357
358 #else /* !HAVE_WINDOW_SYSTEM */
359 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
360 #endif /* HAVE_WINDOW_SYSTEM */
361
362 /* Test if the display element loaded in IT is a space or tab
363 character. This is used to determine word wrapping. */
364
365 #define IT_DISPLAYING_WHITESPACE(it) \
366 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
367
368 /* Non-nil means show the text cursor in void text areas
369 i.e. in blank areas after eol and eob. This used to be
370 the default in 21.3. */
371
372 Lisp_Object Vvoid_text_area_pointer;
373
374 /* Name of the face used to highlight trailing whitespace. */
375
376 Lisp_Object Qtrailing_whitespace;
377
378 /* Name and number of the face used to highlight escape glyphs. */
379
380 Lisp_Object Qescape_glyph;
381
382 /* Name and number of the face used to highlight non-breaking spaces. */
383
384 Lisp_Object Qnobreak_space;
385
386 /* The symbol `image' which is the car of the lists used to represent
387 images in Lisp. */
388
389 Lisp_Object Qimage;
390
391 /* The image map types. */
392 Lisp_Object QCmap, QCpointer;
393 Lisp_Object Qrect, Qcircle, Qpoly;
394
395 /* Non-zero means print newline to stdout before next mini-buffer
396 message. */
397
398 int noninteractive_need_newline;
399
400 /* Non-zero means print newline to message log before next message. */
401
402 static int message_log_need_newline;
403
404 /* Three markers that message_dolog uses.
405 It could allocate them itself, but that causes trouble
406 in handling memory-full errors. */
407 static Lisp_Object message_dolog_marker1;
408 static Lisp_Object message_dolog_marker2;
409 static Lisp_Object message_dolog_marker3;
410 \f
411 /* The buffer position of the first character appearing entirely or
412 partially on the line of the selected window which contains the
413 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
414 redisplay optimization in redisplay_internal. */
415
416 static struct text_pos this_line_start_pos;
417
418 /* Number of characters past the end of the line above, including the
419 terminating newline. */
420
421 static struct text_pos this_line_end_pos;
422
423 /* The vertical positions and the height of this line. */
424
425 static int this_line_vpos;
426 static int this_line_y;
427 static int this_line_pixel_height;
428
429 /* X position at which this display line starts. Usually zero;
430 negative if first character is partially visible. */
431
432 static int this_line_start_x;
433
434 /* Buffer that this_line_.* variables are referring to. */
435
436 static struct buffer *this_line_buffer;
437
438 /* Nonzero means truncate lines in all windows less wide than the
439 frame. */
440
441 Lisp_Object Vtruncate_partial_width_windows;
442
443 /* A flag to control how to display unibyte 8-bit character. */
444
445 int unibyte_display_via_language_environment;
446
447 /* Nonzero means we have more than one non-mini-buffer-only frame.
448 Not guaranteed to be accurate except while parsing
449 frame-title-format. */
450
451 int multiple_frames;
452
453 Lisp_Object Vglobal_mode_string;
454
455
456 /* List of variables (symbols) which hold markers for overlay arrows.
457 The symbols on this list are examined during redisplay to determine
458 where to display overlay arrows. */
459
460 Lisp_Object Voverlay_arrow_variable_list;
461
462 /* Marker for where to display an arrow on top of the buffer text. */
463
464 Lisp_Object Voverlay_arrow_position;
465
466 /* String to display for the arrow. Only used on terminal frames. */
467
468 Lisp_Object Voverlay_arrow_string;
469
470 /* Values of those variables at last redisplay are stored as
471 properties on `overlay-arrow-position' symbol. However, if
472 Voverlay_arrow_position is a marker, last-arrow-position is its
473 numerical position. */
474
475 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
476
477 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
478 properties on a symbol in overlay-arrow-variable-list. */
479
480 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
481
482 /* Like mode-line-format, but for the title bar on a visible frame. */
483
484 Lisp_Object Vframe_title_format;
485
486 /* Like mode-line-format, but for the title bar on an iconified frame. */
487
488 Lisp_Object Vicon_title_format;
489
490 /* List of functions to call when a window's size changes. These
491 functions get one arg, a frame on which one or more windows' sizes
492 have changed. */
493
494 static Lisp_Object Vwindow_size_change_functions;
495
496 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
497
498 /* Nonzero if an overlay arrow has been displayed in this window. */
499
500 static int overlay_arrow_seen;
501
502 /* Nonzero means highlight the region even in nonselected windows. */
503
504 int highlight_nonselected_windows;
505
506 /* If cursor motion alone moves point off frame, try scrolling this
507 many lines up or down if that will bring it back. */
508
509 static EMACS_INT scroll_step;
510
511 /* Nonzero means scroll just far enough to bring point back on the
512 screen, when appropriate. */
513
514 static EMACS_INT scroll_conservatively;
515
516 /* Recenter the window whenever point gets within this many lines of
517 the top or bottom of the window. This value is translated into a
518 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
519 that there is really a fixed pixel height scroll margin. */
520
521 EMACS_INT scroll_margin;
522
523 /* Number of windows showing the buffer of the selected window (or
524 another buffer with the same base buffer). keyboard.c refers to
525 this. */
526
527 int buffer_shared;
528
529 /* Vector containing glyphs for an ellipsis `...'. */
530
531 static Lisp_Object default_invis_vector[3];
532
533 /* Zero means display the mode-line/header-line/menu-bar in the default face
534 (this slightly odd definition is for compatibility with previous versions
535 of emacs), non-zero means display them using their respective faces.
536
537 This variable is deprecated. */
538
539 int mode_line_inverse_video;
540
541 /* Prompt to display in front of the mini-buffer contents. */
542
543 Lisp_Object minibuf_prompt;
544
545 /* Width of current mini-buffer prompt. Only set after display_line
546 of the line that contains the prompt. */
547
548 int minibuf_prompt_width;
549
550 /* This is the window where the echo area message was displayed. It
551 is always a mini-buffer window, but it may not be the same window
552 currently active as a mini-buffer. */
553
554 Lisp_Object echo_area_window;
555
556 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
557 pushes the current message and the value of
558 message_enable_multibyte on the stack, the function restore_message
559 pops the stack and displays MESSAGE again. */
560
561 Lisp_Object Vmessage_stack;
562
563 /* Nonzero means multibyte characters were enabled when the echo area
564 message was specified. */
565
566 int message_enable_multibyte;
567
568 /* Nonzero if we should redraw the mode lines on the next redisplay. */
569
570 int update_mode_lines;
571
572 /* Nonzero if window sizes or contents have changed since last
573 redisplay that finished. */
574
575 int windows_or_buffers_changed;
576
577 /* Nonzero means a frame's cursor type has been changed. */
578
579 int cursor_type_changed;
580
581 /* Nonzero after display_mode_line if %l was used and it displayed a
582 line number. */
583
584 int line_number_displayed;
585
586 /* Maximum buffer size for which to display line numbers. */
587
588 Lisp_Object Vline_number_display_limit;
589
590 /* Line width to consider when repositioning for line number display. */
591
592 static EMACS_INT line_number_display_limit_width;
593
594 /* Number of lines to keep in the message log buffer. t means
595 infinite. nil means don't log at all. */
596
597 Lisp_Object Vmessage_log_max;
598
599 /* The name of the *Messages* buffer, a string. */
600
601 static Lisp_Object Vmessages_buffer_name;
602
603 /* Current, index 0, and last displayed echo area message. Either
604 buffers from echo_buffers, or nil to indicate no message. */
605
606 Lisp_Object echo_area_buffer[2];
607
608 /* The buffers referenced from echo_area_buffer. */
609
610 static Lisp_Object echo_buffer[2];
611
612 /* A vector saved used in with_area_buffer to reduce consing. */
613
614 static Lisp_Object Vwith_echo_area_save_vector;
615
616 /* Non-zero means display_echo_area should display the last echo area
617 message again. Set by redisplay_preserve_echo_area. */
618
619 static int display_last_displayed_message_p;
620
621 /* Nonzero if echo area is being used by print; zero if being used by
622 message. */
623
624 int message_buf_print;
625
626 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
627
628 Lisp_Object Qinhibit_menubar_update;
629 int inhibit_menubar_update;
630
631 /* When evaluating expressions from menu bar items (enable conditions,
632 for instance), this is the frame they are being processed for. */
633
634 Lisp_Object Vmenu_updating_frame;
635
636 /* Maximum height for resizing mini-windows. Either a float
637 specifying a fraction of the available height, or an integer
638 specifying a number of lines. */
639
640 Lisp_Object Vmax_mini_window_height;
641
642 /* Non-zero means messages should be displayed with truncated
643 lines instead of being continued. */
644
645 int message_truncate_lines;
646 Lisp_Object Qmessage_truncate_lines;
647
648 /* Set to 1 in clear_message to make redisplay_internal aware
649 of an emptied echo area. */
650
651 static int message_cleared_p;
652
653 /* How to blink the default frame cursor off. */
654 Lisp_Object Vblink_cursor_alist;
655
656 /* A scratch glyph row with contents used for generating truncation
657 glyphs. Also used in direct_output_for_insert. */
658
659 #define MAX_SCRATCH_GLYPHS 100
660 struct glyph_row scratch_glyph_row;
661 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
662
663 /* Ascent and height of the last line processed by move_it_to. */
664
665 static int last_max_ascent, last_height;
666
667 /* Non-zero if there's a help-echo in the echo area. */
668
669 int help_echo_showing_p;
670
671 /* If >= 0, computed, exact values of mode-line and header-line height
672 to use in the macros CURRENT_MODE_LINE_HEIGHT and
673 CURRENT_HEADER_LINE_HEIGHT. */
674
675 int current_mode_line_height, current_header_line_height;
676
677 /* The maximum distance to look ahead for text properties. Values
678 that are too small let us call compute_char_face and similar
679 functions too often which is expensive. Values that are too large
680 let us call compute_char_face and alike too often because we
681 might not be interested in text properties that far away. */
682
683 #define TEXT_PROP_DISTANCE_LIMIT 100
684
685 #if GLYPH_DEBUG
686
687 /* Variables to turn off display optimizations from Lisp. */
688
689 int inhibit_try_window_id, inhibit_try_window_reusing;
690 int inhibit_try_cursor_movement;
691
692 /* Non-zero means print traces of redisplay if compiled with
693 GLYPH_DEBUG != 0. */
694
695 int trace_redisplay_p;
696
697 #endif /* GLYPH_DEBUG */
698
699 #ifdef DEBUG_TRACE_MOVE
700 /* Non-zero means trace with TRACE_MOVE to stderr. */
701 int trace_move;
702
703 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
704 #else
705 #define TRACE_MOVE(x) (void) 0
706 #endif
707
708 /* Non-zero means automatically scroll windows horizontally to make
709 point visible. */
710
711 int automatic_hscrolling_p;
712 Lisp_Object Qauto_hscroll_mode;
713
714 /* How close to the margin can point get before the window is scrolled
715 horizontally. */
716 EMACS_INT hscroll_margin;
717
718 /* How much to scroll horizontally when point is inside the above margin. */
719 Lisp_Object Vhscroll_step;
720
721 /* The variable `resize-mini-windows'. If nil, don't resize
722 mini-windows. If t, always resize them to fit the text they
723 display. If `grow-only', let mini-windows grow only until they
724 become empty. */
725
726 Lisp_Object Vresize_mini_windows;
727
728 /* Buffer being redisplayed -- for redisplay_window_error. */
729
730 struct buffer *displayed_buffer;
731
732 /* Space between overline and text. */
733
734 EMACS_INT overline_margin;
735
736 /* Require underline to be at least this many screen pixels below baseline
737 This to avoid underline "merging" with the base of letters at small
738 font sizes, particularly when x_use_underline_position_properties is on. */
739
740 EMACS_INT underline_minimum_offset;
741
742 /* Value returned from text property handlers (see below). */
743
744 enum prop_handled
745 {
746 HANDLED_NORMALLY,
747 HANDLED_RECOMPUTE_PROPS,
748 HANDLED_OVERLAY_STRING_CONSUMED,
749 HANDLED_RETURN
750 };
751
752 /* A description of text properties that redisplay is interested
753 in. */
754
755 struct props
756 {
757 /* The name of the property. */
758 Lisp_Object *name;
759
760 /* A unique index for the property. */
761 enum prop_idx idx;
762
763 /* A handler function called to set up iterator IT from the property
764 at IT's current position. Value is used to steer handle_stop. */
765 enum prop_handled (*handler) P_ ((struct it *it));
766 };
767
768 static enum prop_handled handle_face_prop P_ ((struct it *));
769 static enum prop_handled handle_invisible_prop P_ ((struct it *));
770 static enum prop_handled handle_display_prop P_ ((struct it *));
771 static enum prop_handled handle_composition_prop P_ ((struct it *));
772 static enum prop_handled handle_overlay_change P_ ((struct it *));
773 static enum prop_handled handle_fontified_prop P_ ((struct it *));
774
775 /* Properties handled by iterators. */
776
777 static struct props it_props[] =
778 {
779 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
780 /* Handle `face' before `display' because some sub-properties of
781 `display' need to know the face. */
782 {&Qface, FACE_PROP_IDX, handle_face_prop},
783 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
784 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
785 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
786 {NULL, 0, NULL}
787 };
788
789 /* Value is the position described by X. If X is a marker, value is
790 the marker_position of X. Otherwise, value is X. */
791
792 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
793
794 /* Enumeration returned by some move_it_.* functions internally. */
795
796 enum move_it_result
797 {
798 /* Not used. Undefined value. */
799 MOVE_UNDEFINED,
800
801 /* Move ended at the requested buffer position or ZV. */
802 MOVE_POS_MATCH_OR_ZV,
803
804 /* Move ended at the requested X pixel position. */
805 MOVE_X_REACHED,
806
807 /* Move within a line ended at the end of a line that must be
808 continued. */
809 MOVE_LINE_CONTINUED,
810
811 /* Move within a line ended at the end of a line that would
812 be displayed truncated. */
813 MOVE_LINE_TRUNCATED,
814
815 /* Move within a line ended at a line end. */
816 MOVE_NEWLINE_OR_CR
817 };
818
819 /* This counter is used to clear the face cache every once in a while
820 in redisplay_internal. It is incremented for each redisplay.
821 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
822 cleared. */
823
824 #define CLEAR_FACE_CACHE_COUNT 500
825 static int clear_face_cache_count;
826
827 /* Similarly for the image cache. */
828
829 #ifdef HAVE_WINDOW_SYSTEM
830 #define CLEAR_IMAGE_CACHE_COUNT 101
831 static int clear_image_cache_count;
832 #endif
833
834 /* Non-zero while redisplay_internal is in progress. */
835
836 int redisplaying_p;
837
838 /* Non-zero means don't free realized faces. Bound while freeing
839 realized faces is dangerous because glyph matrices might still
840 reference them. */
841
842 int inhibit_free_realized_faces;
843 Lisp_Object Qinhibit_free_realized_faces;
844
845 /* If a string, XTread_socket generates an event to display that string.
846 (The display is done in read_char.) */
847
848 Lisp_Object help_echo_string;
849 Lisp_Object help_echo_window;
850 Lisp_Object help_echo_object;
851 int help_echo_pos;
852
853 /* Temporary variable for XTread_socket. */
854
855 Lisp_Object previous_help_echo_string;
856
857 /* Null glyph slice */
858
859 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
860
861 /* Platform-independent portion of hourglass implementation. */
862
863 /* Non-zero means we're allowed to display a hourglass pointer. */
864 int display_hourglass_p;
865
866 /* Non-zero means an hourglass cursor is currently shown. */
867 int hourglass_shown_p;
868
869 /* If non-null, an asynchronous timer that, when it expires, displays
870 an hourglass cursor on all frames. */
871 struct atimer *hourglass_atimer;
872
873 /* Number of seconds to wait before displaying an hourglass cursor. */
874 Lisp_Object Vhourglass_delay;
875
876 /* Default number of seconds to wait before displaying an hourglass
877 cursor. */
878 #define DEFAULT_HOURGLASS_DELAY 1
879
880 \f
881 /* Function prototypes. */
882
883 static void setup_for_ellipsis P_ ((struct it *, int));
884 static void mark_window_display_accurate_1 P_ ((struct window *, int));
885 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
886 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
887 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
888 static int redisplay_mode_lines P_ ((Lisp_Object, int));
889 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
890
891 static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
892
893 static void handle_line_prefix P_ ((struct it *));
894
895 static void pint2str P_ ((char *, int, int));
896 static void pint2hrstr P_ ((char *, int, int));
897 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
898 struct text_pos));
899 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
900 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
901 static void store_mode_line_noprop_char P_ ((char));
902 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
903 static void x_consider_frame_title P_ ((Lisp_Object));
904 static void handle_stop P_ ((struct it *));
905 static int tool_bar_lines_needed P_ ((struct frame *, int *));
906 static int single_display_spec_intangible_p P_ ((Lisp_Object));
907 static void ensure_echo_area_buffers P_ ((void));
908 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
909 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
910 static int with_echo_area_buffer P_ ((struct window *, int,
911 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
912 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
913 static void clear_garbaged_frames P_ ((void));
914 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
915 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
916 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
917 static int display_echo_area P_ ((struct window *));
918 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
919 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
920 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
921 static int string_char_and_length P_ ((const unsigned char *, int, int *));
922 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
923 struct text_pos));
924 static int compute_window_start_on_continuation_line P_ ((struct window *));
925 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
926 static void insert_left_trunc_glyphs P_ ((struct it *));
927 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
928 Lisp_Object));
929 static void extend_face_to_end_of_line P_ ((struct it *));
930 static int append_space_for_newline P_ ((struct it *, int));
931 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
932 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
933 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
934 static int trailing_whitespace_p P_ ((int));
935 static int message_log_check_duplicate P_ ((int, int, int, int));
936 static void push_it P_ ((struct it *));
937 static void pop_it P_ ((struct it *));
938 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
939 static void select_frame_for_redisplay P_ ((Lisp_Object));
940 static void redisplay_internal P_ ((int));
941 static int echo_area_display P_ ((int));
942 static void redisplay_windows P_ ((Lisp_Object));
943 static void redisplay_window P_ ((Lisp_Object, int));
944 static Lisp_Object redisplay_window_error ();
945 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
946 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
947 static int update_menu_bar P_ ((struct frame *, int, int));
948 static int try_window_reusing_current_matrix P_ ((struct window *));
949 static int try_window_id P_ ((struct window *));
950 static int display_line P_ ((struct it *));
951 static int display_mode_lines P_ ((struct window *));
952 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
953 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
954 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
955 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
956 static void display_menu_bar P_ ((struct window *));
957 static int display_count_lines P_ ((int, int, int, int, int *));
958 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
959 EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
960 static void compute_line_metrics P_ ((struct it *));
961 static void run_redisplay_end_trigger_hook P_ ((struct it *));
962 static int get_overlay_strings P_ ((struct it *, int));
963 static int get_overlay_strings_1 P_ ((struct it *, int, int));
964 static void next_overlay_string P_ ((struct it *));
965 static void reseat P_ ((struct it *, struct text_pos, int));
966 static void reseat_1 P_ ((struct it *, struct text_pos, int));
967 static void back_to_previous_visible_line_start P_ ((struct it *));
968 void reseat_at_previous_visible_line_start P_ ((struct it *));
969 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
970 static int next_element_from_ellipsis P_ ((struct it *));
971 static int next_element_from_display_vector P_ ((struct it *));
972 static int next_element_from_string P_ ((struct it *));
973 static int next_element_from_c_string P_ ((struct it *));
974 static int next_element_from_buffer P_ ((struct it *));
975 static int next_element_from_composition P_ ((struct it *));
976 static int next_element_from_image P_ ((struct it *));
977 static int next_element_from_stretch P_ ((struct it *));
978 static void load_overlay_strings P_ ((struct it *, int));
979 static int init_from_display_pos P_ ((struct it *, struct window *,
980 struct display_pos *));
981 static void reseat_to_string P_ ((struct it *, unsigned char *,
982 Lisp_Object, int, int, int, int));
983 static enum move_it_result
984 move_it_in_display_line_to (struct it *, EMACS_INT, int,
985 enum move_operation_enum);
986 void move_it_vertically_backward P_ ((struct it *, int));
987 static void init_to_row_start P_ ((struct it *, struct window *,
988 struct glyph_row *));
989 static int init_to_row_end P_ ((struct it *, struct window *,
990 struct glyph_row *));
991 static void back_to_previous_line_start P_ ((struct it *));
992 static int forward_to_next_line_start P_ ((struct it *, int *));
993 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
994 Lisp_Object, int));
995 static struct text_pos string_pos P_ ((int, Lisp_Object));
996 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
997 static int number_of_chars P_ ((unsigned char *, int));
998 static void compute_stop_pos P_ ((struct it *));
999 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
1000 Lisp_Object));
1001 static int face_before_or_after_it_pos P_ ((struct it *, int));
1002 static EMACS_INT next_overlay_change P_ ((EMACS_INT));
1003 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
1004 Lisp_Object, Lisp_Object,
1005 struct text_pos *, int));
1006 static int underlying_face_id P_ ((struct it *));
1007 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
1008 struct window *));
1009
1010 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1011 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1012
1013 #ifdef HAVE_WINDOW_SYSTEM
1014
1015 static void update_tool_bar P_ ((struct frame *, int));
1016 static void build_desired_tool_bar_string P_ ((struct frame *f));
1017 static int redisplay_tool_bar P_ ((struct frame *));
1018 static void display_tool_bar_line P_ ((struct it *, int));
1019 static void notice_overwritten_cursor P_ ((struct window *,
1020 enum glyph_row_area,
1021 int, int, int, int));
1022
1023
1024
1025 #endif /* HAVE_WINDOW_SYSTEM */
1026
1027 \f
1028 /***********************************************************************
1029 Window display dimensions
1030 ***********************************************************************/
1031
1032 /* Return the bottom boundary y-position for text lines in window W.
1033 This is the first y position at which a line cannot start.
1034 It is relative to the top of the window.
1035
1036 This is the height of W minus the height of a mode line, if any. */
1037
1038 INLINE int
1039 window_text_bottom_y (w)
1040 struct window *w;
1041 {
1042 int height = WINDOW_TOTAL_HEIGHT (w);
1043
1044 if (WINDOW_WANTS_MODELINE_P (w))
1045 height -= CURRENT_MODE_LINE_HEIGHT (w);
1046 return height;
1047 }
1048
1049 /* Return the pixel width of display area AREA of window W. AREA < 0
1050 means return the total width of W, not including fringes to
1051 the left and right of the window. */
1052
1053 INLINE int
1054 window_box_width (w, area)
1055 struct window *w;
1056 int area;
1057 {
1058 int cols = XFASTINT (w->total_cols);
1059 int pixels = 0;
1060
1061 if (!w->pseudo_window_p)
1062 {
1063 cols -= WINDOW_SCROLL_BAR_COLS (w);
1064
1065 if (area == TEXT_AREA)
1066 {
1067 if (INTEGERP (w->left_margin_cols))
1068 cols -= XFASTINT (w->left_margin_cols);
1069 if (INTEGERP (w->right_margin_cols))
1070 cols -= XFASTINT (w->right_margin_cols);
1071 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1072 }
1073 else if (area == LEFT_MARGIN_AREA)
1074 {
1075 cols = (INTEGERP (w->left_margin_cols)
1076 ? XFASTINT (w->left_margin_cols) : 0);
1077 pixels = 0;
1078 }
1079 else if (area == RIGHT_MARGIN_AREA)
1080 {
1081 cols = (INTEGERP (w->right_margin_cols)
1082 ? XFASTINT (w->right_margin_cols) : 0);
1083 pixels = 0;
1084 }
1085 }
1086
1087 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1088 }
1089
1090
1091 /* Return the pixel height of the display area of window W, not
1092 including mode lines of W, if any. */
1093
1094 INLINE int
1095 window_box_height (w)
1096 struct window *w;
1097 {
1098 struct frame *f = XFRAME (w->frame);
1099 int height = WINDOW_TOTAL_HEIGHT (w);
1100
1101 xassert (height >= 0);
1102
1103 /* Note: the code below that determines the mode-line/header-line
1104 height is essentially the same as that contained in the macro
1105 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1106 the appropriate glyph row has its `mode_line_p' flag set,
1107 and if it doesn't, uses estimate_mode_line_height instead. */
1108
1109 if (WINDOW_WANTS_MODELINE_P (w))
1110 {
1111 struct glyph_row *ml_row
1112 = (w->current_matrix && w->current_matrix->rows
1113 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1114 : 0);
1115 if (ml_row && ml_row->mode_line_p)
1116 height -= ml_row->height;
1117 else
1118 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1119 }
1120
1121 if (WINDOW_WANTS_HEADER_LINE_P (w))
1122 {
1123 struct glyph_row *hl_row
1124 = (w->current_matrix && w->current_matrix->rows
1125 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1126 : 0);
1127 if (hl_row && hl_row->mode_line_p)
1128 height -= hl_row->height;
1129 else
1130 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1131 }
1132
1133 /* With a very small font and a mode-line that's taller than
1134 default, we might end up with a negative height. */
1135 return max (0, height);
1136 }
1137
1138 /* Return the window-relative coordinate of the left edge of display
1139 area AREA of window W. AREA < 0 means return the left edge of the
1140 whole window, to the right of the left fringe of W. */
1141
1142 INLINE int
1143 window_box_left_offset (w, area)
1144 struct window *w;
1145 int area;
1146 {
1147 int x;
1148
1149 if (w->pseudo_window_p)
1150 return 0;
1151
1152 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1153
1154 if (area == TEXT_AREA)
1155 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1156 + window_box_width (w, LEFT_MARGIN_AREA));
1157 else if (area == RIGHT_MARGIN_AREA)
1158 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1159 + window_box_width (w, LEFT_MARGIN_AREA)
1160 + window_box_width (w, TEXT_AREA)
1161 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1162 ? 0
1163 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1164 else if (area == LEFT_MARGIN_AREA
1165 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1166 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1167
1168 return x;
1169 }
1170
1171
1172 /* Return the window-relative coordinate of the right edge of display
1173 area AREA of window W. AREA < 0 means return the left edge of the
1174 whole window, to the left of the right fringe of W. */
1175
1176 INLINE int
1177 window_box_right_offset (w, area)
1178 struct window *w;
1179 int area;
1180 {
1181 return window_box_left_offset (w, area) + window_box_width (w, area);
1182 }
1183
1184 /* Return the frame-relative coordinate of the left edge of display
1185 area AREA of window W. AREA < 0 means return the left edge of the
1186 whole window, to the right of the left fringe of W. */
1187
1188 INLINE int
1189 window_box_left (w, area)
1190 struct window *w;
1191 int area;
1192 {
1193 struct frame *f = XFRAME (w->frame);
1194 int x;
1195
1196 if (w->pseudo_window_p)
1197 return FRAME_INTERNAL_BORDER_WIDTH (f);
1198
1199 x = (WINDOW_LEFT_EDGE_X (w)
1200 + window_box_left_offset (w, area));
1201
1202 return x;
1203 }
1204
1205
1206 /* Return the frame-relative coordinate of the right edge of display
1207 area AREA of window W. AREA < 0 means return the left edge of the
1208 whole window, to the left of the right fringe of W. */
1209
1210 INLINE int
1211 window_box_right (w, area)
1212 struct window *w;
1213 int area;
1214 {
1215 return window_box_left (w, area) + window_box_width (w, area);
1216 }
1217
1218 /* Get the bounding box of the display area AREA of window W, without
1219 mode lines, in frame-relative coordinates. AREA < 0 means the
1220 whole window, not including the left and right fringes of
1221 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1222 coordinates of the upper-left corner of the box. Return in
1223 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1224
1225 INLINE void
1226 window_box (w, area, box_x, box_y, box_width, box_height)
1227 struct window *w;
1228 int area;
1229 int *box_x, *box_y, *box_width, *box_height;
1230 {
1231 if (box_width)
1232 *box_width = window_box_width (w, area);
1233 if (box_height)
1234 *box_height = window_box_height (w);
1235 if (box_x)
1236 *box_x = window_box_left (w, area);
1237 if (box_y)
1238 {
1239 *box_y = WINDOW_TOP_EDGE_Y (w);
1240 if (WINDOW_WANTS_HEADER_LINE_P (w))
1241 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1242 }
1243 }
1244
1245
1246 /* Get the bounding box of the display area AREA of window W, without
1247 mode lines. AREA < 0 means the whole window, not including the
1248 left and right fringe of the window. Return in *TOP_LEFT_X
1249 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1250 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1251 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1252 box. */
1253
1254 INLINE void
1255 window_box_edges (w, area, top_left_x, top_left_y,
1256 bottom_right_x, bottom_right_y)
1257 struct window *w;
1258 int area;
1259 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1260 {
1261 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1262 bottom_right_y);
1263 *bottom_right_x += *top_left_x;
1264 *bottom_right_y += *top_left_y;
1265 }
1266
1267
1268 \f
1269 /***********************************************************************
1270 Utilities
1271 ***********************************************************************/
1272
1273 /* Return the bottom y-position of the line the iterator IT is in.
1274 This can modify IT's settings. */
1275
1276 int
1277 line_bottom_y (it)
1278 struct it *it;
1279 {
1280 int line_height = it->max_ascent + it->max_descent;
1281 int line_top_y = it->current_y;
1282
1283 if (line_height == 0)
1284 {
1285 if (last_height)
1286 line_height = last_height;
1287 else if (IT_CHARPOS (*it) < ZV)
1288 {
1289 move_it_by_lines (it, 1, 1);
1290 line_height = (it->max_ascent || it->max_descent
1291 ? it->max_ascent + it->max_descent
1292 : last_height);
1293 }
1294 else
1295 {
1296 struct glyph_row *row = it->glyph_row;
1297
1298 /* Use the default character height. */
1299 it->glyph_row = NULL;
1300 it->what = IT_CHARACTER;
1301 it->c = ' ';
1302 it->len = 1;
1303 PRODUCE_GLYPHS (it);
1304 line_height = it->ascent + it->descent;
1305 it->glyph_row = row;
1306 }
1307 }
1308
1309 return line_top_y + line_height;
1310 }
1311
1312
1313 /* Return 1 if position CHARPOS is visible in window W.
1314 CHARPOS < 0 means return info about WINDOW_END position.
1315 If visible, set *X and *Y to pixel coordinates of top left corner.
1316 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1317 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1318
1319 int
1320 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1321 struct window *w;
1322 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1323 {
1324 struct it it;
1325 struct text_pos top;
1326 int visible_p = 0;
1327 struct buffer *old_buffer = NULL;
1328
1329 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1330 return visible_p;
1331
1332 if (XBUFFER (w->buffer) != current_buffer)
1333 {
1334 old_buffer = current_buffer;
1335 set_buffer_internal_1 (XBUFFER (w->buffer));
1336 }
1337
1338 SET_TEXT_POS_FROM_MARKER (top, w->start);
1339
1340 /* Compute exact mode line heights. */
1341 if (WINDOW_WANTS_MODELINE_P (w))
1342 current_mode_line_height
1343 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1344 current_buffer->mode_line_format);
1345
1346 if (WINDOW_WANTS_HEADER_LINE_P (w))
1347 current_header_line_height
1348 = display_mode_line (w, HEADER_LINE_FACE_ID,
1349 current_buffer->header_line_format);
1350
1351 start_display (&it, w, top);
1352 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1353 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1354
1355 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1356 {
1357 /* We have reached CHARPOS, or passed it. How the call to
1358 move_it_to can overshoot: (i) If CHARPOS is on invisible
1359 text, move_it_to stops at the end of the invisible text,
1360 after CHARPOS. (ii) If CHARPOS is in a display vector,
1361 move_it_to stops on its last glyph. */
1362 int top_x = it.current_x;
1363 int top_y = it.current_y;
1364 enum it_method it_method = it.method;
1365 /* Calling line_bottom_y may change it.method. */
1366 int bottom_y = (last_height = 0, line_bottom_y (&it));
1367 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1368
1369 if (top_y < window_top_y)
1370 visible_p = bottom_y > window_top_y;
1371 else if (top_y < it.last_visible_y)
1372 visible_p = 1;
1373 if (visible_p)
1374 {
1375 if (it_method == GET_FROM_BUFFER)
1376 {
1377 Lisp_Object window, prop;
1378
1379 XSETWINDOW (window, w);
1380 prop = Fget_char_property (make_number (it.position.charpos),
1381 Qinvisible, window);
1382
1383 /* If charpos coincides with invisible text covered with an
1384 ellipsis, use the first glyph of the ellipsis to compute
1385 the pixel positions. */
1386 if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
1387 {
1388 struct glyph_row *row = it.glyph_row;
1389 struct glyph *glyph = row->glyphs[TEXT_AREA];
1390 struct glyph *end = glyph + row->used[TEXT_AREA];
1391 int x = row->x;
1392
1393 for (; glyph < end
1394 && (!BUFFERP (glyph->object)
1395 || glyph->charpos < charpos);
1396 glyph++)
1397 x += glyph->pixel_width;
1398 top_x = x;
1399 }
1400 }
1401 else if (it_method == GET_FROM_DISPLAY_VECTOR)
1402 {
1403 /* We stopped on the last glyph of a display vector.
1404 Try and recompute. Hack alert! */
1405 if (charpos < 2 || top.charpos >= charpos)
1406 top_x = it.glyph_row->x;
1407 else
1408 {
1409 struct it it2;
1410 start_display (&it2, w, top);
1411 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1412 get_next_display_element (&it2);
1413 PRODUCE_GLYPHS (&it2);
1414 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1415 || it2.current_x > it2.last_visible_x)
1416 top_x = it.glyph_row->x;
1417 else
1418 {
1419 top_x = it2.current_x;
1420 top_y = it2.current_y;
1421 }
1422 }
1423 }
1424
1425 *x = top_x;
1426 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1427 *rtop = max (0, window_top_y - top_y);
1428 *rbot = max (0, bottom_y - it.last_visible_y);
1429 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1430 - max (top_y, window_top_y)));
1431 *vpos = it.vpos;
1432 }
1433 }
1434 else
1435 {
1436 struct it it2;
1437
1438 it2 = it;
1439 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1440 move_it_by_lines (&it, 1, 0);
1441 if (charpos < IT_CHARPOS (it)
1442 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1443 {
1444 visible_p = 1;
1445 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1446 *x = it2.current_x;
1447 *y = it2.current_y + it2.max_ascent - it2.ascent;
1448 *rtop = max (0, -it2.current_y);
1449 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1450 - it.last_visible_y));
1451 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1452 it.last_visible_y)
1453 - max (it2.current_y,
1454 WINDOW_HEADER_LINE_HEIGHT (w))));
1455 *vpos = it2.vpos;
1456 }
1457 }
1458
1459 if (old_buffer)
1460 set_buffer_internal_1 (old_buffer);
1461
1462 current_header_line_height = current_mode_line_height = -1;
1463
1464 if (visible_p && XFASTINT (w->hscroll) > 0)
1465 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1466
1467 #if 0
1468 /* Debugging code. */
1469 if (visible_p)
1470 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1471 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1472 else
1473 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1474 #endif
1475
1476 return visible_p;
1477 }
1478
1479
1480 /* Return the next character from STR which is MAXLEN bytes long.
1481 Return in *LEN the length of the character. This is like
1482 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1483 we find one, we return a `?', but with the length of the invalid
1484 character. */
1485
1486 static INLINE int
1487 string_char_and_length (str, maxlen, len)
1488 const unsigned char *str;
1489 int maxlen, *len;
1490 {
1491 int c;
1492
1493 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1494 if (!CHAR_VALID_P (c, 1))
1495 /* We may not change the length here because other places in Emacs
1496 don't use this function, i.e. they silently accept invalid
1497 characters. */
1498 c = '?';
1499
1500 return c;
1501 }
1502
1503
1504
1505 /* Given a position POS containing a valid character and byte position
1506 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1507
1508 static struct text_pos
1509 string_pos_nchars_ahead (pos, string, nchars)
1510 struct text_pos pos;
1511 Lisp_Object string;
1512 int nchars;
1513 {
1514 xassert (STRINGP (string) && nchars >= 0);
1515
1516 if (STRING_MULTIBYTE (string))
1517 {
1518 int rest = SBYTES (string) - BYTEPOS (pos);
1519 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1520 int len;
1521
1522 while (nchars--)
1523 {
1524 string_char_and_length (p, rest, &len);
1525 p += len, rest -= len;
1526 xassert (rest >= 0);
1527 CHARPOS (pos) += 1;
1528 BYTEPOS (pos) += len;
1529 }
1530 }
1531 else
1532 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1533
1534 return pos;
1535 }
1536
1537
1538 /* Value is the text position, i.e. character and byte position,
1539 for character position CHARPOS in STRING. */
1540
1541 static INLINE struct text_pos
1542 string_pos (charpos, string)
1543 int charpos;
1544 Lisp_Object string;
1545 {
1546 struct text_pos pos;
1547 xassert (STRINGP (string));
1548 xassert (charpos >= 0);
1549 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1550 return pos;
1551 }
1552
1553
1554 /* Value is a text position, i.e. character and byte position, for
1555 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1556 means recognize multibyte characters. */
1557
1558 static struct text_pos
1559 c_string_pos (charpos, s, multibyte_p)
1560 int charpos;
1561 unsigned char *s;
1562 int multibyte_p;
1563 {
1564 struct text_pos pos;
1565
1566 xassert (s != NULL);
1567 xassert (charpos >= 0);
1568
1569 if (multibyte_p)
1570 {
1571 int rest = strlen (s), len;
1572
1573 SET_TEXT_POS (pos, 0, 0);
1574 while (charpos--)
1575 {
1576 string_char_and_length (s, rest, &len);
1577 s += len, rest -= len;
1578 xassert (rest >= 0);
1579 CHARPOS (pos) += 1;
1580 BYTEPOS (pos) += len;
1581 }
1582 }
1583 else
1584 SET_TEXT_POS (pos, charpos, charpos);
1585
1586 return pos;
1587 }
1588
1589
1590 /* Value is the number of characters in C string S. MULTIBYTE_P
1591 non-zero means recognize multibyte characters. */
1592
1593 static int
1594 number_of_chars (s, multibyte_p)
1595 unsigned char *s;
1596 int multibyte_p;
1597 {
1598 int nchars;
1599
1600 if (multibyte_p)
1601 {
1602 int rest = strlen (s), len;
1603 unsigned char *p = (unsigned char *) s;
1604
1605 for (nchars = 0; rest > 0; ++nchars)
1606 {
1607 string_char_and_length (p, rest, &len);
1608 rest -= len, p += len;
1609 }
1610 }
1611 else
1612 nchars = strlen (s);
1613
1614 return nchars;
1615 }
1616
1617
1618 /* Compute byte position NEWPOS->bytepos corresponding to
1619 NEWPOS->charpos. POS is a known position in string STRING.
1620 NEWPOS->charpos must be >= POS.charpos. */
1621
1622 static void
1623 compute_string_pos (newpos, pos, string)
1624 struct text_pos *newpos, pos;
1625 Lisp_Object string;
1626 {
1627 xassert (STRINGP (string));
1628 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1629
1630 if (STRING_MULTIBYTE (string))
1631 *newpos = string_pos_nchars_ahead (pos, string,
1632 CHARPOS (*newpos) - CHARPOS (pos));
1633 else
1634 BYTEPOS (*newpos) = CHARPOS (*newpos);
1635 }
1636
1637 /* EXPORT:
1638 Return an estimation of the pixel height of mode or top lines on
1639 frame F. FACE_ID specifies what line's height to estimate. */
1640
1641 int
1642 estimate_mode_line_height (f, face_id)
1643 struct frame *f;
1644 enum face_id face_id;
1645 {
1646 #ifdef HAVE_WINDOW_SYSTEM
1647 if (FRAME_WINDOW_P (f))
1648 {
1649 int height = FONT_HEIGHT (FRAME_FONT (f));
1650
1651 /* This function is called so early when Emacs starts that the face
1652 cache and mode line face are not yet initialized. */
1653 if (FRAME_FACE_CACHE (f))
1654 {
1655 struct face *face = FACE_FROM_ID (f, face_id);
1656 if (face)
1657 {
1658 if (face->font)
1659 height = FONT_HEIGHT (face->font);
1660 if (face->box_line_width > 0)
1661 height += 2 * face->box_line_width;
1662 }
1663 }
1664
1665 return height;
1666 }
1667 #endif
1668
1669 return 1;
1670 }
1671
1672 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1673 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1674 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1675 not force the value into range. */
1676
1677 void
1678 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1679 FRAME_PTR f;
1680 register int pix_x, pix_y;
1681 int *x, *y;
1682 NativeRectangle *bounds;
1683 int noclip;
1684 {
1685
1686 #ifdef HAVE_WINDOW_SYSTEM
1687 if (FRAME_WINDOW_P (f))
1688 {
1689 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1690 even for negative values. */
1691 if (pix_x < 0)
1692 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1693 if (pix_y < 0)
1694 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1695
1696 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1697 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1698
1699 if (bounds)
1700 STORE_NATIVE_RECT (*bounds,
1701 FRAME_COL_TO_PIXEL_X (f, pix_x),
1702 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1703 FRAME_COLUMN_WIDTH (f) - 1,
1704 FRAME_LINE_HEIGHT (f) - 1);
1705
1706 if (!noclip)
1707 {
1708 if (pix_x < 0)
1709 pix_x = 0;
1710 else if (pix_x > FRAME_TOTAL_COLS (f))
1711 pix_x = FRAME_TOTAL_COLS (f);
1712
1713 if (pix_y < 0)
1714 pix_y = 0;
1715 else if (pix_y > FRAME_LINES (f))
1716 pix_y = FRAME_LINES (f);
1717 }
1718 }
1719 #endif
1720
1721 *x = pix_x;
1722 *y = pix_y;
1723 }
1724
1725
1726 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1727 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1728 can't tell the positions because W's display is not up to date,
1729 return 0. */
1730
1731 int
1732 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1733 struct window *w;
1734 int hpos, vpos;
1735 int *frame_x, *frame_y;
1736 {
1737 #ifdef HAVE_WINDOW_SYSTEM
1738 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1739 {
1740 int success_p;
1741
1742 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1743 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1744
1745 if (display_completed)
1746 {
1747 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1748 struct glyph *glyph = row->glyphs[TEXT_AREA];
1749 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1750
1751 hpos = row->x;
1752 vpos = row->y;
1753 while (glyph < end)
1754 {
1755 hpos += glyph->pixel_width;
1756 ++glyph;
1757 }
1758
1759 /* If first glyph is partially visible, its first visible position is still 0. */
1760 if (hpos < 0)
1761 hpos = 0;
1762
1763 success_p = 1;
1764 }
1765 else
1766 {
1767 hpos = vpos = 0;
1768 success_p = 0;
1769 }
1770
1771 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1772 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1773 return success_p;
1774 }
1775 #endif
1776
1777 *frame_x = hpos;
1778 *frame_y = vpos;
1779 return 1;
1780 }
1781
1782
1783 #ifdef HAVE_WINDOW_SYSTEM
1784
1785 /* Find the glyph under window-relative coordinates X/Y in window W.
1786 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1787 strings. Return in *HPOS and *VPOS the row and column number of
1788 the glyph found. Return in *AREA the glyph area containing X.
1789 Value is a pointer to the glyph found or null if X/Y is not on
1790 text, or we can't tell because W's current matrix is not up to
1791 date. */
1792
1793 static
1794 struct glyph *
1795 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1796 struct window *w;
1797 int x, y;
1798 int *hpos, *vpos, *dx, *dy, *area;
1799 {
1800 struct glyph *glyph, *end;
1801 struct glyph_row *row = NULL;
1802 int x0, i;
1803
1804 /* Find row containing Y. Give up if some row is not enabled. */
1805 for (i = 0; i < w->current_matrix->nrows; ++i)
1806 {
1807 row = MATRIX_ROW (w->current_matrix, i);
1808 if (!row->enabled_p)
1809 return NULL;
1810 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1811 break;
1812 }
1813
1814 *vpos = i;
1815 *hpos = 0;
1816
1817 /* Give up if Y is not in the window. */
1818 if (i == w->current_matrix->nrows)
1819 return NULL;
1820
1821 /* Get the glyph area containing X. */
1822 if (w->pseudo_window_p)
1823 {
1824 *area = TEXT_AREA;
1825 x0 = 0;
1826 }
1827 else
1828 {
1829 if (x < window_box_left_offset (w, TEXT_AREA))
1830 {
1831 *area = LEFT_MARGIN_AREA;
1832 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1833 }
1834 else if (x < window_box_right_offset (w, TEXT_AREA))
1835 {
1836 *area = TEXT_AREA;
1837 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1838 }
1839 else
1840 {
1841 *area = RIGHT_MARGIN_AREA;
1842 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1843 }
1844 }
1845
1846 /* Find glyph containing X. */
1847 glyph = row->glyphs[*area];
1848 end = glyph + row->used[*area];
1849 x -= x0;
1850 while (glyph < end && x >= glyph->pixel_width)
1851 {
1852 x -= glyph->pixel_width;
1853 ++glyph;
1854 }
1855
1856 if (glyph == end)
1857 return NULL;
1858
1859 if (dx)
1860 {
1861 *dx = x;
1862 *dy = y - (row->y + row->ascent - glyph->ascent);
1863 }
1864
1865 *hpos = glyph - row->glyphs[*area];
1866 return glyph;
1867 }
1868
1869
1870 /* EXPORT:
1871 Convert frame-relative x/y to coordinates relative to window W.
1872 Takes pseudo-windows into account. */
1873
1874 void
1875 frame_to_window_pixel_xy (w, x, y)
1876 struct window *w;
1877 int *x, *y;
1878 {
1879 if (w->pseudo_window_p)
1880 {
1881 /* A pseudo-window is always full-width, and starts at the
1882 left edge of the frame, plus a frame border. */
1883 struct frame *f = XFRAME (w->frame);
1884 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1885 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1886 }
1887 else
1888 {
1889 *x -= WINDOW_LEFT_EDGE_X (w);
1890 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1891 }
1892 }
1893
1894 /* EXPORT:
1895 Return in RECTS[] at most N clipping rectangles for glyph string S.
1896 Return the number of stored rectangles. */
1897
1898 int
1899 get_glyph_string_clip_rects (s, rects, n)
1900 struct glyph_string *s;
1901 NativeRectangle *rects;
1902 int n;
1903 {
1904 XRectangle r;
1905
1906 if (n <= 0)
1907 return 0;
1908
1909 if (s->row->full_width_p)
1910 {
1911 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1912 r.x = WINDOW_LEFT_EDGE_X (s->w);
1913 r.width = WINDOW_TOTAL_WIDTH (s->w);
1914
1915 /* Unless displaying a mode or menu bar line, which are always
1916 fully visible, clip to the visible part of the row. */
1917 if (s->w->pseudo_window_p)
1918 r.height = s->row->visible_height;
1919 else
1920 r.height = s->height;
1921 }
1922 else
1923 {
1924 /* This is a text line that may be partially visible. */
1925 r.x = window_box_left (s->w, s->area);
1926 r.width = window_box_width (s->w, s->area);
1927 r.height = s->row->visible_height;
1928 }
1929
1930 if (s->clip_head)
1931 if (r.x < s->clip_head->x)
1932 {
1933 if (r.width >= s->clip_head->x - r.x)
1934 r.width -= s->clip_head->x - r.x;
1935 else
1936 r.width = 0;
1937 r.x = s->clip_head->x;
1938 }
1939 if (s->clip_tail)
1940 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1941 {
1942 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1943 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1944 else
1945 r.width = 0;
1946 }
1947
1948 /* If S draws overlapping rows, it's sufficient to use the top and
1949 bottom of the window for clipping because this glyph string
1950 intentionally draws over other lines. */
1951 if (s->for_overlaps)
1952 {
1953 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1954 r.height = window_text_bottom_y (s->w) - r.y;
1955
1956 /* Alas, the above simple strategy does not work for the
1957 environments with anti-aliased text: if the same text is
1958 drawn onto the same place multiple times, it gets thicker.
1959 If the overlap we are processing is for the erased cursor, we
1960 take the intersection with the rectagle of the cursor. */
1961 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1962 {
1963 XRectangle rc, r_save = r;
1964
1965 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1966 rc.y = s->w->phys_cursor.y;
1967 rc.width = s->w->phys_cursor_width;
1968 rc.height = s->w->phys_cursor_height;
1969
1970 x_intersect_rectangles (&r_save, &rc, &r);
1971 }
1972 }
1973 else
1974 {
1975 /* Don't use S->y for clipping because it doesn't take partially
1976 visible lines into account. For example, it can be negative for
1977 partially visible lines at the top of a window. */
1978 if (!s->row->full_width_p
1979 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1980 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1981 else
1982 r.y = max (0, s->row->y);
1983
1984 /* If drawing a tool-bar window, draw it over the internal border
1985 at the top of the window. */
1986 if (WINDOWP (s->f->tool_bar_window)
1987 && s->w == XWINDOW (s->f->tool_bar_window))
1988 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1989 }
1990
1991 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1992
1993 /* If drawing the cursor, don't let glyph draw outside its
1994 advertised boundaries. Cleartype does this under some circumstances. */
1995 if (s->hl == DRAW_CURSOR)
1996 {
1997 struct glyph *glyph = s->first_glyph;
1998 int height, max_y;
1999
2000 if (s->x > r.x)
2001 {
2002 r.width -= s->x - r.x;
2003 r.x = s->x;
2004 }
2005 r.width = min (r.width, glyph->pixel_width);
2006
2007 /* If r.y is below window bottom, ensure that we still see a cursor. */
2008 height = min (glyph->ascent + glyph->descent,
2009 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2010 max_y = window_text_bottom_y (s->w) - height;
2011 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2012 if (s->ybase - glyph->ascent > max_y)
2013 {
2014 r.y = max_y;
2015 r.height = height;
2016 }
2017 else
2018 {
2019 /* Don't draw cursor glyph taller than our actual glyph. */
2020 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2021 if (height < r.height)
2022 {
2023 max_y = r.y + r.height;
2024 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2025 r.height = min (max_y - r.y, height);
2026 }
2027 }
2028 }
2029
2030 if (s->row->clip)
2031 {
2032 XRectangle r_save = r;
2033
2034 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2035 r.width = 0;
2036 }
2037
2038 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2039 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2040 {
2041 #ifdef CONVERT_FROM_XRECT
2042 CONVERT_FROM_XRECT (r, *rects);
2043 #else
2044 *rects = r;
2045 #endif
2046 return 1;
2047 }
2048 else
2049 {
2050 /* If we are processing overlapping and allowed to return
2051 multiple clipping rectangles, we exclude the row of the glyph
2052 string from the clipping rectangle. This is to avoid drawing
2053 the same text on the environment with anti-aliasing. */
2054 #ifdef CONVERT_FROM_XRECT
2055 XRectangle rs[2];
2056 #else
2057 XRectangle *rs = rects;
2058 #endif
2059 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2060
2061 if (s->for_overlaps & OVERLAPS_PRED)
2062 {
2063 rs[i] = r;
2064 if (r.y + r.height > row_y)
2065 {
2066 if (r.y < row_y)
2067 rs[i].height = row_y - r.y;
2068 else
2069 rs[i].height = 0;
2070 }
2071 i++;
2072 }
2073 if (s->for_overlaps & OVERLAPS_SUCC)
2074 {
2075 rs[i] = r;
2076 if (r.y < row_y + s->row->visible_height)
2077 {
2078 if (r.y + r.height > row_y + s->row->visible_height)
2079 {
2080 rs[i].y = row_y + s->row->visible_height;
2081 rs[i].height = r.y + r.height - rs[i].y;
2082 }
2083 else
2084 rs[i].height = 0;
2085 }
2086 i++;
2087 }
2088
2089 n = i;
2090 #ifdef CONVERT_FROM_XRECT
2091 for (i = 0; i < n; i++)
2092 CONVERT_FROM_XRECT (rs[i], rects[i]);
2093 #endif
2094 return n;
2095 }
2096 }
2097
2098 /* EXPORT:
2099 Return in *NR the clipping rectangle for glyph string S. */
2100
2101 void
2102 get_glyph_string_clip_rect (s, nr)
2103 struct glyph_string *s;
2104 NativeRectangle *nr;
2105 {
2106 get_glyph_string_clip_rects (s, nr, 1);
2107 }
2108
2109
2110 /* EXPORT:
2111 Return the position and height of the phys cursor in window W.
2112 Set w->phys_cursor_width to width of phys cursor.
2113 */
2114
2115 void
2116 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2117 struct window *w;
2118 struct glyph_row *row;
2119 struct glyph *glyph;
2120 int *xp, *yp, *heightp;
2121 {
2122 struct frame *f = XFRAME (WINDOW_FRAME (w));
2123 int x, y, wd, h, h0, y0;
2124
2125 /* Compute the width of the rectangle to draw. If on a stretch
2126 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2127 rectangle as wide as the glyph, but use a canonical character
2128 width instead. */
2129 wd = glyph->pixel_width - 1;
2130 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2131 wd++; /* Why? */
2132 #endif
2133
2134 x = w->phys_cursor.x;
2135 if (x < 0)
2136 {
2137 wd += x;
2138 x = 0;
2139 }
2140
2141 if (glyph->type == STRETCH_GLYPH
2142 && !x_stretch_cursor_p)
2143 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2144 w->phys_cursor_width = wd;
2145
2146 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2147
2148 /* If y is below window bottom, ensure that we still see a cursor. */
2149 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2150
2151 h = max (h0, glyph->ascent + glyph->descent);
2152 h0 = min (h0, glyph->ascent + glyph->descent);
2153
2154 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2155 if (y < y0)
2156 {
2157 h = max (h - (y0 - y) + 1, h0);
2158 y = y0 - 1;
2159 }
2160 else
2161 {
2162 y0 = window_text_bottom_y (w) - h0;
2163 if (y > y0)
2164 {
2165 h += y - y0;
2166 y = y0;
2167 }
2168 }
2169
2170 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2171 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2172 *heightp = h;
2173 }
2174
2175 /*
2176 * Remember which glyph the mouse is over.
2177 */
2178
2179 void
2180 remember_mouse_glyph (f, gx, gy, rect)
2181 struct frame *f;
2182 int gx, gy;
2183 NativeRectangle *rect;
2184 {
2185 Lisp_Object window;
2186 struct window *w;
2187 struct glyph_row *r, *gr, *end_row;
2188 enum window_part part;
2189 enum glyph_row_area area;
2190 int x, y, width, height;
2191
2192 /* Try to determine frame pixel position and size of the glyph under
2193 frame pixel coordinates X/Y on frame F. */
2194
2195 if (!f->glyphs_initialized_p
2196 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2197 NILP (window)))
2198 {
2199 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2200 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2201 goto virtual_glyph;
2202 }
2203
2204 w = XWINDOW (window);
2205 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2206 height = WINDOW_FRAME_LINE_HEIGHT (w);
2207
2208 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2209 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2210
2211 if (w->pseudo_window_p)
2212 {
2213 area = TEXT_AREA;
2214 part = ON_MODE_LINE; /* Don't adjust margin. */
2215 goto text_glyph;
2216 }
2217
2218 switch (part)
2219 {
2220 case ON_LEFT_MARGIN:
2221 area = LEFT_MARGIN_AREA;
2222 goto text_glyph;
2223
2224 case ON_RIGHT_MARGIN:
2225 area = RIGHT_MARGIN_AREA;
2226 goto text_glyph;
2227
2228 case ON_HEADER_LINE:
2229 case ON_MODE_LINE:
2230 gr = (part == ON_HEADER_LINE
2231 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2232 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2233 gy = gr->y;
2234 area = TEXT_AREA;
2235 goto text_glyph_row_found;
2236
2237 case ON_TEXT:
2238 area = TEXT_AREA;
2239
2240 text_glyph:
2241 gr = 0; gy = 0;
2242 for (; r <= end_row && r->enabled_p; ++r)
2243 if (r->y + r->height > y)
2244 {
2245 gr = r; gy = r->y;
2246 break;
2247 }
2248
2249 text_glyph_row_found:
2250 if (gr && gy <= y)
2251 {
2252 struct glyph *g = gr->glyphs[area];
2253 struct glyph *end = g + gr->used[area];
2254
2255 height = gr->height;
2256 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2257 if (gx + g->pixel_width > x)
2258 break;
2259
2260 if (g < end)
2261 {
2262 if (g->type == IMAGE_GLYPH)
2263 {
2264 /* Don't remember when mouse is over image, as
2265 image may have hot-spots. */
2266 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2267 return;
2268 }
2269 width = g->pixel_width;
2270 }
2271 else
2272 {
2273 /* Use nominal char spacing at end of line. */
2274 x -= gx;
2275 gx += (x / width) * width;
2276 }
2277
2278 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2279 gx += window_box_left_offset (w, area);
2280 }
2281 else
2282 {
2283 /* Use nominal line height at end of window. */
2284 gx = (x / width) * width;
2285 y -= gy;
2286 gy += (y / height) * height;
2287 }
2288 break;
2289
2290 case ON_LEFT_FRINGE:
2291 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2292 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2293 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2294 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2295 goto row_glyph;
2296
2297 case ON_RIGHT_FRINGE:
2298 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2299 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2300 : window_box_right_offset (w, TEXT_AREA));
2301 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2302 goto row_glyph;
2303
2304 case ON_SCROLL_BAR:
2305 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2306 ? 0
2307 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2308 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2309 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2310 : 0)));
2311 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2312
2313 row_glyph:
2314 gr = 0, gy = 0;
2315 for (; r <= end_row && r->enabled_p; ++r)
2316 if (r->y + r->height > y)
2317 {
2318 gr = r; gy = r->y;
2319 break;
2320 }
2321
2322 if (gr && gy <= y)
2323 height = gr->height;
2324 else
2325 {
2326 /* Use nominal line height at end of window. */
2327 y -= gy;
2328 gy += (y / height) * height;
2329 }
2330 break;
2331
2332 default:
2333 ;
2334 virtual_glyph:
2335 /* If there is no glyph under the mouse, then we divide the screen
2336 into a grid of the smallest glyph in the frame, and use that
2337 as our "glyph". */
2338
2339 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2340 round down even for negative values. */
2341 if (gx < 0)
2342 gx -= width - 1;
2343 if (gy < 0)
2344 gy -= height - 1;
2345
2346 gx = (gx / width) * width;
2347 gy = (gy / height) * height;
2348
2349 goto store_rect;
2350 }
2351
2352 gx += WINDOW_LEFT_EDGE_X (w);
2353 gy += WINDOW_TOP_EDGE_Y (w);
2354
2355 store_rect:
2356 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2357
2358 /* Visible feedback for debugging. */
2359 #if 0
2360 #if HAVE_X_WINDOWS
2361 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2362 f->output_data.x->normal_gc,
2363 gx, gy, width, height);
2364 #endif
2365 #endif
2366 }
2367
2368
2369 #endif /* HAVE_WINDOW_SYSTEM */
2370
2371 \f
2372 /***********************************************************************
2373 Lisp form evaluation
2374 ***********************************************************************/
2375
2376 /* Error handler for safe_eval and safe_call. */
2377
2378 static Lisp_Object
2379 safe_eval_handler (arg)
2380 Lisp_Object arg;
2381 {
2382 add_to_log ("Error during redisplay: %s", arg, Qnil);
2383 return Qnil;
2384 }
2385
2386
2387 /* Evaluate SEXPR and return the result, or nil if something went
2388 wrong. Prevent redisplay during the evaluation. */
2389
2390 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2391 Return the result, or nil if something went wrong. Prevent
2392 redisplay during the evaluation. */
2393
2394 Lisp_Object
2395 safe_call (nargs, args)
2396 int nargs;
2397 Lisp_Object *args;
2398 {
2399 Lisp_Object val;
2400
2401 if (inhibit_eval_during_redisplay)
2402 val = Qnil;
2403 else
2404 {
2405 int count = SPECPDL_INDEX ();
2406 struct gcpro gcpro1;
2407
2408 GCPRO1 (args[0]);
2409 gcpro1.nvars = nargs;
2410 specbind (Qinhibit_redisplay, Qt);
2411 /* Use Qt to ensure debugger does not run,
2412 so there is no possibility of wanting to redisplay. */
2413 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2414 safe_eval_handler);
2415 UNGCPRO;
2416 val = unbind_to (count, val);
2417 }
2418
2419 return val;
2420 }
2421
2422
2423 /* Call function FN with one argument ARG.
2424 Return the result, or nil if something went wrong. */
2425
2426 Lisp_Object
2427 safe_call1 (fn, arg)
2428 Lisp_Object fn, arg;
2429 {
2430 Lisp_Object args[2];
2431 args[0] = fn;
2432 args[1] = arg;
2433 return safe_call (2, args);
2434 }
2435
2436 static Lisp_Object Qeval;
2437
2438 Lisp_Object
2439 safe_eval (Lisp_Object sexpr)
2440 {
2441 return safe_call1 (Qeval, sexpr);
2442 }
2443
2444 /* Call function FN with one argument ARG.
2445 Return the result, or nil if something went wrong. */
2446
2447 Lisp_Object
2448 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2449 {
2450 Lisp_Object args[3];
2451 args[0] = fn;
2452 args[1] = arg1;
2453 args[2] = arg2;
2454 return safe_call (3, args);
2455 }
2456
2457
2458 \f
2459 /***********************************************************************
2460 Debugging
2461 ***********************************************************************/
2462
2463 #if 0
2464
2465 /* Define CHECK_IT to perform sanity checks on iterators.
2466 This is for debugging. It is too slow to do unconditionally. */
2467
2468 static void
2469 check_it (it)
2470 struct it *it;
2471 {
2472 if (it->method == GET_FROM_STRING)
2473 {
2474 xassert (STRINGP (it->string));
2475 xassert (IT_STRING_CHARPOS (*it) >= 0);
2476 }
2477 else
2478 {
2479 xassert (IT_STRING_CHARPOS (*it) < 0);
2480 if (it->method == GET_FROM_BUFFER)
2481 {
2482 /* Check that character and byte positions agree. */
2483 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2484 }
2485 }
2486
2487 if (it->dpvec)
2488 xassert (it->current.dpvec_index >= 0);
2489 else
2490 xassert (it->current.dpvec_index < 0);
2491 }
2492
2493 #define CHECK_IT(IT) check_it ((IT))
2494
2495 #else /* not 0 */
2496
2497 #define CHECK_IT(IT) (void) 0
2498
2499 #endif /* not 0 */
2500
2501
2502 #if GLYPH_DEBUG
2503
2504 /* Check that the window end of window W is what we expect it
2505 to be---the last row in the current matrix displaying text. */
2506
2507 static void
2508 check_window_end (w)
2509 struct window *w;
2510 {
2511 if (!MINI_WINDOW_P (w)
2512 && !NILP (w->window_end_valid))
2513 {
2514 struct glyph_row *row;
2515 xassert ((row = MATRIX_ROW (w->current_matrix,
2516 XFASTINT (w->window_end_vpos)),
2517 !row->enabled_p
2518 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2519 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2520 }
2521 }
2522
2523 #define CHECK_WINDOW_END(W) check_window_end ((W))
2524
2525 #else /* not GLYPH_DEBUG */
2526
2527 #define CHECK_WINDOW_END(W) (void) 0
2528
2529 #endif /* not GLYPH_DEBUG */
2530
2531
2532 \f
2533 /***********************************************************************
2534 Iterator initialization
2535 ***********************************************************************/
2536
2537 /* Initialize IT for displaying current_buffer in window W, starting
2538 at character position CHARPOS. CHARPOS < 0 means that no buffer
2539 position is specified which is useful when the iterator is assigned
2540 a position later. BYTEPOS is the byte position corresponding to
2541 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2542
2543 If ROW is not null, calls to produce_glyphs with IT as parameter
2544 will produce glyphs in that row.
2545
2546 BASE_FACE_ID is the id of a base face to use. It must be one of
2547 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2548 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2549 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2550
2551 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2552 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2553 will be initialized to use the corresponding mode line glyph row of
2554 the desired matrix of W. */
2555
2556 void
2557 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2558 struct it *it;
2559 struct window *w;
2560 int charpos, bytepos;
2561 struct glyph_row *row;
2562 enum face_id base_face_id;
2563 {
2564 int highlight_region_p;
2565 enum face_id remapped_base_face_id = base_face_id;
2566
2567 /* Some precondition checks. */
2568 xassert (w != NULL && it != NULL);
2569 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2570 && charpos <= ZV));
2571
2572 /* If face attributes have been changed since the last redisplay,
2573 free realized faces now because they depend on face definitions
2574 that might have changed. Don't free faces while there might be
2575 desired matrices pending which reference these faces. */
2576 if (face_change_count && !inhibit_free_realized_faces)
2577 {
2578 face_change_count = 0;
2579 free_all_realized_faces (Qnil);
2580 }
2581
2582 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2583 if (! NILP (Vface_remapping_alist))
2584 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2585
2586 /* Use one of the mode line rows of W's desired matrix if
2587 appropriate. */
2588 if (row == NULL)
2589 {
2590 if (base_face_id == MODE_LINE_FACE_ID
2591 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2592 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2593 else if (base_face_id == HEADER_LINE_FACE_ID)
2594 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2595 }
2596
2597 /* Clear IT. */
2598 bzero (it, sizeof *it);
2599 it->current.overlay_string_index = -1;
2600 it->current.dpvec_index = -1;
2601 it->base_face_id = remapped_base_face_id;
2602 it->string = Qnil;
2603 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2604
2605 /* The window in which we iterate over current_buffer: */
2606 XSETWINDOW (it->window, w);
2607 it->w = w;
2608 it->f = XFRAME (w->frame);
2609
2610 it->cmp_it.id = -1;
2611
2612 /* Extra space between lines (on window systems only). */
2613 if (base_face_id == DEFAULT_FACE_ID
2614 && FRAME_WINDOW_P (it->f))
2615 {
2616 if (NATNUMP (current_buffer->extra_line_spacing))
2617 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2618 else if (FLOATP (current_buffer->extra_line_spacing))
2619 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2620 * FRAME_LINE_HEIGHT (it->f));
2621 else if (it->f->extra_line_spacing > 0)
2622 it->extra_line_spacing = it->f->extra_line_spacing;
2623 it->max_extra_line_spacing = 0;
2624 }
2625
2626 /* If realized faces have been removed, e.g. because of face
2627 attribute changes of named faces, recompute them. When running
2628 in batch mode, the face cache of the initial frame is null. If
2629 we happen to get called, make a dummy face cache. */
2630 if (FRAME_FACE_CACHE (it->f) == NULL)
2631 init_frame_faces (it->f);
2632 if (FRAME_FACE_CACHE (it->f)->used == 0)
2633 recompute_basic_faces (it->f);
2634
2635 /* Current value of the `slice', `space-width', and 'height' properties. */
2636 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2637 it->space_width = Qnil;
2638 it->font_height = Qnil;
2639 it->override_ascent = -1;
2640
2641 /* Are control characters displayed as `^C'? */
2642 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2643
2644 /* -1 means everything between a CR and the following line end
2645 is invisible. >0 means lines indented more than this value are
2646 invisible. */
2647 it->selective = (INTEGERP (current_buffer->selective_display)
2648 ? XFASTINT (current_buffer->selective_display)
2649 : (!NILP (current_buffer->selective_display)
2650 ? -1 : 0));
2651 it->selective_display_ellipsis_p
2652 = !NILP (current_buffer->selective_display_ellipses);
2653
2654 /* Display table to use. */
2655 it->dp = window_display_table (w);
2656
2657 /* Are multibyte characters enabled in current_buffer? */
2658 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2659
2660 /* Non-zero if we should highlight the region. */
2661 highlight_region_p
2662 = (!NILP (Vtransient_mark_mode)
2663 && !NILP (current_buffer->mark_active)
2664 && XMARKER (current_buffer->mark)->buffer != 0);
2665
2666 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2667 start and end of a visible region in window IT->w. Set both to
2668 -1 to indicate no region. */
2669 if (highlight_region_p
2670 /* Maybe highlight only in selected window. */
2671 && (/* Either show region everywhere. */
2672 highlight_nonselected_windows
2673 /* Or show region in the selected window. */
2674 || w == XWINDOW (selected_window)
2675 /* Or show the region if we are in the mini-buffer and W is
2676 the window the mini-buffer refers to. */
2677 || (MINI_WINDOW_P (XWINDOW (selected_window))
2678 && WINDOWP (minibuf_selected_window)
2679 && w == XWINDOW (minibuf_selected_window))))
2680 {
2681 int charpos = marker_position (current_buffer->mark);
2682 it->region_beg_charpos = min (PT, charpos);
2683 it->region_end_charpos = max (PT, charpos);
2684 }
2685 else
2686 it->region_beg_charpos = it->region_end_charpos = -1;
2687
2688 /* Get the position at which the redisplay_end_trigger hook should
2689 be run, if it is to be run at all. */
2690 if (MARKERP (w->redisplay_end_trigger)
2691 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2692 it->redisplay_end_trigger_charpos
2693 = marker_position (w->redisplay_end_trigger);
2694 else if (INTEGERP (w->redisplay_end_trigger))
2695 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2696
2697 /* Correct bogus values of tab_width. */
2698 it->tab_width = XINT (current_buffer->tab_width);
2699 if (it->tab_width <= 0 || it->tab_width > 1000)
2700 it->tab_width = 8;
2701
2702 /* Are lines in the display truncated? */
2703 if (base_face_id != DEFAULT_FACE_ID
2704 || XINT (it->w->hscroll)
2705 || (! WINDOW_FULL_WIDTH_P (it->w)
2706 && ((!NILP (Vtruncate_partial_width_windows)
2707 && !INTEGERP (Vtruncate_partial_width_windows))
2708 || (INTEGERP (Vtruncate_partial_width_windows)
2709 && (WINDOW_TOTAL_COLS (it->w)
2710 < XINT (Vtruncate_partial_width_windows))))))
2711 it->line_wrap = TRUNCATE;
2712 else if (NILP (current_buffer->truncate_lines))
2713 it->line_wrap = NILP (current_buffer->word_wrap)
2714 ? WINDOW_WRAP : WORD_WRAP;
2715 else
2716 it->line_wrap = TRUNCATE;
2717
2718 /* Get dimensions of truncation and continuation glyphs. These are
2719 displayed as fringe bitmaps under X, so we don't need them for such
2720 frames. */
2721 if (!FRAME_WINDOW_P (it->f))
2722 {
2723 if (it->line_wrap == TRUNCATE)
2724 {
2725 /* We will need the truncation glyph. */
2726 xassert (it->glyph_row == NULL);
2727 produce_special_glyphs (it, IT_TRUNCATION);
2728 it->truncation_pixel_width = it->pixel_width;
2729 }
2730 else
2731 {
2732 /* We will need the continuation glyph. */
2733 xassert (it->glyph_row == NULL);
2734 produce_special_glyphs (it, IT_CONTINUATION);
2735 it->continuation_pixel_width = it->pixel_width;
2736 }
2737
2738 /* Reset these values to zero because the produce_special_glyphs
2739 above has changed them. */
2740 it->pixel_width = it->ascent = it->descent = 0;
2741 it->phys_ascent = it->phys_descent = 0;
2742 }
2743
2744 /* Set this after getting the dimensions of truncation and
2745 continuation glyphs, so that we don't produce glyphs when calling
2746 produce_special_glyphs, above. */
2747 it->glyph_row = row;
2748 it->area = TEXT_AREA;
2749
2750 /* Get the dimensions of the display area. The display area
2751 consists of the visible window area plus a horizontally scrolled
2752 part to the left of the window. All x-values are relative to the
2753 start of this total display area. */
2754 if (base_face_id != DEFAULT_FACE_ID)
2755 {
2756 /* Mode lines, menu bar in terminal frames. */
2757 it->first_visible_x = 0;
2758 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2759 }
2760 else
2761 {
2762 it->first_visible_x
2763 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2764 it->last_visible_x = (it->first_visible_x
2765 + window_box_width (w, TEXT_AREA));
2766
2767 /* If we truncate lines, leave room for the truncator glyph(s) at
2768 the right margin. Otherwise, leave room for the continuation
2769 glyph(s). Truncation and continuation glyphs are not inserted
2770 for window-based redisplay. */
2771 if (!FRAME_WINDOW_P (it->f))
2772 {
2773 if (it->line_wrap == TRUNCATE)
2774 it->last_visible_x -= it->truncation_pixel_width;
2775 else
2776 it->last_visible_x -= it->continuation_pixel_width;
2777 }
2778
2779 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2780 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2781 }
2782
2783 /* Leave room for a border glyph. */
2784 if (!FRAME_WINDOW_P (it->f)
2785 && !WINDOW_RIGHTMOST_P (it->w))
2786 it->last_visible_x -= 1;
2787
2788 it->last_visible_y = window_text_bottom_y (w);
2789
2790 /* For mode lines and alike, arrange for the first glyph having a
2791 left box line if the face specifies a box. */
2792 if (base_face_id != DEFAULT_FACE_ID)
2793 {
2794 struct face *face;
2795
2796 it->face_id = remapped_base_face_id;
2797
2798 /* If we have a boxed mode line, make the first character appear
2799 with a left box line. */
2800 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2801 if (face->box != FACE_NO_BOX)
2802 it->start_of_box_run_p = 1;
2803 }
2804
2805 /* If a buffer position was specified, set the iterator there,
2806 getting overlays and face properties from that position. */
2807 if (charpos >= BUF_BEG (current_buffer))
2808 {
2809 it->end_charpos = ZV;
2810 it->face_id = -1;
2811 IT_CHARPOS (*it) = charpos;
2812
2813 /* Compute byte position if not specified. */
2814 if (bytepos < charpos)
2815 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2816 else
2817 IT_BYTEPOS (*it) = bytepos;
2818
2819 it->start = it->current;
2820
2821 /* Compute faces etc. */
2822 reseat (it, it->current.pos, 1);
2823 }
2824
2825 CHECK_IT (it);
2826 }
2827
2828
2829 /* Initialize IT for the display of window W with window start POS. */
2830
2831 void
2832 start_display (it, w, pos)
2833 struct it *it;
2834 struct window *w;
2835 struct text_pos pos;
2836 {
2837 struct glyph_row *row;
2838 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2839
2840 row = w->desired_matrix->rows + first_vpos;
2841 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2842 it->first_vpos = first_vpos;
2843
2844 /* Don't reseat to previous visible line start if current start
2845 position is in a string or image. */
2846 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2847 {
2848 int start_at_line_beg_p;
2849 int first_y = it->current_y;
2850
2851 /* If window start is not at a line start, skip forward to POS to
2852 get the correct continuation lines width. */
2853 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2854 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2855 if (!start_at_line_beg_p)
2856 {
2857 int new_x;
2858
2859 reseat_at_previous_visible_line_start (it);
2860 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2861
2862 new_x = it->current_x + it->pixel_width;
2863
2864 /* If lines are continued, this line may end in the middle
2865 of a multi-glyph character (e.g. a control character
2866 displayed as \003, or in the middle of an overlay
2867 string). In this case move_it_to above will not have
2868 taken us to the start of the continuation line but to the
2869 end of the continued line. */
2870 if (it->current_x > 0
2871 && it->line_wrap != TRUNCATE /* Lines are continued. */
2872 && (/* And glyph doesn't fit on the line. */
2873 new_x > it->last_visible_x
2874 /* Or it fits exactly and we're on a window
2875 system frame. */
2876 || (new_x == it->last_visible_x
2877 && FRAME_WINDOW_P (it->f))))
2878 {
2879 if (it->current.dpvec_index >= 0
2880 || it->current.overlay_string_index >= 0)
2881 {
2882 set_iterator_to_next (it, 1);
2883 move_it_in_display_line_to (it, -1, -1, 0);
2884 }
2885
2886 it->continuation_lines_width += it->current_x;
2887 }
2888
2889 /* We're starting a new display line, not affected by the
2890 height of the continued line, so clear the appropriate
2891 fields in the iterator structure. */
2892 it->max_ascent = it->max_descent = 0;
2893 it->max_phys_ascent = it->max_phys_descent = 0;
2894
2895 it->current_y = first_y;
2896 it->vpos = 0;
2897 it->current_x = it->hpos = 0;
2898 }
2899 }
2900 }
2901
2902
2903 /* Return 1 if POS is a position in ellipses displayed for invisible
2904 text. W is the window we display, for text property lookup. */
2905
2906 static int
2907 in_ellipses_for_invisible_text_p (pos, w)
2908 struct display_pos *pos;
2909 struct window *w;
2910 {
2911 Lisp_Object prop, window;
2912 int ellipses_p = 0;
2913 int charpos = CHARPOS (pos->pos);
2914
2915 /* If POS specifies a position in a display vector, this might
2916 be for an ellipsis displayed for invisible text. We won't
2917 get the iterator set up for delivering that ellipsis unless
2918 we make sure that it gets aware of the invisible text. */
2919 if (pos->dpvec_index >= 0
2920 && pos->overlay_string_index < 0
2921 && CHARPOS (pos->string_pos) < 0
2922 && charpos > BEGV
2923 && (XSETWINDOW (window, w),
2924 prop = Fget_char_property (make_number (charpos),
2925 Qinvisible, window),
2926 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2927 {
2928 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2929 window);
2930 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2931 }
2932
2933 return ellipses_p;
2934 }
2935
2936
2937 /* Initialize IT for stepping through current_buffer in window W,
2938 starting at position POS that includes overlay string and display
2939 vector/ control character translation position information. Value
2940 is zero if there are overlay strings with newlines at POS. */
2941
2942 static int
2943 init_from_display_pos (it, w, pos)
2944 struct it *it;
2945 struct window *w;
2946 struct display_pos *pos;
2947 {
2948 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2949 int i, overlay_strings_with_newlines = 0;
2950
2951 /* If POS specifies a position in a display vector, this might
2952 be for an ellipsis displayed for invisible text. We won't
2953 get the iterator set up for delivering that ellipsis unless
2954 we make sure that it gets aware of the invisible text. */
2955 if (in_ellipses_for_invisible_text_p (pos, w))
2956 {
2957 --charpos;
2958 bytepos = 0;
2959 }
2960
2961 /* Keep in mind: the call to reseat in init_iterator skips invisible
2962 text, so we might end up at a position different from POS. This
2963 is only a problem when POS is a row start after a newline and an
2964 overlay starts there with an after-string, and the overlay has an
2965 invisible property. Since we don't skip invisible text in
2966 display_line and elsewhere immediately after consuming the
2967 newline before the row start, such a POS will not be in a string,
2968 but the call to init_iterator below will move us to the
2969 after-string. */
2970 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2971
2972 /* This only scans the current chunk -- it should scan all chunks.
2973 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2974 to 16 in 22.1 to make this a lesser problem. */
2975 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2976 {
2977 const char *s = SDATA (it->overlay_strings[i]);
2978 const char *e = s + SBYTES (it->overlay_strings[i]);
2979
2980 while (s < e && *s != '\n')
2981 ++s;
2982
2983 if (s < e)
2984 {
2985 overlay_strings_with_newlines = 1;
2986 break;
2987 }
2988 }
2989
2990 /* If position is within an overlay string, set up IT to the right
2991 overlay string. */
2992 if (pos->overlay_string_index >= 0)
2993 {
2994 int relative_index;
2995
2996 /* If the first overlay string happens to have a `display'
2997 property for an image, the iterator will be set up for that
2998 image, and we have to undo that setup first before we can
2999 correct the overlay string index. */
3000 if (it->method == GET_FROM_IMAGE)
3001 pop_it (it);
3002
3003 /* We already have the first chunk of overlay strings in
3004 IT->overlay_strings. Load more until the one for
3005 pos->overlay_string_index is in IT->overlay_strings. */
3006 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3007 {
3008 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3009 it->current.overlay_string_index = 0;
3010 while (n--)
3011 {
3012 load_overlay_strings (it, 0);
3013 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3014 }
3015 }
3016
3017 it->current.overlay_string_index = pos->overlay_string_index;
3018 relative_index = (it->current.overlay_string_index
3019 % OVERLAY_STRING_CHUNK_SIZE);
3020 it->string = it->overlay_strings[relative_index];
3021 xassert (STRINGP (it->string));
3022 it->current.string_pos = pos->string_pos;
3023 it->method = GET_FROM_STRING;
3024 }
3025
3026 if (CHARPOS (pos->string_pos) >= 0)
3027 {
3028 /* Recorded position is not in an overlay string, but in another
3029 string. This can only be a string from a `display' property.
3030 IT should already be filled with that string. */
3031 it->current.string_pos = pos->string_pos;
3032 xassert (STRINGP (it->string));
3033 }
3034
3035 /* Restore position in display vector translations, control
3036 character translations or ellipses. */
3037 if (pos->dpvec_index >= 0)
3038 {
3039 if (it->dpvec == NULL)
3040 get_next_display_element (it);
3041 xassert (it->dpvec && it->current.dpvec_index == 0);
3042 it->current.dpvec_index = pos->dpvec_index;
3043 }
3044
3045 CHECK_IT (it);
3046 return !overlay_strings_with_newlines;
3047 }
3048
3049
3050 /* Initialize IT for stepping through current_buffer in window W
3051 starting at ROW->start. */
3052
3053 static void
3054 init_to_row_start (it, w, row)
3055 struct it *it;
3056 struct window *w;
3057 struct glyph_row *row;
3058 {
3059 init_from_display_pos (it, w, &row->start);
3060 it->start = row->start;
3061 it->continuation_lines_width = row->continuation_lines_width;
3062 CHECK_IT (it);
3063 }
3064
3065
3066 /* Initialize IT for stepping through current_buffer in window W
3067 starting in the line following ROW, i.e. starting at ROW->end.
3068 Value is zero if there are overlay strings with newlines at ROW's
3069 end position. */
3070
3071 static int
3072 init_to_row_end (it, w, row)
3073 struct it *it;
3074 struct window *w;
3075 struct glyph_row *row;
3076 {
3077 int success = 0;
3078
3079 if (init_from_display_pos (it, w, &row->end))
3080 {
3081 if (row->continued_p)
3082 it->continuation_lines_width
3083 = row->continuation_lines_width + row->pixel_width;
3084 CHECK_IT (it);
3085 success = 1;
3086 }
3087
3088 return success;
3089 }
3090
3091
3092
3093 \f
3094 /***********************************************************************
3095 Text properties
3096 ***********************************************************************/
3097
3098 /* Called when IT reaches IT->stop_charpos. Handle text property and
3099 overlay changes. Set IT->stop_charpos to the next position where
3100 to stop. */
3101
3102 static void
3103 handle_stop (it)
3104 struct it *it;
3105 {
3106 enum prop_handled handled;
3107 int handle_overlay_change_p;
3108 struct props *p;
3109
3110 it->dpvec = NULL;
3111 it->current.dpvec_index = -1;
3112 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3113 it->ignore_overlay_strings_at_pos_p = 0;
3114 it->ellipsis_p = 0;
3115
3116 /* Use face of preceding text for ellipsis (if invisible) */
3117 if (it->selective_display_ellipsis_p)
3118 it->saved_face_id = it->face_id;
3119
3120 do
3121 {
3122 handled = HANDLED_NORMALLY;
3123
3124 /* Call text property handlers. */
3125 for (p = it_props; p->handler; ++p)
3126 {
3127 handled = p->handler (it);
3128
3129 if (handled == HANDLED_RECOMPUTE_PROPS)
3130 break;
3131 else if (handled == HANDLED_RETURN)
3132 {
3133 /* We still want to show before and after strings from
3134 overlays even if the actual buffer text is replaced. */
3135 if (!handle_overlay_change_p
3136 || it->sp > 1
3137 || !get_overlay_strings_1 (it, 0, 0))
3138 {
3139 if (it->ellipsis_p)
3140 setup_for_ellipsis (it, 0);
3141 /* When handling a display spec, we might load an
3142 empty string. In that case, discard it here. We
3143 used to discard it in handle_single_display_spec,
3144 but that causes get_overlay_strings_1, above, to
3145 ignore overlay strings that we must check. */
3146 if (STRINGP (it->string) && !SCHARS (it->string))
3147 pop_it (it);
3148 return;
3149 }
3150 else if (STRINGP (it->string) && !SCHARS (it->string))
3151 pop_it (it);
3152 else
3153 {
3154 it->ignore_overlay_strings_at_pos_p = 1;
3155 it->string_from_display_prop_p = 0;
3156 handle_overlay_change_p = 0;
3157 }
3158 handled = HANDLED_RECOMPUTE_PROPS;
3159 break;
3160 }
3161 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3162 handle_overlay_change_p = 0;
3163 }
3164
3165 if (handled != HANDLED_RECOMPUTE_PROPS)
3166 {
3167 /* Don't check for overlay strings below when set to deliver
3168 characters from a display vector. */
3169 if (it->method == GET_FROM_DISPLAY_VECTOR)
3170 handle_overlay_change_p = 0;
3171
3172 /* Handle overlay changes.
3173 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3174 if it finds overlays. */
3175 if (handle_overlay_change_p)
3176 handled = handle_overlay_change (it);
3177 }
3178
3179 if (it->ellipsis_p)
3180 {
3181 setup_for_ellipsis (it, 0);
3182 break;
3183 }
3184 }
3185 while (handled == HANDLED_RECOMPUTE_PROPS);
3186
3187 /* Determine where to stop next. */
3188 if (handled == HANDLED_NORMALLY)
3189 compute_stop_pos (it);
3190 }
3191
3192
3193 /* Compute IT->stop_charpos from text property and overlay change
3194 information for IT's current position. */
3195
3196 static void
3197 compute_stop_pos (it)
3198 struct it *it;
3199 {
3200 register INTERVAL iv, next_iv;
3201 Lisp_Object object, limit, position;
3202 EMACS_INT charpos, bytepos;
3203
3204 /* If nowhere else, stop at the end. */
3205 it->stop_charpos = it->end_charpos;
3206
3207 if (STRINGP (it->string))
3208 {
3209 /* Strings are usually short, so don't limit the search for
3210 properties. */
3211 object = it->string;
3212 limit = Qnil;
3213 charpos = IT_STRING_CHARPOS (*it);
3214 bytepos = IT_STRING_BYTEPOS (*it);
3215 }
3216 else
3217 {
3218 EMACS_INT pos;
3219
3220 /* If next overlay change is in front of the current stop pos
3221 (which is IT->end_charpos), stop there. Note: value of
3222 next_overlay_change is point-max if no overlay change
3223 follows. */
3224 charpos = IT_CHARPOS (*it);
3225 bytepos = IT_BYTEPOS (*it);
3226 pos = next_overlay_change (charpos);
3227 if (pos < it->stop_charpos)
3228 it->stop_charpos = pos;
3229
3230 /* If showing the region, we have to stop at the region
3231 start or end because the face might change there. */
3232 if (it->region_beg_charpos > 0)
3233 {
3234 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3235 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3236 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3237 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3238 }
3239
3240 /* Set up variables for computing the stop position from text
3241 property changes. */
3242 XSETBUFFER (object, current_buffer);
3243 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3244 }
3245
3246 /* Get the interval containing IT's position. Value is a null
3247 interval if there isn't such an interval. */
3248 position = make_number (charpos);
3249 iv = validate_interval_range (object, &position, &position, 0);
3250 if (!NULL_INTERVAL_P (iv))
3251 {
3252 Lisp_Object values_here[LAST_PROP_IDX];
3253 struct props *p;
3254
3255 /* Get properties here. */
3256 for (p = it_props; p->handler; ++p)
3257 values_here[p->idx] = textget (iv->plist, *p->name);
3258
3259 /* Look for an interval following iv that has different
3260 properties. */
3261 for (next_iv = next_interval (iv);
3262 (!NULL_INTERVAL_P (next_iv)
3263 && (NILP (limit)
3264 || XFASTINT (limit) > next_iv->position));
3265 next_iv = next_interval (next_iv))
3266 {
3267 for (p = it_props; p->handler; ++p)
3268 {
3269 Lisp_Object new_value;
3270
3271 new_value = textget (next_iv->plist, *p->name);
3272 if (!EQ (values_here[p->idx], new_value))
3273 break;
3274 }
3275
3276 if (p->handler)
3277 break;
3278 }
3279
3280 if (!NULL_INTERVAL_P (next_iv))
3281 {
3282 if (INTEGERP (limit)
3283 && next_iv->position >= XFASTINT (limit))
3284 /* No text property change up to limit. */
3285 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3286 else
3287 /* Text properties change in next_iv. */
3288 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3289 }
3290 }
3291
3292 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3293 it->stop_charpos, it->string);
3294
3295 xassert (STRINGP (it->string)
3296 || (it->stop_charpos >= BEGV
3297 && it->stop_charpos >= IT_CHARPOS (*it)));
3298 }
3299
3300
3301 /* Return the position of the next overlay change after POS in
3302 current_buffer. Value is point-max if no overlay change
3303 follows. This is like `next-overlay-change' but doesn't use
3304 xmalloc. */
3305
3306 static EMACS_INT
3307 next_overlay_change (pos)
3308 EMACS_INT pos;
3309 {
3310 int noverlays;
3311 EMACS_INT endpos;
3312 Lisp_Object *overlays;
3313 int i;
3314
3315 /* Get all overlays at the given position. */
3316 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3317
3318 /* If any of these overlays ends before endpos,
3319 use its ending point instead. */
3320 for (i = 0; i < noverlays; ++i)
3321 {
3322 Lisp_Object oend;
3323 EMACS_INT oendpos;
3324
3325 oend = OVERLAY_END (overlays[i]);
3326 oendpos = OVERLAY_POSITION (oend);
3327 endpos = min (endpos, oendpos);
3328 }
3329
3330 return endpos;
3331 }
3332
3333
3334 \f
3335 /***********************************************************************
3336 Fontification
3337 ***********************************************************************/
3338
3339 /* Handle changes in the `fontified' property of the current buffer by
3340 calling hook functions from Qfontification_functions to fontify
3341 regions of text. */
3342
3343 static enum prop_handled
3344 handle_fontified_prop (it)
3345 struct it *it;
3346 {
3347 Lisp_Object prop, pos;
3348 enum prop_handled handled = HANDLED_NORMALLY;
3349
3350 if (!NILP (Vmemory_full))
3351 return handled;
3352
3353 /* Get the value of the `fontified' property at IT's current buffer
3354 position. (The `fontified' property doesn't have a special
3355 meaning in strings.) If the value is nil, call functions from
3356 Qfontification_functions. */
3357 if (!STRINGP (it->string)
3358 && it->s == NULL
3359 && !NILP (Vfontification_functions)
3360 && !NILP (Vrun_hooks)
3361 && (pos = make_number (IT_CHARPOS (*it)),
3362 prop = Fget_char_property (pos, Qfontified, Qnil),
3363 /* Ignore the special cased nil value always present at EOB since
3364 no amount of fontifying will be able to change it. */
3365 NILP (prop) && IT_CHARPOS (*it) < Z))
3366 {
3367 int count = SPECPDL_INDEX ();
3368 Lisp_Object val;
3369
3370 val = Vfontification_functions;
3371 specbind (Qfontification_functions, Qnil);
3372
3373 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3374 safe_call1 (val, pos);
3375 else
3376 {
3377 Lisp_Object globals, fn;
3378 struct gcpro gcpro1, gcpro2;
3379
3380 globals = Qnil;
3381 GCPRO2 (val, globals);
3382
3383 for (; CONSP (val); val = XCDR (val))
3384 {
3385 fn = XCAR (val);
3386
3387 if (EQ (fn, Qt))
3388 {
3389 /* A value of t indicates this hook has a local
3390 binding; it means to run the global binding too.
3391 In a global value, t should not occur. If it
3392 does, we must ignore it to avoid an endless
3393 loop. */
3394 for (globals = Fdefault_value (Qfontification_functions);
3395 CONSP (globals);
3396 globals = XCDR (globals))
3397 {
3398 fn = XCAR (globals);
3399 if (!EQ (fn, Qt))
3400 safe_call1 (fn, pos);
3401 }
3402 }
3403 else
3404 safe_call1 (fn, pos);
3405 }
3406
3407 UNGCPRO;
3408 }
3409
3410 unbind_to (count, Qnil);
3411
3412 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3413 something. This avoids an endless loop if they failed to
3414 fontify the text for which reason ever. */
3415 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3416 handled = HANDLED_RECOMPUTE_PROPS;
3417 }
3418
3419 return handled;
3420 }
3421
3422
3423 \f
3424 /***********************************************************************
3425 Faces
3426 ***********************************************************************/
3427
3428 /* Set up iterator IT from face properties at its current position.
3429 Called from handle_stop. */
3430
3431 static enum prop_handled
3432 handle_face_prop (it)
3433 struct it *it;
3434 {
3435 int new_face_id;
3436 EMACS_INT next_stop;
3437
3438 if (!STRINGP (it->string))
3439 {
3440 new_face_id
3441 = face_at_buffer_position (it->w,
3442 IT_CHARPOS (*it),
3443 it->region_beg_charpos,
3444 it->region_end_charpos,
3445 &next_stop,
3446 (IT_CHARPOS (*it)
3447 + TEXT_PROP_DISTANCE_LIMIT),
3448 0, it->base_face_id);
3449
3450 /* Is this a start of a run of characters with box face?
3451 Caveat: this can be called for a freshly initialized
3452 iterator; face_id is -1 in this case. We know that the new
3453 face will not change until limit, i.e. if the new face has a
3454 box, all characters up to limit will have one. But, as
3455 usual, we don't know whether limit is really the end. */
3456 if (new_face_id != it->face_id)
3457 {
3458 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3459
3460 /* If new face has a box but old face has not, this is
3461 the start of a run of characters with box, i.e. it has
3462 a shadow on the left side. The value of face_id of the
3463 iterator will be -1 if this is the initial call that gets
3464 the face. In this case, we have to look in front of IT's
3465 position and see whether there is a face != new_face_id. */
3466 it->start_of_box_run_p
3467 = (new_face->box != FACE_NO_BOX
3468 && (it->face_id >= 0
3469 || IT_CHARPOS (*it) == BEG
3470 || new_face_id != face_before_it_pos (it)));
3471 it->face_box_p = new_face->box != FACE_NO_BOX;
3472 }
3473 }
3474 else
3475 {
3476 int base_face_id, bufpos;
3477 int i;
3478 Lisp_Object from_overlay
3479 = (it->current.overlay_string_index >= 0
3480 ? it->string_overlays[it->current.overlay_string_index]
3481 : Qnil);
3482
3483 /* See if we got to this string directly or indirectly from
3484 an overlay property. That includes the before-string or
3485 after-string of an overlay, strings in display properties
3486 provided by an overlay, their text properties, etc.
3487
3488 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3489 if (! NILP (from_overlay))
3490 for (i = it->sp - 1; i >= 0; i--)
3491 {
3492 if (it->stack[i].current.overlay_string_index >= 0)
3493 from_overlay
3494 = it->string_overlays[it->stack[i].current.overlay_string_index];
3495 else if (! NILP (it->stack[i].from_overlay))
3496 from_overlay = it->stack[i].from_overlay;
3497
3498 if (!NILP (from_overlay))
3499 break;
3500 }
3501
3502 if (! NILP (from_overlay))
3503 {
3504 bufpos = IT_CHARPOS (*it);
3505 /* For a string from an overlay, the base face depends
3506 only on text properties and ignores overlays. */
3507 base_face_id
3508 = face_for_overlay_string (it->w,
3509 IT_CHARPOS (*it),
3510 it->region_beg_charpos,
3511 it->region_end_charpos,
3512 &next_stop,
3513 (IT_CHARPOS (*it)
3514 + TEXT_PROP_DISTANCE_LIMIT),
3515 0,
3516 from_overlay);
3517 }
3518 else
3519 {
3520 bufpos = 0;
3521
3522 /* For strings from a `display' property, use the face at
3523 IT's current buffer position as the base face to merge
3524 with, so that overlay strings appear in the same face as
3525 surrounding text, unless they specify their own
3526 faces. */
3527 base_face_id = underlying_face_id (it);
3528 }
3529
3530 new_face_id = face_at_string_position (it->w,
3531 it->string,
3532 IT_STRING_CHARPOS (*it),
3533 bufpos,
3534 it->region_beg_charpos,
3535 it->region_end_charpos,
3536 &next_stop,
3537 base_face_id, 0);
3538
3539 /* Is this a start of a run of characters with box? Caveat:
3540 this can be called for a freshly allocated iterator; face_id
3541 is -1 is this case. We know that the new face will not
3542 change until the next check pos, i.e. if the new face has a
3543 box, all characters up to that position will have a
3544 box. But, as usual, we don't know whether that position
3545 is really the end. */
3546 if (new_face_id != it->face_id)
3547 {
3548 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3549 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3550
3551 /* If new face has a box but old face hasn't, this is the
3552 start of a run of characters with box, i.e. it has a
3553 shadow on the left side. */
3554 it->start_of_box_run_p
3555 = new_face->box && (old_face == NULL || !old_face->box);
3556 it->face_box_p = new_face->box != FACE_NO_BOX;
3557 }
3558 }
3559
3560 it->face_id = new_face_id;
3561 return HANDLED_NORMALLY;
3562 }
3563
3564
3565 /* Return the ID of the face ``underlying'' IT's current position,
3566 which is in a string. If the iterator is associated with a
3567 buffer, return the face at IT's current buffer position.
3568 Otherwise, use the iterator's base_face_id. */
3569
3570 static int
3571 underlying_face_id (it)
3572 struct it *it;
3573 {
3574 int face_id = it->base_face_id, i;
3575
3576 xassert (STRINGP (it->string));
3577
3578 for (i = it->sp - 1; i >= 0; --i)
3579 if (NILP (it->stack[i].string))
3580 face_id = it->stack[i].face_id;
3581
3582 return face_id;
3583 }
3584
3585
3586 /* Compute the face one character before or after the current position
3587 of IT. BEFORE_P non-zero means get the face in front of IT's
3588 position. Value is the id of the face. */
3589
3590 static int
3591 face_before_or_after_it_pos (it, before_p)
3592 struct it *it;
3593 int before_p;
3594 {
3595 int face_id, limit;
3596 EMACS_INT next_check_charpos;
3597 struct text_pos pos;
3598
3599 xassert (it->s == NULL);
3600
3601 if (STRINGP (it->string))
3602 {
3603 int bufpos, base_face_id;
3604
3605 /* No face change past the end of the string (for the case
3606 we are padding with spaces). No face change before the
3607 string start. */
3608 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3609 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3610 return it->face_id;
3611
3612 /* Set pos to the position before or after IT's current position. */
3613 if (before_p)
3614 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3615 else
3616 /* For composition, we must check the character after the
3617 composition. */
3618 pos = (it->what == IT_COMPOSITION
3619 ? string_pos (IT_STRING_CHARPOS (*it)
3620 + it->cmp_it.nchars, it->string)
3621 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3622
3623 if (it->current.overlay_string_index >= 0)
3624 bufpos = IT_CHARPOS (*it);
3625 else
3626 bufpos = 0;
3627
3628 base_face_id = underlying_face_id (it);
3629
3630 /* Get the face for ASCII, or unibyte. */
3631 face_id = face_at_string_position (it->w,
3632 it->string,
3633 CHARPOS (pos),
3634 bufpos,
3635 it->region_beg_charpos,
3636 it->region_end_charpos,
3637 &next_check_charpos,
3638 base_face_id, 0);
3639
3640 /* Correct the face for charsets different from ASCII. Do it
3641 for the multibyte case only. The face returned above is
3642 suitable for unibyte text if IT->string is unibyte. */
3643 if (STRING_MULTIBYTE (it->string))
3644 {
3645 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3646 int rest = SBYTES (it->string) - BYTEPOS (pos);
3647 int c, len;
3648 struct face *face = FACE_FROM_ID (it->f, face_id);
3649
3650 c = string_char_and_length (p, rest, &len);
3651 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3652 }
3653 }
3654 else
3655 {
3656 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3657 || (IT_CHARPOS (*it) <= BEGV && before_p))
3658 return it->face_id;
3659
3660 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3661 pos = it->current.pos;
3662
3663 if (before_p)
3664 DEC_TEXT_POS (pos, it->multibyte_p);
3665 else
3666 {
3667 if (it->what == IT_COMPOSITION)
3668 /* For composition, we must check the position after the
3669 composition. */
3670 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3671 else
3672 INC_TEXT_POS (pos, it->multibyte_p);
3673 }
3674
3675 /* Determine face for CHARSET_ASCII, or unibyte. */
3676 face_id = face_at_buffer_position (it->w,
3677 CHARPOS (pos),
3678 it->region_beg_charpos,
3679 it->region_end_charpos,
3680 &next_check_charpos,
3681 limit, 0, -1);
3682
3683 /* Correct the face for charsets different from ASCII. Do it
3684 for the multibyte case only. The face returned above is
3685 suitable for unibyte text if current_buffer is unibyte. */
3686 if (it->multibyte_p)
3687 {
3688 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3689 struct face *face = FACE_FROM_ID (it->f, face_id);
3690 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3691 }
3692 }
3693
3694 return face_id;
3695 }
3696
3697
3698 \f
3699 /***********************************************************************
3700 Invisible text
3701 ***********************************************************************/
3702
3703 /* Set up iterator IT from invisible properties at its current
3704 position. Called from handle_stop. */
3705
3706 static enum prop_handled
3707 handle_invisible_prop (it)
3708 struct it *it;
3709 {
3710 enum prop_handled handled = HANDLED_NORMALLY;
3711
3712 if (STRINGP (it->string))
3713 {
3714 extern Lisp_Object Qinvisible;
3715 Lisp_Object prop, end_charpos, limit, charpos;
3716
3717 /* Get the value of the invisible text property at the
3718 current position. Value will be nil if there is no such
3719 property. */
3720 charpos = make_number (IT_STRING_CHARPOS (*it));
3721 prop = Fget_text_property (charpos, Qinvisible, it->string);
3722
3723 if (!NILP (prop)
3724 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3725 {
3726 handled = HANDLED_RECOMPUTE_PROPS;
3727
3728 /* Get the position at which the next change of the
3729 invisible text property can be found in IT->string.
3730 Value will be nil if the property value is the same for
3731 all the rest of IT->string. */
3732 XSETINT (limit, SCHARS (it->string));
3733 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3734 it->string, limit);
3735
3736 /* Text at current position is invisible. The next
3737 change in the property is at position end_charpos.
3738 Move IT's current position to that position. */
3739 if (INTEGERP (end_charpos)
3740 && XFASTINT (end_charpos) < XFASTINT (limit))
3741 {
3742 struct text_pos old;
3743 old = it->current.string_pos;
3744 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3745 compute_string_pos (&it->current.string_pos, old, it->string);
3746 }
3747 else
3748 {
3749 /* The rest of the string is invisible. If this is an
3750 overlay string, proceed with the next overlay string
3751 or whatever comes and return a character from there. */
3752 if (it->current.overlay_string_index >= 0)
3753 {
3754 next_overlay_string (it);
3755 /* Don't check for overlay strings when we just
3756 finished processing them. */
3757 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3758 }
3759 else
3760 {
3761 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3762 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3763 }
3764 }
3765 }
3766 }
3767 else
3768 {
3769 int invis_p;
3770 EMACS_INT newpos, next_stop, start_charpos;
3771 Lisp_Object pos, prop, overlay;
3772
3773 /* First of all, is there invisible text at this position? */
3774 start_charpos = IT_CHARPOS (*it);
3775 pos = make_number (IT_CHARPOS (*it));
3776 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3777 &overlay);
3778 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3779
3780 /* If we are on invisible text, skip over it. */
3781 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3782 {
3783 /* Record whether we have to display an ellipsis for the
3784 invisible text. */
3785 int display_ellipsis_p = invis_p == 2;
3786
3787 handled = HANDLED_RECOMPUTE_PROPS;
3788
3789 /* Loop skipping over invisible text. The loop is left at
3790 ZV or with IT on the first char being visible again. */
3791 do
3792 {
3793 /* Try to skip some invisible text. Return value is the
3794 position reached which can be equal to IT's position
3795 if there is nothing invisible here. This skips both
3796 over invisible text properties and overlays with
3797 invisible property. */
3798 newpos = skip_invisible (IT_CHARPOS (*it),
3799 &next_stop, ZV, it->window);
3800
3801 /* If we skipped nothing at all we weren't at invisible
3802 text in the first place. If everything to the end of
3803 the buffer was skipped, end the loop. */
3804 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3805 invis_p = 0;
3806 else
3807 {
3808 /* We skipped some characters but not necessarily
3809 all there are. Check if we ended up on visible
3810 text. Fget_char_property returns the property of
3811 the char before the given position, i.e. if we
3812 get invis_p = 0, this means that the char at
3813 newpos is visible. */
3814 pos = make_number (newpos);
3815 prop = Fget_char_property (pos, Qinvisible, it->window);
3816 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3817 }
3818
3819 /* If we ended up on invisible text, proceed to
3820 skip starting with next_stop. */
3821 if (invis_p)
3822 IT_CHARPOS (*it) = next_stop;
3823
3824 /* If there are adjacent invisible texts, don't lose the
3825 second one's ellipsis. */
3826 if (invis_p == 2)
3827 display_ellipsis_p = 1;
3828 }
3829 while (invis_p);
3830
3831 /* The position newpos is now either ZV or on visible text. */
3832 IT_CHARPOS (*it) = newpos;
3833 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3834
3835 /* If there are before-strings at the start of invisible
3836 text, and the text is invisible because of a text
3837 property, arrange to show before-strings because 20.x did
3838 it that way. (If the text is invisible because of an
3839 overlay property instead of a text property, this is
3840 already handled in the overlay code.) */
3841 if (NILP (overlay)
3842 && get_overlay_strings (it, start_charpos))
3843 {
3844 handled = HANDLED_RECOMPUTE_PROPS;
3845 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3846 }
3847 else if (display_ellipsis_p)
3848 {
3849 /* Make sure that the glyphs of the ellipsis will get
3850 correct `charpos' values. If we would not update
3851 it->position here, the glyphs would belong to the
3852 last visible character _before_ the invisible
3853 text, which confuses `set_cursor_from_row'.
3854
3855 We use the last invisible position instead of the
3856 first because this way the cursor is always drawn on
3857 the first "." of the ellipsis, whenever PT is inside
3858 the invisible text. Otherwise the cursor would be
3859 placed _after_ the ellipsis when the point is after the
3860 first invisible character. */
3861 if (!STRINGP (it->object))
3862 {
3863 it->position.charpos = IT_CHARPOS (*it) - 1;
3864 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3865 }
3866 it->ellipsis_p = 1;
3867 /* Let the ellipsis display before
3868 considering any properties of the following char.
3869 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3870 handled = HANDLED_RETURN;
3871 }
3872 }
3873 }
3874
3875 return handled;
3876 }
3877
3878
3879 /* Make iterator IT return `...' next.
3880 Replaces LEN characters from buffer. */
3881
3882 static void
3883 setup_for_ellipsis (it, len)
3884 struct it *it;
3885 int len;
3886 {
3887 /* Use the display table definition for `...'. Invalid glyphs
3888 will be handled by the method returning elements from dpvec. */
3889 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3890 {
3891 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3892 it->dpvec = v->contents;
3893 it->dpend = v->contents + v->size;
3894 }
3895 else
3896 {
3897 /* Default `...'. */
3898 it->dpvec = default_invis_vector;
3899 it->dpend = default_invis_vector + 3;
3900 }
3901
3902 it->dpvec_char_len = len;
3903 it->current.dpvec_index = 0;
3904 it->dpvec_face_id = -1;
3905
3906 /* Remember the current face id in case glyphs specify faces.
3907 IT's face is restored in set_iterator_to_next.
3908 saved_face_id was set to preceding char's face in handle_stop. */
3909 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3910 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3911
3912 it->method = GET_FROM_DISPLAY_VECTOR;
3913 it->ellipsis_p = 1;
3914 }
3915
3916
3917 \f
3918 /***********************************************************************
3919 'display' property
3920 ***********************************************************************/
3921
3922 /* Set up iterator IT from `display' property at its current position.
3923 Called from handle_stop.
3924 We return HANDLED_RETURN if some part of the display property
3925 overrides the display of the buffer text itself.
3926 Otherwise we return HANDLED_NORMALLY. */
3927
3928 static enum prop_handled
3929 handle_display_prop (it)
3930 struct it *it;
3931 {
3932 Lisp_Object prop, object, overlay;
3933 struct text_pos *position;
3934 /* Nonzero if some property replaces the display of the text itself. */
3935 int display_replaced_p = 0;
3936
3937 if (STRINGP (it->string))
3938 {
3939 object = it->string;
3940 position = &it->current.string_pos;
3941 }
3942 else
3943 {
3944 XSETWINDOW (object, it->w);
3945 position = &it->current.pos;
3946 }
3947
3948 /* Reset those iterator values set from display property values. */
3949 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3950 it->space_width = Qnil;
3951 it->font_height = Qnil;
3952 it->voffset = 0;
3953
3954 /* We don't support recursive `display' properties, i.e. string
3955 values that have a string `display' property, that have a string
3956 `display' property etc. */
3957 if (!it->string_from_display_prop_p)
3958 it->area = TEXT_AREA;
3959
3960 prop = get_char_property_and_overlay (make_number (position->charpos),
3961 Qdisplay, object, &overlay);
3962 if (NILP (prop))
3963 return HANDLED_NORMALLY;
3964 /* Now OVERLAY is the overlay that gave us this property, or nil
3965 if it was a text property. */
3966
3967 if (!STRINGP (it->string))
3968 object = it->w->buffer;
3969
3970 if (CONSP (prop)
3971 /* Simple properties. */
3972 && !EQ (XCAR (prop), Qimage)
3973 && !EQ (XCAR (prop), Qspace)
3974 && !EQ (XCAR (prop), Qwhen)
3975 && !EQ (XCAR (prop), Qslice)
3976 && !EQ (XCAR (prop), Qspace_width)
3977 && !EQ (XCAR (prop), Qheight)
3978 && !EQ (XCAR (prop), Qraise)
3979 /* Marginal area specifications. */
3980 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3981 && !EQ (XCAR (prop), Qleft_fringe)
3982 && !EQ (XCAR (prop), Qright_fringe)
3983 && !NILP (XCAR (prop)))
3984 {
3985 for (; CONSP (prop); prop = XCDR (prop))
3986 {
3987 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3988 position, display_replaced_p))
3989 {
3990 display_replaced_p = 1;
3991 /* If some text in a string is replaced, `position' no
3992 longer points to the position of `object'. */
3993 if (STRINGP (object))
3994 break;
3995 }
3996 }
3997 }
3998 else if (VECTORP (prop))
3999 {
4000 int i;
4001 for (i = 0; i < ASIZE (prop); ++i)
4002 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4003 position, display_replaced_p))
4004 {
4005 display_replaced_p = 1;
4006 /* If some text in a string is replaced, `position' no
4007 longer points to the position of `object'. */
4008 if (STRINGP (object))
4009 break;
4010 }
4011 }
4012 else
4013 {
4014 if (handle_single_display_spec (it, prop, object, overlay,
4015 position, 0))
4016 display_replaced_p = 1;
4017 }
4018
4019 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4020 }
4021
4022
4023 /* Value is the position of the end of the `display' property starting
4024 at START_POS in OBJECT. */
4025
4026 static struct text_pos
4027 display_prop_end (it, object, start_pos)
4028 struct it *it;
4029 Lisp_Object object;
4030 struct text_pos start_pos;
4031 {
4032 Lisp_Object end;
4033 struct text_pos end_pos;
4034
4035 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4036 Qdisplay, object, Qnil);
4037 CHARPOS (end_pos) = XFASTINT (end);
4038 if (STRINGP (object))
4039 compute_string_pos (&end_pos, start_pos, it->string);
4040 else
4041 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4042
4043 return end_pos;
4044 }
4045
4046
4047 /* Set up IT from a single `display' specification PROP. OBJECT
4048 is the object in which the `display' property was found. *POSITION
4049 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4050 means that we previously saw a display specification which already
4051 replaced text display with something else, for example an image;
4052 we ignore such properties after the first one has been processed.
4053
4054 OVERLAY is the overlay this `display' property came from,
4055 or nil if it was a text property.
4056
4057 If PROP is a `space' or `image' specification, and in some other
4058 cases too, set *POSITION to the position where the `display'
4059 property ends.
4060
4061 Value is non-zero if something was found which replaces the display
4062 of buffer or string text. */
4063
4064 static int
4065 handle_single_display_spec (it, spec, object, overlay, position,
4066 display_replaced_before_p)
4067 struct it *it;
4068 Lisp_Object spec;
4069 Lisp_Object object;
4070 Lisp_Object overlay;
4071 struct text_pos *position;
4072 int display_replaced_before_p;
4073 {
4074 Lisp_Object form;
4075 Lisp_Object location, value;
4076 struct text_pos start_pos, save_pos;
4077 int valid_p;
4078
4079 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4080 If the result is non-nil, use VALUE instead of SPEC. */
4081 form = Qt;
4082 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4083 {
4084 spec = XCDR (spec);
4085 if (!CONSP (spec))
4086 return 0;
4087 form = XCAR (spec);
4088 spec = XCDR (spec);
4089 }
4090
4091 if (!NILP (form) && !EQ (form, Qt))
4092 {
4093 int count = SPECPDL_INDEX ();
4094 struct gcpro gcpro1;
4095
4096 /* Bind `object' to the object having the `display' property, a
4097 buffer or string. Bind `position' to the position in the
4098 object where the property was found, and `buffer-position'
4099 to the current position in the buffer. */
4100 specbind (Qobject, object);
4101 specbind (Qposition, make_number (CHARPOS (*position)));
4102 specbind (Qbuffer_position,
4103 make_number (STRINGP (object)
4104 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4105 GCPRO1 (form);
4106 form = safe_eval (form);
4107 UNGCPRO;
4108 unbind_to (count, Qnil);
4109 }
4110
4111 if (NILP (form))
4112 return 0;
4113
4114 /* Handle `(height HEIGHT)' specifications. */
4115 if (CONSP (spec)
4116 && EQ (XCAR (spec), Qheight)
4117 && CONSP (XCDR (spec)))
4118 {
4119 if (!FRAME_WINDOW_P (it->f))
4120 return 0;
4121
4122 it->font_height = XCAR (XCDR (spec));
4123 if (!NILP (it->font_height))
4124 {
4125 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4126 int new_height = -1;
4127
4128 if (CONSP (it->font_height)
4129 && (EQ (XCAR (it->font_height), Qplus)
4130 || EQ (XCAR (it->font_height), Qminus))
4131 && CONSP (XCDR (it->font_height))
4132 && INTEGERP (XCAR (XCDR (it->font_height))))
4133 {
4134 /* `(+ N)' or `(- N)' where N is an integer. */
4135 int steps = XINT (XCAR (XCDR (it->font_height)));
4136 if (EQ (XCAR (it->font_height), Qplus))
4137 steps = - steps;
4138 it->face_id = smaller_face (it->f, it->face_id, steps);
4139 }
4140 else if (FUNCTIONP (it->font_height))
4141 {
4142 /* Call function with current height as argument.
4143 Value is the new height. */
4144 Lisp_Object height;
4145 height = safe_call1 (it->font_height,
4146 face->lface[LFACE_HEIGHT_INDEX]);
4147 if (NUMBERP (height))
4148 new_height = XFLOATINT (height);
4149 }
4150 else if (NUMBERP (it->font_height))
4151 {
4152 /* Value is a multiple of the canonical char height. */
4153 struct face *face;
4154
4155 face = FACE_FROM_ID (it->f,
4156 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4157 new_height = (XFLOATINT (it->font_height)
4158 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4159 }
4160 else
4161 {
4162 /* Evaluate IT->font_height with `height' bound to the
4163 current specified height to get the new height. */
4164 int count = SPECPDL_INDEX ();
4165
4166 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4167 value = safe_eval (it->font_height);
4168 unbind_to (count, Qnil);
4169
4170 if (NUMBERP (value))
4171 new_height = XFLOATINT (value);
4172 }
4173
4174 if (new_height > 0)
4175 it->face_id = face_with_height (it->f, it->face_id, new_height);
4176 }
4177
4178 return 0;
4179 }
4180
4181 /* Handle `(space-width WIDTH)'. */
4182 if (CONSP (spec)
4183 && EQ (XCAR (spec), Qspace_width)
4184 && CONSP (XCDR (spec)))
4185 {
4186 if (!FRAME_WINDOW_P (it->f))
4187 return 0;
4188
4189 value = XCAR (XCDR (spec));
4190 if (NUMBERP (value) && XFLOATINT (value) > 0)
4191 it->space_width = value;
4192
4193 return 0;
4194 }
4195
4196 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4197 if (CONSP (spec)
4198 && EQ (XCAR (spec), Qslice))
4199 {
4200 Lisp_Object tem;
4201
4202 if (!FRAME_WINDOW_P (it->f))
4203 return 0;
4204
4205 if (tem = XCDR (spec), CONSP (tem))
4206 {
4207 it->slice.x = XCAR (tem);
4208 if (tem = XCDR (tem), CONSP (tem))
4209 {
4210 it->slice.y = XCAR (tem);
4211 if (tem = XCDR (tem), CONSP (tem))
4212 {
4213 it->slice.width = XCAR (tem);
4214 if (tem = XCDR (tem), CONSP (tem))
4215 it->slice.height = XCAR (tem);
4216 }
4217 }
4218 }
4219
4220 return 0;
4221 }
4222
4223 /* Handle `(raise FACTOR)'. */
4224 if (CONSP (spec)
4225 && EQ (XCAR (spec), Qraise)
4226 && CONSP (XCDR (spec)))
4227 {
4228 if (!FRAME_WINDOW_P (it->f))
4229 return 0;
4230
4231 #ifdef HAVE_WINDOW_SYSTEM
4232 value = XCAR (XCDR (spec));
4233 if (NUMBERP (value))
4234 {
4235 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4236 it->voffset = - (XFLOATINT (value)
4237 * (FONT_HEIGHT (face->font)));
4238 }
4239 #endif /* HAVE_WINDOW_SYSTEM */
4240
4241 return 0;
4242 }
4243
4244 /* Don't handle the other kinds of display specifications
4245 inside a string that we got from a `display' property. */
4246 if (it->string_from_display_prop_p)
4247 return 0;
4248
4249 /* Characters having this form of property are not displayed, so
4250 we have to find the end of the property. */
4251 start_pos = *position;
4252 *position = display_prop_end (it, object, start_pos);
4253 value = Qnil;
4254
4255 /* Stop the scan at that end position--we assume that all
4256 text properties change there. */
4257 it->stop_charpos = position->charpos;
4258
4259 /* Handle `(left-fringe BITMAP [FACE])'
4260 and `(right-fringe BITMAP [FACE])'. */
4261 if (CONSP (spec)
4262 && (EQ (XCAR (spec), Qleft_fringe)
4263 || EQ (XCAR (spec), Qright_fringe))
4264 && CONSP (XCDR (spec)))
4265 {
4266 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4267 int fringe_bitmap;
4268
4269 if (!FRAME_WINDOW_P (it->f))
4270 /* If we return here, POSITION has been advanced
4271 across the text with this property. */
4272 return 0;
4273
4274 #ifdef HAVE_WINDOW_SYSTEM
4275 value = XCAR (XCDR (spec));
4276 if (!SYMBOLP (value)
4277 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4278 /* If we return here, POSITION has been advanced
4279 across the text with this property. */
4280 return 0;
4281
4282 if (CONSP (XCDR (XCDR (spec))))
4283 {
4284 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4285 int face_id2 = lookup_derived_face (it->f, face_name,
4286 FRINGE_FACE_ID, 0);
4287 if (face_id2 >= 0)
4288 face_id = face_id2;
4289 }
4290
4291 /* Save current settings of IT so that we can restore them
4292 when we are finished with the glyph property value. */
4293
4294 save_pos = it->position;
4295 it->position = *position;
4296 push_it (it);
4297 it->position = save_pos;
4298
4299 it->area = TEXT_AREA;
4300 it->what = IT_IMAGE;
4301 it->image_id = -1; /* no image */
4302 it->position = start_pos;
4303 it->object = NILP (object) ? it->w->buffer : object;
4304 it->method = GET_FROM_IMAGE;
4305 it->from_overlay = Qnil;
4306 it->face_id = face_id;
4307
4308 /* Say that we haven't consumed the characters with
4309 `display' property yet. The call to pop_it in
4310 set_iterator_to_next will clean this up. */
4311 *position = start_pos;
4312
4313 if (EQ (XCAR (spec), Qleft_fringe))
4314 {
4315 it->left_user_fringe_bitmap = fringe_bitmap;
4316 it->left_user_fringe_face_id = face_id;
4317 }
4318 else
4319 {
4320 it->right_user_fringe_bitmap = fringe_bitmap;
4321 it->right_user_fringe_face_id = face_id;
4322 }
4323 #endif /* HAVE_WINDOW_SYSTEM */
4324 return 1;
4325 }
4326
4327 /* Prepare to handle `((margin left-margin) ...)',
4328 `((margin right-margin) ...)' and `((margin nil) ...)'
4329 prefixes for display specifications. */
4330 location = Qunbound;
4331 if (CONSP (spec) && CONSP (XCAR (spec)))
4332 {
4333 Lisp_Object tem;
4334
4335 value = XCDR (spec);
4336 if (CONSP (value))
4337 value = XCAR (value);
4338
4339 tem = XCAR (spec);
4340 if (EQ (XCAR (tem), Qmargin)
4341 && (tem = XCDR (tem),
4342 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4343 (NILP (tem)
4344 || EQ (tem, Qleft_margin)
4345 || EQ (tem, Qright_margin))))
4346 location = tem;
4347 }
4348
4349 if (EQ (location, Qunbound))
4350 {
4351 location = Qnil;
4352 value = spec;
4353 }
4354
4355 /* After this point, VALUE is the property after any
4356 margin prefix has been stripped. It must be a string,
4357 an image specification, or `(space ...)'.
4358
4359 LOCATION specifies where to display: `left-margin',
4360 `right-margin' or nil. */
4361
4362 valid_p = (STRINGP (value)
4363 #ifdef HAVE_WINDOW_SYSTEM
4364 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4365 #endif /* not HAVE_WINDOW_SYSTEM */
4366 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4367
4368 if (valid_p && !display_replaced_before_p)
4369 {
4370 /* Save current settings of IT so that we can restore them
4371 when we are finished with the glyph property value. */
4372 save_pos = it->position;
4373 it->position = *position;
4374 push_it (it);
4375 it->position = save_pos;
4376 it->from_overlay = overlay;
4377
4378 if (NILP (location))
4379 it->area = TEXT_AREA;
4380 else if (EQ (location, Qleft_margin))
4381 it->area = LEFT_MARGIN_AREA;
4382 else
4383 it->area = RIGHT_MARGIN_AREA;
4384
4385 if (STRINGP (value))
4386 {
4387 it->string = value;
4388 it->multibyte_p = STRING_MULTIBYTE (it->string);
4389 it->current.overlay_string_index = -1;
4390 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4391 it->end_charpos = it->string_nchars = SCHARS (it->string);
4392 it->method = GET_FROM_STRING;
4393 it->stop_charpos = 0;
4394 it->string_from_display_prop_p = 1;
4395 /* Say that we haven't consumed the characters with
4396 `display' property yet. The call to pop_it in
4397 set_iterator_to_next will clean this up. */
4398 if (BUFFERP (object))
4399 *position = start_pos;
4400 }
4401 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4402 {
4403 it->method = GET_FROM_STRETCH;
4404 it->object = value;
4405 *position = it->position = start_pos;
4406 }
4407 #ifdef HAVE_WINDOW_SYSTEM
4408 else
4409 {
4410 it->what = IT_IMAGE;
4411 it->image_id = lookup_image (it->f, value);
4412 it->position = start_pos;
4413 it->object = NILP (object) ? it->w->buffer : object;
4414 it->method = GET_FROM_IMAGE;
4415
4416 /* Say that we haven't consumed the characters with
4417 `display' property yet. The call to pop_it in
4418 set_iterator_to_next will clean this up. */
4419 *position = start_pos;
4420 }
4421 #endif /* HAVE_WINDOW_SYSTEM */
4422
4423 return 1;
4424 }
4425
4426 /* Invalid property or property not supported. Restore
4427 POSITION to what it was before. */
4428 *position = start_pos;
4429 return 0;
4430 }
4431
4432
4433 /* Check if SPEC is a display sub-property value whose text should be
4434 treated as intangible. */
4435
4436 static int
4437 single_display_spec_intangible_p (prop)
4438 Lisp_Object prop;
4439 {
4440 /* Skip over `when FORM'. */
4441 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4442 {
4443 prop = XCDR (prop);
4444 if (!CONSP (prop))
4445 return 0;
4446 prop = XCDR (prop);
4447 }
4448
4449 if (STRINGP (prop))
4450 return 1;
4451
4452 if (!CONSP (prop))
4453 return 0;
4454
4455 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4456 we don't need to treat text as intangible. */
4457 if (EQ (XCAR (prop), Qmargin))
4458 {
4459 prop = XCDR (prop);
4460 if (!CONSP (prop))
4461 return 0;
4462
4463 prop = XCDR (prop);
4464 if (!CONSP (prop)
4465 || EQ (XCAR (prop), Qleft_margin)
4466 || EQ (XCAR (prop), Qright_margin))
4467 return 0;
4468 }
4469
4470 return (CONSP (prop)
4471 && (EQ (XCAR (prop), Qimage)
4472 || EQ (XCAR (prop), Qspace)));
4473 }
4474
4475
4476 /* Check if PROP is a display property value whose text should be
4477 treated as intangible. */
4478
4479 int
4480 display_prop_intangible_p (prop)
4481 Lisp_Object prop;
4482 {
4483 if (CONSP (prop)
4484 && CONSP (XCAR (prop))
4485 && !EQ (Qmargin, XCAR (XCAR (prop))))
4486 {
4487 /* A list of sub-properties. */
4488 while (CONSP (prop))
4489 {
4490 if (single_display_spec_intangible_p (XCAR (prop)))
4491 return 1;
4492 prop = XCDR (prop);
4493 }
4494 }
4495 else if (VECTORP (prop))
4496 {
4497 /* A vector of sub-properties. */
4498 int i;
4499 for (i = 0; i < ASIZE (prop); ++i)
4500 if (single_display_spec_intangible_p (AREF (prop, i)))
4501 return 1;
4502 }
4503 else
4504 return single_display_spec_intangible_p (prop);
4505
4506 return 0;
4507 }
4508
4509
4510 /* Return 1 if PROP is a display sub-property value containing STRING. */
4511
4512 static int
4513 single_display_spec_string_p (prop, string)
4514 Lisp_Object prop, string;
4515 {
4516 if (EQ (string, prop))
4517 return 1;
4518
4519 /* Skip over `when FORM'. */
4520 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4521 {
4522 prop = XCDR (prop);
4523 if (!CONSP (prop))
4524 return 0;
4525 prop = XCDR (prop);
4526 }
4527
4528 if (CONSP (prop))
4529 /* Skip over `margin LOCATION'. */
4530 if (EQ (XCAR (prop), Qmargin))
4531 {
4532 prop = XCDR (prop);
4533 if (!CONSP (prop))
4534 return 0;
4535
4536 prop = XCDR (prop);
4537 if (!CONSP (prop))
4538 return 0;
4539 }
4540
4541 return CONSP (prop) && EQ (XCAR (prop), string);
4542 }
4543
4544
4545 /* Return 1 if STRING appears in the `display' property PROP. */
4546
4547 static int
4548 display_prop_string_p (prop, string)
4549 Lisp_Object prop, string;
4550 {
4551 if (CONSP (prop)
4552 && CONSP (XCAR (prop))
4553 && !EQ (Qmargin, XCAR (XCAR (prop))))
4554 {
4555 /* A list of sub-properties. */
4556 while (CONSP (prop))
4557 {
4558 if (single_display_spec_string_p (XCAR (prop), string))
4559 return 1;
4560 prop = XCDR (prop);
4561 }
4562 }
4563 else if (VECTORP (prop))
4564 {
4565 /* A vector of sub-properties. */
4566 int i;
4567 for (i = 0; i < ASIZE (prop); ++i)
4568 if (single_display_spec_string_p (AREF (prop, i), string))
4569 return 1;
4570 }
4571 else
4572 return single_display_spec_string_p (prop, string);
4573
4574 return 0;
4575 }
4576
4577
4578 /* Determine from which buffer position in W's buffer STRING comes
4579 from. AROUND_CHARPOS is an approximate position where it could
4580 be from. Value is the buffer position or 0 if it couldn't be
4581 determined.
4582
4583 W's buffer must be current.
4584
4585 This function is necessary because we don't record buffer positions
4586 in glyphs generated from strings (to keep struct glyph small).
4587 This function may only use code that doesn't eval because it is
4588 called asynchronously from note_mouse_highlight. */
4589
4590 int
4591 string_buffer_position (w, string, around_charpos)
4592 struct window *w;
4593 Lisp_Object string;
4594 int around_charpos;
4595 {
4596 Lisp_Object limit, prop, pos;
4597 const int MAX_DISTANCE = 1000;
4598 int found = 0;
4599
4600 pos = make_number (around_charpos);
4601 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4602 while (!found && !EQ (pos, limit))
4603 {
4604 prop = Fget_char_property (pos, Qdisplay, Qnil);
4605 if (!NILP (prop) && display_prop_string_p (prop, string))
4606 found = 1;
4607 else
4608 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4609 }
4610
4611 if (!found)
4612 {
4613 pos = make_number (around_charpos);
4614 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4615 while (!found && !EQ (pos, limit))
4616 {
4617 prop = Fget_char_property (pos, Qdisplay, Qnil);
4618 if (!NILP (prop) && display_prop_string_p (prop, string))
4619 found = 1;
4620 else
4621 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4622 limit);
4623 }
4624 }
4625
4626 return found ? XINT (pos) : 0;
4627 }
4628
4629
4630 \f
4631 /***********************************************************************
4632 `composition' property
4633 ***********************************************************************/
4634
4635 /* Set up iterator IT from `composition' property at its current
4636 position. Called from handle_stop. */
4637
4638 static enum prop_handled
4639 handle_composition_prop (it)
4640 struct it *it;
4641 {
4642 Lisp_Object prop, string;
4643 EMACS_INT pos, pos_byte, start, end;
4644
4645 if (STRINGP (it->string))
4646 {
4647 unsigned char *s;
4648
4649 pos = IT_STRING_CHARPOS (*it);
4650 pos_byte = IT_STRING_BYTEPOS (*it);
4651 string = it->string;
4652 s = SDATA (string) + pos_byte;
4653 it->c = STRING_CHAR (s, 0);
4654 }
4655 else
4656 {
4657 pos = IT_CHARPOS (*it);
4658 pos_byte = IT_BYTEPOS (*it);
4659 string = Qnil;
4660 it->c = FETCH_CHAR (pos_byte);
4661 }
4662
4663 /* If there's a valid composition and point is not inside of the
4664 composition (in the case that the composition is from the current
4665 buffer), draw a glyph composed from the composition components. */
4666 if (find_composition (pos, -1, &start, &end, &prop, string)
4667 && COMPOSITION_VALID_P (start, end, prop)
4668 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4669 {
4670 if (start != pos)
4671 {
4672 if (STRINGP (it->string))
4673 pos_byte = string_char_to_byte (it->string, start);
4674 else
4675 pos_byte = CHAR_TO_BYTE (start);
4676 }
4677 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4678 prop, string);
4679
4680 if (it->cmp_it.id >= 0)
4681 {
4682 it->cmp_it.ch = -1;
4683 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4684 it->cmp_it.nglyphs = -1;
4685 }
4686 }
4687
4688 return HANDLED_NORMALLY;
4689 }
4690
4691
4692 \f
4693 /***********************************************************************
4694 Overlay strings
4695 ***********************************************************************/
4696
4697 /* The following structure is used to record overlay strings for
4698 later sorting in load_overlay_strings. */
4699
4700 struct overlay_entry
4701 {
4702 Lisp_Object overlay;
4703 Lisp_Object string;
4704 int priority;
4705 int after_string_p;
4706 };
4707
4708
4709 /* Set up iterator IT from overlay strings at its current position.
4710 Called from handle_stop. */
4711
4712 static enum prop_handled
4713 handle_overlay_change (it)
4714 struct it *it;
4715 {
4716 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4717 return HANDLED_RECOMPUTE_PROPS;
4718 else
4719 return HANDLED_NORMALLY;
4720 }
4721
4722
4723 /* Set up the next overlay string for delivery by IT, if there is an
4724 overlay string to deliver. Called by set_iterator_to_next when the
4725 end of the current overlay string is reached. If there are more
4726 overlay strings to display, IT->string and
4727 IT->current.overlay_string_index are set appropriately here.
4728 Otherwise IT->string is set to nil. */
4729
4730 static void
4731 next_overlay_string (it)
4732 struct it *it;
4733 {
4734 ++it->current.overlay_string_index;
4735 if (it->current.overlay_string_index == it->n_overlay_strings)
4736 {
4737 /* No more overlay strings. Restore IT's settings to what
4738 they were before overlay strings were processed, and
4739 continue to deliver from current_buffer. */
4740
4741 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4742 pop_it (it);
4743 xassert (it->sp > 0
4744 || (NILP (it->string)
4745 && it->method == GET_FROM_BUFFER
4746 && it->stop_charpos >= BEGV
4747 && it->stop_charpos <= it->end_charpos));
4748 it->current.overlay_string_index = -1;
4749 it->n_overlay_strings = 0;
4750
4751 /* If we're at the end of the buffer, record that we have
4752 processed the overlay strings there already, so that
4753 next_element_from_buffer doesn't try it again. */
4754 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4755 it->overlay_strings_at_end_processed_p = 1;
4756 }
4757 else
4758 {
4759 /* There are more overlay strings to process. If
4760 IT->current.overlay_string_index has advanced to a position
4761 where we must load IT->overlay_strings with more strings, do
4762 it. */
4763 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4764
4765 if (it->current.overlay_string_index && i == 0)
4766 load_overlay_strings (it, 0);
4767
4768 /* Initialize IT to deliver display elements from the overlay
4769 string. */
4770 it->string = it->overlay_strings[i];
4771 it->multibyte_p = STRING_MULTIBYTE (it->string);
4772 SET_TEXT_POS (it->current.string_pos, 0, 0);
4773 it->method = GET_FROM_STRING;
4774 it->stop_charpos = 0;
4775 if (it->cmp_it.stop_pos >= 0)
4776 it->cmp_it.stop_pos = 0;
4777 }
4778
4779 CHECK_IT (it);
4780 }
4781
4782
4783 /* Compare two overlay_entry structures E1 and E2. Used as a
4784 comparison function for qsort in load_overlay_strings. Overlay
4785 strings for the same position are sorted so that
4786
4787 1. All after-strings come in front of before-strings, except
4788 when they come from the same overlay.
4789
4790 2. Within after-strings, strings are sorted so that overlay strings
4791 from overlays with higher priorities come first.
4792
4793 2. Within before-strings, strings are sorted so that overlay
4794 strings from overlays with higher priorities come last.
4795
4796 Value is analogous to strcmp. */
4797
4798
4799 static int
4800 compare_overlay_entries (e1, e2)
4801 void *e1, *e2;
4802 {
4803 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4804 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4805 int result;
4806
4807 if (entry1->after_string_p != entry2->after_string_p)
4808 {
4809 /* Let after-strings appear in front of before-strings if
4810 they come from different overlays. */
4811 if (EQ (entry1->overlay, entry2->overlay))
4812 result = entry1->after_string_p ? 1 : -1;
4813 else
4814 result = entry1->after_string_p ? -1 : 1;
4815 }
4816 else if (entry1->after_string_p)
4817 /* After-strings sorted in order of decreasing priority. */
4818 result = entry2->priority - entry1->priority;
4819 else
4820 /* Before-strings sorted in order of increasing priority. */
4821 result = entry1->priority - entry2->priority;
4822
4823 return result;
4824 }
4825
4826
4827 /* Load the vector IT->overlay_strings with overlay strings from IT's
4828 current buffer position, or from CHARPOS if that is > 0. Set
4829 IT->n_overlays to the total number of overlay strings found.
4830
4831 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4832 a time. On entry into load_overlay_strings,
4833 IT->current.overlay_string_index gives the number of overlay
4834 strings that have already been loaded by previous calls to this
4835 function.
4836
4837 IT->add_overlay_start contains an additional overlay start
4838 position to consider for taking overlay strings from, if non-zero.
4839 This position comes into play when the overlay has an `invisible'
4840 property, and both before and after-strings. When we've skipped to
4841 the end of the overlay, because of its `invisible' property, we
4842 nevertheless want its before-string to appear.
4843 IT->add_overlay_start will contain the overlay start position
4844 in this case.
4845
4846 Overlay strings are sorted so that after-string strings come in
4847 front of before-string strings. Within before and after-strings,
4848 strings are sorted by overlay priority. See also function
4849 compare_overlay_entries. */
4850
4851 static void
4852 load_overlay_strings (it, charpos)
4853 struct it *it;
4854 int charpos;
4855 {
4856 extern Lisp_Object Qwindow, Qpriority;
4857 Lisp_Object overlay, window, str, invisible;
4858 struct Lisp_Overlay *ov;
4859 int start, end;
4860 int size = 20;
4861 int n = 0, i, j, invis_p;
4862 struct overlay_entry *entries
4863 = (struct overlay_entry *) alloca (size * sizeof *entries);
4864
4865 if (charpos <= 0)
4866 charpos = IT_CHARPOS (*it);
4867
4868 /* Append the overlay string STRING of overlay OVERLAY to vector
4869 `entries' which has size `size' and currently contains `n'
4870 elements. AFTER_P non-zero means STRING is an after-string of
4871 OVERLAY. */
4872 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4873 do \
4874 { \
4875 Lisp_Object priority; \
4876 \
4877 if (n == size) \
4878 { \
4879 int new_size = 2 * size; \
4880 struct overlay_entry *old = entries; \
4881 entries = \
4882 (struct overlay_entry *) alloca (new_size \
4883 * sizeof *entries); \
4884 bcopy (old, entries, size * sizeof *entries); \
4885 size = new_size; \
4886 } \
4887 \
4888 entries[n].string = (STRING); \
4889 entries[n].overlay = (OVERLAY); \
4890 priority = Foverlay_get ((OVERLAY), Qpriority); \
4891 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4892 entries[n].after_string_p = (AFTER_P); \
4893 ++n; \
4894 } \
4895 while (0)
4896
4897 /* Process overlay before the overlay center. */
4898 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4899 {
4900 XSETMISC (overlay, ov);
4901 xassert (OVERLAYP (overlay));
4902 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4903 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4904
4905 if (end < charpos)
4906 break;
4907
4908 /* Skip this overlay if it doesn't start or end at IT's current
4909 position. */
4910 if (end != charpos && start != charpos)
4911 continue;
4912
4913 /* Skip this overlay if it doesn't apply to IT->w. */
4914 window = Foverlay_get (overlay, Qwindow);
4915 if (WINDOWP (window) && XWINDOW (window) != it->w)
4916 continue;
4917
4918 /* If the text ``under'' the overlay is invisible, both before-
4919 and after-strings from this overlay are visible; start and
4920 end position are indistinguishable. */
4921 invisible = Foverlay_get (overlay, Qinvisible);
4922 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4923
4924 /* If overlay has a non-empty before-string, record it. */
4925 if ((start == charpos || (end == charpos && invis_p))
4926 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4927 && SCHARS (str))
4928 RECORD_OVERLAY_STRING (overlay, str, 0);
4929
4930 /* If overlay has a non-empty after-string, record it. */
4931 if ((end == charpos || (start == charpos && invis_p))
4932 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4933 && SCHARS (str))
4934 RECORD_OVERLAY_STRING (overlay, str, 1);
4935 }
4936
4937 /* Process overlays after the overlay center. */
4938 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4939 {
4940 XSETMISC (overlay, ov);
4941 xassert (OVERLAYP (overlay));
4942 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4943 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4944
4945 if (start > charpos)
4946 break;
4947
4948 /* Skip this overlay if it doesn't start or end at IT's current
4949 position. */
4950 if (end != charpos && start != charpos)
4951 continue;
4952
4953 /* Skip this overlay if it doesn't apply to IT->w. */
4954 window = Foverlay_get (overlay, Qwindow);
4955 if (WINDOWP (window) && XWINDOW (window) != it->w)
4956 continue;
4957
4958 /* If the text ``under'' the overlay is invisible, it has a zero
4959 dimension, and both before- and after-strings apply. */
4960 invisible = Foverlay_get (overlay, Qinvisible);
4961 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4962
4963 /* If overlay has a non-empty before-string, record it. */
4964 if ((start == charpos || (end == charpos && invis_p))
4965 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4966 && SCHARS (str))
4967 RECORD_OVERLAY_STRING (overlay, str, 0);
4968
4969 /* If overlay has a non-empty after-string, record it. */
4970 if ((end == charpos || (start == charpos && invis_p))
4971 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4972 && SCHARS (str))
4973 RECORD_OVERLAY_STRING (overlay, str, 1);
4974 }
4975
4976 #undef RECORD_OVERLAY_STRING
4977
4978 /* Sort entries. */
4979 if (n > 1)
4980 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4981
4982 /* Record the total number of strings to process. */
4983 it->n_overlay_strings = n;
4984
4985 /* IT->current.overlay_string_index is the number of overlay strings
4986 that have already been consumed by IT. Copy some of the
4987 remaining overlay strings to IT->overlay_strings. */
4988 i = 0;
4989 j = it->current.overlay_string_index;
4990 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4991 {
4992 it->overlay_strings[i] = entries[j].string;
4993 it->string_overlays[i++] = entries[j++].overlay;
4994 }
4995
4996 CHECK_IT (it);
4997 }
4998
4999
5000 /* Get the first chunk of overlay strings at IT's current buffer
5001 position, or at CHARPOS if that is > 0. Value is non-zero if at
5002 least one overlay string was found. */
5003
5004 static int
5005 get_overlay_strings_1 (it, charpos, compute_stop_p)
5006 struct it *it;
5007 int charpos;
5008 int compute_stop_p;
5009 {
5010 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5011 process. This fills IT->overlay_strings with strings, and sets
5012 IT->n_overlay_strings to the total number of strings to process.
5013 IT->pos.overlay_string_index has to be set temporarily to zero
5014 because load_overlay_strings needs this; it must be set to -1
5015 when no overlay strings are found because a zero value would
5016 indicate a position in the first overlay string. */
5017 it->current.overlay_string_index = 0;
5018 load_overlay_strings (it, charpos);
5019
5020 /* If we found overlay strings, set up IT to deliver display
5021 elements from the first one. Otherwise set up IT to deliver
5022 from current_buffer. */
5023 if (it->n_overlay_strings)
5024 {
5025 /* Make sure we know settings in current_buffer, so that we can
5026 restore meaningful values when we're done with the overlay
5027 strings. */
5028 if (compute_stop_p)
5029 compute_stop_pos (it);
5030 xassert (it->face_id >= 0);
5031
5032 /* Save IT's settings. They are restored after all overlay
5033 strings have been processed. */
5034 xassert (!compute_stop_p || it->sp == 0);
5035
5036 /* When called from handle_stop, there might be an empty display
5037 string loaded. In that case, don't bother saving it. */
5038 if (!STRINGP (it->string) || SCHARS (it->string))
5039 push_it (it);
5040
5041 /* Set up IT to deliver display elements from the first overlay
5042 string. */
5043 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5044 it->string = it->overlay_strings[0];
5045 it->from_overlay = Qnil;
5046 it->stop_charpos = 0;
5047 xassert (STRINGP (it->string));
5048 it->end_charpos = SCHARS (it->string);
5049 it->multibyte_p = STRING_MULTIBYTE (it->string);
5050 it->method = GET_FROM_STRING;
5051 return 1;
5052 }
5053
5054 it->current.overlay_string_index = -1;
5055 return 0;
5056 }
5057
5058 static int
5059 get_overlay_strings (it, charpos)
5060 struct it *it;
5061 int charpos;
5062 {
5063 it->string = Qnil;
5064 it->method = GET_FROM_BUFFER;
5065
5066 (void) get_overlay_strings_1 (it, charpos, 1);
5067
5068 CHECK_IT (it);
5069
5070 /* Value is non-zero if we found at least one overlay string. */
5071 return STRINGP (it->string);
5072 }
5073
5074
5075 \f
5076 /***********************************************************************
5077 Saving and restoring state
5078 ***********************************************************************/
5079
5080 /* Save current settings of IT on IT->stack. Called, for example,
5081 before setting up IT for an overlay string, to be able to restore
5082 IT's settings to what they were after the overlay string has been
5083 processed. */
5084
5085 static void
5086 push_it (it)
5087 struct it *it;
5088 {
5089 struct iterator_stack_entry *p;
5090
5091 xassert (it->sp < IT_STACK_SIZE);
5092 p = it->stack + it->sp;
5093
5094 p->stop_charpos = it->stop_charpos;
5095 p->cmp_it = it->cmp_it;
5096 xassert (it->face_id >= 0);
5097 p->face_id = it->face_id;
5098 p->string = it->string;
5099 p->method = it->method;
5100 p->from_overlay = it->from_overlay;
5101 switch (p->method)
5102 {
5103 case GET_FROM_IMAGE:
5104 p->u.image.object = it->object;
5105 p->u.image.image_id = it->image_id;
5106 p->u.image.slice = it->slice;
5107 break;
5108 case GET_FROM_STRETCH:
5109 p->u.stretch.object = it->object;
5110 break;
5111 }
5112 p->position = it->position;
5113 p->current = it->current;
5114 p->end_charpos = it->end_charpos;
5115 p->string_nchars = it->string_nchars;
5116 p->area = it->area;
5117 p->multibyte_p = it->multibyte_p;
5118 p->avoid_cursor_p = it->avoid_cursor_p;
5119 p->space_width = it->space_width;
5120 p->font_height = it->font_height;
5121 p->voffset = it->voffset;
5122 p->string_from_display_prop_p = it->string_from_display_prop_p;
5123 p->display_ellipsis_p = 0;
5124 p->line_wrap = it->line_wrap;
5125 ++it->sp;
5126 }
5127
5128
5129 /* Restore IT's settings from IT->stack. Called, for example, when no
5130 more overlay strings must be processed, and we return to delivering
5131 display elements from a buffer, or when the end of a string from a
5132 `display' property is reached and we return to delivering display
5133 elements from an overlay string, or from a buffer. */
5134
5135 static void
5136 pop_it (it)
5137 struct it *it;
5138 {
5139 struct iterator_stack_entry *p;
5140
5141 xassert (it->sp > 0);
5142 --it->sp;
5143 p = it->stack + it->sp;
5144 it->stop_charpos = p->stop_charpos;
5145 it->cmp_it = p->cmp_it;
5146 it->face_id = p->face_id;
5147 it->current = p->current;
5148 it->position = p->position;
5149 it->string = p->string;
5150 it->from_overlay = p->from_overlay;
5151 if (NILP (it->string))
5152 SET_TEXT_POS (it->current.string_pos, -1, -1);
5153 it->method = p->method;
5154 switch (it->method)
5155 {
5156 case GET_FROM_IMAGE:
5157 it->image_id = p->u.image.image_id;
5158 it->object = p->u.image.object;
5159 it->slice = p->u.image.slice;
5160 break;
5161 case GET_FROM_STRETCH:
5162 it->object = p->u.comp.object;
5163 break;
5164 case GET_FROM_BUFFER:
5165 it->object = it->w->buffer;
5166 break;
5167 case GET_FROM_STRING:
5168 it->object = it->string;
5169 break;
5170 }
5171 it->end_charpos = p->end_charpos;
5172 it->string_nchars = p->string_nchars;
5173 it->area = p->area;
5174 it->multibyte_p = p->multibyte_p;
5175 it->avoid_cursor_p = p->avoid_cursor_p;
5176 it->space_width = p->space_width;
5177 it->font_height = p->font_height;
5178 it->voffset = p->voffset;
5179 it->string_from_display_prop_p = p->string_from_display_prop_p;
5180 it->line_wrap = p->line_wrap;
5181 }
5182
5183
5184 \f
5185 /***********************************************************************
5186 Moving over lines
5187 ***********************************************************************/
5188
5189 /* Set IT's current position to the previous line start. */
5190
5191 static void
5192 back_to_previous_line_start (it)
5193 struct it *it;
5194 {
5195 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5196 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5197 }
5198
5199
5200 /* Move IT to the next line start.
5201
5202 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5203 we skipped over part of the text (as opposed to moving the iterator
5204 continuously over the text). Otherwise, don't change the value
5205 of *SKIPPED_P.
5206
5207 Newlines may come from buffer text, overlay strings, or strings
5208 displayed via the `display' property. That's the reason we can't
5209 simply use find_next_newline_no_quit.
5210
5211 Note that this function may not skip over invisible text that is so
5212 because of text properties and immediately follows a newline. If
5213 it would, function reseat_at_next_visible_line_start, when called
5214 from set_iterator_to_next, would effectively make invisible
5215 characters following a newline part of the wrong glyph row, which
5216 leads to wrong cursor motion. */
5217
5218 static int
5219 forward_to_next_line_start (it, skipped_p)
5220 struct it *it;
5221 int *skipped_p;
5222 {
5223 int old_selective, newline_found_p, n;
5224 const int MAX_NEWLINE_DISTANCE = 500;
5225
5226 /* If already on a newline, just consume it to avoid unintended
5227 skipping over invisible text below. */
5228 if (it->what == IT_CHARACTER
5229 && it->c == '\n'
5230 && CHARPOS (it->position) == IT_CHARPOS (*it))
5231 {
5232 set_iterator_to_next (it, 0);
5233 it->c = 0;
5234 return 1;
5235 }
5236
5237 /* Don't handle selective display in the following. It's (a)
5238 unnecessary because it's done by the caller, and (b) leads to an
5239 infinite recursion because next_element_from_ellipsis indirectly
5240 calls this function. */
5241 old_selective = it->selective;
5242 it->selective = 0;
5243
5244 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5245 from buffer text. */
5246 for (n = newline_found_p = 0;
5247 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5248 n += STRINGP (it->string) ? 0 : 1)
5249 {
5250 if (!get_next_display_element (it))
5251 return 0;
5252 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5253 set_iterator_to_next (it, 0);
5254 }
5255
5256 /* If we didn't find a newline near enough, see if we can use a
5257 short-cut. */
5258 if (!newline_found_p)
5259 {
5260 int start = IT_CHARPOS (*it);
5261 int limit = find_next_newline_no_quit (start, 1);
5262 Lisp_Object pos;
5263
5264 xassert (!STRINGP (it->string));
5265
5266 /* If there isn't any `display' property in sight, and no
5267 overlays, we can just use the position of the newline in
5268 buffer text. */
5269 if (it->stop_charpos >= limit
5270 || ((pos = Fnext_single_property_change (make_number (start),
5271 Qdisplay,
5272 Qnil, make_number (limit)),
5273 NILP (pos))
5274 && next_overlay_change (start) == ZV))
5275 {
5276 IT_CHARPOS (*it) = limit;
5277 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5278 *skipped_p = newline_found_p = 1;
5279 }
5280 else
5281 {
5282 while (get_next_display_element (it)
5283 && !newline_found_p)
5284 {
5285 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5286 set_iterator_to_next (it, 0);
5287 }
5288 }
5289 }
5290
5291 it->selective = old_selective;
5292 return newline_found_p;
5293 }
5294
5295
5296 /* Set IT's current position to the previous visible line start. Skip
5297 invisible text that is so either due to text properties or due to
5298 selective display. Caution: this does not change IT->current_x and
5299 IT->hpos. */
5300
5301 static void
5302 back_to_previous_visible_line_start (it)
5303 struct it *it;
5304 {
5305 while (IT_CHARPOS (*it) > BEGV)
5306 {
5307 back_to_previous_line_start (it);
5308
5309 if (IT_CHARPOS (*it) <= BEGV)
5310 break;
5311
5312 /* If selective > 0, then lines indented more than that values
5313 are invisible. */
5314 if (it->selective > 0
5315 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5316 (double) it->selective)) /* iftc */
5317 continue;
5318
5319 /* Check the newline before point for invisibility. */
5320 {
5321 Lisp_Object prop;
5322 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5323 Qinvisible, it->window);
5324 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5325 continue;
5326 }
5327
5328 if (IT_CHARPOS (*it) <= BEGV)
5329 break;
5330
5331 {
5332 struct it it2;
5333 int pos;
5334 EMACS_INT beg, end;
5335 Lisp_Object val, overlay;
5336
5337 /* If newline is part of a composition, continue from start of composition */
5338 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5339 && beg < IT_CHARPOS (*it))
5340 goto replaced;
5341
5342 /* If newline is replaced by a display property, find start of overlay
5343 or interval and continue search from that point. */
5344 it2 = *it;
5345 pos = --IT_CHARPOS (it2);
5346 --IT_BYTEPOS (it2);
5347 it2.sp = 0;
5348 it2.string_from_display_prop_p = 0;
5349 if (handle_display_prop (&it2) == HANDLED_RETURN
5350 && !NILP (val = get_char_property_and_overlay
5351 (make_number (pos), Qdisplay, Qnil, &overlay))
5352 && (OVERLAYP (overlay)
5353 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5354 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5355 goto replaced;
5356
5357 /* Newline is not replaced by anything -- so we are done. */
5358 break;
5359
5360 replaced:
5361 if (beg < BEGV)
5362 beg = BEGV;
5363 IT_CHARPOS (*it) = beg;
5364 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5365 }
5366 }
5367
5368 it->continuation_lines_width = 0;
5369
5370 xassert (IT_CHARPOS (*it) >= BEGV);
5371 xassert (IT_CHARPOS (*it) == BEGV
5372 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5373 CHECK_IT (it);
5374 }
5375
5376
5377 /* Reseat iterator IT at the previous visible line start. Skip
5378 invisible text that is so either due to text properties or due to
5379 selective display. At the end, update IT's overlay information,
5380 face information etc. */
5381
5382 void
5383 reseat_at_previous_visible_line_start (it)
5384 struct it *it;
5385 {
5386 back_to_previous_visible_line_start (it);
5387 reseat (it, it->current.pos, 1);
5388 CHECK_IT (it);
5389 }
5390
5391
5392 /* Reseat iterator IT on the next visible line start in the current
5393 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5394 preceding the line start. Skip over invisible text that is so
5395 because of selective display. Compute faces, overlays etc at the
5396 new position. Note that this function does not skip over text that
5397 is invisible because of text properties. */
5398
5399 static void
5400 reseat_at_next_visible_line_start (it, on_newline_p)
5401 struct it *it;
5402 int on_newline_p;
5403 {
5404 int newline_found_p, skipped_p = 0;
5405
5406 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5407
5408 /* Skip over lines that are invisible because they are indented
5409 more than the value of IT->selective. */
5410 if (it->selective > 0)
5411 while (IT_CHARPOS (*it) < ZV
5412 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5413 (double) it->selective)) /* iftc */
5414 {
5415 xassert (IT_BYTEPOS (*it) == BEGV
5416 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5417 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5418 }
5419
5420 /* Position on the newline if that's what's requested. */
5421 if (on_newline_p && newline_found_p)
5422 {
5423 if (STRINGP (it->string))
5424 {
5425 if (IT_STRING_CHARPOS (*it) > 0)
5426 {
5427 --IT_STRING_CHARPOS (*it);
5428 --IT_STRING_BYTEPOS (*it);
5429 }
5430 }
5431 else if (IT_CHARPOS (*it) > BEGV)
5432 {
5433 --IT_CHARPOS (*it);
5434 --IT_BYTEPOS (*it);
5435 reseat (it, it->current.pos, 0);
5436 }
5437 }
5438 else if (skipped_p)
5439 reseat (it, it->current.pos, 0);
5440
5441 CHECK_IT (it);
5442 }
5443
5444
5445 \f
5446 /***********************************************************************
5447 Changing an iterator's position
5448 ***********************************************************************/
5449
5450 /* Change IT's current position to POS in current_buffer. If FORCE_P
5451 is non-zero, always check for text properties at the new position.
5452 Otherwise, text properties are only looked up if POS >=
5453 IT->check_charpos of a property. */
5454
5455 static void
5456 reseat (it, pos, force_p)
5457 struct it *it;
5458 struct text_pos pos;
5459 int force_p;
5460 {
5461 int original_pos = IT_CHARPOS (*it);
5462
5463 reseat_1 (it, pos, 0);
5464
5465 /* Determine where to check text properties. Avoid doing it
5466 where possible because text property lookup is very expensive. */
5467 if (force_p
5468 || CHARPOS (pos) > it->stop_charpos
5469 || CHARPOS (pos) < original_pos)
5470 handle_stop (it);
5471
5472 CHECK_IT (it);
5473 }
5474
5475
5476 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5477 IT->stop_pos to POS, also. */
5478
5479 static void
5480 reseat_1 (it, pos, set_stop_p)
5481 struct it *it;
5482 struct text_pos pos;
5483 int set_stop_p;
5484 {
5485 /* Don't call this function when scanning a C string. */
5486 xassert (it->s == NULL);
5487
5488 /* POS must be a reasonable value. */
5489 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5490
5491 it->current.pos = it->position = pos;
5492 it->end_charpos = ZV;
5493 it->dpvec = NULL;
5494 it->current.dpvec_index = -1;
5495 it->current.overlay_string_index = -1;
5496 IT_STRING_CHARPOS (*it) = -1;
5497 IT_STRING_BYTEPOS (*it) = -1;
5498 it->string = Qnil;
5499 it->string_from_display_prop_p = 0;
5500 it->method = GET_FROM_BUFFER;
5501 it->object = it->w->buffer;
5502 it->area = TEXT_AREA;
5503 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5504 it->sp = 0;
5505 it->string_from_display_prop_p = 0;
5506 it->face_before_selective_p = 0;
5507
5508 if (set_stop_p)
5509 it->stop_charpos = CHARPOS (pos);
5510 }
5511
5512
5513 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5514 If S is non-null, it is a C string to iterate over. Otherwise,
5515 STRING gives a Lisp string to iterate over.
5516
5517 If PRECISION > 0, don't return more then PRECISION number of
5518 characters from the string.
5519
5520 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5521 characters have been returned. FIELD_WIDTH < 0 means an infinite
5522 field width.
5523
5524 MULTIBYTE = 0 means disable processing of multibyte characters,
5525 MULTIBYTE > 0 means enable it,
5526 MULTIBYTE < 0 means use IT->multibyte_p.
5527
5528 IT must be initialized via a prior call to init_iterator before
5529 calling this function. */
5530
5531 static void
5532 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5533 struct it *it;
5534 unsigned char *s;
5535 Lisp_Object string;
5536 int charpos;
5537 int precision, field_width, multibyte;
5538 {
5539 /* No region in strings. */
5540 it->region_beg_charpos = it->region_end_charpos = -1;
5541
5542 /* No text property checks performed by default, but see below. */
5543 it->stop_charpos = -1;
5544
5545 /* Set iterator position and end position. */
5546 bzero (&it->current, sizeof it->current);
5547 it->current.overlay_string_index = -1;
5548 it->current.dpvec_index = -1;
5549 xassert (charpos >= 0);
5550
5551 /* If STRING is specified, use its multibyteness, otherwise use the
5552 setting of MULTIBYTE, if specified. */
5553 if (multibyte >= 0)
5554 it->multibyte_p = multibyte > 0;
5555
5556 if (s == NULL)
5557 {
5558 xassert (STRINGP (string));
5559 it->string = string;
5560 it->s = NULL;
5561 it->end_charpos = it->string_nchars = SCHARS (string);
5562 it->method = GET_FROM_STRING;
5563 it->current.string_pos = string_pos (charpos, string);
5564 }
5565 else
5566 {
5567 it->s = s;
5568 it->string = Qnil;
5569
5570 /* Note that we use IT->current.pos, not it->current.string_pos,
5571 for displaying C strings. */
5572 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5573 if (it->multibyte_p)
5574 {
5575 it->current.pos = c_string_pos (charpos, s, 1);
5576 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5577 }
5578 else
5579 {
5580 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5581 it->end_charpos = it->string_nchars = strlen (s);
5582 }
5583
5584 it->method = GET_FROM_C_STRING;
5585 }
5586
5587 /* PRECISION > 0 means don't return more than PRECISION characters
5588 from the string. */
5589 if (precision > 0 && it->end_charpos - charpos > precision)
5590 it->end_charpos = it->string_nchars = charpos + precision;
5591
5592 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5593 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5594 FIELD_WIDTH < 0 means infinite field width. This is useful for
5595 padding with `-' at the end of a mode line. */
5596 if (field_width < 0)
5597 field_width = INFINITY;
5598 if (field_width > it->end_charpos - charpos)
5599 it->end_charpos = charpos + field_width;
5600
5601 /* Use the standard display table for displaying strings. */
5602 if (DISP_TABLE_P (Vstandard_display_table))
5603 it->dp = XCHAR_TABLE (Vstandard_display_table);
5604
5605 it->stop_charpos = charpos;
5606 CHECK_IT (it);
5607 }
5608
5609
5610 \f
5611 /***********************************************************************
5612 Iteration
5613 ***********************************************************************/
5614
5615 /* Map enum it_method value to corresponding next_element_from_* function. */
5616
5617 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5618 {
5619 next_element_from_buffer,
5620 next_element_from_display_vector,
5621 next_element_from_string,
5622 next_element_from_c_string,
5623 next_element_from_image,
5624 next_element_from_stretch
5625 };
5626
5627 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5628
5629
5630 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5631 (possibly with the following characters). */
5632
5633 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS) \
5634 ((IT)->cmp_it.id >= 0 \
5635 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5636 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5637 (IT)->end_charpos, (IT)->w, \
5638 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5639 (IT)->string)))
5640
5641
5642 /* Load IT's display element fields with information about the next
5643 display element from the current position of IT. Value is zero if
5644 end of buffer (or C string) is reached. */
5645
5646 static struct frame *last_escape_glyph_frame = NULL;
5647 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5648 static int last_escape_glyph_merged_face_id = 0;
5649
5650 int
5651 get_next_display_element (it)
5652 struct it *it;
5653 {
5654 /* Non-zero means that we found a display element. Zero means that
5655 we hit the end of what we iterate over. Performance note: the
5656 function pointer `method' used here turns out to be faster than
5657 using a sequence of if-statements. */
5658 int success_p;
5659
5660 get_next:
5661 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5662
5663 if (it->what == IT_CHARACTER)
5664 {
5665 /* Map via display table or translate control characters.
5666 IT->c, IT->len etc. have been set to the next character by
5667 the function call above. If we have a display table, and it
5668 contains an entry for IT->c, translate it. Don't do this if
5669 IT->c itself comes from a display table, otherwise we could
5670 end up in an infinite recursion. (An alternative could be to
5671 count the recursion depth of this function and signal an
5672 error when a certain maximum depth is reached.) Is it worth
5673 it? */
5674 if (success_p && it->dpvec == NULL)
5675 {
5676 Lisp_Object dv;
5677
5678 if (it->dp
5679 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5680 VECTORP (dv)))
5681 {
5682 struct Lisp_Vector *v = XVECTOR (dv);
5683
5684 /* Return the first character from the display table
5685 entry, if not empty. If empty, don't display the
5686 current character. */
5687 if (v->size)
5688 {
5689 it->dpvec_char_len = it->len;
5690 it->dpvec = v->contents;
5691 it->dpend = v->contents + v->size;
5692 it->current.dpvec_index = 0;
5693 it->dpvec_face_id = -1;
5694 it->saved_face_id = it->face_id;
5695 it->method = GET_FROM_DISPLAY_VECTOR;
5696 it->ellipsis_p = 0;
5697 }
5698 else
5699 {
5700 set_iterator_to_next (it, 0);
5701 }
5702 goto get_next;
5703 }
5704
5705 /* Translate control characters into `\003' or `^C' form.
5706 Control characters coming from a display table entry are
5707 currently not translated because we use IT->dpvec to hold
5708 the translation. This could easily be changed but I
5709 don't believe that it is worth doing.
5710
5711 If it->multibyte_p is nonzero, non-printable non-ASCII
5712 characters are also translated to octal form.
5713
5714 If it->multibyte_p is zero, eight-bit characters that
5715 don't have corresponding multibyte char code are also
5716 translated to octal form. */
5717 else if ((it->c < ' '
5718 ? (it->area != TEXT_AREA
5719 /* In mode line, treat \n, \t like other crl chars. */
5720 || (it->c != '\t'
5721 && it->glyph_row
5722 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5723 || (it->c != '\n' && it->c != '\t'))
5724 : (it->multibyte_p
5725 ? (!CHAR_PRINTABLE_P (it->c)
5726 || (!NILP (Vnobreak_char_display)
5727 && (it->c == 0xA0 /* NO-BREAK SPACE */
5728 || it->c == 0xAD /* SOFT HYPHEN */)))
5729 : (it->c >= 127
5730 && (! unibyte_display_via_language_environment
5731 || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
5732 {
5733 /* IT->c is a control character which must be displayed
5734 either as '\003' or as `^C' where the '\\' and '^'
5735 can be defined in the display table. Fill
5736 IT->ctl_chars with glyphs for what we have to
5737 display. Then, set IT->dpvec to these glyphs. */
5738 Lisp_Object gc;
5739 int ctl_len;
5740 int face_id, lface_id = 0 ;
5741 int escape_glyph;
5742
5743 /* Handle control characters with ^. */
5744
5745 if (it->c < 128 && it->ctl_arrow_p)
5746 {
5747 int g;
5748
5749 g = '^'; /* default glyph for Control */
5750 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5751 if (it->dp
5752 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5753 && GLYPH_CODE_CHAR_VALID_P (gc))
5754 {
5755 g = GLYPH_CODE_CHAR (gc);
5756 lface_id = GLYPH_CODE_FACE (gc);
5757 }
5758 if (lface_id)
5759 {
5760 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5761 }
5762 else if (it->f == last_escape_glyph_frame
5763 && it->face_id == last_escape_glyph_face_id)
5764 {
5765 face_id = last_escape_glyph_merged_face_id;
5766 }
5767 else
5768 {
5769 /* Merge the escape-glyph face into the current face. */
5770 face_id = merge_faces (it->f, Qescape_glyph, 0,
5771 it->face_id);
5772 last_escape_glyph_frame = it->f;
5773 last_escape_glyph_face_id = it->face_id;
5774 last_escape_glyph_merged_face_id = face_id;
5775 }
5776
5777 XSETINT (it->ctl_chars[0], g);
5778 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5779 ctl_len = 2;
5780 goto display_control;
5781 }
5782
5783 /* Handle non-break space in the mode where it only gets
5784 highlighting. */
5785
5786 if (EQ (Vnobreak_char_display, Qt)
5787 && it->c == 0xA0)
5788 {
5789 /* Merge the no-break-space face into the current face. */
5790 face_id = merge_faces (it->f, Qnobreak_space, 0,
5791 it->face_id);
5792
5793 it->c = ' ';
5794 XSETINT (it->ctl_chars[0], ' ');
5795 ctl_len = 1;
5796 goto display_control;
5797 }
5798
5799 /* Handle sequences that start with the "escape glyph". */
5800
5801 /* the default escape glyph is \. */
5802 escape_glyph = '\\';
5803
5804 if (it->dp
5805 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5806 && GLYPH_CODE_CHAR_VALID_P (gc))
5807 {
5808 escape_glyph = GLYPH_CODE_CHAR (gc);
5809 lface_id = GLYPH_CODE_FACE (gc);
5810 }
5811 if (lface_id)
5812 {
5813 /* The display table specified a face.
5814 Merge it into face_id and also into escape_glyph. */
5815 face_id = merge_faces (it->f, Qt, lface_id,
5816 it->face_id);
5817 }
5818 else if (it->f == last_escape_glyph_frame
5819 && it->face_id == last_escape_glyph_face_id)
5820 {
5821 face_id = last_escape_glyph_merged_face_id;
5822 }
5823 else
5824 {
5825 /* Merge the escape-glyph face into the current face. */
5826 face_id = merge_faces (it->f, Qescape_glyph, 0,
5827 it->face_id);
5828 last_escape_glyph_frame = it->f;
5829 last_escape_glyph_face_id = it->face_id;
5830 last_escape_glyph_merged_face_id = face_id;
5831 }
5832
5833 /* Handle soft hyphens in the mode where they only get
5834 highlighting. */
5835
5836 if (EQ (Vnobreak_char_display, Qt)
5837 && it->c == 0xAD)
5838 {
5839 it->c = '-';
5840 XSETINT (it->ctl_chars[0], '-');
5841 ctl_len = 1;
5842 goto display_control;
5843 }
5844
5845 /* Handle non-break space and soft hyphen
5846 with the escape glyph. */
5847
5848 if (it->c == 0xA0 || it->c == 0xAD)
5849 {
5850 XSETINT (it->ctl_chars[0], escape_glyph);
5851 it->c = (it->c == 0xA0 ? ' ' : '-');
5852 XSETINT (it->ctl_chars[1], it->c);
5853 ctl_len = 2;
5854 goto display_control;
5855 }
5856
5857 {
5858 unsigned char str[MAX_MULTIBYTE_LENGTH];
5859 int len;
5860 int i;
5861
5862 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5863 if (CHAR_BYTE8_P (it->c))
5864 {
5865 str[0] = CHAR_TO_BYTE8 (it->c);
5866 len = 1;
5867 }
5868 else if (it->c < 256)
5869 {
5870 str[0] = it->c;
5871 len = 1;
5872 }
5873 else
5874 {
5875 /* It's an invalid character, which shouldn't
5876 happen actually, but due to bugs it may
5877 happen. Let's print the char as is, there's
5878 not much meaningful we can do with it. */
5879 str[0] = it->c;
5880 str[1] = it->c >> 8;
5881 str[2] = it->c >> 16;
5882 str[3] = it->c >> 24;
5883 len = 4;
5884 }
5885
5886 for (i = 0; i < len; i++)
5887 {
5888 int g;
5889 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5890 /* Insert three more glyphs into IT->ctl_chars for
5891 the octal display of the character. */
5892 g = ((str[i] >> 6) & 7) + '0';
5893 XSETINT (it->ctl_chars[i * 4 + 1], g);
5894 g = ((str[i] >> 3) & 7) + '0';
5895 XSETINT (it->ctl_chars[i * 4 + 2], g);
5896 g = (str[i] & 7) + '0';
5897 XSETINT (it->ctl_chars[i * 4 + 3], g);
5898 }
5899 ctl_len = len * 4;
5900 }
5901
5902 display_control:
5903 /* Set up IT->dpvec and return first character from it. */
5904 it->dpvec_char_len = it->len;
5905 it->dpvec = it->ctl_chars;
5906 it->dpend = it->dpvec + ctl_len;
5907 it->current.dpvec_index = 0;
5908 it->dpvec_face_id = face_id;
5909 it->saved_face_id = it->face_id;
5910 it->method = GET_FROM_DISPLAY_VECTOR;
5911 it->ellipsis_p = 0;
5912 goto get_next;
5913 }
5914 }
5915 }
5916
5917 #ifdef HAVE_WINDOW_SYSTEM
5918 /* Adjust face id for a multibyte character. There are no multibyte
5919 character in unibyte text. */
5920 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5921 && it->multibyte_p
5922 && success_p
5923 && FRAME_WINDOW_P (it->f))
5924 {
5925 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5926
5927 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
5928 {
5929 /* Automatic composition with glyph-string. */
5930 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
5931
5932 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
5933 }
5934 else
5935 {
5936 int pos = (it->s ? -1
5937 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5938 : IT_CHARPOS (*it));
5939
5940 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5941 }
5942 }
5943 #endif
5944
5945 /* Is this character the last one of a run of characters with
5946 box? If yes, set IT->end_of_box_run_p to 1. */
5947 if (it->face_box_p
5948 && it->s == NULL)
5949 {
5950 if (it->method == GET_FROM_STRING && it->sp)
5951 {
5952 int face_id = underlying_face_id (it);
5953 struct face *face = FACE_FROM_ID (it->f, face_id);
5954
5955 if (face)
5956 {
5957 if (face->box == FACE_NO_BOX)
5958 {
5959 /* If the box comes from face properties in a
5960 display string, check faces in that string. */
5961 int string_face_id = face_after_it_pos (it);
5962 it->end_of_box_run_p
5963 = (FACE_FROM_ID (it->f, string_face_id)->box
5964 == FACE_NO_BOX);
5965 }
5966 /* Otherwise, the box comes from the underlying face.
5967 If this is the last string character displayed, check
5968 the next buffer location. */
5969 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
5970 && (it->current.overlay_string_index
5971 == it->n_overlay_strings - 1))
5972 {
5973 EMACS_INT ignore;
5974 int next_face_id;
5975 struct text_pos pos = it->current.pos;
5976 INC_TEXT_POS (pos, it->multibyte_p);
5977
5978 next_face_id = face_at_buffer_position
5979 (it->w, CHARPOS (pos), it->region_beg_charpos,
5980 it->region_end_charpos, &ignore,
5981 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
5982 -1);
5983 it->end_of_box_run_p
5984 = (FACE_FROM_ID (it->f, next_face_id)->box
5985 == FACE_NO_BOX);
5986 }
5987 }
5988 }
5989 else
5990 {
5991 int face_id = face_after_it_pos (it);
5992 it->end_of_box_run_p
5993 = (face_id != it->face_id
5994 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
5995 }
5996 }
5997
5998 /* Value is 0 if end of buffer or string reached. */
5999 return success_p;
6000 }
6001
6002
6003 /* Move IT to the next display element.
6004
6005 RESEAT_P non-zero means if called on a newline in buffer text,
6006 skip to the next visible line start.
6007
6008 Functions get_next_display_element and set_iterator_to_next are
6009 separate because I find this arrangement easier to handle than a
6010 get_next_display_element function that also increments IT's
6011 position. The way it is we can first look at an iterator's current
6012 display element, decide whether it fits on a line, and if it does,
6013 increment the iterator position. The other way around we probably
6014 would either need a flag indicating whether the iterator has to be
6015 incremented the next time, or we would have to implement a
6016 decrement position function which would not be easy to write. */
6017
6018 void
6019 set_iterator_to_next (it, reseat_p)
6020 struct it *it;
6021 int reseat_p;
6022 {
6023 /* Reset flags indicating start and end of a sequence of characters
6024 with box. Reset them at the start of this function because
6025 moving the iterator to a new position might set them. */
6026 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6027
6028 switch (it->method)
6029 {
6030 case GET_FROM_BUFFER:
6031 /* The current display element of IT is a character from
6032 current_buffer. Advance in the buffer, and maybe skip over
6033 invisible lines that are so because of selective display. */
6034 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6035 reseat_at_next_visible_line_start (it, 0);
6036 else if (it->cmp_it.id >= 0)
6037 {
6038 IT_CHARPOS (*it) += it->cmp_it.nchars;
6039 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6040 if (it->cmp_it.to < it->cmp_it.nglyphs)
6041 it->cmp_it.from = it->cmp_it.to;
6042 else
6043 {
6044 it->cmp_it.id = -1;
6045 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6046 IT_BYTEPOS (*it), it->stop_charpos,
6047 Qnil);
6048 }
6049 }
6050 else
6051 {
6052 xassert (it->len != 0);
6053 IT_BYTEPOS (*it) += it->len;
6054 IT_CHARPOS (*it) += 1;
6055 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6056 }
6057 break;
6058
6059 case GET_FROM_C_STRING:
6060 /* Current display element of IT is from a C string. */
6061 IT_BYTEPOS (*it) += it->len;
6062 IT_CHARPOS (*it) += 1;
6063 break;
6064
6065 case GET_FROM_DISPLAY_VECTOR:
6066 /* Current display element of IT is from a display table entry.
6067 Advance in the display table definition. Reset it to null if
6068 end reached, and continue with characters from buffers/
6069 strings. */
6070 ++it->current.dpvec_index;
6071
6072 /* Restore face of the iterator to what they were before the
6073 display vector entry (these entries may contain faces). */
6074 it->face_id = it->saved_face_id;
6075
6076 if (it->dpvec + it->current.dpvec_index == it->dpend)
6077 {
6078 int recheck_faces = it->ellipsis_p;
6079
6080 if (it->s)
6081 it->method = GET_FROM_C_STRING;
6082 else if (STRINGP (it->string))
6083 it->method = GET_FROM_STRING;
6084 else
6085 {
6086 it->method = GET_FROM_BUFFER;
6087 it->object = it->w->buffer;
6088 }
6089
6090 it->dpvec = NULL;
6091 it->current.dpvec_index = -1;
6092
6093 /* Skip over characters which were displayed via IT->dpvec. */
6094 if (it->dpvec_char_len < 0)
6095 reseat_at_next_visible_line_start (it, 1);
6096 else if (it->dpvec_char_len > 0)
6097 {
6098 if (it->method == GET_FROM_STRING
6099 && it->n_overlay_strings > 0)
6100 it->ignore_overlay_strings_at_pos_p = 1;
6101 it->len = it->dpvec_char_len;
6102 set_iterator_to_next (it, reseat_p);
6103 }
6104
6105 /* Maybe recheck faces after display vector */
6106 if (recheck_faces)
6107 it->stop_charpos = IT_CHARPOS (*it);
6108 }
6109 break;
6110
6111 case GET_FROM_STRING:
6112 /* Current display element is a character from a Lisp string. */
6113 xassert (it->s == NULL && STRINGP (it->string));
6114 if (it->cmp_it.id >= 0)
6115 {
6116 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6117 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6118 if (it->cmp_it.to < it->cmp_it.nglyphs)
6119 it->cmp_it.from = it->cmp_it.to;
6120 else
6121 {
6122 it->cmp_it.id = -1;
6123 composition_compute_stop_pos (&it->cmp_it,
6124 IT_STRING_CHARPOS (*it),
6125 IT_STRING_BYTEPOS (*it),
6126 it->stop_charpos, it->string);
6127 }
6128 }
6129 else
6130 {
6131 IT_STRING_BYTEPOS (*it) += it->len;
6132 IT_STRING_CHARPOS (*it) += 1;
6133 }
6134
6135 consider_string_end:
6136
6137 if (it->current.overlay_string_index >= 0)
6138 {
6139 /* IT->string is an overlay string. Advance to the
6140 next, if there is one. */
6141 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6142 {
6143 it->ellipsis_p = 0;
6144 next_overlay_string (it);
6145 if (it->ellipsis_p)
6146 setup_for_ellipsis (it, 0);
6147 }
6148 }
6149 else
6150 {
6151 /* IT->string is not an overlay string. If we reached
6152 its end, and there is something on IT->stack, proceed
6153 with what is on the stack. This can be either another
6154 string, this time an overlay string, or a buffer. */
6155 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6156 && it->sp > 0)
6157 {
6158 pop_it (it);
6159 if (it->method == GET_FROM_STRING)
6160 goto consider_string_end;
6161 }
6162 }
6163 break;
6164
6165 case GET_FROM_IMAGE:
6166 case GET_FROM_STRETCH:
6167 /* The position etc with which we have to proceed are on
6168 the stack. The position may be at the end of a string,
6169 if the `display' property takes up the whole string. */
6170 xassert (it->sp > 0);
6171 pop_it (it);
6172 if (it->method == GET_FROM_STRING)
6173 goto consider_string_end;
6174 break;
6175
6176 default:
6177 /* There are no other methods defined, so this should be a bug. */
6178 abort ();
6179 }
6180
6181 xassert (it->method != GET_FROM_STRING
6182 || (STRINGP (it->string)
6183 && IT_STRING_CHARPOS (*it) >= 0));
6184 }
6185
6186 /* Load IT's display element fields with information about the next
6187 display element which comes from a display table entry or from the
6188 result of translating a control character to one of the forms `^C'
6189 or `\003'.
6190
6191 IT->dpvec holds the glyphs to return as characters.
6192 IT->saved_face_id holds the face id before the display vector--
6193 it is restored into IT->face_idin set_iterator_to_next. */
6194
6195 static int
6196 next_element_from_display_vector (it)
6197 struct it *it;
6198 {
6199 Lisp_Object gc;
6200
6201 /* Precondition. */
6202 xassert (it->dpvec && it->current.dpvec_index >= 0);
6203
6204 it->face_id = it->saved_face_id;
6205
6206 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6207 That seemed totally bogus - so I changed it... */
6208 gc = it->dpvec[it->current.dpvec_index];
6209
6210 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6211 {
6212 it->c = GLYPH_CODE_CHAR (gc);
6213 it->len = CHAR_BYTES (it->c);
6214
6215 /* The entry may contain a face id to use. Such a face id is
6216 the id of a Lisp face, not a realized face. A face id of
6217 zero means no face is specified. */
6218 if (it->dpvec_face_id >= 0)
6219 it->face_id = it->dpvec_face_id;
6220 else
6221 {
6222 int lface_id = GLYPH_CODE_FACE (gc);
6223 if (lface_id > 0)
6224 it->face_id = merge_faces (it->f, Qt, lface_id,
6225 it->saved_face_id);
6226 }
6227 }
6228 else
6229 /* Display table entry is invalid. Return a space. */
6230 it->c = ' ', it->len = 1;
6231
6232 /* Don't change position and object of the iterator here. They are
6233 still the values of the character that had this display table
6234 entry or was translated, and that's what we want. */
6235 it->what = IT_CHARACTER;
6236 return 1;
6237 }
6238
6239
6240 /* Load IT with the next display element from Lisp string IT->string.
6241 IT->current.string_pos is the current position within the string.
6242 If IT->current.overlay_string_index >= 0, the Lisp string is an
6243 overlay string. */
6244
6245 static int
6246 next_element_from_string (it)
6247 struct it *it;
6248 {
6249 struct text_pos position;
6250
6251 xassert (STRINGP (it->string));
6252 xassert (IT_STRING_CHARPOS (*it) >= 0);
6253 position = it->current.string_pos;
6254
6255 /* Time to check for invisible text? */
6256 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6257 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6258 {
6259 handle_stop (it);
6260
6261 /* Since a handler may have changed IT->method, we must
6262 recurse here. */
6263 return GET_NEXT_DISPLAY_ELEMENT (it);
6264 }
6265
6266 if (it->current.overlay_string_index >= 0)
6267 {
6268 /* Get the next character from an overlay string. In overlay
6269 strings, There is no field width or padding with spaces to
6270 do. */
6271 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6272 {
6273 it->what = IT_EOB;
6274 return 0;
6275 }
6276 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6277 IT_STRING_BYTEPOS (*it))
6278 && next_element_from_composition (it))
6279 {
6280 return 1;
6281 }
6282 else if (STRING_MULTIBYTE (it->string))
6283 {
6284 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6285 const unsigned char *s = (SDATA (it->string)
6286 + IT_STRING_BYTEPOS (*it));
6287 it->c = string_char_and_length (s, remaining, &it->len);
6288 }
6289 else
6290 {
6291 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6292 it->len = 1;
6293 }
6294 }
6295 else
6296 {
6297 /* Get the next character from a Lisp string that is not an
6298 overlay string. Such strings come from the mode line, for
6299 example. We may have to pad with spaces, or truncate the
6300 string. See also next_element_from_c_string. */
6301 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6302 {
6303 it->what = IT_EOB;
6304 return 0;
6305 }
6306 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6307 {
6308 /* Pad with spaces. */
6309 it->c = ' ', it->len = 1;
6310 CHARPOS (position) = BYTEPOS (position) = -1;
6311 }
6312 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6313 IT_STRING_BYTEPOS (*it))
6314 && next_element_from_composition (it))
6315 {
6316 return 1;
6317 }
6318 else if (STRING_MULTIBYTE (it->string))
6319 {
6320 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6321 const unsigned char *s = (SDATA (it->string)
6322 + IT_STRING_BYTEPOS (*it));
6323 it->c = string_char_and_length (s, maxlen, &it->len);
6324 }
6325 else
6326 {
6327 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6328 it->len = 1;
6329 }
6330 }
6331
6332 /* Record what we have and where it came from. */
6333 it->what = IT_CHARACTER;
6334 it->object = it->string;
6335 it->position = position;
6336 return 1;
6337 }
6338
6339
6340 /* Load IT with next display element from C string IT->s.
6341 IT->string_nchars is the maximum number of characters to return
6342 from the string. IT->end_charpos may be greater than
6343 IT->string_nchars when this function is called, in which case we
6344 may have to return padding spaces. Value is zero if end of string
6345 reached, including padding spaces. */
6346
6347 static int
6348 next_element_from_c_string (it)
6349 struct it *it;
6350 {
6351 int success_p = 1;
6352
6353 xassert (it->s);
6354 it->what = IT_CHARACTER;
6355 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6356 it->object = Qnil;
6357
6358 /* IT's position can be greater IT->string_nchars in case a field
6359 width or precision has been specified when the iterator was
6360 initialized. */
6361 if (IT_CHARPOS (*it) >= it->end_charpos)
6362 {
6363 /* End of the game. */
6364 it->what = IT_EOB;
6365 success_p = 0;
6366 }
6367 else if (IT_CHARPOS (*it) >= it->string_nchars)
6368 {
6369 /* Pad with spaces. */
6370 it->c = ' ', it->len = 1;
6371 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6372 }
6373 else if (it->multibyte_p)
6374 {
6375 /* Implementation note: The calls to strlen apparently aren't a
6376 performance problem because there is no noticeable performance
6377 difference between Emacs running in unibyte or multibyte mode. */
6378 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6379 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6380 maxlen, &it->len);
6381 }
6382 else
6383 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6384
6385 return success_p;
6386 }
6387
6388
6389 /* Set up IT to return characters from an ellipsis, if appropriate.
6390 The definition of the ellipsis glyphs may come from a display table
6391 entry. This function Fills IT with the first glyph from the
6392 ellipsis if an ellipsis is to be displayed. */
6393
6394 static int
6395 next_element_from_ellipsis (it)
6396 struct it *it;
6397 {
6398 if (it->selective_display_ellipsis_p)
6399 setup_for_ellipsis (it, it->len);
6400 else
6401 {
6402 /* The face at the current position may be different from the
6403 face we find after the invisible text. Remember what it
6404 was in IT->saved_face_id, and signal that it's there by
6405 setting face_before_selective_p. */
6406 it->saved_face_id = it->face_id;
6407 it->method = GET_FROM_BUFFER;
6408 it->object = it->w->buffer;
6409 reseat_at_next_visible_line_start (it, 1);
6410 it->face_before_selective_p = 1;
6411 }
6412
6413 return GET_NEXT_DISPLAY_ELEMENT (it);
6414 }
6415
6416
6417 /* Deliver an image display element. The iterator IT is already
6418 filled with image information (done in handle_display_prop). Value
6419 is always 1. */
6420
6421
6422 static int
6423 next_element_from_image (it)
6424 struct it *it;
6425 {
6426 it->what = IT_IMAGE;
6427 return 1;
6428 }
6429
6430
6431 /* Fill iterator IT with next display element from a stretch glyph
6432 property. IT->object is the value of the text property. Value is
6433 always 1. */
6434
6435 static int
6436 next_element_from_stretch (it)
6437 struct it *it;
6438 {
6439 it->what = IT_STRETCH;
6440 return 1;
6441 }
6442
6443
6444 /* Load IT with the next display element from current_buffer. Value
6445 is zero if end of buffer reached. IT->stop_charpos is the next
6446 position at which to stop and check for text properties or buffer
6447 end. */
6448
6449 static int
6450 next_element_from_buffer (it)
6451 struct it *it;
6452 {
6453 int success_p = 1;
6454
6455 xassert (IT_CHARPOS (*it) >= BEGV);
6456
6457 if (IT_CHARPOS (*it) >= it->stop_charpos)
6458 {
6459 if (IT_CHARPOS (*it) >= it->end_charpos)
6460 {
6461 int overlay_strings_follow_p;
6462
6463 /* End of the game, except when overlay strings follow that
6464 haven't been returned yet. */
6465 if (it->overlay_strings_at_end_processed_p)
6466 overlay_strings_follow_p = 0;
6467 else
6468 {
6469 it->overlay_strings_at_end_processed_p = 1;
6470 overlay_strings_follow_p = get_overlay_strings (it, 0);
6471 }
6472
6473 if (overlay_strings_follow_p)
6474 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6475 else
6476 {
6477 it->what = IT_EOB;
6478 it->position = it->current.pos;
6479 success_p = 0;
6480 }
6481 }
6482 else
6483 {
6484 handle_stop (it);
6485 return GET_NEXT_DISPLAY_ELEMENT (it);
6486 }
6487 }
6488 else
6489 {
6490 /* No face changes, overlays etc. in sight, so just return a
6491 character from current_buffer. */
6492 unsigned char *p;
6493
6494 /* Maybe run the redisplay end trigger hook. Performance note:
6495 This doesn't seem to cost measurable time. */
6496 if (it->redisplay_end_trigger_charpos
6497 && it->glyph_row
6498 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6499 run_redisplay_end_trigger_hook (it);
6500
6501 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
6502 && next_element_from_composition (it))
6503 {
6504 return 1;
6505 }
6506
6507 /* Get the next character, maybe multibyte. */
6508 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6509 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6510 it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
6511 else
6512 it->c = *p, it->len = 1;
6513
6514 /* Record what we have and where it came from. */
6515 it->what = IT_CHARACTER;
6516 it->object = it->w->buffer;
6517 it->position = it->current.pos;
6518
6519 /* Normally we return the character found above, except when we
6520 really want to return an ellipsis for selective display. */
6521 if (it->selective)
6522 {
6523 if (it->c == '\n')
6524 {
6525 /* A value of selective > 0 means hide lines indented more
6526 than that number of columns. */
6527 if (it->selective > 0
6528 && IT_CHARPOS (*it) + 1 < ZV
6529 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6530 IT_BYTEPOS (*it) + 1,
6531 (double) it->selective)) /* iftc */
6532 {
6533 success_p = next_element_from_ellipsis (it);
6534 it->dpvec_char_len = -1;
6535 }
6536 }
6537 else if (it->c == '\r' && it->selective == -1)
6538 {
6539 /* A value of selective == -1 means that everything from the
6540 CR to the end of the line is invisible, with maybe an
6541 ellipsis displayed for it. */
6542 success_p = next_element_from_ellipsis (it);
6543 it->dpvec_char_len = -1;
6544 }
6545 }
6546 }
6547
6548 /* Value is zero if end of buffer reached. */
6549 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6550 return success_p;
6551 }
6552
6553
6554 /* Run the redisplay end trigger hook for IT. */
6555
6556 static void
6557 run_redisplay_end_trigger_hook (it)
6558 struct it *it;
6559 {
6560 Lisp_Object args[3];
6561
6562 /* IT->glyph_row should be non-null, i.e. we should be actually
6563 displaying something, or otherwise we should not run the hook. */
6564 xassert (it->glyph_row);
6565
6566 /* Set up hook arguments. */
6567 args[0] = Qredisplay_end_trigger_functions;
6568 args[1] = it->window;
6569 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6570 it->redisplay_end_trigger_charpos = 0;
6571
6572 /* Since we are *trying* to run these functions, don't try to run
6573 them again, even if they get an error. */
6574 it->w->redisplay_end_trigger = Qnil;
6575 Frun_hook_with_args (3, args);
6576
6577 /* Notice if it changed the face of the character we are on. */
6578 handle_face_prop (it);
6579 }
6580
6581
6582 /* Deliver a composition display element. Unlike the other
6583 next_element_from_XXX, this function is not registered in the array
6584 get_next_element[]. It is called from next_element_from_buffer and
6585 next_element_from_string when necessary. */
6586
6587 static int
6588 next_element_from_composition (it)
6589 struct it *it;
6590 {
6591 it->what = IT_COMPOSITION;
6592 it->len = it->cmp_it.nbytes;
6593 if (STRINGP (it->string))
6594 {
6595 if (it->c < 0)
6596 {
6597 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6598 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6599 return 0;
6600 }
6601 it->position = it->current.string_pos;
6602 it->object = it->string;
6603 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6604 IT_STRING_BYTEPOS (*it), it->string);
6605 }
6606 else
6607 {
6608 if (it->c < 0)
6609 {
6610 IT_CHARPOS (*it) += it->cmp_it.nchars;
6611 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6612 return 0;
6613 }
6614 it->position = it->current.pos;
6615 it->object = it->w->buffer;
6616 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6617 IT_BYTEPOS (*it), Qnil);
6618 }
6619 return 1;
6620 }
6621
6622
6623 \f
6624 /***********************************************************************
6625 Moving an iterator without producing glyphs
6626 ***********************************************************************/
6627
6628 /* Check if iterator is at a position corresponding to a valid buffer
6629 position after some move_it_ call. */
6630
6631 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6632 ((it)->method == GET_FROM_STRING \
6633 ? IT_STRING_CHARPOS (*it) == 0 \
6634 : 1)
6635
6636
6637 /* Move iterator IT to a specified buffer or X position within one
6638 line on the display without producing glyphs.
6639
6640 OP should be a bit mask including some or all of these bits:
6641 MOVE_TO_X: Stop on reaching x-position TO_X.
6642 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6643 Regardless of OP's value, stop in reaching the end of the display line.
6644
6645 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6646 This means, in particular, that TO_X includes window's horizontal
6647 scroll amount.
6648
6649 The return value has several possible values that
6650 say what condition caused the scan to stop:
6651
6652 MOVE_POS_MATCH_OR_ZV
6653 - when TO_POS or ZV was reached.
6654
6655 MOVE_X_REACHED
6656 -when TO_X was reached before TO_POS or ZV were reached.
6657
6658 MOVE_LINE_CONTINUED
6659 - when we reached the end of the display area and the line must
6660 be continued.
6661
6662 MOVE_LINE_TRUNCATED
6663 - when we reached the end of the display area and the line is
6664 truncated.
6665
6666 MOVE_NEWLINE_OR_CR
6667 - when we stopped at a line end, i.e. a newline or a CR and selective
6668 display is on. */
6669
6670 static enum move_it_result
6671 move_it_in_display_line_to (struct it *it,
6672 EMACS_INT to_charpos, int to_x,
6673 enum move_operation_enum op)
6674 {
6675 enum move_it_result result = MOVE_UNDEFINED;
6676 struct glyph_row *saved_glyph_row;
6677 struct it wrap_it, atpos_it, atx_it;
6678 int may_wrap = 0;
6679
6680 /* Don't produce glyphs in produce_glyphs. */
6681 saved_glyph_row = it->glyph_row;
6682 it->glyph_row = NULL;
6683
6684 /* Use wrap_it to save a copy of IT wherever a word wrap could
6685 occur. Use atpos_it to save a copy of IT at the desired buffer
6686 position, if found, so that we can scan ahead and check if the
6687 word later overshoots the window edge. Use atx_it similarly, for
6688 pixel positions. */
6689 wrap_it.sp = -1;
6690 atpos_it.sp = -1;
6691 atx_it.sp = -1;
6692
6693 #define BUFFER_POS_REACHED_P() \
6694 ((op & MOVE_TO_POS) != 0 \
6695 && BUFFERP (it->object) \
6696 && IT_CHARPOS (*it) >= to_charpos \
6697 && (it->method == GET_FROM_BUFFER \
6698 || (it->method == GET_FROM_DISPLAY_VECTOR \
6699 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6700
6701 /* If there's a line-/wrap-prefix, handle it. */
6702 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
6703 && it->current_y < it->last_visible_y)
6704 handle_line_prefix (it);
6705
6706 while (1)
6707 {
6708 int x, i, ascent = 0, descent = 0;
6709
6710 /* Utility macro to reset an iterator with x, ascent, and descent. */
6711 #define IT_RESET_X_ASCENT_DESCENT(IT) \
6712 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
6713 (IT)->max_descent = descent)
6714
6715 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
6716 glyph). */
6717 if ((op & MOVE_TO_POS) != 0
6718 && BUFFERP (it->object)
6719 && it->method == GET_FROM_BUFFER
6720 && IT_CHARPOS (*it) > to_charpos)
6721 {
6722 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6723 {
6724 result = MOVE_POS_MATCH_OR_ZV;
6725 break;
6726 }
6727 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6728 /* If wrap_it is valid, the current position might be in a
6729 word that is wrapped. So, save the iterator in
6730 atpos_it and continue to see if wrapping happens. */
6731 atpos_it = *it;
6732 }
6733
6734 /* Stop when ZV reached.
6735 We used to stop here when TO_CHARPOS reached as well, but that is
6736 too soon if this glyph does not fit on this line. So we handle it
6737 explicitly below. */
6738 if (!get_next_display_element (it))
6739 {
6740 result = MOVE_POS_MATCH_OR_ZV;
6741 break;
6742 }
6743
6744 if (it->line_wrap == TRUNCATE)
6745 {
6746 if (BUFFER_POS_REACHED_P ())
6747 {
6748 result = MOVE_POS_MATCH_OR_ZV;
6749 break;
6750 }
6751 }
6752 else
6753 {
6754 if (it->line_wrap == WORD_WRAP)
6755 {
6756 if (IT_DISPLAYING_WHITESPACE (it))
6757 may_wrap = 1;
6758 else if (may_wrap)
6759 {
6760 /* We have reached a glyph that follows one or more
6761 whitespace characters. If the position is
6762 already found, we are done. */
6763 if (atpos_it.sp >= 0)
6764 {
6765 *it = atpos_it;
6766 result = MOVE_POS_MATCH_OR_ZV;
6767 goto done;
6768 }
6769 if (atx_it.sp >= 0)
6770 {
6771 *it = atx_it;
6772 result = MOVE_X_REACHED;
6773 goto done;
6774 }
6775 /* Otherwise, we can wrap here. */
6776 wrap_it = *it;
6777 may_wrap = 0;
6778 }
6779 }
6780 }
6781
6782 /* Remember the line height for the current line, in case
6783 the next element doesn't fit on the line. */
6784 ascent = it->max_ascent;
6785 descent = it->max_descent;
6786
6787 /* The call to produce_glyphs will get the metrics of the
6788 display element IT is loaded with. Record the x-position
6789 before this display element, in case it doesn't fit on the
6790 line. */
6791 x = it->current_x;
6792
6793 PRODUCE_GLYPHS (it);
6794
6795 if (it->area != TEXT_AREA)
6796 {
6797 set_iterator_to_next (it, 1);
6798 continue;
6799 }
6800
6801 /* The number of glyphs we get back in IT->nglyphs will normally
6802 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6803 character on a terminal frame, or (iii) a line end. For the
6804 second case, IT->nglyphs - 1 padding glyphs will be present
6805 (on X frames, there is only one glyph produced for a
6806 composite character.
6807
6808 The behavior implemented below means, for continuation lines,
6809 that as many spaces of a TAB as fit on the current line are
6810 displayed there. For terminal frames, as many glyphs of a
6811 multi-glyph character are displayed in the current line, too.
6812 This is what the old redisplay code did, and we keep it that
6813 way. Under X, the whole shape of a complex character must
6814 fit on the line or it will be completely displayed in the
6815 next line.
6816
6817 Note that both for tabs and padding glyphs, all glyphs have
6818 the same width. */
6819 if (it->nglyphs)
6820 {
6821 /* More than one glyph or glyph doesn't fit on line. All
6822 glyphs have the same width. */
6823 int single_glyph_width = it->pixel_width / it->nglyphs;
6824 int new_x;
6825 int x_before_this_char = x;
6826 int hpos_before_this_char = it->hpos;
6827
6828 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6829 {
6830 new_x = x + single_glyph_width;
6831
6832 /* We want to leave anything reaching TO_X to the caller. */
6833 if ((op & MOVE_TO_X) && new_x > to_x)
6834 {
6835 if (BUFFER_POS_REACHED_P ())
6836 {
6837 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6838 goto buffer_pos_reached;
6839 if (atpos_it.sp < 0)
6840 {
6841 atpos_it = *it;
6842 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6843 }
6844 }
6845 else
6846 {
6847 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6848 {
6849 it->current_x = x;
6850 result = MOVE_X_REACHED;
6851 break;
6852 }
6853 if (atx_it.sp < 0)
6854 {
6855 atx_it = *it;
6856 IT_RESET_X_ASCENT_DESCENT (&atx_it);
6857 }
6858 }
6859 }
6860
6861 if (/* Lines are continued. */
6862 it->line_wrap != TRUNCATE
6863 && (/* And glyph doesn't fit on the line. */
6864 new_x > it->last_visible_x
6865 /* Or it fits exactly and we're on a window
6866 system frame. */
6867 || (new_x == it->last_visible_x
6868 && FRAME_WINDOW_P (it->f))))
6869 {
6870 if (/* IT->hpos == 0 means the very first glyph
6871 doesn't fit on the line, e.g. a wide image. */
6872 it->hpos == 0
6873 || (new_x == it->last_visible_x
6874 && FRAME_WINDOW_P (it->f)))
6875 {
6876 ++it->hpos;
6877 it->current_x = new_x;
6878
6879 /* The character's last glyph just barely fits
6880 in this row. */
6881 if (i == it->nglyphs - 1)
6882 {
6883 /* If this is the destination position,
6884 return a position *before* it in this row,
6885 now that we know it fits in this row. */
6886 if (BUFFER_POS_REACHED_P ())
6887 {
6888 if (it->line_wrap != WORD_WRAP
6889 || wrap_it.sp < 0)
6890 {
6891 it->hpos = hpos_before_this_char;
6892 it->current_x = x_before_this_char;
6893 result = MOVE_POS_MATCH_OR_ZV;
6894 break;
6895 }
6896 if (it->line_wrap == WORD_WRAP
6897 && atpos_it.sp < 0)
6898 {
6899 atpos_it = *it;
6900 atpos_it.current_x = x_before_this_char;
6901 atpos_it.hpos = hpos_before_this_char;
6902 }
6903 }
6904
6905 set_iterator_to_next (it, 1);
6906 /* One graphical terminals, newlines may
6907 "overflow" into the fringe if
6908 overflow-newline-into-fringe is non-nil.
6909 On text-only terminals, newlines may
6910 overflow into the last glyph on the
6911 display line.*/
6912 if (!FRAME_WINDOW_P (it->f)
6913 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6914 {
6915 if (!get_next_display_element (it))
6916 {
6917 result = MOVE_POS_MATCH_OR_ZV;
6918 break;
6919 }
6920 if (BUFFER_POS_REACHED_P ())
6921 {
6922 if (ITERATOR_AT_END_OF_LINE_P (it))
6923 result = MOVE_POS_MATCH_OR_ZV;
6924 else
6925 result = MOVE_LINE_CONTINUED;
6926 break;
6927 }
6928 if (ITERATOR_AT_END_OF_LINE_P (it))
6929 {
6930 result = MOVE_NEWLINE_OR_CR;
6931 break;
6932 }
6933 }
6934 }
6935 }
6936 else
6937 IT_RESET_X_ASCENT_DESCENT (it);
6938
6939 if (wrap_it.sp >= 0)
6940 {
6941 *it = wrap_it;
6942 atpos_it.sp = -1;
6943 atx_it.sp = -1;
6944 }
6945
6946 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6947 IT_CHARPOS (*it)));
6948 result = MOVE_LINE_CONTINUED;
6949 break;
6950 }
6951
6952 if (BUFFER_POS_REACHED_P ())
6953 {
6954 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6955 goto buffer_pos_reached;
6956 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6957 {
6958 atpos_it = *it;
6959 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6960 }
6961 }
6962
6963 if (new_x > it->first_visible_x)
6964 {
6965 /* Glyph is visible. Increment number of glyphs that
6966 would be displayed. */
6967 ++it->hpos;
6968 }
6969 }
6970
6971 if (result != MOVE_UNDEFINED)
6972 break;
6973 }
6974 else if (BUFFER_POS_REACHED_P ())
6975 {
6976 buffer_pos_reached:
6977 IT_RESET_X_ASCENT_DESCENT (it);
6978 result = MOVE_POS_MATCH_OR_ZV;
6979 break;
6980 }
6981 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6982 {
6983 /* Stop when TO_X specified and reached. This check is
6984 necessary here because of lines consisting of a line end,
6985 only. The line end will not produce any glyphs and we
6986 would never get MOVE_X_REACHED. */
6987 xassert (it->nglyphs == 0);
6988 result = MOVE_X_REACHED;
6989 break;
6990 }
6991
6992 /* Is this a line end? If yes, we're done. */
6993 if (ITERATOR_AT_END_OF_LINE_P (it))
6994 {
6995 result = MOVE_NEWLINE_OR_CR;
6996 break;
6997 }
6998
6999 /* The current display element has been consumed. Advance
7000 to the next. */
7001 set_iterator_to_next (it, 1);
7002
7003 /* Stop if lines are truncated and IT's current x-position is
7004 past the right edge of the window now. */
7005 if (it->line_wrap == TRUNCATE
7006 && it->current_x >= it->last_visible_x)
7007 {
7008 if (!FRAME_WINDOW_P (it->f)
7009 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7010 {
7011 if (!get_next_display_element (it)
7012 || BUFFER_POS_REACHED_P ())
7013 {
7014 result = MOVE_POS_MATCH_OR_ZV;
7015 break;
7016 }
7017 if (ITERATOR_AT_END_OF_LINE_P (it))
7018 {
7019 result = MOVE_NEWLINE_OR_CR;
7020 break;
7021 }
7022 }
7023 result = MOVE_LINE_TRUNCATED;
7024 break;
7025 }
7026 #undef IT_RESET_X_ASCENT_DESCENT
7027 }
7028
7029 #undef BUFFER_POS_REACHED_P
7030
7031 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7032 restore the saved iterator. */
7033 if (atpos_it.sp >= 0)
7034 *it = atpos_it;
7035 else if (atx_it.sp >= 0)
7036 *it = atx_it;
7037
7038 done:
7039
7040 /* Restore the iterator settings altered at the beginning of this
7041 function. */
7042 it->glyph_row = saved_glyph_row;
7043 return result;
7044 }
7045
7046 /* For external use. */
7047 void
7048 move_it_in_display_line (struct it *it,
7049 EMACS_INT to_charpos, int to_x,
7050 enum move_operation_enum op)
7051 {
7052 if (it->line_wrap == WORD_WRAP
7053 && (op & MOVE_TO_X))
7054 {
7055 struct it save_it = *it;
7056 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7057 /* When word-wrap is on, TO_X may lie past the end
7058 of a wrapped line. Then it->current is the
7059 character on the next line, so backtrack to the
7060 space before the wrap point. */
7061 if (skip == MOVE_LINE_CONTINUED)
7062 {
7063 int prev_x = max (it->current_x - 1, 0);
7064 *it = save_it;
7065 move_it_in_display_line_to
7066 (it, -1, prev_x, MOVE_TO_X);
7067 }
7068 }
7069 else
7070 move_it_in_display_line_to (it, to_charpos, to_x, op);
7071 }
7072
7073
7074 /* Move IT forward until it satisfies one or more of the criteria in
7075 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7076
7077 OP is a bit-mask that specifies where to stop, and in particular,
7078 which of those four position arguments makes a difference. See the
7079 description of enum move_operation_enum.
7080
7081 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7082 screen line, this function will set IT to the next position >
7083 TO_CHARPOS. */
7084
7085 void
7086 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7087 struct it *it;
7088 int to_charpos, to_x, to_y, to_vpos;
7089 int op;
7090 {
7091 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7092 int line_height;
7093 int reached = 0;
7094
7095 for (;;)
7096 {
7097 if (op & MOVE_TO_VPOS)
7098 {
7099 /* If no TO_CHARPOS and no TO_X specified, stop at the
7100 start of the line TO_VPOS. */
7101 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7102 {
7103 if (it->vpos == to_vpos)
7104 {
7105 reached = 1;
7106 break;
7107 }
7108 else
7109 skip = move_it_in_display_line_to (it, -1, -1, 0);
7110 }
7111 else
7112 {
7113 /* TO_VPOS >= 0 means stop at TO_X in the line at
7114 TO_VPOS, or at TO_POS, whichever comes first. */
7115 if (it->vpos == to_vpos)
7116 {
7117 reached = 2;
7118 break;
7119 }
7120
7121 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7122
7123 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7124 {
7125 reached = 3;
7126 break;
7127 }
7128 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7129 {
7130 /* We have reached TO_X but not in the line we want. */
7131 skip = move_it_in_display_line_to (it, to_charpos,
7132 -1, MOVE_TO_POS);
7133 if (skip == MOVE_POS_MATCH_OR_ZV)
7134 {
7135 reached = 4;
7136 break;
7137 }
7138 }
7139 }
7140 }
7141 else if (op & MOVE_TO_Y)
7142 {
7143 struct it it_backup;
7144
7145 if (it->line_wrap == WORD_WRAP)
7146 it_backup = *it;
7147
7148 /* TO_Y specified means stop at TO_X in the line containing
7149 TO_Y---or at TO_CHARPOS if this is reached first. The
7150 problem is that we can't really tell whether the line
7151 contains TO_Y before we have completely scanned it, and
7152 this may skip past TO_X. What we do is to first scan to
7153 TO_X.
7154
7155 If TO_X is not specified, use a TO_X of zero. The reason
7156 is to make the outcome of this function more predictable.
7157 If we didn't use TO_X == 0, we would stop at the end of
7158 the line which is probably not what a caller would expect
7159 to happen. */
7160 skip = move_it_in_display_line_to
7161 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7162 (MOVE_TO_X | (op & MOVE_TO_POS)));
7163
7164 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7165 if (skip == MOVE_POS_MATCH_OR_ZV)
7166 reached = 5;
7167 else if (skip == MOVE_X_REACHED)
7168 {
7169 /* If TO_X was reached, we want to know whether TO_Y is
7170 in the line. We know this is the case if the already
7171 scanned glyphs make the line tall enough. Otherwise,
7172 we must check by scanning the rest of the line. */
7173 line_height = it->max_ascent + it->max_descent;
7174 if (to_y >= it->current_y
7175 && to_y < it->current_y + line_height)
7176 {
7177 reached = 6;
7178 break;
7179 }
7180 it_backup = *it;
7181 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7182 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7183 op & MOVE_TO_POS);
7184 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7185 line_height = it->max_ascent + it->max_descent;
7186 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7187
7188 if (to_y >= it->current_y
7189 && to_y < it->current_y + line_height)
7190 {
7191 /* If TO_Y is in this line and TO_X was reached
7192 above, we scanned too far. We have to restore
7193 IT's settings to the ones before skipping. */
7194 *it = it_backup;
7195 reached = 6;
7196 }
7197 else
7198 {
7199 skip = skip2;
7200 if (skip == MOVE_POS_MATCH_OR_ZV)
7201 reached = 7;
7202 }
7203 }
7204 else
7205 {
7206 /* Check whether TO_Y is in this line. */
7207 line_height = it->max_ascent + it->max_descent;
7208 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7209
7210 if (to_y >= it->current_y
7211 && to_y < it->current_y + line_height)
7212 {
7213 /* When word-wrap is on, TO_X may lie past the end
7214 of a wrapped line. Then it->current is the
7215 character on the next line, so backtrack to the
7216 space before the wrap point. */
7217 if (skip == MOVE_LINE_CONTINUED
7218 && it->line_wrap == WORD_WRAP)
7219 {
7220 int prev_x = max (it->current_x - 1, 0);
7221 *it = it_backup;
7222 skip = move_it_in_display_line_to
7223 (it, -1, prev_x, MOVE_TO_X);
7224 }
7225 reached = 6;
7226 }
7227 }
7228
7229 if (reached)
7230 break;
7231 }
7232 else if (BUFFERP (it->object)
7233 && (it->method == GET_FROM_BUFFER
7234 || it->method == GET_FROM_STRETCH)
7235 && IT_CHARPOS (*it) >= to_charpos)
7236 skip = MOVE_POS_MATCH_OR_ZV;
7237 else
7238 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7239
7240 switch (skip)
7241 {
7242 case MOVE_POS_MATCH_OR_ZV:
7243 reached = 8;
7244 goto out;
7245
7246 case MOVE_NEWLINE_OR_CR:
7247 set_iterator_to_next (it, 1);
7248 it->continuation_lines_width = 0;
7249 break;
7250
7251 case MOVE_LINE_TRUNCATED:
7252 it->continuation_lines_width = 0;
7253 reseat_at_next_visible_line_start (it, 0);
7254 if ((op & MOVE_TO_POS) != 0
7255 && IT_CHARPOS (*it) > to_charpos)
7256 {
7257 reached = 9;
7258 goto out;
7259 }
7260 break;
7261
7262 case MOVE_LINE_CONTINUED:
7263 /* For continued lines ending in a tab, some of the glyphs
7264 associated with the tab are displayed on the current
7265 line. Since it->current_x does not include these glyphs,
7266 we use it->last_visible_x instead. */
7267 if (it->c == '\t')
7268 {
7269 it->continuation_lines_width += it->last_visible_x;
7270 /* When moving by vpos, ensure that the iterator really
7271 advances to the next line (bug#847, bug#969). Fixme:
7272 do we need to do this in other circumstances? */
7273 if (it->current_x != it->last_visible_x
7274 && (op & MOVE_TO_VPOS)
7275 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7276 set_iterator_to_next (it, 0);
7277 }
7278 else
7279 it->continuation_lines_width += it->current_x;
7280 break;
7281
7282 default:
7283 abort ();
7284 }
7285
7286 /* Reset/increment for the next run. */
7287 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7288 it->current_x = it->hpos = 0;
7289 it->current_y += it->max_ascent + it->max_descent;
7290 ++it->vpos;
7291 last_height = it->max_ascent + it->max_descent;
7292 last_max_ascent = it->max_ascent;
7293 it->max_ascent = it->max_descent = 0;
7294 }
7295
7296 out:
7297
7298 /* On text terminals, we may stop at the end of a line in the middle
7299 of a multi-character glyph. If the glyph itself is continued,
7300 i.e. it is actually displayed on the next line, don't treat this
7301 stopping point as valid; move to the next line instead (unless
7302 that brings us offscreen). */
7303 if (!FRAME_WINDOW_P (it->f)
7304 && op & MOVE_TO_POS
7305 && IT_CHARPOS (*it) == to_charpos
7306 && it->what == IT_CHARACTER
7307 && it->nglyphs > 1
7308 && it->line_wrap == WINDOW_WRAP
7309 && it->current_x == it->last_visible_x - 1
7310 && it->c != '\n'
7311 && it->c != '\t'
7312 && it->vpos < XFASTINT (it->w->window_end_vpos))
7313 {
7314 it->continuation_lines_width += it->current_x;
7315 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7316 it->current_y += it->max_ascent + it->max_descent;
7317 ++it->vpos;
7318 last_height = it->max_ascent + it->max_descent;
7319 last_max_ascent = it->max_ascent;
7320 }
7321
7322 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7323 }
7324
7325
7326 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7327
7328 If DY > 0, move IT backward at least that many pixels. DY = 0
7329 means move IT backward to the preceding line start or BEGV. This
7330 function may move over more than DY pixels if IT->current_y - DY
7331 ends up in the middle of a line; in this case IT->current_y will be
7332 set to the top of the line moved to. */
7333
7334 void
7335 move_it_vertically_backward (it, dy)
7336 struct it *it;
7337 int dy;
7338 {
7339 int nlines, h;
7340 struct it it2, it3;
7341 int start_pos;
7342
7343 move_further_back:
7344 xassert (dy >= 0);
7345
7346 start_pos = IT_CHARPOS (*it);
7347
7348 /* Estimate how many newlines we must move back. */
7349 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7350
7351 /* Set the iterator's position that many lines back. */
7352 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7353 back_to_previous_visible_line_start (it);
7354
7355 /* Reseat the iterator here. When moving backward, we don't want
7356 reseat to skip forward over invisible text, set up the iterator
7357 to deliver from overlay strings at the new position etc. So,
7358 use reseat_1 here. */
7359 reseat_1 (it, it->current.pos, 1);
7360
7361 /* We are now surely at a line start. */
7362 it->current_x = it->hpos = 0;
7363 it->continuation_lines_width = 0;
7364
7365 /* Move forward and see what y-distance we moved. First move to the
7366 start of the next line so that we get its height. We need this
7367 height to be able to tell whether we reached the specified
7368 y-distance. */
7369 it2 = *it;
7370 it2.max_ascent = it2.max_descent = 0;
7371 do
7372 {
7373 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7374 MOVE_TO_POS | MOVE_TO_VPOS);
7375 }
7376 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7377 xassert (IT_CHARPOS (*it) >= BEGV);
7378 it3 = it2;
7379
7380 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7381 xassert (IT_CHARPOS (*it) >= BEGV);
7382 /* H is the actual vertical distance from the position in *IT
7383 and the starting position. */
7384 h = it2.current_y - it->current_y;
7385 /* NLINES is the distance in number of lines. */
7386 nlines = it2.vpos - it->vpos;
7387
7388 /* Correct IT's y and vpos position
7389 so that they are relative to the starting point. */
7390 it->vpos -= nlines;
7391 it->current_y -= h;
7392
7393 if (dy == 0)
7394 {
7395 /* DY == 0 means move to the start of the screen line. The
7396 value of nlines is > 0 if continuation lines were involved. */
7397 if (nlines > 0)
7398 move_it_by_lines (it, nlines, 1);
7399 }
7400 else
7401 {
7402 /* The y-position we try to reach, relative to *IT.
7403 Note that H has been subtracted in front of the if-statement. */
7404 int target_y = it->current_y + h - dy;
7405 int y0 = it3.current_y;
7406 int y1 = line_bottom_y (&it3);
7407 int line_height = y1 - y0;
7408
7409 /* If we did not reach target_y, try to move further backward if
7410 we can. If we moved too far backward, try to move forward. */
7411 if (target_y < it->current_y
7412 /* This is heuristic. In a window that's 3 lines high, with
7413 a line height of 13 pixels each, recentering with point
7414 on the bottom line will try to move -39/2 = 19 pixels
7415 backward. Try to avoid moving into the first line. */
7416 && (it->current_y - target_y
7417 > min (window_box_height (it->w), line_height * 2 / 3))
7418 && IT_CHARPOS (*it) > BEGV)
7419 {
7420 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7421 target_y - it->current_y));
7422 dy = it->current_y - target_y;
7423 goto move_further_back;
7424 }
7425 else if (target_y >= it->current_y + line_height
7426 && IT_CHARPOS (*it) < ZV)
7427 {
7428 /* Should move forward by at least one line, maybe more.
7429
7430 Note: Calling move_it_by_lines can be expensive on
7431 terminal frames, where compute_motion is used (via
7432 vmotion) to do the job, when there are very long lines
7433 and truncate-lines is nil. That's the reason for
7434 treating terminal frames specially here. */
7435
7436 if (!FRAME_WINDOW_P (it->f))
7437 move_it_vertically (it, target_y - (it->current_y + line_height));
7438 else
7439 {
7440 do
7441 {
7442 move_it_by_lines (it, 1, 1);
7443 }
7444 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7445 }
7446 }
7447 }
7448 }
7449
7450
7451 /* Move IT by a specified amount of pixel lines DY. DY negative means
7452 move backwards. DY = 0 means move to start of screen line. At the
7453 end, IT will be on the start of a screen line. */
7454
7455 void
7456 move_it_vertically (it, dy)
7457 struct it *it;
7458 int dy;
7459 {
7460 if (dy <= 0)
7461 move_it_vertically_backward (it, -dy);
7462 else
7463 {
7464 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7465 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7466 MOVE_TO_POS | MOVE_TO_Y);
7467 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7468
7469 /* If buffer ends in ZV without a newline, move to the start of
7470 the line to satisfy the post-condition. */
7471 if (IT_CHARPOS (*it) == ZV
7472 && ZV > BEGV
7473 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7474 move_it_by_lines (it, 0, 0);
7475 }
7476 }
7477
7478
7479 /* Move iterator IT past the end of the text line it is in. */
7480
7481 void
7482 move_it_past_eol (it)
7483 struct it *it;
7484 {
7485 enum move_it_result rc;
7486
7487 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7488 if (rc == MOVE_NEWLINE_OR_CR)
7489 set_iterator_to_next (it, 0);
7490 }
7491
7492
7493 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7494 negative means move up. DVPOS == 0 means move to the start of the
7495 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7496 NEED_Y_P is zero, IT->current_y will be left unchanged.
7497
7498 Further optimization ideas: If we would know that IT->f doesn't use
7499 a face with proportional font, we could be faster for
7500 truncate-lines nil. */
7501
7502 void
7503 move_it_by_lines (it, dvpos, need_y_p)
7504 struct it *it;
7505 int dvpos, need_y_p;
7506 {
7507 struct position pos;
7508
7509 /* The commented-out optimization uses vmotion on terminals. This
7510 gives bad results, because elements like it->what, on which
7511 callers such as pos_visible_p rely, aren't updated. */
7512 /* if (!FRAME_WINDOW_P (it->f))
7513 {
7514 struct text_pos textpos;
7515
7516 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7517 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7518 reseat (it, textpos, 1);
7519 it->vpos += pos.vpos;
7520 it->current_y += pos.vpos;
7521 }
7522 else */
7523
7524 if (dvpos == 0)
7525 {
7526 /* DVPOS == 0 means move to the start of the screen line. */
7527 move_it_vertically_backward (it, 0);
7528 xassert (it->current_x == 0 && it->hpos == 0);
7529 /* Let next call to line_bottom_y calculate real line height */
7530 last_height = 0;
7531 }
7532 else if (dvpos > 0)
7533 {
7534 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7535 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7536 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7537 }
7538 else
7539 {
7540 struct it it2;
7541 int start_charpos, i;
7542
7543 /* Start at the beginning of the screen line containing IT's
7544 position. This may actually move vertically backwards,
7545 in case of overlays, so adjust dvpos accordingly. */
7546 dvpos += it->vpos;
7547 move_it_vertically_backward (it, 0);
7548 dvpos -= it->vpos;
7549
7550 /* Go back -DVPOS visible lines and reseat the iterator there. */
7551 start_charpos = IT_CHARPOS (*it);
7552 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7553 back_to_previous_visible_line_start (it);
7554 reseat (it, it->current.pos, 1);
7555
7556 /* Move further back if we end up in a string or an image. */
7557 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7558 {
7559 /* First try to move to start of display line. */
7560 dvpos += it->vpos;
7561 move_it_vertically_backward (it, 0);
7562 dvpos -= it->vpos;
7563 if (IT_POS_VALID_AFTER_MOVE_P (it))
7564 break;
7565 /* If start of line is still in string or image,
7566 move further back. */
7567 back_to_previous_visible_line_start (it);
7568 reseat (it, it->current.pos, 1);
7569 dvpos--;
7570 }
7571
7572 it->current_x = it->hpos = 0;
7573
7574 /* Above call may have moved too far if continuation lines
7575 are involved. Scan forward and see if it did. */
7576 it2 = *it;
7577 it2.vpos = it2.current_y = 0;
7578 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7579 it->vpos -= it2.vpos;
7580 it->current_y -= it2.current_y;
7581 it->current_x = it->hpos = 0;
7582
7583 /* If we moved too far back, move IT some lines forward. */
7584 if (it2.vpos > -dvpos)
7585 {
7586 int delta = it2.vpos + dvpos;
7587 it2 = *it;
7588 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7589 /* Move back again if we got too far ahead. */
7590 if (IT_CHARPOS (*it) >= start_charpos)
7591 *it = it2;
7592 }
7593 }
7594 }
7595
7596 /* Return 1 if IT points into the middle of a display vector. */
7597
7598 int
7599 in_display_vector_p (it)
7600 struct it *it;
7601 {
7602 return (it->method == GET_FROM_DISPLAY_VECTOR
7603 && it->current.dpvec_index > 0
7604 && it->dpvec + it->current.dpvec_index != it->dpend);
7605 }
7606
7607 \f
7608 /***********************************************************************
7609 Messages
7610 ***********************************************************************/
7611
7612
7613 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7614 to *Messages*. */
7615
7616 void
7617 add_to_log (format, arg1, arg2)
7618 char *format;
7619 Lisp_Object arg1, arg2;
7620 {
7621 Lisp_Object args[3];
7622 Lisp_Object msg, fmt;
7623 char *buffer;
7624 int len;
7625 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7626 USE_SAFE_ALLOCA;
7627
7628 /* Do nothing if called asynchronously. Inserting text into
7629 a buffer may call after-change-functions and alike and
7630 that would means running Lisp asynchronously. */
7631 if (handling_signal)
7632 return;
7633
7634 fmt = msg = Qnil;
7635 GCPRO4 (fmt, msg, arg1, arg2);
7636
7637 args[0] = fmt = build_string (format);
7638 args[1] = arg1;
7639 args[2] = arg2;
7640 msg = Fformat (3, args);
7641
7642 len = SBYTES (msg) + 1;
7643 SAFE_ALLOCA (buffer, char *, len);
7644 bcopy (SDATA (msg), buffer, len);
7645
7646 message_dolog (buffer, len - 1, 1, 0);
7647 SAFE_FREE ();
7648
7649 UNGCPRO;
7650 }
7651
7652
7653 /* Output a newline in the *Messages* buffer if "needs" one. */
7654
7655 void
7656 message_log_maybe_newline ()
7657 {
7658 if (message_log_need_newline)
7659 message_dolog ("", 0, 1, 0);
7660 }
7661
7662
7663 /* Add a string M of length NBYTES to the message log, optionally
7664 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7665 nonzero, means interpret the contents of M as multibyte. This
7666 function calls low-level routines in order to bypass text property
7667 hooks, etc. which might not be safe to run.
7668
7669 This may GC (insert may run before/after change hooks),
7670 so the buffer M must NOT point to a Lisp string. */
7671
7672 void
7673 message_dolog (m, nbytes, nlflag, multibyte)
7674 const char *m;
7675 int nbytes, nlflag, multibyte;
7676 {
7677 if (!NILP (Vmemory_full))
7678 return;
7679
7680 if (!NILP (Vmessage_log_max))
7681 {
7682 struct buffer *oldbuf;
7683 Lisp_Object oldpoint, oldbegv, oldzv;
7684 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7685 int point_at_end = 0;
7686 int zv_at_end = 0;
7687 Lisp_Object old_deactivate_mark, tem;
7688 struct gcpro gcpro1;
7689
7690 old_deactivate_mark = Vdeactivate_mark;
7691 oldbuf = current_buffer;
7692 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7693 current_buffer->undo_list = Qt;
7694
7695 oldpoint = message_dolog_marker1;
7696 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7697 oldbegv = message_dolog_marker2;
7698 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7699 oldzv = message_dolog_marker3;
7700 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7701 GCPRO1 (old_deactivate_mark);
7702
7703 if (PT == Z)
7704 point_at_end = 1;
7705 if (ZV == Z)
7706 zv_at_end = 1;
7707
7708 BEGV = BEG;
7709 BEGV_BYTE = BEG_BYTE;
7710 ZV = Z;
7711 ZV_BYTE = Z_BYTE;
7712 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7713
7714 /* Insert the string--maybe converting multibyte to single byte
7715 or vice versa, so that all the text fits the buffer. */
7716 if (multibyte
7717 && NILP (current_buffer->enable_multibyte_characters))
7718 {
7719 int i, c, char_bytes;
7720 unsigned char work[1];
7721
7722 /* Convert a multibyte string to single-byte
7723 for the *Message* buffer. */
7724 for (i = 0; i < nbytes; i += char_bytes)
7725 {
7726 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7727 work[0] = (ASCII_CHAR_P (c)
7728 ? c
7729 : multibyte_char_to_unibyte (c, Qnil));
7730 insert_1_both (work, 1, 1, 1, 0, 0);
7731 }
7732 }
7733 else if (! multibyte
7734 && ! NILP (current_buffer->enable_multibyte_characters))
7735 {
7736 int i, c, char_bytes;
7737 unsigned char *msg = (unsigned char *) m;
7738 unsigned char str[MAX_MULTIBYTE_LENGTH];
7739 /* Convert a single-byte string to multibyte
7740 for the *Message* buffer. */
7741 for (i = 0; i < nbytes; i++)
7742 {
7743 c = msg[i];
7744 c = unibyte_char_to_multibyte (c);
7745 char_bytes = CHAR_STRING (c, str);
7746 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7747 }
7748 }
7749 else if (nbytes)
7750 insert_1 (m, nbytes, 1, 0, 0);
7751
7752 if (nlflag)
7753 {
7754 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7755 insert_1 ("\n", 1, 1, 0, 0);
7756
7757 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7758 this_bol = PT;
7759 this_bol_byte = PT_BYTE;
7760
7761 /* See if this line duplicates the previous one.
7762 If so, combine duplicates. */
7763 if (this_bol > BEG)
7764 {
7765 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7766 prev_bol = PT;
7767 prev_bol_byte = PT_BYTE;
7768
7769 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7770 this_bol, this_bol_byte);
7771 if (dup)
7772 {
7773 del_range_both (prev_bol, prev_bol_byte,
7774 this_bol, this_bol_byte, 0);
7775 if (dup > 1)
7776 {
7777 char dupstr[40];
7778 int duplen;
7779
7780 /* If you change this format, don't forget to also
7781 change message_log_check_duplicate. */
7782 sprintf (dupstr, " [%d times]", dup);
7783 duplen = strlen (dupstr);
7784 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7785 insert_1 (dupstr, duplen, 1, 0, 1);
7786 }
7787 }
7788 }
7789
7790 /* If we have more than the desired maximum number of lines
7791 in the *Messages* buffer now, delete the oldest ones.
7792 This is safe because we don't have undo in this buffer. */
7793
7794 if (NATNUMP (Vmessage_log_max))
7795 {
7796 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7797 -XFASTINT (Vmessage_log_max) - 1, 0);
7798 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7799 }
7800 }
7801 BEGV = XMARKER (oldbegv)->charpos;
7802 BEGV_BYTE = marker_byte_position (oldbegv);
7803
7804 if (zv_at_end)
7805 {
7806 ZV = Z;
7807 ZV_BYTE = Z_BYTE;
7808 }
7809 else
7810 {
7811 ZV = XMARKER (oldzv)->charpos;
7812 ZV_BYTE = marker_byte_position (oldzv);
7813 }
7814
7815 if (point_at_end)
7816 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7817 else
7818 /* We can't do Fgoto_char (oldpoint) because it will run some
7819 Lisp code. */
7820 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7821 XMARKER (oldpoint)->bytepos);
7822
7823 UNGCPRO;
7824 unchain_marker (XMARKER (oldpoint));
7825 unchain_marker (XMARKER (oldbegv));
7826 unchain_marker (XMARKER (oldzv));
7827
7828 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7829 set_buffer_internal (oldbuf);
7830 if (NILP (tem))
7831 windows_or_buffers_changed = old_windows_or_buffers_changed;
7832 message_log_need_newline = !nlflag;
7833 Vdeactivate_mark = old_deactivate_mark;
7834 }
7835 }
7836
7837
7838 /* We are at the end of the buffer after just having inserted a newline.
7839 (Note: We depend on the fact we won't be crossing the gap.)
7840 Check to see if the most recent message looks a lot like the previous one.
7841 Return 0 if different, 1 if the new one should just replace it, or a
7842 value N > 1 if we should also append " [N times]". */
7843
7844 static int
7845 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7846 int prev_bol, this_bol;
7847 int prev_bol_byte, this_bol_byte;
7848 {
7849 int i;
7850 int len = Z_BYTE - 1 - this_bol_byte;
7851 int seen_dots = 0;
7852 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7853 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7854
7855 for (i = 0; i < len; i++)
7856 {
7857 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7858 seen_dots = 1;
7859 if (p1[i] != p2[i])
7860 return seen_dots;
7861 }
7862 p1 += len;
7863 if (*p1 == '\n')
7864 return 2;
7865 if (*p1++ == ' ' && *p1++ == '[')
7866 {
7867 int n = 0;
7868 while (*p1 >= '0' && *p1 <= '9')
7869 n = n * 10 + *p1++ - '0';
7870 if (strncmp (p1, " times]\n", 8) == 0)
7871 return n+1;
7872 }
7873 return 0;
7874 }
7875 \f
7876
7877 /* Display an echo area message M with a specified length of NBYTES
7878 bytes. The string may include null characters. If M is 0, clear
7879 out any existing message, and let the mini-buffer text show
7880 through.
7881
7882 This may GC, so the buffer M must NOT point to a Lisp string. */
7883
7884 void
7885 message2 (m, nbytes, multibyte)
7886 const char *m;
7887 int nbytes;
7888 int multibyte;
7889 {
7890 /* First flush out any partial line written with print. */
7891 message_log_maybe_newline ();
7892 if (m)
7893 message_dolog (m, nbytes, 1, multibyte);
7894 message2_nolog (m, nbytes, multibyte);
7895 }
7896
7897
7898 /* The non-logging counterpart of message2. */
7899
7900 void
7901 message2_nolog (m, nbytes, multibyte)
7902 const char *m;
7903 int nbytes, multibyte;
7904 {
7905 struct frame *sf = SELECTED_FRAME ();
7906 message_enable_multibyte = multibyte;
7907
7908 if (FRAME_INITIAL_P (sf))
7909 {
7910 if (noninteractive_need_newline)
7911 putc ('\n', stderr);
7912 noninteractive_need_newline = 0;
7913 if (m)
7914 fwrite (m, nbytes, 1, stderr);
7915 if (cursor_in_echo_area == 0)
7916 fprintf (stderr, "\n");
7917 fflush (stderr);
7918 }
7919 /* A null message buffer means that the frame hasn't really been
7920 initialized yet. Error messages get reported properly by
7921 cmd_error, so this must be just an informative message; toss it. */
7922 else if (INTERACTIVE
7923 && sf->glyphs_initialized_p
7924 && FRAME_MESSAGE_BUF (sf))
7925 {
7926 Lisp_Object mini_window;
7927 struct frame *f;
7928
7929 /* Get the frame containing the mini-buffer
7930 that the selected frame is using. */
7931 mini_window = FRAME_MINIBUF_WINDOW (sf);
7932 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7933
7934 FRAME_SAMPLE_VISIBILITY (f);
7935 if (FRAME_VISIBLE_P (sf)
7936 && ! FRAME_VISIBLE_P (f))
7937 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7938
7939 if (m)
7940 {
7941 set_message (m, Qnil, nbytes, multibyte);
7942 if (minibuffer_auto_raise)
7943 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7944 }
7945 else
7946 clear_message (1, 1);
7947
7948 do_pending_window_change (0);
7949 echo_area_display (1);
7950 do_pending_window_change (0);
7951 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7952 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7953 }
7954 }
7955
7956
7957 /* Display an echo area message M with a specified length of NBYTES
7958 bytes. The string may include null characters. If M is not a
7959 string, clear out any existing message, and let the mini-buffer
7960 text show through.
7961
7962 This function cancels echoing. */
7963
7964 void
7965 message3 (m, nbytes, multibyte)
7966 Lisp_Object m;
7967 int nbytes;
7968 int multibyte;
7969 {
7970 struct gcpro gcpro1;
7971
7972 GCPRO1 (m);
7973 clear_message (1,1);
7974 cancel_echoing ();
7975
7976 /* First flush out any partial line written with print. */
7977 message_log_maybe_newline ();
7978 if (STRINGP (m))
7979 {
7980 char *buffer;
7981 USE_SAFE_ALLOCA;
7982
7983 SAFE_ALLOCA (buffer, char *, nbytes);
7984 bcopy (SDATA (m), buffer, nbytes);
7985 message_dolog (buffer, nbytes, 1, multibyte);
7986 SAFE_FREE ();
7987 }
7988 message3_nolog (m, nbytes, multibyte);
7989
7990 UNGCPRO;
7991 }
7992
7993
7994 /* The non-logging version of message3.
7995 This does not cancel echoing, because it is used for echoing.
7996 Perhaps we need to make a separate function for echoing
7997 and make this cancel echoing. */
7998
7999 void
8000 message3_nolog (m, nbytes, multibyte)
8001 Lisp_Object m;
8002 int nbytes, multibyte;
8003 {
8004 struct frame *sf = SELECTED_FRAME ();
8005 message_enable_multibyte = multibyte;
8006
8007 if (FRAME_INITIAL_P (sf))
8008 {
8009 if (noninteractive_need_newline)
8010 putc ('\n', stderr);
8011 noninteractive_need_newline = 0;
8012 if (STRINGP (m))
8013 fwrite (SDATA (m), nbytes, 1, stderr);
8014 if (cursor_in_echo_area == 0)
8015 fprintf (stderr, "\n");
8016 fflush (stderr);
8017 }
8018 /* A null message buffer means that the frame hasn't really been
8019 initialized yet. Error messages get reported properly by
8020 cmd_error, so this must be just an informative message; toss it. */
8021 else if (INTERACTIVE
8022 && sf->glyphs_initialized_p
8023 && FRAME_MESSAGE_BUF (sf))
8024 {
8025 Lisp_Object mini_window;
8026 Lisp_Object frame;
8027 struct frame *f;
8028
8029 /* Get the frame containing the mini-buffer
8030 that the selected frame is using. */
8031 mini_window = FRAME_MINIBUF_WINDOW (sf);
8032 frame = XWINDOW (mini_window)->frame;
8033 f = XFRAME (frame);
8034
8035 FRAME_SAMPLE_VISIBILITY (f);
8036 if (FRAME_VISIBLE_P (sf)
8037 && !FRAME_VISIBLE_P (f))
8038 Fmake_frame_visible (frame);
8039
8040 if (STRINGP (m) && SCHARS (m) > 0)
8041 {
8042 set_message (NULL, m, nbytes, multibyte);
8043 if (minibuffer_auto_raise)
8044 Fraise_frame (frame);
8045 /* Assume we are not echoing.
8046 (If we are, echo_now will override this.) */
8047 echo_message_buffer = Qnil;
8048 }
8049 else
8050 clear_message (1, 1);
8051
8052 do_pending_window_change (0);
8053 echo_area_display (1);
8054 do_pending_window_change (0);
8055 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8056 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8057 }
8058 }
8059
8060
8061 /* Display a null-terminated echo area message M. If M is 0, clear
8062 out any existing message, and let the mini-buffer text show through.
8063
8064 The buffer M must continue to exist until after the echo area gets
8065 cleared or some other message gets displayed there. Do not pass
8066 text that is stored in a Lisp string. Do not pass text in a buffer
8067 that was alloca'd. */
8068
8069 void
8070 message1 (m)
8071 char *m;
8072 {
8073 message2 (m, (m ? strlen (m) : 0), 0);
8074 }
8075
8076
8077 /* The non-logging counterpart of message1. */
8078
8079 void
8080 message1_nolog (m)
8081 char *m;
8082 {
8083 message2_nolog (m, (m ? strlen (m) : 0), 0);
8084 }
8085
8086 /* Display a message M which contains a single %s
8087 which gets replaced with STRING. */
8088
8089 void
8090 message_with_string (m, string, log)
8091 char *m;
8092 Lisp_Object string;
8093 int log;
8094 {
8095 CHECK_STRING (string);
8096
8097 if (noninteractive)
8098 {
8099 if (m)
8100 {
8101 if (noninteractive_need_newline)
8102 putc ('\n', stderr);
8103 noninteractive_need_newline = 0;
8104 fprintf (stderr, m, SDATA (string));
8105 if (!cursor_in_echo_area)
8106 fprintf (stderr, "\n");
8107 fflush (stderr);
8108 }
8109 }
8110 else if (INTERACTIVE)
8111 {
8112 /* The frame whose minibuffer we're going to display the message on.
8113 It may be larger than the selected frame, so we need
8114 to use its buffer, not the selected frame's buffer. */
8115 Lisp_Object mini_window;
8116 struct frame *f, *sf = SELECTED_FRAME ();
8117
8118 /* Get the frame containing the minibuffer
8119 that the selected frame is using. */
8120 mini_window = FRAME_MINIBUF_WINDOW (sf);
8121 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8122
8123 /* A null message buffer means that the frame hasn't really been
8124 initialized yet. Error messages get reported properly by
8125 cmd_error, so this must be just an informative message; toss it. */
8126 if (FRAME_MESSAGE_BUF (f))
8127 {
8128 Lisp_Object args[2], message;
8129 struct gcpro gcpro1, gcpro2;
8130
8131 args[0] = build_string (m);
8132 args[1] = message = string;
8133 GCPRO2 (args[0], message);
8134 gcpro1.nvars = 2;
8135
8136 message = Fformat (2, args);
8137
8138 if (log)
8139 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8140 else
8141 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8142
8143 UNGCPRO;
8144
8145 /* Print should start at the beginning of the message
8146 buffer next time. */
8147 message_buf_print = 0;
8148 }
8149 }
8150 }
8151
8152
8153 /* Dump an informative message to the minibuf. If M is 0, clear out
8154 any existing message, and let the mini-buffer text show through. */
8155
8156 /* VARARGS 1 */
8157 void
8158 message (m, a1, a2, a3)
8159 char *m;
8160 EMACS_INT a1, a2, a3;
8161 {
8162 if (noninteractive)
8163 {
8164 if (m)
8165 {
8166 if (noninteractive_need_newline)
8167 putc ('\n', stderr);
8168 noninteractive_need_newline = 0;
8169 fprintf (stderr, m, a1, a2, a3);
8170 if (cursor_in_echo_area == 0)
8171 fprintf (stderr, "\n");
8172 fflush (stderr);
8173 }
8174 }
8175 else if (INTERACTIVE)
8176 {
8177 /* The frame whose mini-buffer we're going to display the message
8178 on. It may be larger than the selected frame, so we need to
8179 use its buffer, not the selected frame's buffer. */
8180 Lisp_Object mini_window;
8181 struct frame *f, *sf = SELECTED_FRAME ();
8182
8183 /* Get the frame containing the mini-buffer
8184 that the selected frame is using. */
8185 mini_window = FRAME_MINIBUF_WINDOW (sf);
8186 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8187
8188 /* A null message buffer means that the frame hasn't really been
8189 initialized yet. Error messages get reported properly by
8190 cmd_error, so this must be just an informative message; toss
8191 it. */
8192 if (FRAME_MESSAGE_BUF (f))
8193 {
8194 if (m)
8195 {
8196 int len;
8197 #ifdef NO_ARG_ARRAY
8198 char *a[3];
8199 a[0] = (char *) a1;
8200 a[1] = (char *) a2;
8201 a[2] = (char *) a3;
8202
8203 len = doprnt (FRAME_MESSAGE_BUF (f),
8204 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
8205 #else
8206 len = doprnt (FRAME_MESSAGE_BUF (f),
8207 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
8208 (char **) &a1);
8209 #endif /* NO_ARG_ARRAY */
8210
8211 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8212 }
8213 else
8214 message1 (0);
8215
8216 /* Print should start at the beginning of the message
8217 buffer next time. */
8218 message_buf_print = 0;
8219 }
8220 }
8221 }
8222
8223
8224 /* The non-logging version of message. */
8225
8226 void
8227 message_nolog (m, a1, a2, a3)
8228 char *m;
8229 EMACS_INT a1, a2, a3;
8230 {
8231 Lisp_Object old_log_max;
8232 old_log_max = Vmessage_log_max;
8233 Vmessage_log_max = Qnil;
8234 message (m, a1, a2, a3);
8235 Vmessage_log_max = old_log_max;
8236 }
8237
8238
8239 /* Display the current message in the current mini-buffer. This is
8240 only called from error handlers in process.c, and is not time
8241 critical. */
8242
8243 void
8244 update_echo_area ()
8245 {
8246 if (!NILP (echo_area_buffer[0]))
8247 {
8248 Lisp_Object string;
8249 string = Fcurrent_message ();
8250 message3 (string, SBYTES (string),
8251 !NILP (current_buffer->enable_multibyte_characters));
8252 }
8253 }
8254
8255
8256 /* Make sure echo area buffers in `echo_buffers' are live.
8257 If they aren't, make new ones. */
8258
8259 static void
8260 ensure_echo_area_buffers ()
8261 {
8262 int i;
8263
8264 for (i = 0; i < 2; ++i)
8265 if (!BUFFERP (echo_buffer[i])
8266 || NILP (XBUFFER (echo_buffer[i])->name))
8267 {
8268 char name[30];
8269 Lisp_Object old_buffer;
8270 int j;
8271
8272 old_buffer = echo_buffer[i];
8273 sprintf (name, " *Echo Area %d*", i);
8274 echo_buffer[i] = Fget_buffer_create (build_string (name));
8275 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8276 /* to force word wrap in echo area -
8277 it was decided to postpone this*/
8278 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8279
8280 for (j = 0; j < 2; ++j)
8281 if (EQ (old_buffer, echo_area_buffer[j]))
8282 echo_area_buffer[j] = echo_buffer[i];
8283 }
8284 }
8285
8286
8287 /* Call FN with args A1..A4 with either the current or last displayed
8288 echo_area_buffer as current buffer.
8289
8290 WHICH zero means use the current message buffer
8291 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8292 from echo_buffer[] and clear it.
8293
8294 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8295 suitable buffer from echo_buffer[] and clear it.
8296
8297 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8298 that the current message becomes the last displayed one, make
8299 choose a suitable buffer for echo_area_buffer[0], and clear it.
8300
8301 Value is what FN returns. */
8302
8303 static int
8304 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
8305 struct window *w;
8306 int which;
8307 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
8308 EMACS_INT a1;
8309 Lisp_Object a2;
8310 EMACS_INT a3, a4;
8311 {
8312 Lisp_Object buffer;
8313 int this_one, the_other, clear_buffer_p, rc;
8314 int count = SPECPDL_INDEX ();
8315
8316 /* If buffers aren't live, make new ones. */
8317 ensure_echo_area_buffers ();
8318
8319 clear_buffer_p = 0;
8320
8321 if (which == 0)
8322 this_one = 0, the_other = 1;
8323 else if (which > 0)
8324 this_one = 1, the_other = 0;
8325 else
8326 {
8327 this_one = 0, the_other = 1;
8328 clear_buffer_p = 1;
8329
8330 /* We need a fresh one in case the current echo buffer equals
8331 the one containing the last displayed echo area message. */
8332 if (!NILP (echo_area_buffer[this_one])
8333 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8334 echo_area_buffer[this_one] = Qnil;
8335 }
8336
8337 /* Choose a suitable buffer from echo_buffer[] is we don't
8338 have one. */
8339 if (NILP (echo_area_buffer[this_one]))
8340 {
8341 echo_area_buffer[this_one]
8342 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8343 ? echo_buffer[the_other]
8344 : echo_buffer[this_one]);
8345 clear_buffer_p = 1;
8346 }
8347
8348 buffer = echo_area_buffer[this_one];
8349
8350 /* Don't get confused by reusing the buffer used for echoing
8351 for a different purpose. */
8352 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8353 cancel_echoing ();
8354
8355 record_unwind_protect (unwind_with_echo_area_buffer,
8356 with_echo_area_buffer_unwind_data (w));
8357
8358 /* Make the echo area buffer current. Note that for display
8359 purposes, it is not necessary that the displayed window's buffer
8360 == current_buffer, except for text property lookup. So, let's
8361 only set that buffer temporarily here without doing a full
8362 Fset_window_buffer. We must also change w->pointm, though,
8363 because otherwise an assertions in unshow_buffer fails, and Emacs
8364 aborts. */
8365 set_buffer_internal_1 (XBUFFER (buffer));
8366 if (w)
8367 {
8368 w->buffer = buffer;
8369 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8370 }
8371
8372 current_buffer->undo_list = Qt;
8373 current_buffer->read_only = Qnil;
8374 specbind (Qinhibit_read_only, Qt);
8375 specbind (Qinhibit_modification_hooks, Qt);
8376
8377 if (clear_buffer_p && Z > BEG)
8378 del_range (BEG, Z);
8379
8380 xassert (BEGV >= BEG);
8381 xassert (ZV <= Z && ZV >= BEGV);
8382
8383 rc = fn (a1, a2, a3, a4);
8384
8385 xassert (BEGV >= BEG);
8386 xassert (ZV <= Z && ZV >= BEGV);
8387
8388 unbind_to (count, Qnil);
8389 return rc;
8390 }
8391
8392
8393 /* Save state that should be preserved around the call to the function
8394 FN called in with_echo_area_buffer. */
8395
8396 static Lisp_Object
8397 with_echo_area_buffer_unwind_data (w)
8398 struct window *w;
8399 {
8400 int i = 0;
8401 Lisp_Object vector, tmp;
8402
8403 /* Reduce consing by keeping one vector in
8404 Vwith_echo_area_save_vector. */
8405 vector = Vwith_echo_area_save_vector;
8406 Vwith_echo_area_save_vector = Qnil;
8407
8408 if (NILP (vector))
8409 vector = Fmake_vector (make_number (7), Qnil);
8410
8411 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8412 ASET (vector, i, Vdeactivate_mark); ++i;
8413 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8414
8415 if (w)
8416 {
8417 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8418 ASET (vector, i, w->buffer); ++i;
8419 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8420 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8421 }
8422 else
8423 {
8424 int end = i + 4;
8425 for (; i < end; ++i)
8426 ASET (vector, i, Qnil);
8427 }
8428
8429 xassert (i == ASIZE (vector));
8430 return vector;
8431 }
8432
8433
8434 /* Restore global state from VECTOR which was created by
8435 with_echo_area_buffer_unwind_data. */
8436
8437 static Lisp_Object
8438 unwind_with_echo_area_buffer (vector)
8439 Lisp_Object vector;
8440 {
8441 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8442 Vdeactivate_mark = AREF (vector, 1);
8443 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8444
8445 if (WINDOWP (AREF (vector, 3)))
8446 {
8447 struct window *w;
8448 Lisp_Object buffer, charpos, bytepos;
8449
8450 w = XWINDOW (AREF (vector, 3));
8451 buffer = AREF (vector, 4);
8452 charpos = AREF (vector, 5);
8453 bytepos = AREF (vector, 6);
8454
8455 w->buffer = buffer;
8456 set_marker_both (w->pointm, buffer,
8457 XFASTINT (charpos), XFASTINT (bytepos));
8458 }
8459
8460 Vwith_echo_area_save_vector = vector;
8461 return Qnil;
8462 }
8463
8464
8465 /* Set up the echo area for use by print functions. MULTIBYTE_P
8466 non-zero means we will print multibyte. */
8467
8468 void
8469 setup_echo_area_for_printing (multibyte_p)
8470 int multibyte_p;
8471 {
8472 /* If we can't find an echo area any more, exit. */
8473 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8474 Fkill_emacs (Qnil);
8475
8476 ensure_echo_area_buffers ();
8477
8478 if (!message_buf_print)
8479 {
8480 /* A message has been output since the last time we printed.
8481 Choose a fresh echo area buffer. */
8482 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8483 echo_area_buffer[0] = echo_buffer[1];
8484 else
8485 echo_area_buffer[0] = echo_buffer[0];
8486
8487 /* Switch to that buffer and clear it. */
8488 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8489 current_buffer->truncate_lines = Qnil;
8490
8491 if (Z > BEG)
8492 {
8493 int count = SPECPDL_INDEX ();
8494 specbind (Qinhibit_read_only, Qt);
8495 /* Note that undo recording is always disabled. */
8496 del_range (BEG, Z);
8497 unbind_to (count, Qnil);
8498 }
8499 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8500
8501 /* Set up the buffer for the multibyteness we need. */
8502 if (multibyte_p
8503 != !NILP (current_buffer->enable_multibyte_characters))
8504 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8505
8506 /* Raise the frame containing the echo area. */
8507 if (minibuffer_auto_raise)
8508 {
8509 struct frame *sf = SELECTED_FRAME ();
8510 Lisp_Object mini_window;
8511 mini_window = FRAME_MINIBUF_WINDOW (sf);
8512 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8513 }
8514
8515 message_log_maybe_newline ();
8516 message_buf_print = 1;
8517 }
8518 else
8519 {
8520 if (NILP (echo_area_buffer[0]))
8521 {
8522 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8523 echo_area_buffer[0] = echo_buffer[1];
8524 else
8525 echo_area_buffer[0] = echo_buffer[0];
8526 }
8527
8528 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8529 {
8530 /* Someone switched buffers between print requests. */
8531 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8532 current_buffer->truncate_lines = Qnil;
8533 }
8534 }
8535 }
8536
8537
8538 /* Display an echo area message in window W. Value is non-zero if W's
8539 height is changed. If display_last_displayed_message_p is
8540 non-zero, display the message that was last displayed, otherwise
8541 display the current message. */
8542
8543 static int
8544 display_echo_area (w)
8545 struct window *w;
8546 {
8547 int i, no_message_p, window_height_changed_p, count;
8548
8549 /* Temporarily disable garbage collections while displaying the echo
8550 area. This is done because a GC can print a message itself.
8551 That message would modify the echo area buffer's contents while a
8552 redisplay of the buffer is going on, and seriously confuse
8553 redisplay. */
8554 count = inhibit_garbage_collection ();
8555
8556 /* If there is no message, we must call display_echo_area_1
8557 nevertheless because it resizes the window. But we will have to
8558 reset the echo_area_buffer in question to nil at the end because
8559 with_echo_area_buffer will sets it to an empty buffer. */
8560 i = display_last_displayed_message_p ? 1 : 0;
8561 no_message_p = NILP (echo_area_buffer[i]);
8562
8563 window_height_changed_p
8564 = with_echo_area_buffer (w, display_last_displayed_message_p,
8565 display_echo_area_1,
8566 (EMACS_INT) w, Qnil, 0, 0);
8567
8568 if (no_message_p)
8569 echo_area_buffer[i] = Qnil;
8570
8571 unbind_to (count, Qnil);
8572 return window_height_changed_p;
8573 }
8574
8575
8576 /* Helper for display_echo_area. Display the current buffer which
8577 contains the current echo area message in window W, a mini-window,
8578 a pointer to which is passed in A1. A2..A4 are currently not used.
8579 Change the height of W so that all of the message is displayed.
8580 Value is non-zero if height of W was changed. */
8581
8582 static int
8583 display_echo_area_1 (a1, a2, a3, a4)
8584 EMACS_INT a1;
8585 Lisp_Object a2;
8586 EMACS_INT a3, a4;
8587 {
8588 struct window *w = (struct window *) a1;
8589 Lisp_Object window;
8590 struct text_pos start;
8591 int window_height_changed_p = 0;
8592
8593 /* Do this before displaying, so that we have a large enough glyph
8594 matrix for the display. If we can't get enough space for the
8595 whole text, display the last N lines. That works by setting w->start. */
8596 window_height_changed_p = resize_mini_window (w, 0);
8597
8598 /* Use the starting position chosen by resize_mini_window. */
8599 SET_TEXT_POS_FROM_MARKER (start, w->start);
8600
8601 /* Display. */
8602 clear_glyph_matrix (w->desired_matrix);
8603 XSETWINDOW (window, w);
8604 try_window (window, start, 0);
8605
8606 return window_height_changed_p;
8607 }
8608
8609
8610 /* Resize the echo area window to exactly the size needed for the
8611 currently displayed message, if there is one. If a mini-buffer
8612 is active, don't shrink it. */
8613
8614 void
8615 resize_echo_area_exactly ()
8616 {
8617 if (BUFFERP (echo_area_buffer[0])
8618 && WINDOWP (echo_area_window))
8619 {
8620 struct window *w = XWINDOW (echo_area_window);
8621 int resized_p;
8622 Lisp_Object resize_exactly;
8623
8624 if (minibuf_level == 0)
8625 resize_exactly = Qt;
8626 else
8627 resize_exactly = Qnil;
8628
8629 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8630 (EMACS_INT) w, resize_exactly, 0, 0);
8631 if (resized_p)
8632 {
8633 ++windows_or_buffers_changed;
8634 ++update_mode_lines;
8635 redisplay_internal (0);
8636 }
8637 }
8638 }
8639
8640
8641 /* Callback function for with_echo_area_buffer, when used from
8642 resize_echo_area_exactly. A1 contains a pointer to the window to
8643 resize, EXACTLY non-nil means resize the mini-window exactly to the
8644 size of the text displayed. A3 and A4 are not used. Value is what
8645 resize_mini_window returns. */
8646
8647 static int
8648 resize_mini_window_1 (a1, exactly, a3, a4)
8649 EMACS_INT a1;
8650 Lisp_Object exactly;
8651 EMACS_INT a3, a4;
8652 {
8653 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8654 }
8655
8656
8657 /* Resize mini-window W to fit the size of its contents. EXACT_P
8658 means size the window exactly to the size needed. Otherwise, it's
8659 only enlarged until W's buffer is empty.
8660
8661 Set W->start to the right place to begin display. If the whole
8662 contents fit, start at the beginning. Otherwise, start so as
8663 to make the end of the contents appear. This is particularly
8664 important for y-or-n-p, but seems desirable generally.
8665
8666 Value is non-zero if the window height has been changed. */
8667
8668 int
8669 resize_mini_window (w, exact_p)
8670 struct window *w;
8671 int exact_p;
8672 {
8673 struct frame *f = XFRAME (w->frame);
8674 int window_height_changed_p = 0;
8675
8676 xassert (MINI_WINDOW_P (w));
8677
8678 /* By default, start display at the beginning. */
8679 set_marker_both (w->start, w->buffer,
8680 BUF_BEGV (XBUFFER (w->buffer)),
8681 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8682
8683 /* Don't resize windows while redisplaying a window; it would
8684 confuse redisplay functions when the size of the window they are
8685 displaying changes from under them. Such a resizing can happen,
8686 for instance, when which-func prints a long message while
8687 we are running fontification-functions. We're running these
8688 functions with safe_call which binds inhibit-redisplay to t. */
8689 if (!NILP (Vinhibit_redisplay))
8690 return 0;
8691
8692 /* Nil means don't try to resize. */
8693 if (NILP (Vresize_mini_windows)
8694 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8695 return 0;
8696
8697 if (!FRAME_MINIBUF_ONLY_P (f))
8698 {
8699 struct it it;
8700 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8701 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8702 int height, max_height;
8703 int unit = FRAME_LINE_HEIGHT (f);
8704 struct text_pos start;
8705 struct buffer *old_current_buffer = NULL;
8706
8707 if (current_buffer != XBUFFER (w->buffer))
8708 {
8709 old_current_buffer = current_buffer;
8710 set_buffer_internal (XBUFFER (w->buffer));
8711 }
8712
8713 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8714
8715 /* Compute the max. number of lines specified by the user. */
8716 if (FLOATP (Vmax_mini_window_height))
8717 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8718 else if (INTEGERP (Vmax_mini_window_height))
8719 max_height = XINT (Vmax_mini_window_height);
8720 else
8721 max_height = total_height / 4;
8722
8723 /* Correct that max. height if it's bogus. */
8724 max_height = max (1, max_height);
8725 max_height = min (total_height, max_height);
8726
8727 /* Find out the height of the text in the window. */
8728 if (it.line_wrap == TRUNCATE)
8729 height = 1;
8730 else
8731 {
8732 last_height = 0;
8733 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8734 if (it.max_ascent == 0 && it.max_descent == 0)
8735 height = it.current_y + last_height;
8736 else
8737 height = it.current_y + it.max_ascent + it.max_descent;
8738 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8739 height = (height + unit - 1) / unit;
8740 }
8741
8742 /* Compute a suitable window start. */
8743 if (height > max_height)
8744 {
8745 height = max_height;
8746 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8747 move_it_vertically_backward (&it, (height - 1) * unit);
8748 start = it.current.pos;
8749 }
8750 else
8751 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8752 SET_MARKER_FROM_TEXT_POS (w->start, start);
8753
8754 if (EQ (Vresize_mini_windows, Qgrow_only))
8755 {
8756 /* Let it grow only, until we display an empty message, in which
8757 case the window shrinks again. */
8758 if (height > WINDOW_TOTAL_LINES (w))
8759 {
8760 int old_height = WINDOW_TOTAL_LINES (w);
8761 freeze_window_starts (f, 1);
8762 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8763 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8764 }
8765 else if (height < WINDOW_TOTAL_LINES (w)
8766 && (exact_p || BEGV == ZV))
8767 {
8768 int old_height = WINDOW_TOTAL_LINES (w);
8769 freeze_window_starts (f, 0);
8770 shrink_mini_window (w);
8771 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8772 }
8773 }
8774 else
8775 {
8776 /* Always resize to exact size needed. */
8777 if (height > WINDOW_TOTAL_LINES (w))
8778 {
8779 int old_height = WINDOW_TOTAL_LINES (w);
8780 freeze_window_starts (f, 1);
8781 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8782 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8783 }
8784 else if (height < WINDOW_TOTAL_LINES (w))
8785 {
8786 int old_height = WINDOW_TOTAL_LINES (w);
8787 freeze_window_starts (f, 0);
8788 shrink_mini_window (w);
8789
8790 if (height)
8791 {
8792 freeze_window_starts (f, 1);
8793 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8794 }
8795
8796 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8797 }
8798 }
8799
8800 if (old_current_buffer)
8801 set_buffer_internal (old_current_buffer);
8802 }
8803
8804 return window_height_changed_p;
8805 }
8806
8807
8808 /* Value is the current message, a string, or nil if there is no
8809 current message. */
8810
8811 Lisp_Object
8812 current_message ()
8813 {
8814 Lisp_Object msg;
8815
8816 if (!BUFFERP (echo_area_buffer[0]))
8817 msg = Qnil;
8818 else
8819 {
8820 with_echo_area_buffer (0, 0, current_message_1,
8821 (EMACS_INT) &msg, Qnil, 0, 0);
8822 if (NILP (msg))
8823 echo_area_buffer[0] = Qnil;
8824 }
8825
8826 return msg;
8827 }
8828
8829
8830 static int
8831 current_message_1 (a1, a2, a3, a4)
8832 EMACS_INT a1;
8833 Lisp_Object a2;
8834 EMACS_INT a3, a4;
8835 {
8836 Lisp_Object *msg = (Lisp_Object *) a1;
8837
8838 if (Z > BEG)
8839 *msg = make_buffer_string (BEG, Z, 1);
8840 else
8841 *msg = Qnil;
8842 return 0;
8843 }
8844
8845
8846 /* Push the current message on Vmessage_stack for later restauration
8847 by restore_message. Value is non-zero if the current message isn't
8848 empty. This is a relatively infrequent operation, so it's not
8849 worth optimizing. */
8850
8851 int
8852 push_message ()
8853 {
8854 Lisp_Object msg;
8855 msg = current_message ();
8856 Vmessage_stack = Fcons (msg, Vmessage_stack);
8857 return STRINGP (msg);
8858 }
8859
8860
8861 /* Restore message display from the top of Vmessage_stack. */
8862
8863 void
8864 restore_message ()
8865 {
8866 Lisp_Object msg;
8867
8868 xassert (CONSP (Vmessage_stack));
8869 msg = XCAR (Vmessage_stack);
8870 if (STRINGP (msg))
8871 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8872 else
8873 message3_nolog (msg, 0, 0);
8874 }
8875
8876
8877 /* Handler for record_unwind_protect calling pop_message. */
8878
8879 Lisp_Object
8880 pop_message_unwind (dummy)
8881 Lisp_Object dummy;
8882 {
8883 pop_message ();
8884 return Qnil;
8885 }
8886
8887 /* Pop the top-most entry off Vmessage_stack. */
8888
8889 void
8890 pop_message ()
8891 {
8892 xassert (CONSP (Vmessage_stack));
8893 Vmessage_stack = XCDR (Vmessage_stack);
8894 }
8895
8896
8897 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8898 exits. If the stack is not empty, we have a missing pop_message
8899 somewhere. */
8900
8901 void
8902 check_message_stack ()
8903 {
8904 if (!NILP (Vmessage_stack))
8905 abort ();
8906 }
8907
8908
8909 /* Truncate to NCHARS what will be displayed in the echo area the next
8910 time we display it---but don't redisplay it now. */
8911
8912 void
8913 truncate_echo_area (nchars)
8914 int nchars;
8915 {
8916 if (nchars == 0)
8917 echo_area_buffer[0] = Qnil;
8918 /* A null message buffer means that the frame hasn't really been
8919 initialized yet. Error messages get reported properly by
8920 cmd_error, so this must be just an informative message; toss it. */
8921 else if (!noninteractive
8922 && INTERACTIVE
8923 && !NILP (echo_area_buffer[0]))
8924 {
8925 struct frame *sf = SELECTED_FRAME ();
8926 if (FRAME_MESSAGE_BUF (sf))
8927 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8928 }
8929 }
8930
8931
8932 /* Helper function for truncate_echo_area. Truncate the current
8933 message to at most NCHARS characters. */
8934
8935 static int
8936 truncate_message_1 (nchars, a2, a3, a4)
8937 EMACS_INT nchars;
8938 Lisp_Object a2;
8939 EMACS_INT a3, a4;
8940 {
8941 if (BEG + nchars < Z)
8942 del_range (BEG + nchars, Z);
8943 if (Z == BEG)
8944 echo_area_buffer[0] = Qnil;
8945 return 0;
8946 }
8947
8948
8949 /* Set the current message to a substring of S or STRING.
8950
8951 If STRING is a Lisp string, set the message to the first NBYTES
8952 bytes from STRING. NBYTES zero means use the whole string. If
8953 STRING is multibyte, the message will be displayed multibyte.
8954
8955 If S is not null, set the message to the first LEN bytes of S. LEN
8956 zero means use the whole string. MULTIBYTE_P non-zero means S is
8957 multibyte. Display the message multibyte in that case.
8958
8959 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8960 to t before calling set_message_1 (which calls insert).
8961 */
8962
8963 void
8964 set_message (s, string, nbytes, multibyte_p)
8965 const char *s;
8966 Lisp_Object string;
8967 int nbytes, multibyte_p;
8968 {
8969 message_enable_multibyte
8970 = ((s && multibyte_p)
8971 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8972
8973 with_echo_area_buffer (0, -1, set_message_1,
8974 (EMACS_INT) s, string, nbytes, multibyte_p);
8975 message_buf_print = 0;
8976 help_echo_showing_p = 0;
8977 }
8978
8979
8980 /* Helper function for set_message. Arguments have the same meaning
8981 as there, with A1 corresponding to S and A2 corresponding to STRING
8982 This function is called with the echo area buffer being
8983 current. */
8984
8985 static int
8986 set_message_1 (a1, a2, nbytes, multibyte_p)
8987 EMACS_INT a1;
8988 Lisp_Object a2;
8989 EMACS_INT nbytes, multibyte_p;
8990 {
8991 const char *s = (const char *) a1;
8992 Lisp_Object string = a2;
8993
8994 /* Change multibyteness of the echo buffer appropriately. */
8995 if (message_enable_multibyte
8996 != !NILP (current_buffer->enable_multibyte_characters))
8997 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8998
8999 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9000
9001 /* Insert new message at BEG. */
9002 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9003
9004 if (STRINGP (string))
9005 {
9006 int nchars;
9007
9008 if (nbytes == 0)
9009 nbytes = SBYTES (string);
9010 nchars = string_byte_to_char (string, nbytes);
9011
9012 /* This function takes care of single/multibyte conversion. We
9013 just have to ensure that the echo area buffer has the right
9014 setting of enable_multibyte_characters. */
9015 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9016 }
9017 else if (s)
9018 {
9019 if (nbytes == 0)
9020 nbytes = strlen (s);
9021
9022 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9023 {
9024 /* Convert from multi-byte to single-byte. */
9025 int i, c, n;
9026 unsigned char work[1];
9027
9028 /* Convert a multibyte string to single-byte. */
9029 for (i = 0; i < nbytes; i += n)
9030 {
9031 c = string_char_and_length (s + i, nbytes - i, &n);
9032 work[0] = (ASCII_CHAR_P (c)
9033 ? c
9034 : multibyte_char_to_unibyte (c, Qnil));
9035 insert_1_both (work, 1, 1, 1, 0, 0);
9036 }
9037 }
9038 else if (!multibyte_p
9039 && !NILP (current_buffer->enable_multibyte_characters))
9040 {
9041 /* Convert from single-byte to multi-byte. */
9042 int i, c, n;
9043 const unsigned char *msg = (const unsigned char *) s;
9044 unsigned char str[MAX_MULTIBYTE_LENGTH];
9045
9046 /* Convert a single-byte string to multibyte. */
9047 for (i = 0; i < nbytes; i++)
9048 {
9049 c = msg[i];
9050 c = unibyte_char_to_multibyte (c);
9051 n = CHAR_STRING (c, str);
9052 insert_1_both (str, 1, n, 1, 0, 0);
9053 }
9054 }
9055 else
9056 insert_1 (s, nbytes, 1, 0, 0);
9057 }
9058
9059 return 0;
9060 }
9061
9062
9063 /* Clear messages. CURRENT_P non-zero means clear the current
9064 message. LAST_DISPLAYED_P non-zero means clear the message
9065 last displayed. */
9066
9067 void
9068 clear_message (current_p, last_displayed_p)
9069 int current_p, last_displayed_p;
9070 {
9071 if (current_p)
9072 {
9073 echo_area_buffer[0] = Qnil;
9074 message_cleared_p = 1;
9075 }
9076
9077 if (last_displayed_p)
9078 echo_area_buffer[1] = Qnil;
9079
9080 message_buf_print = 0;
9081 }
9082
9083 /* Clear garbaged frames.
9084
9085 This function is used where the old redisplay called
9086 redraw_garbaged_frames which in turn called redraw_frame which in
9087 turn called clear_frame. The call to clear_frame was a source of
9088 flickering. I believe a clear_frame is not necessary. It should
9089 suffice in the new redisplay to invalidate all current matrices,
9090 and ensure a complete redisplay of all windows. */
9091
9092 static void
9093 clear_garbaged_frames ()
9094 {
9095 if (frame_garbaged)
9096 {
9097 Lisp_Object tail, frame;
9098 int changed_count = 0;
9099
9100 FOR_EACH_FRAME (tail, frame)
9101 {
9102 struct frame *f = XFRAME (frame);
9103
9104 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9105 {
9106 if (f->resized_p)
9107 {
9108 Fredraw_frame (frame);
9109 f->force_flush_display_p = 1;
9110 }
9111 clear_current_matrices (f);
9112 changed_count++;
9113 f->garbaged = 0;
9114 f->resized_p = 0;
9115 }
9116 }
9117
9118 frame_garbaged = 0;
9119 if (changed_count)
9120 ++windows_or_buffers_changed;
9121 }
9122 }
9123
9124
9125 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9126 is non-zero update selected_frame. Value is non-zero if the
9127 mini-windows height has been changed. */
9128
9129 static int
9130 echo_area_display (update_frame_p)
9131 int update_frame_p;
9132 {
9133 Lisp_Object mini_window;
9134 struct window *w;
9135 struct frame *f;
9136 int window_height_changed_p = 0;
9137 struct frame *sf = SELECTED_FRAME ();
9138
9139 mini_window = FRAME_MINIBUF_WINDOW (sf);
9140 w = XWINDOW (mini_window);
9141 f = XFRAME (WINDOW_FRAME (w));
9142
9143 /* Don't display if frame is invisible or not yet initialized. */
9144 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9145 return 0;
9146
9147 #ifdef HAVE_WINDOW_SYSTEM
9148 /* When Emacs starts, selected_frame may be the initial terminal
9149 frame. If we let this through, a message would be displayed on
9150 the terminal. */
9151 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9152 return 0;
9153 #endif /* HAVE_WINDOW_SYSTEM */
9154
9155 /* Redraw garbaged frames. */
9156 if (frame_garbaged)
9157 clear_garbaged_frames ();
9158
9159 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9160 {
9161 echo_area_window = mini_window;
9162 window_height_changed_p = display_echo_area (w);
9163 w->must_be_updated_p = 1;
9164
9165 /* Update the display, unless called from redisplay_internal.
9166 Also don't update the screen during redisplay itself. The
9167 update will happen at the end of redisplay, and an update
9168 here could cause confusion. */
9169 if (update_frame_p && !redisplaying_p)
9170 {
9171 int n = 0;
9172
9173 /* If the display update has been interrupted by pending
9174 input, update mode lines in the frame. Due to the
9175 pending input, it might have been that redisplay hasn't
9176 been called, so that mode lines above the echo area are
9177 garbaged. This looks odd, so we prevent it here. */
9178 if (!display_completed)
9179 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9180
9181 if (window_height_changed_p
9182 /* Don't do this if Emacs is shutting down. Redisplay
9183 needs to run hooks. */
9184 && !NILP (Vrun_hooks))
9185 {
9186 /* Must update other windows. Likewise as in other
9187 cases, don't let this update be interrupted by
9188 pending input. */
9189 int count = SPECPDL_INDEX ();
9190 specbind (Qredisplay_dont_pause, Qt);
9191 windows_or_buffers_changed = 1;
9192 redisplay_internal (0);
9193 unbind_to (count, Qnil);
9194 }
9195 else if (FRAME_WINDOW_P (f) && n == 0)
9196 {
9197 /* Window configuration is the same as before.
9198 Can do with a display update of the echo area,
9199 unless we displayed some mode lines. */
9200 update_single_window (w, 1);
9201 FRAME_RIF (f)->flush_display (f);
9202 }
9203 else
9204 update_frame (f, 1, 1);
9205
9206 /* If cursor is in the echo area, make sure that the next
9207 redisplay displays the minibuffer, so that the cursor will
9208 be replaced with what the minibuffer wants. */
9209 if (cursor_in_echo_area)
9210 ++windows_or_buffers_changed;
9211 }
9212 }
9213 else if (!EQ (mini_window, selected_window))
9214 windows_or_buffers_changed++;
9215
9216 /* Last displayed message is now the current message. */
9217 echo_area_buffer[1] = echo_area_buffer[0];
9218 /* Inform read_char that we're not echoing. */
9219 echo_message_buffer = Qnil;
9220
9221 /* Prevent redisplay optimization in redisplay_internal by resetting
9222 this_line_start_pos. This is done because the mini-buffer now
9223 displays the message instead of its buffer text. */
9224 if (EQ (mini_window, selected_window))
9225 CHARPOS (this_line_start_pos) = 0;
9226
9227 return window_height_changed_p;
9228 }
9229
9230
9231 \f
9232 /***********************************************************************
9233 Mode Lines and Frame Titles
9234 ***********************************************************************/
9235
9236 /* A buffer for constructing non-propertized mode-line strings and
9237 frame titles in it; allocated from the heap in init_xdisp and
9238 resized as needed in store_mode_line_noprop_char. */
9239
9240 static char *mode_line_noprop_buf;
9241
9242 /* The buffer's end, and a current output position in it. */
9243
9244 static char *mode_line_noprop_buf_end;
9245 static char *mode_line_noprop_ptr;
9246
9247 #define MODE_LINE_NOPROP_LEN(start) \
9248 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9249
9250 static enum {
9251 MODE_LINE_DISPLAY = 0,
9252 MODE_LINE_TITLE,
9253 MODE_LINE_NOPROP,
9254 MODE_LINE_STRING
9255 } mode_line_target;
9256
9257 /* Alist that caches the results of :propertize.
9258 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9259 static Lisp_Object mode_line_proptrans_alist;
9260
9261 /* List of strings making up the mode-line. */
9262 static Lisp_Object mode_line_string_list;
9263
9264 /* Base face property when building propertized mode line string. */
9265 static Lisp_Object mode_line_string_face;
9266 static Lisp_Object mode_line_string_face_prop;
9267
9268
9269 /* Unwind data for mode line strings */
9270
9271 static Lisp_Object Vmode_line_unwind_vector;
9272
9273 static Lisp_Object
9274 format_mode_line_unwind_data (struct buffer *obuf,
9275 Lisp_Object owin,
9276 int save_proptrans)
9277 {
9278 Lisp_Object vector, tmp;
9279
9280 /* Reduce consing by keeping one vector in
9281 Vwith_echo_area_save_vector. */
9282 vector = Vmode_line_unwind_vector;
9283 Vmode_line_unwind_vector = Qnil;
9284
9285 if (NILP (vector))
9286 vector = Fmake_vector (make_number (8), Qnil);
9287
9288 ASET (vector, 0, make_number (mode_line_target));
9289 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9290 ASET (vector, 2, mode_line_string_list);
9291 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9292 ASET (vector, 4, mode_line_string_face);
9293 ASET (vector, 5, mode_line_string_face_prop);
9294
9295 if (obuf)
9296 XSETBUFFER (tmp, obuf);
9297 else
9298 tmp = Qnil;
9299 ASET (vector, 6, tmp);
9300 ASET (vector, 7, owin);
9301
9302 return vector;
9303 }
9304
9305 static Lisp_Object
9306 unwind_format_mode_line (vector)
9307 Lisp_Object vector;
9308 {
9309 mode_line_target = XINT (AREF (vector, 0));
9310 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9311 mode_line_string_list = AREF (vector, 2);
9312 if (! EQ (AREF (vector, 3), Qt))
9313 mode_line_proptrans_alist = AREF (vector, 3);
9314 mode_line_string_face = AREF (vector, 4);
9315 mode_line_string_face_prop = AREF (vector, 5);
9316
9317 if (!NILP (AREF (vector, 7)))
9318 /* Select window before buffer, since it may change the buffer. */
9319 Fselect_window (AREF (vector, 7), Qt);
9320
9321 if (!NILP (AREF (vector, 6)))
9322 {
9323 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9324 ASET (vector, 6, Qnil);
9325 }
9326
9327 Vmode_line_unwind_vector = vector;
9328 return Qnil;
9329 }
9330
9331
9332 /* Store a single character C for the frame title in mode_line_noprop_buf.
9333 Re-allocate mode_line_noprop_buf if necessary. */
9334
9335 static void
9336 #ifdef PROTOTYPES
9337 store_mode_line_noprop_char (char c)
9338 #else
9339 store_mode_line_noprop_char (c)
9340 char c;
9341 #endif
9342 {
9343 /* If output position has reached the end of the allocated buffer,
9344 double the buffer's size. */
9345 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9346 {
9347 int len = MODE_LINE_NOPROP_LEN (0);
9348 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9349 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9350 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9351 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9352 }
9353
9354 *mode_line_noprop_ptr++ = c;
9355 }
9356
9357
9358 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9359 mode_line_noprop_ptr. STR is the string to store. Do not copy
9360 characters that yield more columns than PRECISION; PRECISION <= 0
9361 means copy the whole string. Pad with spaces until FIELD_WIDTH
9362 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9363 pad. Called from display_mode_element when it is used to build a
9364 frame title. */
9365
9366 static int
9367 store_mode_line_noprop (str, field_width, precision)
9368 const unsigned char *str;
9369 int field_width, precision;
9370 {
9371 int n = 0;
9372 int dummy, nbytes;
9373
9374 /* Copy at most PRECISION chars from STR. */
9375 nbytes = strlen (str);
9376 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9377 while (nbytes--)
9378 store_mode_line_noprop_char (*str++);
9379
9380 /* Fill up with spaces until FIELD_WIDTH reached. */
9381 while (field_width > 0
9382 && n < field_width)
9383 {
9384 store_mode_line_noprop_char (' ');
9385 ++n;
9386 }
9387
9388 return n;
9389 }
9390
9391 /***********************************************************************
9392 Frame Titles
9393 ***********************************************************************/
9394
9395 #ifdef HAVE_WINDOW_SYSTEM
9396
9397 /* Set the title of FRAME, if it has changed. The title format is
9398 Vicon_title_format if FRAME is iconified, otherwise it is
9399 frame_title_format. */
9400
9401 static void
9402 x_consider_frame_title (frame)
9403 Lisp_Object frame;
9404 {
9405 struct frame *f = XFRAME (frame);
9406
9407 if (FRAME_WINDOW_P (f)
9408 || FRAME_MINIBUF_ONLY_P (f)
9409 || f->explicit_name)
9410 {
9411 /* Do we have more than one visible frame on this X display? */
9412 Lisp_Object tail;
9413 Lisp_Object fmt;
9414 int title_start;
9415 char *title;
9416 int len;
9417 struct it it;
9418 int count = SPECPDL_INDEX ();
9419
9420 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9421 {
9422 Lisp_Object other_frame = XCAR (tail);
9423 struct frame *tf = XFRAME (other_frame);
9424
9425 if (tf != f
9426 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9427 && !FRAME_MINIBUF_ONLY_P (tf)
9428 && !EQ (other_frame, tip_frame)
9429 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9430 break;
9431 }
9432
9433 /* Set global variable indicating that multiple frames exist. */
9434 multiple_frames = CONSP (tail);
9435
9436 /* Switch to the buffer of selected window of the frame. Set up
9437 mode_line_target so that display_mode_element will output into
9438 mode_line_noprop_buf; then display the title. */
9439 record_unwind_protect (unwind_format_mode_line,
9440 format_mode_line_unwind_data
9441 (current_buffer, selected_window, 0));
9442
9443 Fselect_window (f->selected_window, Qt);
9444 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9445 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9446
9447 mode_line_target = MODE_LINE_TITLE;
9448 title_start = MODE_LINE_NOPROP_LEN (0);
9449 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9450 NULL, DEFAULT_FACE_ID);
9451 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9452 len = MODE_LINE_NOPROP_LEN (title_start);
9453 title = mode_line_noprop_buf + title_start;
9454 unbind_to (count, Qnil);
9455
9456 /* Set the title only if it's changed. This avoids consing in
9457 the common case where it hasn't. (If it turns out that we've
9458 already wasted too much time by walking through the list with
9459 display_mode_element, then we might need to optimize at a
9460 higher level than this.) */
9461 if (! STRINGP (f->name)
9462 || SBYTES (f->name) != len
9463 || bcmp (title, SDATA (f->name), len) != 0)
9464 {
9465 #ifdef HAVE_NS
9466 if (FRAME_NS_P (f))
9467 {
9468 if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
9469 {
9470 if (EQ (fmt, Qt))
9471 ns_set_name_as_filename (f);
9472 else
9473 x_implicitly_set_name (f, make_string(title, len),
9474 Qnil);
9475 }
9476 }
9477 else
9478 #endif
9479 x_implicitly_set_name (f, make_string (title, len), Qnil);
9480 }
9481 #ifdef HAVE_NS
9482 if (FRAME_NS_P (f))
9483 {
9484 /* do this also for frames with explicit names */
9485 ns_implicitly_set_icon_type(f);
9486 ns_set_doc_edited(f, Fbuffer_modified_p
9487 (XWINDOW (f->selected_window)->buffer), Qnil);
9488 }
9489 #endif
9490 }
9491 }
9492
9493 #endif /* not HAVE_WINDOW_SYSTEM */
9494
9495
9496
9497 \f
9498 /***********************************************************************
9499 Menu Bars
9500 ***********************************************************************/
9501
9502
9503 /* Prepare for redisplay by updating menu-bar item lists when
9504 appropriate. This can call eval. */
9505
9506 void
9507 prepare_menu_bars ()
9508 {
9509 int all_windows;
9510 struct gcpro gcpro1, gcpro2;
9511 struct frame *f;
9512 Lisp_Object tooltip_frame;
9513
9514 #ifdef HAVE_WINDOW_SYSTEM
9515 tooltip_frame = tip_frame;
9516 #else
9517 tooltip_frame = Qnil;
9518 #endif
9519
9520 /* Update all frame titles based on their buffer names, etc. We do
9521 this before the menu bars so that the buffer-menu will show the
9522 up-to-date frame titles. */
9523 #ifdef HAVE_WINDOW_SYSTEM
9524 if (windows_or_buffers_changed || update_mode_lines)
9525 {
9526 Lisp_Object tail, frame;
9527
9528 FOR_EACH_FRAME (tail, frame)
9529 {
9530 f = XFRAME (frame);
9531 if (!EQ (frame, tooltip_frame)
9532 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9533 x_consider_frame_title (frame);
9534 }
9535 }
9536 #endif /* HAVE_WINDOW_SYSTEM */
9537
9538 /* Update the menu bar item lists, if appropriate. This has to be
9539 done before any actual redisplay or generation of display lines. */
9540 all_windows = (update_mode_lines
9541 || buffer_shared > 1
9542 || windows_or_buffers_changed);
9543 if (all_windows)
9544 {
9545 Lisp_Object tail, frame;
9546 int count = SPECPDL_INDEX ();
9547 /* 1 means that update_menu_bar has run its hooks
9548 so any further calls to update_menu_bar shouldn't do so again. */
9549 int menu_bar_hooks_run = 0;
9550
9551 record_unwind_save_match_data ();
9552
9553 FOR_EACH_FRAME (tail, frame)
9554 {
9555 f = XFRAME (frame);
9556
9557 /* Ignore tooltip frame. */
9558 if (EQ (frame, tooltip_frame))
9559 continue;
9560
9561 /* If a window on this frame changed size, report that to
9562 the user and clear the size-change flag. */
9563 if (FRAME_WINDOW_SIZES_CHANGED (f))
9564 {
9565 Lisp_Object functions;
9566
9567 /* Clear flag first in case we get an error below. */
9568 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9569 functions = Vwindow_size_change_functions;
9570 GCPRO2 (tail, functions);
9571
9572 while (CONSP (functions))
9573 {
9574 if (!EQ (XCAR (functions), Qt))
9575 call1 (XCAR (functions), frame);
9576 functions = XCDR (functions);
9577 }
9578 UNGCPRO;
9579 }
9580
9581 GCPRO1 (tail);
9582 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9583 #ifdef HAVE_WINDOW_SYSTEM
9584 update_tool_bar (f, 0);
9585 #endif
9586 UNGCPRO;
9587 }
9588
9589 unbind_to (count, Qnil);
9590 }
9591 else
9592 {
9593 struct frame *sf = SELECTED_FRAME ();
9594 update_menu_bar (sf, 1, 0);
9595 #ifdef HAVE_WINDOW_SYSTEM
9596 update_tool_bar (sf, 1);
9597 #endif
9598 }
9599
9600 /* Motif needs this. See comment in xmenu.c. Turn it off when
9601 pending_menu_activation is not defined. */
9602 #ifdef USE_X_TOOLKIT
9603 pending_menu_activation = 0;
9604 #endif
9605 }
9606
9607
9608 /* Update the menu bar item list for frame F. This has to be done
9609 before we start to fill in any display lines, because it can call
9610 eval.
9611
9612 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9613
9614 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9615 already ran the menu bar hooks for this redisplay, so there
9616 is no need to run them again. The return value is the
9617 updated value of this flag, to pass to the next call. */
9618
9619 static int
9620 update_menu_bar (f, save_match_data, hooks_run)
9621 struct frame *f;
9622 int save_match_data;
9623 int hooks_run;
9624 {
9625 Lisp_Object window;
9626 register struct window *w;
9627
9628 /* If called recursively during a menu update, do nothing. This can
9629 happen when, for instance, an activate-menubar-hook causes a
9630 redisplay. */
9631 if (inhibit_menubar_update)
9632 return hooks_run;
9633
9634 window = FRAME_SELECTED_WINDOW (f);
9635 w = XWINDOW (window);
9636
9637 if (FRAME_WINDOW_P (f)
9638 ?
9639 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9640 || defined (HAVE_NS) || defined (USE_GTK)
9641 FRAME_EXTERNAL_MENU_BAR (f)
9642 #else
9643 FRAME_MENU_BAR_LINES (f) > 0
9644 #endif
9645 : FRAME_MENU_BAR_LINES (f) > 0)
9646 {
9647 /* If the user has switched buffers or windows, we need to
9648 recompute to reflect the new bindings. But we'll
9649 recompute when update_mode_lines is set too; that means
9650 that people can use force-mode-line-update to request
9651 that the menu bar be recomputed. The adverse effect on
9652 the rest of the redisplay algorithm is about the same as
9653 windows_or_buffers_changed anyway. */
9654 if (windows_or_buffers_changed
9655 /* This used to test w->update_mode_line, but we believe
9656 there is no need to recompute the menu in that case. */
9657 || update_mode_lines
9658 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9659 < BUF_MODIFF (XBUFFER (w->buffer)))
9660 != !NILP (w->last_had_star))
9661 || ((!NILP (Vtransient_mark_mode)
9662 && !NILP (XBUFFER (w->buffer)->mark_active))
9663 != !NILP (w->region_showing)))
9664 {
9665 struct buffer *prev = current_buffer;
9666 int count = SPECPDL_INDEX ();
9667
9668 specbind (Qinhibit_menubar_update, Qt);
9669
9670 set_buffer_internal_1 (XBUFFER (w->buffer));
9671 if (save_match_data)
9672 record_unwind_save_match_data ();
9673 if (NILP (Voverriding_local_map_menu_flag))
9674 {
9675 specbind (Qoverriding_terminal_local_map, Qnil);
9676 specbind (Qoverriding_local_map, Qnil);
9677 }
9678
9679 if (!hooks_run)
9680 {
9681 /* Run the Lucid hook. */
9682 safe_run_hooks (Qactivate_menubar_hook);
9683
9684 /* If it has changed current-menubar from previous value,
9685 really recompute the menu-bar from the value. */
9686 if (! NILP (Vlucid_menu_bar_dirty_flag))
9687 call0 (Qrecompute_lucid_menubar);
9688
9689 safe_run_hooks (Qmenu_bar_update_hook);
9690
9691 hooks_run = 1;
9692 }
9693
9694 XSETFRAME (Vmenu_updating_frame, f);
9695 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9696
9697 /* Redisplay the menu bar in case we changed it. */
9698 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9699 || defined (HAVE_NS) || defined (USE_GTK)
9700 if (FRAME_WINDOW_P (f))
9701 {
9702 #if defined (HAVE_NS)
9703 /* All frames on Mac OS share the same menubar. So only
9704 the selected frame should be allowed to set it. */
9705 if (f == SELECTED_FRAME ())
9706 #endif
9707 set_frame_menubar (f, 0, 0);
9708 }
9709 else
9710 /* On a terminal screen, the menu bar is an ordinary screen
9711 line, and this makes it get updated. */
9712 w->update_mode_line = Qt;
9713 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9714 /* In the non-toolkit version, the menu bar is an ordinary screen
9715 line, and this makes it get updated. */
9716 w->update_mode_line = Qt;
9717 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9718
9719 unbind_to (count, Qnil);
9720 set_buffer_internal_1 (prev);
9721 }
9722 }
9723
9724 return hooks_run;
9725 }
9726
9727
9728 \f
9729 /***********************************************************************
9730 Output Cursor
9731 ***********************************************************************/
9732
9733 #ifdef HAVE_WINDOW_SYSTEM
9734
9735 /* EXPORT:
9736 Nominal cursor position -- where to draw output.
9737 HPOS and VPOS are window relative glyph matrix coordinates.
9738 X and Y are window relative pixel coordinates. */
9739
9740 struct cursor_pos output_cursor;
9741
9742
9743 /* EXPORT:
9744 Set the global variable output_cursor to CURSOR. All cursor
9745 positions are relative to updated_window. */
9746
9747 void
9748 set_output_cursor (cursor)
9749 struct cursor_pos *cursor;
9750 {
9751 output_cursor.hpos = cursor->hpos;
9752 output_cursor.vpos = cursor->vpos;
9753 output_cursor.x = cursor->x;
9754 output_cursor.y = cursor->y;
9755 }
9756
9757
9758 /* EXPORT for RIF:
9759 Set a nominal cursor position.
9760
9761 HPOS and VPOS are column/row positions in a window glyph matrix. X
9762 and Y are window text area relative pixel positions.
9763
9764 If this is done during an update, updated_window will contain the
9765 window that is being updated and the position is the future output
9766 cursor position for that window. If updated_window is null, use
9767 selected_window and display the cursor at the given position. */
9768
9769 void
9770 x_cursor_to (vpos, hpos, y, x)
9771 int vpos, hpos, y, x;
9772 {
9773 struct window *w;
9774
9775 /* If updated_window is not set, work on selected_window. */
9776 if (updated_window)
9777 w = updated_window;
9778 else
9779 w = XWINDOW (selected_window);
9780
9781 /* Set the output cursor. */
9782 output_cursor.hpos = hpos;
9783 output_cursor.vpos = vpos;
9784 output_cursor.x = x;
9785 output_cursor.y = y;
9786
9787 /* If not called as part of an update, really display the cursor.
9788 This will also set the cursor position of W. */
9789 if (updated_window == NULL)
9790 {
9791 BLOCK_INPUT;
9792 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9793 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9794 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9795 UNBLOCK_INPUT;
9796 }
9797 }
9798
9799 #endif /* HAVE_WINDOW_SYSTEM */
9800
9801 \f
9802 /***********************************************************************
9803 Tool-bars
9804 ***********************************************************************/
9805
9806 #ifdef HAVE_WINDOW_SYSTEM
9807
9808 /* Where the mouse was last time we reported a mouse event. */
9809
9810 FRAME_PTR last_mouse_frame;
9811
9812 /* Tool-bar item index of the item on which a mouse button was pressed
9813 or -1. */
9814
9815 int last_tool_bar_item;
9816
9817
9818 static Lisp_Object
9819 update_tool_bar_unwind (frame)
9820 Lisp_Object frame;
9821 {
9822 selected_frame = frame;
9823 return Qnil;
9824 }
9825
9826 /* Update the tool-bar item list for frame F. This has to be done
9827 before we start to fill in any display lines. Called from
9828 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9829 and restore it here. */
9830
9831 static void
9832 update_tool_bar (f, save_match_data)
9833 struct frame *f;
9834 int save_match_data;
9835 {
9836 #if defined (USE_GTK) || defined (HAVE_NS)
9837 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9838 #else
9839 int do_update = WINDOWP (f->tool_bar_window)
9840 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9841 #endif
9842
9843 if (do_update)
9844 {
9845 Lisp_Object window;
9846 struct window *w;
9847
9848 window = FRAME_SELECTED_WINDOW (f);
9849 w = XWINDOW (window);
9850
9851 /* If the user has switched buffers or windows, we need to
9852 recompute to reflect the new bindings. But we'll
9853 recompute when update_mode_lines is set too; that means
9854 that people can use force-mode-line-update to request
9855 that the menu bar be recomputed. The adverse effect on
9856 the rest of the redisplay algorithm is about the same as
9857 windows_or_buffers_changed anyway. */
9858 if (windows_or_buffers_changed
9859 || !NILP (w->update_mode_line)
9860 || update_mode_lines
9861 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9862 < BUF_MODIFF (XBUFFER (w->buffer)))
9863 != !NILP (w->last_had_star))
9864 || ((!NILP (Vtransient_mark_mode)
9865 && !NILP (XBUFFER (w->buffer)->mark_active))
9866 != !NILP (w->region_showing)))
9867 {
9868 struct buffer *prev = current_buffer;
9869 int count = SPECPDL_INDEX ();
9870 Lisp_Object frame, new_tool_bar;
9871 int new_n_tool_bar;
9872 struct gcpro gcpro1;
9873
9874 /* Set current_buffer to the buffer of the selected
9875 window of the frame, so that we get the right local
9876 keymaps. */
9877 set_buffer_internal_1 (XBUFFER (w->buffer));
9878
9879 /* Save match data, if we must. */
9880 if (save_match_data)
9881 record_unwind_save_match_data ();
9882
9883 /* Make sure that we don't accidentally use bogus keymaps. */
9884 if (NILP (Voverriding_local_map_menu_flag))
9885 {
9886 specbind (Qoverriding_terminal_local_map, Qnil);
9887 specbind (Qoverriding_local_map, Qnil);
9888 }
9889
9890 GCPRO1 (new_tool_bar);
9891
9892 /* We must temporarily set the selected frame to this frame
9893 before calling tool_bar_items, because the calculation of
9894 the tool-bar keymap uses the selected frame (see
9895 `tool-bar-make-keymap' in tool-bar.el). */
9896 record_unwind_protect (update_tool_bar_unwind, selected_frame);
9897 XSETFRAME (frame, f);
9898 selected_frame = frame;
9899
9900 /* Build desired tool-bar items from keymaps. */
9901 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9902 &new_n_tool_bar);
9903
9904 /* Redisplay the tool-bar if we changed it. */
9905 if (new_n_tool_bar != f->n_tool_bar_items
9906 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9907 {
9908 /* Redisplay that happens asynchronously due to an expose event
9909 may access f->tool_bar_items. Make sure we update both
9910 variables within BLOCK_INPUT so no such event interrupts. */
9911 BLOCK_INPUT;
9912 f->tool_bar_items = new_tool_bar;
9913 f->n_tool_bar_items = new_n_tool_bar;
9914 w->update_mode_line = Qt;
9915 UNBLOCK_INPUT;
9916 }
9917
9918 UNGCPRO;
9919
9920 unbind_to (count, Qnil);
9921 set_buffer_internal_1 (prev);
9922 }
9923 }
9924 }
9925
9926
9927 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9928 F's desired tool-bar contents. F->tool_bar_items must have
9929 been set up previously by calling prepare_menu_bars. */
9930
9931 static void
9932 build_desired_tool_bar_string (f)
9933 struct frame *f;
9934 {
9935 int i, size, size_needed;
9936 struct gcpro gcpro1, gcpro2, gcpro3;
9937 Lisp_Object image, plist, props;
9938
9939 image = plist = props = Qnil;
9940 GCPRO3 (image, plist, props);
9941
9942 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9943 Otherwise, make a new string. */
9944
9945 /* The size of the string we might be able to reuse. */
9946 size = (STRINGP (f->desired_tool_bar_string)
9947 ? SCHARS (f->desired_tool_bar_string)
9948 : 0);
9949
9950 /* We need one space in the string for each image. */
9951 size_needed = f->n_tool_bar_items;
9952
9953 /* Reuse f->desired_tool_bar_string, if possible. */
9954 if (size < size_needed || NILP (f->desired_tool_bar_string))
9955 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9956 make_number (' '));
9957 else
9958 {
9959 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9960 Fremove_text_properties (make_number (0), make_number (size),
9961 props, f->desired_tool_bar_string);
9962 }
9963
9964 /* Put a `display' property on the string for the images to display,
9965 put a `menu_item' property on tool-bar items with a value that
9966 is the index of the item in F's tool-bar item vector. */
9967 for (i = 0; i < f->n_tool_bar_items; ++i)
9968 {
9969 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9970
9971 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9972 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9973 int hmargin, vmargin, relief, idx, end;
9974 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9975
9976 /* If image is a vector, choose the image according to the
9977 button state. */
9978 image = PROP (TOOL_BAR_ITEM_IMAGES);
9979 if (VECTORP (image))
9980 {
9981 if (enabled_p)
9982 idx = (selected_p
9983 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9984 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9985 else
9986 idx = (selected_p
9987 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9988 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9989
9990 xassert (ASIZE (image) >= idx);
9991 image = AREF (image, idx);
9992 }
9993 else
9994 idx = -1;
9995
9996 /* Ignore invalid image specifications. */
9997 if (!valid_image_p (image))
9998 continue;
9999
10000 /* Display the tool-bar button pressed, or depressed. */
10001 plist = Fcopy_sequence (XCDR (image));
10002
10003 /* Compute margin and relief to draw. */
10004 relief = (tool_bar_button_relief >= 0
10005 ? tool_bar_button_relief
10006 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10007 hmargin = vmargin = relief;
10008
10009 if (INTEGERP (Vtool_bar_button_margin)
10010 && XINT (Vtool_bar_button_margin) > 0)
10011 {
10012 hmargin += XFASTINT (Vtool_bar_button_margin);
10013 vmargin += XFASTINT (Vtool_bar_button_margin);
10014 }
10015 else if (CONSP (Vtool_bar_button_margin))
10016 {
10017 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10018 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10019 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10020
10021 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10022 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10023 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10024 }
10025
10026 if (auto_raise_tool_bar_buttons_p)
10027 {
10028 /* Add a `:relief' property to the image spec if the item is
10029 selected. */
10030 if (selected_p)
10031 {
10032 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10033 hmargin -= relief;
10034 vmargin -= relief;
10035 }
10036 }
10037 else
10038 {
10039 /* If image is selected, display it pressed, i.e. with a
10040 negative relief. If it's not selected, display it with a
10041 raised relief. */
10042 plist = Fplist_put (plist, QCrelief,
10043 (selected_p
10044 ? make_number (-relief)
10045 : make_number (relief)));
10046 hmargin -= relief;
10047 vmargin -= relief;
10048 }
10049
10050 /* Put a margin around the image. */
10051 if (hmargin || vmargin)
10052 {
10053 if (hmargin == vmargin)
10054 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10055 else
10056 plist = Fplist_put (plist, QCmargin,
10057 Fcons (make_number (hmargin),
10058 make_number (vmargin)));
10059 }
10060
10061 /* If button is not enabled, and we don't have special images
10062 for the disabled state, make the image appear disabled by
10063 applying an appropriate algorithm to it. */
10064 if (!enabled_p && idx < 0)
10065 plist = Fplist_put (plist, QCconversion, Qdisabled);
10066
10067 /* Put a `display' text property on the string for the image to
10068 display. Put a `menu-item' property on the string that gives
10069 the start of this item's properties in the tool-bar items
10070 vector. */
10071 image = Fcons (Qimage, plist);
10072 props = list4 (Qdisplay, image,
10073 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10074
10075 /* Let the last image hide all remaining spaces in the tool bar
10076 string. The string can be longer than needed when we reuse a
10077 previous string. */
10078 if (i + 1 == f->n_tool_bar_items)
10079 end = SCHARS (f->desired_tool_bar_string);
10080 else
10081 end = i + 1;
10082 Fadd_text_properties (make_number (i), make_number (end),
10083 props, f->desired_tool_bar_string);
10084 #undef PROP
10085 }
10086
10087 UNGCPRO;
10088 }
10089
10090
10091 /* Display one line of the tool-bar of frame IT->f.
10092
10093 HEIGHT specifies the desired height of the tool-bar line.
10094 If the actual height of the glyph row is less than HEIGHT, the
10095 row's height is increased to HEIGHT, and the icons are centered
10096 vertically in the new height.
10097
10098 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10099 count a final empty row in case the tool-bar width exactly matches
10100 the window width.
10101 */
10102
10103 static void
10104 display_tool_bar_line (it, height)
10105 struct it *it;
10106 int height;
10107 {
10108 struct glyph_row *row = it->glyph_row;
10109 int max_x = it->last_visible_x;
10110 struct glyph *last;
10111
10112 prepare_desired_row (row);
10113 row->y = it->current_y;
10114
10115 /* Note that this isn't made use of if the face hasn't a box,
10116 so there's no need to check the face here. */
10117 it->start_of_box_run_p = 1;
10118
10119 while (it->current_x < max_x)
10120 {
10121 int x, n_glyphs_before, i, nglyphs;
10122 struct it it_before;
10123
10124 /* Get the next display element. */
10125 if (!get_next_display_element (it))
10126 {
10127 /* Don't count empty row if we are counting needed tool-bar lines. */
10128 if (height < 0 && !it->hpos)
10129 return;
10130 break;
10131 }
10132
10133 /* Produce glyphs. */
10134 n_glyphs_before = row->used[TEXT_AREA];
10135 it_before = *it;
10136
10137 PRODUCE_GLYPHS (it);
10138
10139 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10140 i = 0;
10141 x = it_before.current_x;
10142 while (i < nglyphs)
10143 {
10144 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10145
10146 if (x + glyph->pixel_width > max_x)
10147 {
10148 /* Glyph doesn't fit on line. Backtrack. */
10149 row->used[TEXT_AREA] = n_glyphs_before;
10150 *it = it_before;
10151 /* If this is the only glyph on this line, it will never fit on the
10152 toolbar, so skip it. But ensure there is at least one glyph,
10153 so we don't accidentally disable the tool-bar. */
10154 if (n_glyphs_before == 0
10155 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10156 break;
10157 goto out;
10158 }
10159
10160 ++it->hpos;
10161 x += glyph->pixel_width;
10162 ++i;
10163 }
10164
10165 /* Stop at line ends. */
10166 if (ITERATOR_AT_END_OF_LINE_P (it))
10167 break;
10168
10169 set_iterator_to_next (it, 1);
10170 }
10171
10172 out:;
10173
10174 row->displays_text_p = row->used[TEXT_AREA] != 0;
10175
10176 /* Use default face for the border below the tool bar.
10177
10178 FIXME: When auto-resize-tool-bars is grow-only, there is
10179 no additional border below the possibly empty tool-bar lines.
10180 So to make the extra empty lines look "normal", we have to
10181 use the tool-bar face for the border too. */
10182 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10183 it->face_id = DEFAULT_FACE_ID;
10184
10185 extend_face_to_end_of_line (it);
10186 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10187 last->right_box_line_p = 1;
10188 if (last == row->glyphs[TEXT_AREA])
10189 last->left_box_line_p = 1;
10190
10191 /* Make line the desired height and center it vertically. */
10192 if ((height -= it->max_ascent + it->max_descent) > 0)
10193 {
10194 /* Don't add more than one line height. */
10195 height %= FRAME_LINE_HEIGHT (it->f);
10196 it->max_ascent += height / 2;
10197 it->max_descent += (height + 1) / 2;
10198 }
10199
10200 compute_line_metrics (it);
10201
10202 /* If line is empty, make it occupy the rest of the tool-bar. */
10203 if (!row->displays_text_p)
10204 {
10205 row->height = row->phys_height = it->last_visible_y - row->y;
10206 row->visible_height = row->height;
10207 row->ascent = row->phys_ascent = 0;
10208 row->extra_line_spacing = 0;
10209 }
10210
10211 row->full_width_p = 1;
10212 row->continued_p = 0;
10213 row->truncated_on_left_p = 0;
10214 row->truncated_on_right_p = 0;
10215
10216 it->current_x = it->hpos = 0;
10217 it->current_y += row->height;
10218 ++it->vpos;
10219 ++it->glyph_row;
10220 }
10221
10222
10223 /* Max tool-bar height. */
10224
10225 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10226 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10227
10228 /* Value is the number of screen lines needed to make all tool-bar
10229 items of frame F visible. The number of actual rows needed is
10230 returned in *N_ROWS if non-NULL. */
10231
10232 static int
10233 tool_bar_lines_needed (f, n_rows)
10234 struct frame *f;
10235 int *n_rows;
10236 {
10237 struct window *w = XWINDOW (f->tool_bar_window);
10238 struct it it;
10239 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10240 the desired matrix, so use (unused) mode-line row as temporary row to
10241 avoid destroying the first tool-bar row. */
10242 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10243
10244 /* Initialize an iterator for iteration over
10245 F->desired_tool_bar_string in the tool-bar window of frame F. */
10246 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10247 it.first_visible_x = 0;
10248 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10249 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10250
10251 while (!ITERATOR_AT_END_P (&it))
10252 {
10253 clear_glyph_row (temp_row);
10254 it.glyph_row = temp_row;
10255 display_tool_bar_line (&it, -1);
10256 }
10257 clear_glyph_row (temp_row);
10258
10259 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10260 if (n_rows)
10261 *n_rows = it.vpos > 0 ? it.vpos : -1;
10262
10263 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10264 }
10265
10266
10267 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10268 0, 1, 0,
10269 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10270 (frame)
10271 Lisp_Object frame;
10272 {
10273 struct frame *f;
10274 struct window *w;
10275 int nlines = 0;
10276
10277 if (NILP (frame))
10278 frame = selected_frame;
10279 else
10280 CHECK_FRAME (frame);
10281 f = XFRAME (frame);
10282
10283 if (WINDOWP (f->tool_bar_window)
10284 || (w = XWINDOW (f->tool_bar_window),
10285 WINDOW_TOTAL_LINES (w) > 0))
10286 {
10287 update_tool_bar (f, 1);
10288 if (f->n_tool_bar_items)
10289 {
10290 build_desired_tool_bar_string (f);
10291 nlines = tool_bar_lines_needed (f, NULL);
10292 }
10293 }
10294
10295 return make_number (nlines);
10296 }
10297
10298
10299 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10300 height should be changed. */
10301
10302 static int
10303 redisplay_tool_bar (f)
10304 struct frame *f;
10305 {
10306 struct window *w;
10307 struct it it;
10308 struct glyph_row *row;
10309
10310 #if defined (USE_GTK) || defined (HAVE_NS)
10311 if (FRAME_EXTERNAL_TOOL_BAR (f))
10312 update_frame_tool_bar (f);
10313 return 0;
10314 #endif
10315
10316 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10317 do anything. This means you must start with tool-bar-lines
10318 non-zero to get the auto-sizing effect. Or in other words, you
10319 can turn off tool-bars by specifying tool-bar-lines zero. */
10320 if (!WINDOWP (f->tool_bar_window)
10321 || (w = XWINDOW (f->tool_bar_window),
10322 WINDOW_TOTAL_LINES (w) == 0))
10323 return 0;
10324
10325 /* Set up an iterator for the tool-bar window. */
10326 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10327 it.first_visible_x = 0;
10328 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10329 row = it.glyph_row;
10330
10331 /* Build a string that represents the contents of the tool-bar. */
10332 build_desired_tool_bar_string (f);
10333 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10334
10335 if (f->n_tool_bar_rows == 0)
10336 {
10337 int nlines;
10338
10339 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10340 nlines != WINDOW_TOTAL_LINES (w)))
10341 {
10342 extern Lisp_Object Qtool_bar_lines;
10343 Lisp_Object frame;
10344 int old_height = WINDOW_TOTAL_LINES (w);
10345
10346 XSETFRAME (frame, f);
10347 Fmodify_frame_parameters (frame,
10348 Fcons (Fcons (Qtool_bar_lines,
10349 make_number (nlines)),
10350 Qnil));
10351 if (WINDOW_TOTAL_LINES (w) != old_height)
10352 {
10353 clear_glyph_matrix (w->desired_matrix);
10354 fonts_changed_p = 1;
10355 return 1;
10356 }
10357 }
10358 }
10359
10360 /* Display as many lines as needed to display all tool-bar items. */
10361
10362 if (f->n_tool_bar_rows > 0)
10363 {
10364 int border, rows, height, extra;
10365
10366 if (INTEGERP (Vtool_bar_border))
10367 border = XINT (Vtool_bar_border);
10368 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10369 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10370 else if (EQ (Vtool_bar_border, Qborder_width))
10371 border = f->border_width;
10372 else
10373 border = 0;
10374 if (border < 0)
10375 border = 0;
10376
10377 rows = f->n_tool_bar_rows;
10378 height = max (1, (it.last_visible_y - border) / rows);
10379 extra = it.last_visible_y - border - height * rows;
10380
10381 while (it.current_y < it.last_visible_y)
10382 {
10383 int h = 0;
10384 if (extra > 0 && rows-- > 0)
10385 {
10386 h = (extra + rows - 1) / rows;
10387 extra -= h;
10388 }
10389 display_tool_bar_line (&it, height + h);
10390 }
10391 }
10392 else
10393 {
10394 while (it.current_y < it.last_visible_y)
10395 display_tool_bar_line (&it, 0);
10396 }
10397
10398 /* It doesn't make much sense to try scrolling in the tool-bar
10399 window, so don't do it. */
10400 w->desired_matrix->no_scrolling_p = 1;
10401 w->must_be_updated_p = 1;
10402
10403 if (!NILP (Vauto_resize_tool_bars))
10404 {
10405 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10406 int change_height_p = 0;
10407
10408 /* If we couldn't display everything, change the tool-bar's
10409 height if there is room for more. */
10410 if (IT_STRING_CHARPOS (it) < it.end_charpos
10411 && it.current_y < max_tool_bar_height)
10412 change_height_p = 1;
10413
10414 row = it.glyph_row - 1;
10415
10416 /* If there are blank lines at the end, except for a partially
10417 visible blank line at the end that is smaller than
10418 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10419 if (!row->displays_text_p
10420 && row->height >= FRAME_LINE_HEIGHT (f))
10421 change_height_p = 1;
10422
10423 /* If row displays tool-bar items, but is partially visible,
10424 change the tool-bar's height. */
10425 if (row->displays_text_p
10426 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10427 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10428 change_height_p = 1;
10429
10430 /* Resize windows as needed by changing the `tool-bar-lines'
10431 frame parameter. */
10432 if (change_height_p)
10433 {
10434 extern Lisp_Object Qtool_bar_lines;
10435 Lisp_Object frame;
10436 int old_height = WINDOW_TOTAL_LINES (w);
10437 int nrows;
10438 int nlines = tool_bar_lines_needed (f, &nrows);
10439
10440 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10441 && !f->minimize_tool_bar_window_p)
10442 ? (nlines > old_height)
10443 : (nlines != old_height));
10444 f->minimize_tool_bar_window_p = 0;
10445
10446 if (change_height_p)
10447 {
10448 XSETFRAME (frame, f);
10449 Fmodify_frame_parameters (frame,
10450 Fcons (Fcons (Qtool_bar_lines,
10451 make_number (nlines)),
10452 Qnil));
10453 if (WINDOW_TOTAL_LINES (w) != old_height)
10454 {
10455 clear_glyph_matrix (w->desired_matrix);
10456 f->n_tool_bar_rows = nrows;
10457 fonts_changed_p = 1;
10458 return 1;
10459 }
10460 }
10461 }
10462 }
10463
10464 f->minimize_tool_bar_window_p = 0;
10465 return 0;
10466 }
10467
10468
10469 /* Get information about the tool-bar item which is displayed in GLYPH
10470 on frame F. Return in *PROP_IDX the index where tool-bar item
10471 properties start in F->tool_bar_items. Value is zero if
10472 GLYPH doesn't display a tool-bar item. */
10473
10474 static int
10475 tool_bar_item_info (f, glyph, prop_idx)
10476 struct frame *f;
10477 struct glyph *glyph;
10478 int *prop_idx;
10479 {
10480 Lisp_Object prop;
10481 int success_p;
10482 int charpos;
10483
10484 /* This function can be called asynchronously, which means we must
10485 exclude any possibility that Fget_text_property signals an
10486 error. */
10487 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10488 charpos = max (0, charpos);
10489
10490 /* Get the text property `menu-item' at pos. The value of that
10491 property is the start index of this item's properties in
10492 F->tool_bar_items. */
10493 prop = Fget_text_property (make_number (charpos),
10494 Qmenu_item, f->current_tool_bar_string);
10495 if (INTEGERP (prop))
10496 {
10497 *prop_idx = XINT (prop);
10498 success_p = 1;
10499 }
10500 else
10501 success_p = 0;
10502
10503 return success_p;
10504 }
10505
10506 \f
10507 /* Get information about the tool-bar item at position X/Y on frame F.
10508 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10509 the current matrix of the tool-bar window of F, or NULL if not
10510 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10511 item in F->tool_bar_items. Value is
10512
10513 -1 if X/Y is not on a tool-bar item
10514 0 if X/Y is on the same item that was highlighted before.
10515 1 otherwise. */
10516
10517 static int
10518 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10519 struct frame *f;
10520 int x, y;
10521 struct glyph **glyph;
10522 int *hpos, *vpos, *prop_idx;
10523 {
10524 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10525 struct window *w = XWINDOW (f->tool_bar_window);
10526 int area;
10527
10528 /* Find the glyph under X/Y. */
10529 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10530 if (*glyph == NULL)
10531 return -1;
10532
10533 /* Get the start of this tool-bar item's properties in
10534 f->tool_bar_items. */
10535 if (!tool_bar_item_info (f, *glyph, prop_idx))
10536 return -1;
10537
10538 /* Is mouse on the highlighted item? */
10539 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10540 && *vpos >= dpyinfo->mouse_face_beg_row
10541 && *vpos <= dpyinfo->mouse_face_end_row
10542 && (*vpos > dpyinfo->mouse_face_beg_row
10543 || *hpos >= dpyinfo->mouse_face_beg_col)
10544 && (*vpos < dpyinfo->mouse_face_end_row
10545 || *hpos < dpyinfo->mouse_face_end_col
10546 || dpyinfo->mouse_face_past_end))
10547 return 0;
10548
10549 return 1;
10550 }
10551
10552
10553 /* EXPORT:
10554 Handle mouse button event on the tool-bar of frame F, at
10555 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10556 0 for button release. MODIFIERS is event modifiers for button
10557 release. */
10558
10559 void
10560 handle_tool_bar_click (f, x, y, down_p, modifiers)
10561 struct frame *f;
10562 int x, y, down_p;
10563 unsigned int modifiers;
10564 {
10565 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10566 struct window *w = XWINDOW (f->tool_bar_window);
10567 int hpos, vpos, prop_idx;
10568 struct glyph *glyph;
10569 Lisp_Object enabled_p;
10570
10571 /* If not on the highlighted tool-bar item, return. */
10572 frame_to_window_pixel_xy (w, &x, &y);
10573 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10574 return;
10575
10576 /* If item is disabled, do nothing. */
10577 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10578 if (NILP (enabled_p))
10579 return;
10580
10581 if (down_p)
10582 {
10583 /* Show item in pressed state. */
10584 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10585 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10586 last_tool_bar_item = prop_idx;
10587 }
10588 else
10589 {
10590 Lisp_Object key, frame;
10591 struct input_event event;
10592 EVENT_INIT (event);
10593
10594 /* Show item in released state. */
10595 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10596 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10597
10598 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10599
10600 XSETFRAME (frame, f);
10601 event.kind = TOOL_BAR_EVENT;
10602 event.frame_or_window = frame;
10603 event.arg = frame;
10604 kbd_buffer_store_event (&event);
10605
10606 event.kind = TOOL_BAR_EVENT;
10607 event.frame_or_window = frame;
10608 event.arg = key;
10609 event.modifiers = modifiers;
10610 kbd_buffer_store_event (&event);
10611 last_tool_bar_item = -1;
10612 }
10613 }
10614
10615
10616 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10617 tool-bar window-relative coordinates X/Y. Called from
10618 note_mouse_highlight. */
10619
10620 static void
10621 note_tool_bar_highlight (f, x, y)
10622 struct frame *f;
10623 int x, y;
10624 {
10625 Lisp_Object window = f->tool_bar_window;
10626 struct window *w = XWINDOW (window);
10627 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10628 int hpos, vpos;
10629 struct glyph *glyph;
10630 struct glyph_row *row;
10631 int i;
10632 Lisp_Object enabled_p;
10633 int prop_idx;
10634 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10635 int mouse_down_p, rc;
10636
10637 /* Function note_mouse_highlight is called with negative x(y
10638 values when mouse moves outside of the frame. */
10639 if (x <= 0 || y <= 0)
10640 {
10641 clear_mouse_face (dpyinfo);
10642 return;
10643 }
10644
10645 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10646 if (rc < 0)
10647 {
10648 /* Not on tool-bar item. */
10649 clear_mouse_face (dpyinfo);
10650 return;
10651 }
10652 else if (rc == 0)
10653 /* On same tool-bar item as before. */
10654 goto set_help_echo;
10655
10656 clear_mouse_face (dpyinfo);
10657
10658 /* Mouse is down, but on different tool-bar item? */
10659 mouse_down_p = (dpyinfo->grabbed
10660 && f == last_mouse_frame
10661 && FRAME_LIVE_P (f));
10662 if (mouse_down_p
10663 && last_tool_bar_item != prop_idx)
10664 return;
10665
10666 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10667 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10668
10669 /* If tool-bar item is not enabled, don't highlight it. */
10670 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10671 if (!NILP (enabled_p))
10672 {
10673 /* Compute the x-position of the glyph. In front and past the
10674 image is a space. We include this in the highlighted area. */
10675 row = MATRIX_ROW (w->current_matrix, vpos);
10676 for (i = x = 0; i < hpos; ++i)
10677 x += row->glyphs[TEXT_AREA][i].pixel_width;
10678
10679 /* Record this as the current active region. */
10680 dpyinfo->mouse_face_beg_col = hpos;
10681 dpyinfo->mouse_face_beg_row = vpos;
10682 dpyinfo->mouse_face_beg_x = x;
10683 dpyinfo->mouse_face_beg_y = row->y;
10684 dpyinfo->mouse_face_past_end = 0;
10685
10686 dpyinfo->mouse_face_end_col = hpos + 1;
10687 dpyinfo->mouse_face_end_row = vpos;
10688 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10689 dpyinfo->mouse_face_end_y = row->y;
10690 dpyinfo->mouse_face_window = window;
10691 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10692
10693 /* Display it as active. */
10694 show_mouse_face (dpyinfo, draw);
10695 dpyinfo->mouse_face_image_state = draw;
10696 }
10697
10698 set_help_echo:
10699
10700 /* Set help_echo_string to a help string to display for this tool-bar item.
10701 XTread_socket does the rest. */
10702 help_echo_object = help_echo_window = Qnil;
10703 help_echo_pos = -1;
10704 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10705 if (NILP (help_echo_string))
10706 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10707 }
10708
10709 #endif /* HAVE_WINDOW_SYSTEM */
10710
10711
10712 \f
10713 /************************************************************************
10714 Horizontal scrolling
10715 ************************************************************************/
10716
10717 static int hscroll_window_tree P_ ((Lisp_Object));
10718 static int hscroll_windows P_ ((Lisp_Object));
10719
10720 /* For all leaf windows in the window tree rooted at WINDOW, set their
10721 hscroll value so that PT is (i) visible in the window, and (ii) so
10722 that it is not within a certain margin at the window's left and
10723 right border. Value is non-zero if any window's hscroll has been
10724 changed. */
10725
10726 static int
10727 hscroll_window_tree (window)
10728 Lisp_Object window;
10729 {
10730 int hscrolled_p = 0;
10731 int hscroll_relative_p = FLOATP (Vhscroll_step);
10732 int hscroll_step_abs = 0;
10733 double hscroll_step_rel = 0;
10734
10735 if (hscroll_relative_p)
10736 {
10737 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10738 if (hscroll_step_rel < 0)
10739 {
10740 hscroll_relative_p = 0;
10741 hscroll_step_abs = 0;
10742 }
10743 }
10744 else if (INTEGERP (Vhscroll_step))
10745 {
10746 hscroll_step_abs = XINT (Vhscroll_step);
10747 if (hscroll_step_abs < 0)
10748 hscroll_step_abs = 0;
10749 }
10750 else
10751 hscroll_step_abs = 0;
10752
10753 while (WINDOWP (window))
10754 {
10755 struct window *w = XWINDOW (window);
10756
10757 if (WINDOWP (w->hchild))
10758 hscrolled_p |= hscroll_window_tree (w->hchild);
10759 else if (WINDOWP (w->vchild))
10760 hscrolled_p |= hscroll_window_tree (w->vchild);
10761 else if (w->cursor.vpos >= 0)
10762 {
10763 int h_margin;
10764 int text_area_width;
10765 struct glyph_row *current_cursor_row
10766 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10767 struct glyph_row *desired_cursor_row
10768 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10769 struct glyph_row *cursor_row
10770 = (desired_cursor_row->enabled_p
10771 ? desired_cursor_row
10772 : current_cursor_row);
10773
10774 text_area_width = window_box_width (w, TEXT_AREA);
10775
10776 /* Scroll when cursor is inside this scroll margin. */
10777 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10778
10779 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10780 && ((XFASTINT (w->hscroll)
10781 && w->cursor.x <= h_margin)
10782 || (cursor_row->enabled_p
10783 && cursor_row->truncated_on_right_p
10784 && (w->cursor.x >= text_area_width - h_margin))))
10785 {
10786 struct it it;
10787 int hscroll;
10788 struct buffer *saved_current_buffer;
10789 int pt;
10790 int wanted_x;
10791
10792 /* Find point in a display of infinite width. */
10793 saved_current_buffer = current_buffer;
10794 current_buffer = XBUFFER (w->buffer);
10795
10796 if (w == XWINDOW (selected_window))
10797 pt = BUF_PT (current_buffer);
10798 else
10799 {
10800 pt = marker_position (w->pointm);
10801 pt = max (BEGV, pt);
10802 pt = min (ZV, pt);
10803 }
10804
10805 /* Move iterator to pt starting at cursor_row->start in
10806 a line with infinite width. */
10807 init_to_row_start (&it, w, cursor_row);
10808 it.last_visible_x = INFINITY;
10809 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10810 current_buffer = saved_current_buffer;
10811
10812 /* Position cursor in window. */
10813 if (!hscroll_relative_p && hscroll_step_abs == 0)
10814 hscroll = max (0, (it.current_x
10815 - (ITERATOR_AT_END_OF_LINE_P (&it)
10816 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10817 : (text_area_width / 2))))
10818 / FRAME_COLUMN_WIDTH (it.f);
10819 else if (w->cursor.x >= text_area_width - h_margin)
10820 {
10821 if (hscroll_relative_p)
10822 wanted_x = text_area_width * (1 - hscroll_step_rel)
10823 - h_margin;
10824 else
10825 wanted_x = text_area_width
10826 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10827 - h_margin;
10828 hscroll
10829 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10830 }
10831 else
10832 {
10833 if (hscroll_relative_p)
10834 wanted_x = text_area_width * hscroll_step_rel
10835 + h_margin;
10836 else
10837 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10838 + h_margin;
10839 hscroll
10840 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10841 }
10842 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10843
10844 /* Don't call Fset_window_hscroll if value hasn't
10845 changed because it will prevent redisplay
10846 optimizations. */
10847 if (XFASTINT (w->hscroll) != hscroll)
10848 {
10849 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10850 w->hscroll = make_number (hscroll);
10851 hscrolled_p = 1;
10852 }
10853 }
10854 }
10855
10856 window = w->next;
10857 }
10858
10859 /* Value is non-zero if hscroll of any leaf window has been changed. */
10860 return hscrolled_p;
10861 }
10862
10863
10864 /* Set hscroll so that cursor is visible and not inside horizontal
10865 scroll margins for all windows in the tree rooted at WINDOW. See
10866 also hscroll_window_tree above. Value is non-zero if any window's
10867 hscroll has been changed. If it has, desired matrices on the frame
10868 of WINDOW are cleared. */
10869
10870 static int
10871 hscroll_windows (window)
10872 Lisp_Object window;
10873 {
10874 int hscrolled_p = hscroll_window_tree (window);
10875 if (hscrolled_p)
10876 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10877 return hscrolled_p;
10878 }
10879
10880
10881 \f
10882 /************************************************************************
10883 Redisplay
10884 ************************************************************************/
10885
10886 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10887 to a non-zero value. This is sometimes handy to have in a debugger
10888 session. */
10889
10890 #if GLYPH_DEBUG
10891
10892 /* First and last unchanged row for try_window_id. */
10893
10894 int debug_first_unchanged_at_end_vpos;
10895 int debug_last_unchanged_at_beg_vpos;
10896
10897 /* Delta vpos and y. */
10898
10899 int debug_dvpos, debug_dy;
10900
10901 /* Delta in characters and bytes for try_window_id. */
10902
10903 int debug_delta, debug_delta_bytes;
10904
10905 /* Values of window_end_pos and window_end_vpos at the end of
10906 try_window_id. */
10907
10908 EMACS_INT debug_end_pos, debug_end_vpos;
10909
10910 /* Append a string to W->desired_matrix->method. FMT is a printf
10911 format string. A1...A9 are a supplement for a variable-length
10912 argument list. If trace_redisplay_p is non-zero also printf the
10913 resulting string to stderr. */
10914
10915 static void
10916 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10917 struct window *w;
10918 char *fmt;
10919 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10920 {
10921 char buffer[512];
10922 char *method = w->desired_matrix->method;
10923 int len = strlen (method);
10924 int size = sizeof w->desired_matrix->method;
10925 int remaining = size - len - 1;
10926
10927 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10928 if (len && remaining)
10929 {
10930 method[len] = '|';
10931 --remaining, ++len;
10932 }
10933
10934 strncpy (method + len, buffer, remaining);
10935
10936 if (trace_redisplay_p)
10937 fprintf (stderr, "%p (%s): %s\n",
10938 w,
10939 ((BUFFERP (w->buffer)
10940 && STRINGP (XBUFFER (w->buffer)->name))
10941 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10942 : "no buffer"),
10943 buffer);
10944 }
10945
10946 #endif /* GLYPH_DEBUG */
10947
10948
10949 /* Value is non-zero if all changes in window W, which displays
10950 current_buffer, are in the text between START and END. START is a
10951 buffer position, END is given as a distance from Z. Used in
10952 redisplay_internal for display optimization. */
10953
10954 static INLINE int
10955 text_outside_line_unchanged_p (w, start, end)
10956 struct window *w;
10957 int start, end;
10958 {
10959 int unchanged_p = 1;
10960
10961 /* If text or overlays have changed, see where. */
10962 if (XFASTINT (w->last_modified) < MODIFF
10963 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10964 {
10965 /* Gap in the line? */
10966 if (GPT < start || Z - GPT < end)
10967 unchanged_p = 0;
10968
10969 /* Changes start in front of the line, or end after it? */
10970 if (unchanged_p
10971 && (BEG_UNCHANGED < start - 1
10972 || END_UNCHANGED < end))
10973 unchanged_p = 0;
10974
10975 /* If selective display, can't optimize if changes start at the
10976 beginning of the line. */
10977 if (unchanged_p
10978 && INTEGERP (current_buffer->selective_display)
10979 && XINT (current_buffer->selective_display) > 0
10980 && (BEG_UNCHANGED < start || GPT <= start))
10981 unchanged_p = 0;
10982
10983 /* If there are overlays at the start or end of the line, these
10984 may have overlay strings with newlines in them. A change at
10985 START, for instance, may actually concern the display of such
10986 overlay strings as well, and they are displayed on different
10987 lines. So, quickly rule out this case. (For the future, it
10988 might be desirable to implement something more telling than
10989 just BEG/END_UNCHANGED.) */
10990 if (unchanged_p)
10991 {
10992 if (BEG + BEG_UNCHANGED == start
10993 && overlay_touches_p (start))
10994 unchanged_p = 0;
10995 if (END_UNCHANGED == end
10996 && overlay_touches_p (Z - end))
10997 unchanged_p = 0;
10998 }
10999 }
11000
11001 return unchanged_p;
11002 }
11003
11004
11005 /* Do a frame update, taking possible shortcuts into account. This is
11006 the main external entry point for redisplay.
11007
11008 If the last redisplay displayed an echo area message and that message
11009 is no longer requested, we clear the echo area or bring back the
11010 mini-buffer if that is in use. */
11011
11012 void
11013 redisplay ()
11014 {
11015 redisplay_internal (0);
11016 }
11017
11018
11019 static Lisp_Object
11020 overlay_arrow_string_or_property (var)
11021 Lisp_Object var;
11022 {
11023 Lisp_Object val;
11024
11025 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11026 return val;
11027
11028 return Voverlay_arrow_string;
11029 }
11030
11031 /* Return 1 if there are any overlay-arrows in current_buffer. */
11032 static int
11033 overlay_arrow_in_current_buffer_p ()
11034 {
11035 Lisp_Object vlist;
11036
11037 for (vlist = Voverlay_arrow_variable_list;
11038 CONSP (vlist);
11039 vlist = XCDR (vlist))
11040 {
11041 Lisp_Object var = XCAR (vlist);
11042 Lisp_Object val;
11043
11044 if (!SYMBOLP (var))
11045 continue;
11046 val = find_symbol_value (var);
11047 if (MARKERP (val)
11048 && current_buffer == XMARKER (val)->buffer)
11049 return 1;
11050 }
11051 return 0;
11052 }
11053
11054
11055 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11056 has changed. */
11057
11058 static int
11059 overlay_arrows_changed_p ()
11060 {
11061 Lisp_Object vlist;
11062
11063 for (vlist = Voverlay_arrow_variable_list;
11064 CONSP (vlist);
11065 vlist = XCDR (vlist))
11066 {
11067 Lisp_Object var = XCAR (vlist);
11068 Lisp_Object val, pstr;
11069
11070 if (!SYMBOLP (var))
11071 continue;
11072 val = find_symbol_value (var);
11073 if (!MARKERP (val))
11074 continue;
11075 if (! EQ (COERCE_MARKER (val),
11076 Fget (var, Qlast_arrow_position))
11077 || ! (pstr = overlay_arrow_string_or_property (var),
11078 EQ (pstr, Fget (var, Qlast_arrow_string))))
11079 return 1;
11080 }
11081 return 0;
11082 }
11083
11084 /* Mark overlay arrows to be updated on next redisplay. */
11085
11086 static void
11087 update_overlay_arrows (up_to_date)
11088 int up_to_date;
11089 {
11090 Lisp_Object vlist;
11091
11092 for (vlist = Voverlay_arrow_variable_list;
11093 CONSP (vlist);
11094 vlist = XCDR (vlist))
11095 {
11096 Lisp_Object var = XCAR (vlist);
11097
11098 if (!SYMBOLP (var))
11099 continue;
11100
11101 if (up_to_date > 0)
11102 {
11103 Lisp_Object val = find_symbol_value (var);
11104 Fput (var, Qlast_arrow_position,
11105 COERCE_MARKER (val));
11106 Fput (var, Qlast_arrow_string,
11107 overlay_arrow_string_or_property (var));
11108 }
11109 else if (up_to_date < 0
11110 || !NILP (Fget (var, Qlast_arrow_position)))
11111 {
11112 Fput (var, Qlast_arrow_position, Qt);
11113 Fput (var, Qlast_arrow_string, Qt);
11114 }
11115 }
11116 }
11117
11118
11119 /* Return overlay arrow string to display at row.
11120 Return integer (bitmap number) for arrow bitmap in left fringe.
11121 Return nil if no overlay arrow. */
11122
11123 static Lisp_Object
11124 overlay_arrow_at_row (it, row)
11125 struct it *it;
11126 struct glyph_row *row;
11127 {
11128 Lisp_Object vlist;
11129
11130 for (vlist = Voverlay_arrow_variable_list;
11131 CONSP (vlist);
11132 vlist = XCDR (vlist))
11133 {
11134 Lisp_Object var = XCAR (vlist);
11135 Lisp_Object val;
11136
11137 if (!SYMBOLP (var))
11138 continue;
11139
11140 val = find_symbol_value (var);
11141
11142 if (MARKERP (val)
11143 && current_buffer == XMARKER (val)->buffer
11144 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11145 {
11146 if (FRAME_WINDOW_P (it->f)
11147 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11148 {
11149 #ifdef HAVE_WINDOW_SYSTEM
11150 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11151 {
11152 int fringe_bitmap;
11153 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11154 return make_number (fringe_bitmap);
11155 }
11156 #endif
11157 return make_number (-1); /* Use default arrow bitmap */
11158 }
11159 return overlay_arrow_string_or_property (var);
11160 }
11161 }
11162
11163 return Qnil;
11164 }
11165
11166 /* Return 1 if point moved out of or into a composition. Otherwise
11167 return 0. PREV_BUF and PREV_PT are the last point buffer and
11168 position. BUF and PT are the current point buffer and position. */
11169
11170 int
11171 check_point_in_composition (prev_buf, prev_pt, buf, pt)
11172 struct buffer *prev_buf, *buf;
11173 int prev_pt, pt;
11174 {
11175 EMACS_INT start, end;
11176 Lisp_Object prop;
11177 Lisp_Object buffer;
11178
11179 XSETBUFFER (buffer, buf);
11180 /* Check a composition at the last point if point moved within the
11181 same buffer. */
11182 if (prev_buf == buf)
11183 {
11184 if (prev_pt == pt)
11185 /* Point didn't move. */
11186 return 0;
11187
11188 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11189 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11190 && COMPOSITION_VALID_P (start, end, prop)
11191 && start < prev_pt && end > prev_pt)
11192 /* The last point was within the composition. Return 1 iff
11193 point moved out of the composition. */
11194 return (pt <= start || pt >= end);
11195 }
11196
11197 /* Check a composition at the current point. */
11198 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11199 && find_composition (pt, -1, &start, &end, &prop, buffer)
11200 && COMPOSITION_VALID_P (start, end, prop)
11201 && start < pt && end > pt);
11202 }
11203
11204
11205 /* Reconsider the setting of B->clip_changed which is displayed
11206 in window W. */
11207
11208 static INLINE void
11209 reconsider_clip_changes (w, b)
11210 struct window *w;
11211 struct buffer *b;
11212 {
11213 if (b->clip_changed
11214 && !NILP (w->window_end_valid)
11215 && w->current_matrix->buffer == b
11216 && w->current_matrix->zv == BUF_ZV (b)
11217 && w->current_matrix->begv == BUF_BEGV (b))
11218 b->clip_changed = 0;
11219
11220 /* If display wasn't paused, and W is not a tool bar window, see if
11221 point has been moved into or out of a composition. In that case,
11222 we set b->clip_changed to 1 to force updating the screen. If
11223 b->clip_changed has already been set to 1, we can skip this
11224 check. */
11225 if (!b->clip_changed
11226 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11227 {
11228 int pt;
11229
11230 if (w == XWINDOW (selected_window))
11231 pt = BUF_PT (current_buffer);
11232 else
11233 pt = marker_position (w->pointm);
11234
11235 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11236 || pt != XINT (w->last_point))
11237 && check_point_in_composition (w->current_matrix->buffer,
11238 XINT (w->last_point),
11239 XBUFFER (w->buffer), pt))
11240 b->clip_changed = 1;
11241 }
11242 }
11243 \f
11244
11245 /* Select FRAME to forward the values of frame-local variables into C
11246 variables so that the redisplay routines can access those values
11247 directly. */
11248
11249 static void
11250 select_frame_for_redisplay (frame)
11251 Lisp_Object frame;
11252 {
11253 Lisp_Object tail, symbol, val;
11254 Lisp_Object old = selected_frame;
11255 struct Lisp_Symbol *sym;
11256
11257 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11258
11259 selected_frame = frame;
11260
11261 do
11262 {
11263 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11264 if (CONSP (XCAR (tail))
11265 && (symbol = XCAR (XCAR (tail)),
11266 SYMBOLP (symbol))
11267 && (sym = indirect_variable (XSYMBOL (symbol)),
11268 val = sym->value,
11269 (BUFFER_LOCAL_VALUEP (val)))
11270 && XBUFFER_LOCAL_VALUE (val)->check_frame)
11271 /* Use find_symbol_value rather than Fsymbol_value
11272 to avoid an error if it is void. */
11273 find_symbol_value (symbol);
11274 } while (!EQ (frame, old) && (frame = old, 1));
11275 }
11276
11277
11278 #define STOP_POLLING \
11279 do { if (! polling_stopped_here) stop_polling (); \
11280 polling_stopped_here = 1; } while (0)
11281
11282 #define RESUME_POLLING \
11283 do { if (polling_stopped_here) start_polling (); \
11284 polling_stopped_here = 0; } while (0)
11285
11286
11287 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11288 response to any user action; therefore, we should preserve the echo
11289 area. (Actually, our caller does that job.) Perhaps in the future
11290 avoid recentering windows if it is not necessary; currently that
11291 causes some problems. */
11292
11293 static void
11294 redisplay_internal (preserve_echo_area)
11295 int preserve_echo_area;
11296 {
11297 struct window *w = XWINDOW (selected_window);
11298 struct frame *f;
11299 int pause;
11300 int must_finish = 0;
11301 struct text_pos tlbufpos, tlendpos;
11302 int number_of_visible_frames;
11303 int count, count1;
11304 struct frame *sf;
11305 int polling_stopped_here = 0;
11306 Lisp_Object old_frame = selected_frame;
11307
11308 /* Non-zero means redisplay has to consider all windows on all
11309 frames. Zero means, only selected_window is considered. */
11310 int consider_all_windows_p;
11311
11312 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11313
11314 /* No redisplay if running in batch mode or frame is not yet fully
11315 initialized, or redisplay is explicitly turned off by setting
11316 Vinhibit_redisplay. */
11317 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11318 || !NILP (Vinhibit_redisplay))
11319 return;
11320
11321 /* Don't examine these until after testing Vinhibit_redisplay.
11322 When Emacs is shutting down, perhaps because its connection to
11323 X has dropped, we should not look at them at all. */
11324 f = XFRAME (w->frame);
11325 sf = SELECTED_FRAME ();
11326
11327 if (!f->glyphs_initialized_p)
11328 return;
11329
11330 /* The flag redisplay_performed_directly_p is set by
11331 direct_output_for_insert when it already did the whole screen
11332 update necessary. */
11333 if (redisplay_performed_directly_p)
11334 {
11335 redisplay_performed_directly_p = 0;
11336 if (!hscroll_windows (selected_window))
11337 return;
11338 }
11339
11340 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11341 if (popup_activated ())
11342 return;
11343 #endif
11344
11345 /* I don't think this happens but let's be paranoid. */
11346 if (redisplaying_p)
11347 return;
11348
11349 /* Record a function that resets redisplaying_p to its old value
11350 when we leave this function. */
11351 count = SPECPDL_INDEX ();
11352 record_unwind_protect (unwind_redisplay,
11353 Fcons (make_number (redisplaying_p), selected_frame));
11354 ++redisplaying_p;
11355 specbind (Qinhibit_free_realized_faces, Qnil);
11356
11357 {
11358 Lisp_Object tail, frame;
11359
11360 FOR_EACH_FRAME (tail, frame)
11361 {
11362 struct frame *f = XFRAME (frame);
11363 f->already_hscrolled_p = 0;
11364 }
11365 }
11366
11367 retry:
11368 if (!EQ (old_frame, selected_frame)
11369 && FRAME_LIVE_P (XFRAME (old_frame)))
11370 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11371 selected_frame and selected_window to be temporarily out-of-sync so
11372 when we come back here via `goto retry', we need to resync because we
11373 may need to run Elisp code (via prepare_menu_bars). */
11374 select_frame_for_redisplay (old_frame);
11375
11376 pause = 0;
11377 reconsider_clip_changes (w, current_buffer);
11378 last_escape_glyph_frame = NULL;
11379 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11380
11381 /* If new fonts have been loaded that make a glyph matrix adjustment
11382 necessary, do it. */
11383 if (fonts_changed_p)
11384 {
11385 adjust_glyphs (NULL);
11386 ++windows_or_buffers_changed;
11387 fonts_changed_p = 0;
11388 }
11389
11390 /* If face_change_count is non-zero, init_iterator will free all
11391 realized faces, which includes the faces referenced from current
11392 matrices. So, we can't reuse current matrices in this case. */
11393 if (face_change_count)
11394 ++windows_or_buffers_changed;
11395
11396 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11397 && FRAME_TTY (sf)->previous_frame != sf)
11398 {
11399 /* Since frames on a single ASCII terminal share the same
11400 display area, displaying a different frame means redisplay
11401 the whole thing. */
11402 windows_or_buffers_changed++;
11403 SET_FRAME_GARBAGED (sf);
11404 #ifndef DOS_NT
11405 set_tty_color_mode (FRAME_TTY (sf), sf);
11406 #endif
11407 FRAME_TTY (sf)->previous_frame = sf;
11408 }
11409
11410 /* Set the visible flags for all frames. Do this before checking
11411 for resized or garbaged frames; they want to know if their frames
11412 are visible. See the comment in frame.h for
11413 FRAME_SAMPLE_VISIBILITY. */
11414 {
11415 Lisp_Object tail, frame;
11416
11417 number_of_visible_frames = 0;
11418
11419 FOR_EACH_FRAME (tail, frame)
11420 {
11421 struct frame *f = XFRAME (frame);
11422
11423 FRAME_SAMPLE_VISIBILITY (f);
11424 if (FRAME_VISIBLE_P (f))
11425 ++number_of_visible_frames;
11426 clear_desired_matrices (f);
11427 }
11428 }
11429
11430 /* Notice any pending interrupt request to change frame size. */
11431 do_pending_window_change (1);
11432
11433 /* Clear frames marked as garbaged. */
11434 if (frame_garbaged)
11435 clear_garbaged_frames ();
11436
11437 /* Build menubar and tool-bar items. */
11438 if (NILP (Vmemory_full))
11439 prepare_menu_bars ();
11440
11441 if (windows_or_buffers_changed)
11442 update_mode_lines++;
11443
11444 /* Detect case that we need to write or remove a star in the mode line. */
11445 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11446 {
11447 w->update_mode_line = Qt;
11448 if (buffer_shared > 1)
11449 update_mode_lines++;
11450 }
11451
11452 /* Avoid invocation of point motion hooks by `current_column' below. */
11453 count1 = SPECPDL_INDEX ();
11454 specbind (Qinhibit_point_motion_hooks, Qt);
11455
11456 /* If %c is in the mode line, update it if needed. */
11457 if (!NILP (w->column_number_displayed)
11458 /* This alternative quickly identifies a common case
11459 where no change is needed. */
11460 && !(PT == XFASTINT (w->last_point)
11461 && XFASTINT (w->last_modified) >= MODIFF
11462 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11463 && (XFASTINT (w->column_number_displayed)
11464 != (int) current_column ())) /* iftc */
11465 w->update_mode_line = Qt;
11466
11467 unbind_to (count1, Qnil);
11468
11469 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11470
11471 /* The variable buffer_shared is set in redisplay_window and
11472 indicates that we redisplay a buffer in different windows. See
11473 there. */
11474 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11475 || cursor_type_changed);
11476
11477 /* If specs for an arrow have changed, do thorough redisplay
11478 to ensure we remove any arrow that should no longer exist. */
11479 if (overlay_arrows_changed_p ())
11480 consider_all_windows_p = windows_or_buffers_changed = 1;
11481
11482 /* Normally the message* functions will have already displayed and
11483 updated the echo area, but the frame may have been trashed, or
11484 the update may have been preempted, so display the echo area
11485 again here. Checking message_cleared_p captures the case that
11486 the echo area should be cleared. */
11487 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11488 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11489 || (message_cleared_p
11490 && minibuf_level == 0
11491 /* If the mini-window is currently selected, this means the
11492 echo-area doesn't show through. */
11493 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11494 {
11495 int window_height_changed_p = echo_area_display (0);
11496 must_finish = 1;
11497
11498 /* If we don't display the current message, don't clear the
11499 message_cleared_p flag, because, if we did, we wouldn't clear
11500 the echo area in the next redisplay which doesn't preserve
11501 the echo area. */
11502 if (!display_last_displayed_message_p)
11503 message_cleared_p = 0;
11504
11505 if (fonts_changed_p)
11506 goto retry;
11507 else if (window_height_changed_p)
11508 {
11509 consider_all_windows_p = 1;
11510 ++update_mode_lines;
11511 ++windows_or_buffers_changed;
11512
11513 /* If window configuration was changed, frames may have been
11514 marked garbaged. Clear them or we will experience
11515 surprises wrt scrolling. */
11516 if (frame_garbaged)
11517 clear_garbaged_frames ();
11518 }
11519 }
11520 else if (EQ (selected_window, minibuf_window)
11521 && (current_buffer->clip_changed
11522 || XFASTINT (w->last_modified) < MODIFF
11523 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11524 && resize_mini_window (w, 0))
11525 {
11526 /* Resized active mini-window to fit the size of what it is
11527 showing if its contents might have changed. */
11528 must_finish = 1;
11529 /* FIXME: this causes all frames to be updated, which seems unnecessary
11530 since only the current frame needs to be considered. This function needs
11531 to be rewritten with two variables, consider_all_windows and
11532 consider_all_frames. */
11533 consider_all_windows_p = 1;
11534 ++windows_or_buffers_changed;
11535 ++update_mode_lines;
11536
11537 /* If window configuration was changed, frames may have been
11538 marked garbaged. Clear them or we will experience
11539 surprises wrt scrolling. */
11540 if (frame_garbaged)
11541 clear_garbaged_frames ();
11542 }
11543
11544
11545 /* If showing the region, and mark has changed, we must redisplay
11546 the whole window. The assignment to this_line_start_pos prevents
11547 the optimization directly below this if-statement. */
11548 if (((!NILP (Vtransient_mark_mode)
11549 && !NILP (XBUFFER (w->buffer)->mark_active))
11550 != !NILP (w->region_showing))
11551 || (!NILP (w->region_showing)
11552 && !EQ (w->region_showing,
11553 Fmarker_position (XBUFFER (w->buffer)->mark))))
11554 CHARPOS (this_line_start_pos) = 0;
11555
11556 /* Optimize the case that only the line containing the cursor in the
11557 selected window has changed. Variables starting with this_ are
11558 set in display_line and record information about the line
11559 containing the cursor. */
11560 tlbufpos = this_line_start_pos;
11561 tlendpos = this_line_end_pos;
11562 if (!consider_all_windows_p
11563 && CHARPOS (tlbufpos) > 0
11564 && NILP (w->update_mode_line)
11565 && !current_buffer->clip_changed
11566 && !current_buffer->prevent_redisplay_optimizations_p
11567 && FRAME_VISIBLE_P (XFRAME (w->frame))
11568 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11569 /* Make sure recorded data applies to current buffer, etc. */
11570 && this_line_buffer == current_buffer
11571 && current_buffer == XBUFFER (w->buffer)
11572 && NILP (w->force_start)
11573 && NILP (w->optional_new_start)
11574 /* Point must be on the line that we have info recorded about. */
11575 && PT >= CHARPOS (tlbufpos)
11576 && PT <= Z - CHARPOS (tlendpos)
11577 /* All text outside that line, including its final newline,
11578 must be unchanged */
11579 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11580 CHARPOS (tlendpos)))
11581 {
11582 if (CHARPOS (tlbufpos) > BEGV
11583 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11584 && (CHARPOS (tlbufpos) == ZV
11585 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11586 /* Former continuation line has disappeared by becoming empty */
11587 goto cancel;
11588 else if (XFASTINT (w->last_modified) < MODIFF
11589 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11590 || MINI_WINDOW_P (w))
11591 {
11592 /* We have to handle the case of continuation around a
11593 wide-column character (See the comment in indent.c around
11594 line 885).
11595
11596 For instance, in the following case:
11597
11598 -------- Insert --------
11599 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11600 J_I_ ==> J_I_ `^^' are cursors.
11601 ^^ ^^
11602 -------- --------
11603
11604 As we have to redraw the line above, we should goto cancel. */
11605
11606 struct it it;
11607 int line_height_before = this_line_pixel_height;
11608
11609 /* Note that start_display will handle the case that the
11610 line starting at tlbufpos is a continuation lines. */
11611 start_display (&it, w, tlbufpos);
11612
11613 /* Implementation note: It this still necessary? */
11614 if (it.current_x != this_line_start_x)
11615 goto cancel;
11616
11617 TRACE ((stderr, "trying display optimization 1\n"));
11618 w->cursor.vpos = -1;
11619 overlay_arrow_seen = 0;
11620 it.vpos = this_line_vpos;
11621 it.current_y = this_line_y;
11622 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11623 display_line (&it);
11624
11625 /* If line contains point, is not continued,
11626 and ends at same distance from eob as before, we win */
11627 if (w->cursor.vpos >= 0
11628 /* Line is not continued, otherwise this_line_start_pos
11629 would have been set to 0 in display_line. */
11630 && CHARPOS (this_line_start_pos)
11631 /* Line ends as before. */
11632 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11633 /* Line has same height as before. Otherwise other lines
11634 would have to be shifted up or down. */
11635 && this_line_pixel_height == line_height_before)
11636 {
11637 /* If this is not the window's last line, we must adjust
11638 the charstarts of the lines below. */
11639 if (it.current_y < it.last_visible_y)
11640 {
11641 struct glyph_row *row
11642 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11643 int delta, delta_bytes;
11644
11645 if (Z - CHARPOS (tlendpos) == ZV)
11646 {
11647 /* This line ends at end of (accessible part of)
11648 buffer. There is no newline to count. */
11649 delta = (Z
11650 - CHARPOS (tlendpos)
11651 - MATRIX_ROW_START_CHARPOS (row));
11652 delta_bytes = (Z_BYTE
11653 - BYTEPOS (tlendpos)
11654 - MATRIX_ROW_START_BYTEPOS (row));
11655 }
11656 else
11657 {
11658 /* This line ends in a newline. Must take
11659 account of the newline and the rest of the
11660 text that follows. */
11661 delta = (Z
11662 - CHARPOS (tlendpos)
11663 - MATRIX_ROW_START_CHARPOS (row));
11664 delta_bytes = (Z_BYTE
11665 - BYTEPOS (tlendpos)
11666 - MATRIX_ROW_START_BYTEPOS (row));
11667 }
11668
11669 increment_matrix_positions (w->current_matrix,
11670 this_line_vpos + 1,
11671 w->current_matrix->nrows,
11672 delta, delta_bytes);
11673 }
11674
11675 /* If this row displays text now but previously didn't,
11676 or vice versa, w->window_end_vpos may have to be
11677 adjusted. */
11678 if ((it.glyph_row - 1)->displays_text_p)
11679 {
11680 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11681 XSETINT (w->window_end_vpos, this_line_vpos);
11682 }
11683 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11684 && this_line_vpos > 0)
11685 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11686 w->window_end_valid = Qnil;
11687
11688 /* Update hint: No need to try to scroll in update_window. */
11689 w->desired_matrix->no_scrolling_p = 1;
11690
11691 #if GLYPH_DEBUG
11692 *w->desired_matrix->method = 0;
11693 debug_method_add (w, "optimization 1");
11694 #endif
11695 #ifdef HAVE_WINDOW_SYSTEM
11696 update_window_fringes (w, 0);
11697 #endif
11698 goto update;
11699 }
11700 else
11701 goto cancel;
11702 }
11703 else if (/* Cursor position hasn't changed. */
11704 PT == XFASTINT (w->last_point)
11705 /* Make sure the cursor was last displayed
11706 in this window. Otherwise we have to reposition it. */
11707 && 0 <= w->cursor.vpos
11708 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11709 {
11710 if (!must_finish)
11711 {
11712 do_pending_window_change (1);
11713
11714 /* We used to always goto end_of_redisplay here, but this
11715 isn't enough if we have a blinking cursor. */
11716 if (w->cursor_off_p == w->last_cursor_off_p)
11717 goto end_of_redisplay;
11718 }
11719 goto update;
11720 }
11721 /* If highlighting the region, or if the cursor is in the echo area,
11722 then we can't just move the cursor. */
11723 else if (! (!NILP (Vtransient_mark_mode)
11724 && !NILP (current_buffer->mark_active))
11725 && (EQ (selected_window, current_buffer->last_selected_window)
11726 || highlight_nonselected_windows)
11727 && NILP (w->region_showing)
11728 && NILP (Vshow_trailing_whitespace)
11729 && !cursor_in_echo_area)
11730 {
11731 struct it it;
11732 struct glyph_row *row;
11733
11734 /* Skip from tlbufpos to PT and see where it is. Note that
11735 PT may be in invisible text. If so, we will end at the
11736 next visible position. */
11737 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11738 NULL, DEFAULT_FACE_ID);
11739 it.current_x = this_line_start_x;
11740 it.current_y = this_line_y;
11741 it.vpos = this_line_vpos;
11742
11743 /* The call to move_it_to stops in front of PT, but
11744 moves over before-strings. */
11745 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11746
11747 if (it.vpos == this_line_vpos
11748 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11749 row->enabled_p))
11750 {
11751 xassert (this_line_vpos == it.vpos);
11752 xassert (this_line_y == it.current_y);
11753 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11754 #if GLYPH_DEBUG
11755 *w->desired_matrix->method = 0;
11756 debug_method_add (w, "optimization 3");
11757 #endif
11758 goto update;
11759 }
11760 else
11761 goto cancel;
11762 }
11763
11764 cancel:
11765 /* Text changed drastically or point moved off of line. */
11766 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11767 }
11768
11769 CHARPOS (this_line_start_pos) = 0;
11770 consider_all_windows_p |= buffer_shared > 1;
11771 ++clear_face_cache_count;
11772 #ifdef HAVE_WINDOW_SYSTEM
11773 ++clear_image_cache_count;
11774 #endif
11775
11776 /* Build desired matrices, and update the display. If
11777 consider_all_windows_p is non-zero, do it for all windows on all
11778 frames. Otherwise do it for selected_window, only. */
11779
11780 if (consider_all_windows_p)
11781 {
11782 Lisp_Object tail, frame;
11783
11784 FOR_EACH_FRAME (tail, frame)
11785 XFRAME (frame)->updated_p = 0;
11786
11787 /* Recompute # windows showing selected buffer. This will be
11788 incremented each time such a window is displayed. */
11789 buffer_shared = 0;
11790
11791 FOR_EACH_FRAME (tail, frame)
11792 {
11793 struct frame *f = XFRAME (frame);
11794
11795 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11796 {
11797 if (! EQ (frame, selected_frame))
11798 /* Select the frame, for the sake of frame-local
11799 variables. */
11800 select_frame_for_redisplay (frame);
11801
11802 /* Mark all the scroll bars to be removed; we'll redeem
11803 the ones we want when we redisplay their windows. */
11804 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11805 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11806
11807 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11808 redisplay_windows (FRAME_ROOT_WINDOW (f));
11809
11810 /* The X error handler may have deleted that frame. */
11811 if (!FRAME_LIVE_P (f))
11812 continue;
11813
11814 /* Any scroll bars which redisplay_windows should have
11815 nuked should now go away. */
11816 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11817 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11818
11819 /* If fonts changed, display again. */
11820 /* ??? rms: I suspect it is a mistake to jump all the way
11821 back to retry here. It should just retry this frame. */
11822 if (fonts_changed_p)
11823 goto retry;
11824
11825 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11826 {
11827 /* See if we have to hscroll. */
11828 if (!f->already_hscrolled_p)
11829 {
11830 f->already_hscrolled_p = 1;
11831 if (hscroll_windows (f->root_window))
11832 goto retry;
11833 }
11834
11835 /* Prevent various kinds of signals during display
11836 update. stdio is not robust about handling
11837 signals, which can cause an apparent I/O
11838 error. */
11839 if (interrupt_input)
11840 unrequest_sigio ();
11841 STOP_POLLING;
11842
11843 /* Update the display. */
11844 set_window_update_flags (XWINDOW (f->root_window), 1);
11845 pause |= update_frame (f, 0, 0);
11846 f->updated_p = 1;
11847 }
11848 }
11849 }
11850
11851 if (!EQ (old_frame, selected_frame)
11852 && FRAME_LIVE_P (XFRAME (old_frame)))
11853 /* We played a bit fast-and-loose above and allowed selected_frame
11854 and selected_window to be temporarily out-of-sync but let's make
11855 sure this stays contained. */
11856 select_frame_for_redisplay (old_frame);
11857 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
11858
11859 if (!pause)
11860 {
11861 /* Do the mark_window_display_accurate after all windows have
11862 been redisplayed because this call resets flags in buffers
11863 which are needed for proper redisplay. */
11864 FOR_EACH_FRAME (tail, frame)
11865 {
11866 struct frame *f = XFRAME (frame);
11867 if (f->updated_p)
11868 {
11869 mark_window_display_accurate (f->root_window, 1);
11870 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11871 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11872 }
11873 }
11874 }
11875 }
11876 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11877 {
11878 Lisp_Object mini_window;
11879 struct frame *mini_frame;
11880
11881 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11882 /* Use list_of_error, not Qerror, so that
11883 we catch only errors and don't run the debugger. */
11884 internal_condition_case_1 (redisplay_window_1, selected_window,
11885 list_of_error,
11886 redisplay_window_error);
11887
11888 /* Compare desired and current matrices, perform output. */
11889
11890 update:
11891 /* If fonts changed, display again. */
11892 if (fonts_changed_p)
11893 goto retry;
11894
11895 /* Prevent various kinds of signals during display update.
11896 stdio is not robust about handling signals,
11897 which can cause an apparent I/O error. */
11898 if (interrupt_input)
11899 unrequest_sigio ();
11900 STOP_POLLING;
11901
11902 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11903 {
11904 if (hscroll_windows (selected_window))
11905 goto retry;
11906
11907 XWINDOW (selected_window)->must_be_updated_p = 1;
11908 pause = update_frame (sf, 0, 0);
11909 }
11910
11911 /* We may have called echo_area_display at the top of this
11912 function. If the echo area is on another frame, that may
11913 have put text on a frame other than the selected one, so the
11914 above call to update_frame would not have caught it. Catch
11915 it here. */
11916 mini_window = FRAME_MINIBUF_WINDOW (sf);
11917 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11918
11919 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11920 {
11921 XWINDOW (mini_window)->must_be_updated_p = 1;
11922 pause |= update_frame (mini_frame, 0, 0);
11923 if (!pause && hscroll_windows (mini_window))
11924 goto retry;
11925 }
11926 }
11927
11928 /* If display was paused because of pending input, make sure we do a
11929 thorough update the next time. */
11930 if (pause)
11931 {
11932 /* Prevent the optimization at the beginning of
11933 redisplay_internal that tries a single-line update of the
11934 line containing the cursor in the selected window. */
11935 CHARPOS (this_line_start_pos) = 0;
11936
11937 /* Let the overlay arrow be updated the next time. */
11938 update_overlay_arrows (0);
11939
11940 /* If we pause after scrolling, some rows in the current
11941 matrices of some windows are not valid. */
11942 if (!WINDOW_FULL_WIDTH_P (w)
11943 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11944 update_mode_lines = 1;
11945 }
11946 else
11947 {
11948 if (!consider_all_windows_p)
11949 {
11950 /* This has already been done above if
11951 consider_all_windows_p is set. */
11952 mark_window_display_accurate_1 (w, 1);
11953
11954 /* Say overlay arrows are up to date. */
11955 update_overlay_arrows (1);
11956
11957 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11958 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11959 }
11960
11961 update_mode_lines = 0;
11962 windows_or_buffers_changed = 0;
11963 cursor_type_changed = 0;
11964 }
11965
11966 /* Start SIGIO interrupts coming again. Having them off during the
11967 code above makes it less likely one will discard output, but not
11968 impossible, since there might be stuff in the system buffer here.
11969 But it is much hairier to try to do anything about that. */
11970 if (interrupt_input)
11971 request_sigio ();
11972 RESUME_POLLING;
11973
11974 /* If a frame has become visible which was not before, redisplay
11975 again, so that we display it. Expose events for such a frame
11976 (which it gets when becoming visible) don't call the parts of
11977 redisplay constructing glyphs, so simply exposing a frame won't
11978 display anything in this case. So, we have to display these
11979 frames here explicitly. */
11980 if (!pause)
11981 {
11982 Lisp_Object tail, frame;
11983 int new_count = 0;
11984
11985 FOR_EACH_FRAME (tail, frame)
11986 {
11987 int this_is_visible = 0;
11988
11989 if (XFRAME (frame)->visible)
11990 this_is_visible = 1;
11991 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11992 if (XFRAME (frame)->visible)
11993 this_is_visible = 1;
11994
11995 if (this_is_visible)
11996 new_count++;
11997 }
11998
11999 if (new_count != number_of_visible_frames)
12000 windows_or_buffers_changed++;
12001 }
12002
12003 /* Change frame size now if a change is pending. */
12004 do_pending_window_change (1);
12005
12006 /* If we just did a pending size change, or have additional
12007 visible frames, redisplay again. */
12008 if (windows_or_buffers_changed && !pause)
12009 goto retry;
12010
12011 /* Clear the face cache eventually. */
12012 if (consider_all_windows_p)
12013 {
12014 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12015 {
12016 clear_face_cache (0);
12017 clear_face_cache_count = 0;
12018 }
12019 #ifdef HAVE_WINDOW_SYSTEM
12020 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12021 {
12022 clear_image_caches (Qnil);
12023 clear_image_cache_count = 0;
12024 }
12025 #endif /* HAVE_WINDOW_SYSTEM */
12026 }
12027
12028 end_of_redisplay:
12029 unbind_to (count, Qnil);
12030 RESUME_POLLING;
12031 }
12032
12033
12034 /* Redisplay, but leave alone any recent echo area message unless
12035 another message has been requested in its place.
12036
12037 This is useful in situations where you need to redisplay but no
12038 user action has occurred, making it inappropriate for the message
12039 area to be cleared. See tracking_off and
12040 wait_reading_process_output for examples of these situations.
12041
12042 FROM_WHERE is an integer saying from where this function was
12043 called. This is useful for debugging. */
12044
12045 void
12046 redisplay_preserve_echo_area (from_where)
12047 int from_where;
12048 {
12049 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12050
12051 if (!NILP (echo_area_buffer[1]))
12052 {
12053 /* We have a previously displayed message, but no current
12054 message. Redisplay the previous message. */
12055 display_last_displayed_message_p = 1;
12056 redisplay_internal (1);
12057 display_last_displayed_message_p = 0;
12058 }
12059 else
12060 redisplay_internal (1);
12061
12062 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12063 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12064 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12065 }
12066
12067
12068 /* Function registered with record_unwind_protect in
12069 redisplay_internal. Reset redisplaying_p to the value it had
12070 before redisplay_internal was called, and clear
12071 prevent_freeing_realized_faces_p. It also selects the previously
12072 selected frame, unless it has been deleted (by an X connection
12073 failure during redisplay, for example). */
12074
12075 static Lisp_Object
12076 unwind_redisplay (val)
12077 Lisp_Object val;
12078 {
12079 Lisp_Object old_redisplaying_p, old_frame;
12080
12081 old_redisplaying_p = XCAR (val);
12082 redisplaying_p = XFASTINT (old_redisplaying_p);
12083 old_frame = XCDR (val);
12084 if (! EQ (old_frame, selected_frame)
12085 && FRAME_LIVE_P (XFRAME (old_frame)))
12086 select_frame_for_redisplay (old_frame);
12087 return Qnil;
12088 }
12089
12090
12091 /* Mark the display of window W as accurate or inaccurate. If
12092 ACCURATE_P is non-zero mark display of W as accurate. If
12093 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12094 redisplay_internal is called. */
12095
12096 static void
12097 mark_window_display_accurate_1 (w, accurate_p)
12098 struct window *w;
12099 int accurate_p;
12100 {
12101 if (BUFFERP (w->buffer))
12102 {
12103 struct buffer *b = XBUFFER (w->buffer);
12104
12105 w->last_modified
12106 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12107 w->last_overlay_modified
12108 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12109 w->last_had_star
12110 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12111
12112 if (accurate_p)
12113 {
12114 b->clip_changed = 0;
12115 b->prevent_redisplay_optimizations_p = 0;
12116
12117 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12118 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12119 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12120 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12121
12122 w->current_matrix->buffer = b;
12123 w->current_matrix->begv = BUF_BEGV (b);
12124 w->current_matrix->zv = BUF_ZV (b);
12125
12126 w->last_cursor = w->cursor;
12127 w->last_cursor_off_p = w->cursor_off_p;
12128
12129 if (w == XWINDOW (selected_window))
12130 w->last_point = make_number (BUF_PT (b));
12131 else
12132 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12133 }
12134 }
12135
12136 if (accurate_p)
12137 {
12138 w->window_end_valid = w->buffer;
12139 w->update_mode_line = Qnil;
12140 }
12141 }
12142
12143
12144 /* Mark the display of windows in the window tree rooted at WINDOW as
12145 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12146 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12147 be redisplayed the next time redisplay_internal is called. */
12148
12149 void
12150 mark_window_display_accurate (window, accurate_p)
12151 Lisp_Object window;
12152 int accurate_p;
12153 {
12154 struct window *w;
12155
12156 for (; !NILP (window); window = w->next)
12157 {
12158 w = XWINDOW (window);
12159 mark_window_display_accurate_1 (w, accurate_p);
12160
12161 if (!NILP (w->vchild))
12162 mark_window_display_accurate (w->vchild, accurate_p);
12163 if (!NILP (w->hchild))
12164 mark_window_display_accurate (w->hchild, accurate_p);
12165 }
12166
12167 if (accurate_p)
12168 {
12169 update_overlay_arrows (1);
12170 }
12171 else
12172 {
12173 /* Force a thorough redisplay the next time by setting
12174 last_arrow_position and last_arrow_string to t, which is
12175 unequal to any useful value of Voverlay_arrow_... */
12176 update_overlay_arrows (-1);
12177 }
12178 }
12179
12180
12181 /* Return value in display table DP (Lisp_Char_Table *) for character
12182 C. Since a display table doesn't have any parent, we don't have to
12183 follow parent. Do not call this function directly but use the
12184 macro DISP_CHAR_VECTOR. */
12185
12186 Lisp_Object
12187 disp_char_vector (dp, c)
12188 struct Lisp_Char_Table *dp;
12189 int c;
12190 {
12191 Lisp_Object val;
12192
12193 if (ASCII_CHAR_P (c))
12194 {
12195 val = dp->ascii;
12196 if (SUB_CHAR_TABLE_P (val))
12197 val = XSUB_CHAR_TABLE (val)->contents[c];
12198 }
12199 else
12200 {
12201 Lisp_Object table;
12202
12203 XSETCHAR_TABLE (table, dp);
12204 val = char_table_ref (table, c);
12205 }
12206 if (NILP (val))
12207 val = dp->defalt;
12208 return val;
12209 }
12210
12211
12212 \f
12213 /***********************************************************************
12214 Window Redisplay
12215 ***********************************************************************/
12216
12217 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12218
12219 static void
12220 redisplay_windows (window)
12221 Lisp_Object window;
12222 {
12223 while (!NILP (window))
12224 {
12225 struct window *w = XWINDOW (window);
12226
12227 if (!NILP (w->hchild))
12228 redisplay_windows (w->hchild);
12229 else if (!NILP (w->vchild))
12230 redisplay_windows (w->vchild);
12231 else if (!NILP (w->buffer))
12232 {
12233 displayed_buffer = XBUFFER (w->buffer);
12234 /* Use list_of_error, not Qerror, so that
12235 we catch only errors and don't run the debugger. */
12236 internal_condition_case_1 (redisplay_window_0, window,
12237 list_of_error,
12238 redisplay_window_error);
12239 }
12240
12241 window = w->next;
12242 }
12243 }
12244
12245 static Lisp_Object
12246 redisplay_window_error ()
12247 {
12248 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12249 return Qnil;
12250 }
12251
12252 static Lisp_Object
12253 redisplay_window_0 (window)
12254 Lisp_Object window;
12255 {
12256 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12257 redisplay_window (window, 0);
12258 return Qnil;
12259 }
12260
12261 static Lisp_Object
12262 redisplay_window_1 (window)
12263 Lisp_Object window;
12264 {
12265 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12266 redisplay_window (window, 1);
12267 return Qnil;
12268 }
12269 \f
12270
12271 /* Increment GLYPH until it reaches END or CONDITION fails while
12272 adding (GLYPH)->pixel_width to X. */
12273
12274 #define SKIP_GLYPHS(glyph, end, x, condition) \
12275 do \
12276 { \
12277 (x) += (glyph)->pixel_width; \
12278 ++(glyph); \
12279 } \
12280 while ((glyph) < (end) && (condition))
12281
12282
12283 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12284 DELTA is the number of bytes by which positions recorded in ROW
12285 differ from current buffer positions.
12286
12287 Return 0 if cursor is not on this row. 1 otherwise. */
12288
12289 int
12290 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12291 struct window *w;
12292 struct glyph_row *row;
12293 struct glyph_matrix *matrix;
12294 int delta, delta_bytes, dy, dvpos;
12295 {
12296 struct glyph *glyph = row->glyphs[TEXT_AREA];
12297 struct glyph *end = glyph + row->used[TEXT_AREA];
12298 struct glyph *cursor = NULL;
12299 /* The first glyph that starts a sequence of glyphs from string. */
12300 struct glyph *string_start;
12301 /* The X coordinate of string_start. */
12302 int string_start_x;
12303 /* The last known character position. */
12304 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12305 /* The last known character position before string_start. */
12306 int string_before_pos;
12307 int x = row->x;
12308 int cursor_x = x;
12309 int cursor_from_overlay_pos = 0;
12310 int pt_old = PT - delta;
12311
12312 /* Skip over glyphs not having an object at the start of the row.
12313 These are special glyphs like truncation marks on terminal
12314 frames. */
12315 if (row->displays_text_p)
12316 while (glyph < end
12317 && INTEGERP (glyph->object)
12318 && glyph->charpos < 0)
12319 {
12320 x += glyph->pixel_width;
12321 ++glyph;
12322 }
12323
12324 string_start = NULL;
12325 while (glyph < end
12326 && !INTEGERP (glyph->object)
12327 && (!BUFFERP (glyph->object)
12328 || (last_pos = glyph->charpos) < pt_old
12329 || glyph->avoid_cursor_p))
12330 {
12331 if (! STRINGP (glyph->object))
12332 {
12333 string_start = NULL;
12334 x += glyph->pixel_width;
12335 ++glyph;
12336 if (cursor_from_overlay_pos
12337 && last_pos >= cursor_from_overlay_pos)
12338 {
12339 cursor_from_overlay_pos = 0;
12340 cursor = 0;
12341 }
12342 }
12343 else
12344 {
12345 if (string_start == NULL)
12346 {
12347 string_before_pos = last_pos;
12348 string_start = glyph;
12349 string_start_x = x;
12350 }
12351 /* Skip all glyphs from string. */
12352 do
12353 {
12354 Lisp_Object cprop;
12355 int pos;
12356 if ((cursor == NULL || glyph > cursor)
12357 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
12358 Qcursor, (glyph)->object),
12359 !NILP (cprop))
12360 && (pos = string_buffer_position (w, glyph->object,
12361 string_before_pos),
12362 (pos == 0 /* From overlay */
12363 || pos == pt_old)))
12364 {
12365 /* Estimate overlay buffer position from the buffer
12366 positions of the glyphs before and after the overlay.
12367 Add 1 to last_pos so that if point corresponds to the
12368 glyph right after the overlay, we still use a 'cursor'
12369 property found in that overlay. */
12370 cursor_from_overlay_pos = (pos ? 0 : last_pos
12371 + (INTEGERP (cprop) ? XINT (cprop) : 0));
12372 cursor = glyph;
12373 cursor_x = x;
12374 }
12375 x += glyph->pixel_width;
12376 ++glyph;
12377 }
12378 while (glyph < end && EQ (glyph->object, string_start->object));
12379 }
12380 }
12381
12382 if (cursor != NULL)
12383 {
12384 glyph = cursor;
12385 x = cursor_x;
12386 }
12387 else if (row->ends_in_ellipsis_p && glyph == end)
12388 {
12389 /* Scan back over the ellipsis glyphs, decrementing positions. */
12390 while (glyph > row->glyphs[TEXT_AREA]
12391 && (glyph - 1)->charpos == last_pos)
12392 glyph--, x -= glyph->pixel_width;
12393 /* That loop always goes one position too far,
12394 including the glyph before the ellipsis.
12395 So scan forward over that one. */
12396 x += glyph->pixel_width;
12397 glyph++;
12398 }
12399 else if (string_start
12400 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12401 {
12402 /* We may have skipped over point because the previous glyphs
12403 are from string. As there's no easy way to know the
12404 character position of the current glyph, find the correct
12405 glyph on point by scanning from string_start again. */
12406 Lisp_Object limit;
12407 Lisp_Object string;
12408 struct glyph *stop = glyph;
12409 int pos;
12410
12411 limit = make_number (pt_old + 1);
12412 glyph = string_start;
12413 x = string_start_x;
12414 string = glyph->object;
12415 pos = string_buffer_position (w, string, string_before_pos);
12416 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
12417 because we always put cursor after overlay strings. */
12418 while (pos == 0 && glyph < stop)
12419 {
12420 string = glyph->object;
12421 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12422 if (glyph < stop)
12423 pos = string_buffer_position (w, glyph->object, string_before_pos);
12424 }
12425
12426 while (glyph < stop)
12427 {
12428 pos = XINT (Fnext_single_char_property_change
12429 (make_number (pos), Qdisplay, Qnil, limit));
12430 if (pos > pt_old)
12431 break;
12432 /* Skip glyphs from the same string. */
12433 string = glyph->object;
12434 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12435 /* Skip glyphs from an overlay. */
12436 while (glyph < stop
12437 && ! string_buffer_position (w, glyph->object, pos))
12438 {
12439 string = glyph->object;
12440 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12441 }
12442 }
12443
12444 /* If we reached the end of the line, and end was from a string,
12445 cursor is not on this line. */
12446 if (glyph == end && row->continued_p)
12447 return 0;
12448 }
12449
12450 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12451 w->cursor.x = x;
12452 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12453 w->cursor.y = row->y + dy;
12454
12455 if (w == XWINDOW (selected_window))
12456 {
12457 if (!row->continued_p
12458 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12459 && row->x == 0)
12460 {
12461 this_line_buffer = XBUFFER (w->buffer);
12462
12463 CHARPOS (this_line_start_pos)
12464 = MATRIX_ROW_START_CHARPOS (row) + delta;
12465 BYTEPOS (this_line_start_pos)
12466 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12467
12468 CHARPOS (this_line_end_pos)
12469 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12470 BYTEPOS (this_line_end_pos)
12471 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12472
12473 this_line_y = w->cursor.y;
12474 this_line_pixel_height = row->height;
12475 this_line_vpos = w->cursor.vpos;
12476 this_line_start_x = row->x;
12477 }
12478 else
12479 CHARPOS (this_line_start_pos) = 0;
12480 }
12481
12482 return 1;
12483 }
12484
12485
12486 /* Run window scroll functions, if any, for WINDOW with new window
12487 start STARTP. Sets the window start of WINDOW to that position.
12488
12489 We assume that the window's buffer is really current. */
12490
12491 static INLINE struct text_pos
12492 run_window_scroll_functions (window, startp)
12493 Lisp_Object window;
12494 struct text_pos startp;
12495 {
12496 struct window *w = XWINDOW (window);
12497 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12498
12499 if (current_buffer != XBUFFER (w->buffer))
12500 abort ();
12501
12502 if (!NILP (Vwindow_scroll_functions))
12503 {
12504 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12505 make_number (CHARPOS (startp)));
12506 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12507 /* In case the hook functions switch buffers. */
12508 if (current_buffer != XBUFFER (w->buffer))
12509 set_buffer_internal_1 (XBUFFER (w->buffer));
12510 }
12511
12512 return startp;
12513 }
12514
12515
12516 /* Make sure the line containing the cursor is fully visible.
12517 A value of 1 means there is nothing to be done.
12518 (Either the line is fully visible, or it cannot be made so,
12519 or we cannot tell.)
12520
12521 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12522 is higher than window.
12523
12524 A value of 0 means the caller should do scrolling
12525 as if point had gone off the screen. */
12526
12527 static int
12528 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12529 struct window *w;
12530 int force_p;
12531 int current_matrix_p;
12532 {
12533 struct glyph_matrix *matrix;
12534 struct glyph_row *row;
12535 int window_height;
12536
12537 if (!make_cursor_line_fully_visible_p)
12538 return 1;
12539
12540 /* It's not always possible to find the cursor, e.g, when a window
12541 is full of overlay strings. Don't do anything in that case. */
12542 if (w->cursor.vpos < 0)
12543 return 1;
12544
12545 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12546 row = MATRIX_ROW (matrix, w->cursor.vpos);
12547
12548 /* If the cursor row is not partially visible, there's nothing to do. */
12549 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12550 return 1;
12551
12552 /* If the row the cursor is in is taller than the window's height,
12553 it's not clear what to do, so do nothing. */
12554 window_height = window_box_height (w);
12555 if (row->height >= window_height)
12556 {
12557 if (!force_p || MINI_WINDOW_P (w)
12558 || w->vscroll || w->cursor.vpos == 0)
12559 return 1;
12560 }
12561 return 0;
12562 }
12563
12564
12565 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12566 non-zero means only WINDOW is redisplayed in redisplay_internal.
12567 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12568 in redisplay_window to bring a partially visible line into view in
12569 the case that only the cursor has moved.
12570
12571 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12572 last screen line's vertical height extends past the end of the screen.
12573
12574 Value is
12575
12576 1 if scrolling succeeded
12577
12578 0 if scrolling didn't find point.
12579
12580 -1 if new fonts have been loaded so that we must interrupt
12581 redisplay, adjust glyph matrices, and try again. */
12582
12583 enum
12584 {
12585 SCROLLING_SUCCESS,
12586 SCROLLING_FAILED,
12587 SCROLLING_NEED_LARGER_MATRICES
12588 };
12589
12590 static int
12591 try_scrolling (window, just_this_one_p, scroll_conservatively,
12592 scroll_step, temp_scroll_step, last_line_misfit)
12593 Lisp_Object window;
12594 int just_this_one_p;
12595 EMACS_INT scroll_conservatively, scroll_step;
12596 int temp_scroll_step;
12597 int last_line_misfit;
12598 {
12599 struct window *w = XWINDOW (window);
12600 struct frame *f = XFRAME (w->frame);
12601 struct text_pos pos, startp;
12602 struct it it;
12603 int this_scroll_margin, scroll_max, rc, height;
12604 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
12605 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12606 Lisp_Object aggressive;
12607 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
12608
12609 #if GLYPH_DEBUG
12610 debug_method_add (w, "try_scrolling");
12611 #endif
12612
12613 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12614
12615 /* Compute scroll margin height in pixels. We scroll when point is
12616 within this distance from the top or bottom of the window. */
12617 if (scroll_margin > 0)
12618 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
12619 * FRAME_LINE_HEIGHT (f);
12620 else
12621 this_scroll_margin = 0;
12622
12623 /* Force scroll_conservatively to have a reasonable value, to avoid
12624 overflow while computing how much to scroll. Note that the user
12625 can supply scroll-conservatively equal to `most-positive-fixnum',
12626 which can be larger than INT_MAX. */
12627 if (scroll_conservatively > scroll_limit)
12628 {
12629 scroll_conservatively = scroll_limit;
12630 scroll_max = INT_MAX;
12631 }
12632 else if (scroll_step || scroll_conservatively || temp_scroll_step)
12633 /* Compute how much we should try to scroll maximally to bring
12634 point into view. */
12635 scroll_max = (max (scroll_step,
12636 max (scroll_conservatively, temp_scroll_step))
12637 * FRAME_LINE_HEIGHT (f));
12638 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12639 || NUMBERP (current_buffer->scroll_up_aggressively))
12640 /* We're trying to scroll because of aggressive scrolling but no
12641 scroll_step is set. Choose an arbitrary one. */
12642 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
12643 else
12644 scroll_max = 0;
12645
12646 too_near_end:
12647
12648 /* Decide whether to scroll down. */
12649 if (PT > CHARPOS (startp))
12650 {
12651 int scroll_margin_y;
12652
12653 /* Compute the pixel ypos of the scroll margin, then move it to
12654 either that ypos or PT, whichever comes first. */
12655 start_display (&it, w, startp);
12656 scroll_margin_y = it.last_visible_y - this_scroll_margin
12657 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
12658 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
12659 (MOVE_TO_POS | MOVE_TO_Y));
12660
12661 if (PT > CHARPOS (it.current.pos))
12662 {
12663 int y0 = line_bottom_y (&it);
12664
12665 /* Compute the distance from the scroll margin to PT
12666 (including the height of the cursor line). Moving the
12667 iterator unconditionally to PT can be slow if PT is far
12668 away, so stop 10 lines past the window bottom (is there a
12669 way to do the right thing quickly?). */
12670 move_it_to (&it, PT, -1,
12671 it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
12672 -1, MOVE_TO_POS | MOVE_TO_Y);
12673 dy = line_bottom_y (&it) - y0;
12674
12675 if (dy > scroll_max)
12676 return SCROLLING_FAILED;
12677
12678 scroll_down_p = 1;
12679 }
12680 }
12681
12682 if (scroll_down_p)
12683 {
12684 /* Point is in or below the bottom scroll margin, so move the
12685 window start down. If scrolling conservatively, move it just
12686 enough down to make point visible. If scroll_step is set,
12687 move it down by scroll_step. */
12688 if (scroll_conservatively)
12689 amount_to_scroll
12690 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12691 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12692 else if (scroll_step || temp_scroll_step)
12693 amount_to_scroll = scroll_max;
12694 else
12695 {
12696 aggressive = current_buffer->scroll_up_aggressively;
12697 height = WINDOW_BOX_TEXT_HEIGHT (w);
12698 if (NUMBERP (aggressive))
12699 {
12700 double float_amount = XFLOATINT (aggressive) * height;
12701 amount_to_scroll = float_amount;
12702 if (amount_to_scroll == 0 && float_amount > 0)
12703 amount_to_scroll = 1;
12704 }
12705 }
12706
12707 if (amount_to_scroll <= 0)
12708 return SCROLLING_FAILED;
12709
12710 start_display (&it, w, startp);
12711 move_it_vertically (&it, amount_to_scroll);
12712
12713 /* If STARTP is unchanged, move it down another screen line. */
12714 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12715 move_it_by_lines (&it, 1, 1);
12716 startp = it.current.pos;
12717 }
12718 else
12719 {
12720 struct text_pos scroll_margin_pos = startp;
12721
12722 /* See if point is inside the scroll margin at the top of the
12723 window. */
12724 if (this_scroll_margin)
12725 {
12726 start_display (&it, w, startp);
12727 move_it_vertically (&it, this_scroll_margin);
12728 scroll_margin_pos = it.current.pos;
12729 }
12730
12731 if (PT < CHARPOS (scroll_margin_pos))
12732 {
12733 /* Point is in the scroll margin at the top of the window or
12734 above what is displayed in the window. */
12735 int y0;
12736
12737 /* Compute the vertical distance from PT to the scroll
12738 margin position. Give up if distance is greater than
12739 scroll_max. */
12740 SET_TEXT_POS (pos, PT, PT_BYTE);
12741 start_display (&it, w, pos);
12742 y0 = it.current_y;
12743 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12744 it.last_visible_y, -1,
12745 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12746 dy = it.current_y - y0;
12747 if (dy > scroll_max)
12748 return SCROLLING_FAILED;
12749
12750 /* Compute new window start. */
12751 start_display (&it, w, startp);
12752
12753 if (scroll_conservatively)
12754 amount_to_scroll
12755 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12756 else if (scroll_step || temp_scroll_step)
12757 amount_to_scroll = scroll_max;
12758 else
12759 {
12760 aggressive = current_buffer->scroll_down_aggressively;
12761 height = WINDOW_BOX_TEXT_HEIGHT (w);
12762 if (NUMBERP (aggressive))
12763 {
12764 double float_amount = XFLOATINT (aggressive) * height;
12765 amount_to_scroll = float_amount;
12766 if (amount_to_scroll == 0 && float_amount > 0)
12767 amount_to_scroll = 1;
12768 }
12769 }
12770
12771 if (amount_to_scroll <= 0)
12772 return SCROLLING_FAILED;
12773
12774 move_it_vertically_backward (&it, amount_to_scroll);
12775 startp = it.current.pos;
12776 }
12777 }
12778
12779 /* Run window scroll functions. */
12780 startp = run_window_scroll_functions (window, startp);
12781
12782 /* Display the window. Give up if new fonts are loaded, or if point
12783 doesn't appear. */
12784 if (!try_window (window, startp, 0))
12785 rc = SCROLLING_NEED_LARGER_MATRICES;
12786 else if (w->cursor.vpos < 0)
12787 {
12788 clear_glyph_matrix (w->desired_matrix);
12789 rc = SCROLLING_FAILED;
12790 }
12791 else
12792 {
12793 /* Maybe forget recorded base line for line number display. */
12794 if (!just_this_one_p
12795 || current_buffer->clip_changed
12796 || BEG_UNCHANGED < CHARPOS (startp))
12797 w->base_line_number = Qnil;
12798
12799 /* If cursor ends up on a partially visible line,
12800 treat that as being off the bottom of the screen. */
12801 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12802 {
12803 clear_glyph_matrix (w->desired_matrix);
12804 ++extra_scroll_margin_lines;
12805 goto too_near_end;
12806 }
12807 rc = SCROLLING_SUCCESS;
12808 }
12809
12810 return rc;
12811 }
12812
12813
12814 /* Compute a suitable window start for window W if display of W starts
12815 on a continuation line. Value is non-zero if a new window start
12816 was computed.
12817
12818 The new window start will be computed, based on W's width, starting
12819 from the start of the continued line. It is the start of the
12820 screen line with the minimum distance from the old start W->start. */
12821
12822 static int
12823 compute_window_start_on_continuation_line (w)
12824 struct window *w;
12825 {
12826 struct text_pos pos, start_pos;
12827 int window_start_changed_p = 0;
12828
12829 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12830
12831 /* If window start is on a continuation line... Window start may be
12832 < BEGV in case there's invisible text at the start of the
12833 buffer (M-x rmail, for example). */
12834 if (CHARPOS (start_pos) > BEGV
12835 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12836 {
12837 struct it it;
12838 struct glyph_row *row;
12839
12840 /* Handle the case that the window start is out of range. */
12841 if (CHARPOS (start_pos) < BEGV)
12842 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12843 else if (CHARPOS (start_pos) > ZV)
12844 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12845
12846 /* Find the start of the continued line. This should be fast
12847 because scan_buffer is fast (newline cache). */
12848 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12849 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12850 row, DEFAULT_FACE_ID);
12851 reseat_at_previous_visible_line_start (&it);
12852
12853 /* If the line start is "too far" away from the window start,
12854 say it takes too much time to compute a new window start. */
12855 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12856 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12857 {
12858 int min_distance, distance;
12859
12860 /* Move forward by display lines to find the new window
12861 start. If window width was enlarged, the new start can
12862 be expected to be > the old start. If window width was
12863 decreased, the new window start will be < the old start.
12864 So, we're looking for the display line start with the
12865 minimum distance from the old window start. */
12866 pos = it.current.pos;
12867 min_distance = INFINITY;
12868 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12869 distance < min_distance)
12870 {
12871 min_distance = distance;
12872 pos = it.current.pos;
12873 move_it_by_lines (&it, 1, 0);
12874 }
12875
12876 /* Set the window start there. */
12877 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12878 window_start_changed_p = 1;
12879 }
12880 }
12881
12882 return window_start_changed_p;
12883 }
12884
12885
12886 /* Try cursor movement in case text has not changed in window WINDOW,
12887 with window start STARTP. Value is
12888
12889 CURSOR_MOVEMENT_SUCCESS if successful
12890
12891 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12892
12893 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12894 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12895 we want to scroll as if scroll-step were set to 1. See the code.
12896
12897 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12898 which case we have to abort this redisplay, and adjust matrices
12899 first. */
12900
12901 enum
12902 {
12903 CURSOR_MOVEMENT_SUCCESS,
12904 CURSOR_MOVEMENT_CANNOT_BE_USED,
12905 CURSOR_MOVEMENT_MUST_SCROLL,
12906 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12907 };
12908
12909 static int
12910 try_cursor_movement (window, startp, scroll_step)
12911 Lisp_Object window;
12912 struct text_pos startp;
12913 int *scroll_step;
12914 {
12915 struct window *w = XWINDOW (window);
12916 struct frame *f = XFRAME (w->frame);
12917 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12918
12919 #if GLYPH_DEBUG
12920 if (inhibit_try_cursor_movement)
12921 return rc;
12922 #endif
12923
12924 /* Handle case where text has not changed, only point, and it has
12925 not moved off the frame. */
12926 if (/* Point may be in this window. */
12927 PT >= CHARPOS (startp)
12928 /* Selective display hasn't changed. */
12929 && !current_buffer->clip_changed
12930 /* Function force-mode-line-update is used to force a thorough
12931 redisplay. It sets either windows_or_buffers_changed or
12932 update_mode_lines. So don't take a shortcut here for these
12933 cases. */
12934 && !update_mode_lines
12935 && !windows_or_buffers_changed
12936 && !cursor_type_changed
12937 /* Can't use this case if highlighting a region. When a
12938 region exists, cursor movement has to do more than just
12939 set the cursor. */
12940 && !(!NILP (Vtransient_mark_mode)
12941 && !NILP (current_buffer->mark_active))
12942 && NILP (w->region_showing)
12943 && NILP (Vshow_trailing_whitespace)
12944 /* Right after splitting windows, last_point may be nil. */
12945 && INTEGERP (w->last_point)
12946 /* This code is not used for mini-buffer for the sake of the case
12947 of redisplaying to replace an echo area message; since in
12948 that case the mini-buffer contents per se are usually
12949 unchanged. This code is of no real use in the mini-buffer
12950 since the handling of this_line_start_pos, etc., in redisplay
12951 handles the same cases. */
12952 && !EQ (window, minibuf_window)
12953 /* When splitting windows or for new windows, it happens that
12954 redisplay is called with a nil window_end_vpos or one being
12955 larger than the window. This should really be fixed in
12956 window.c. I don't have this on my list, now, so we do
12957 approximately the same as the old redisplay code. --gerd. */
12958 && INTEGERP (w->window_end_vpos)
12959 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12960 && (FRAME_WINDOW_P (f)
12961 || !overlay_arrow_in_current_buffer_p ()))
12962 {
12963 int this_scroll_margin, top_scroll_margin;
12964 struct glyph_row *row = NULL;
12965
12966 #if GLYPH_DEBUG
12967 debug_method_add (w, "cursor movement");
12968 #endif
12969
12970 /* Scroll if point within this distance from the top or bottom
12971 of the window. This is a pixel value. */
12972 if (scroll_margin > 0)
12973 {
12974 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12975 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12976 }
12977 else
12978 this_scroll_margin = 0;
12979
12980 top_scroll_margin = this_scroll_margin;
12981 if (WINDOW_WANTS_HEADER_LINE_P (w))
12982 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12983
12984 /* Start with the row the cursor was displayed during the last
12985 not paused redisplay. Give up if that row is not valid. */
12986 if (w->last_cursor.vpos < 0
12987 || w->last_cursor.vpos >= w->current_matrix->nrows)
12988 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12989 else
12990 {
12991 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12992 if (row->mode_line_p)
12993 ++row;
12994 if (!row->enabled_p)
12995 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12996 }
12997
12998 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12999 {
13000 int scroll_p = 0;
13001 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13002
13003 if (PT > XFASTINT (w->last_point))
13004 {
13005 /* Point has moved forward. */
13006 while (MATRIX_ROW_END_CHARPOS (row) < PT
13007 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13008 {
13009 xassert (row->enabled_p);
13010 ++row;
13011 }
13012
13013 /* The end position of a row equals the start position
13014 of the next row. If PT is there, we would rather
13015 display it in the next line. */
13016 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13017 && MATRIX_ROW_END_CHARPOS (row) == PT
13018 && !cursor_row_p (w, row))
13019 ++row;
13020
13021 /* If within the scroll margin, scroll. Note that
13022 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13023 the next line would be drawn, and that
13024 this_scroll_margin can be zero. */
13025 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13026 || PT > MATRIX_ROW_END_CHARPOS (row)
13027 /* Line is completely visible last line in window
13028 and PT is to be set in the next line. */
13029 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13030 && PT == MATRIX_ROW_END_CHARPOS (row)
13031 && !row->ends_at_zv_p
13032 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13033 scroll_p = 1;
13034 }
13035 else if (PT < XFASTINT (w->last_point))
13036 {
13037 /* Cursor has to be moved backward. Note that PT >=
13038 CHARPOS (startp) because of the outer if-statement. */
13039 while (!row->mode_line_p
13040 && (MATRIX_ROW_START_CHARPOS (row) > PT
13041 || (MATRIX_ROW_START_CHARPOS (row) == PT
13042 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13043 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13044 row > w->current_matrix->rows
13045 && (row-1)->ends_in_newline_from_string_p))))
13046 && (row->y > top_scroll_margin
13047 || CHARPOS (startp) == BEGV))
13048 {
13049 xassert (row->enabled_p);
13050 --row;
13051 }
13052
13053 /* Consider the following case: Window starts at BEGV,
13054 there is invisible, intangible text at BEGV, so that
13055 display starts at some point START > BEGV. It can
13056 happen that we are called with PT somewhere between
13057 BEGV and START. Try to handle that case. */
13058 if (row < w->current_matrix->rows
13059 || row->mode_line_p)
13060 {
13061 row = w->current_matrix->rows;
13062 if (row->mode_line_p)
13063 ++row;
13064 }
13065
13066 /* Due to newlines in overlay strings, we may have to
13067 skip forward over overlay strings. */
13068 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13069 && MATRIX_ROW_END_CHARPOS (row) == PT
13070 && !cursor_row_p (w, row))
13071 ++row;
13072
13073 /* If within the scroll margin, scroll. */
13074 if (row->y < top_scroll_margin
13075 && CHARPOS (startp) != BEGV)
13076 scroll_p = 1;
13077 }
13078 else
13079 {
13080 /* Cursor did not move. So don't scroll even if cursor line
13081 is partially visible, as it was so before. */
13082 rc = CURSOR_MOVEMENT_SUCCESS;
13083 }
13084
13085 if (PT < MATRIX_ROW_START_CHARPOS (row)
13086 || PT > MATRIX_ROW_END_CHARPOS (row))
13087 {
13088 /* if PT is not in the glyph row, give up. */
13089 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13090 }
13091 else if (rc != CURSOR_MOVEMENT_SUCCESS
13092 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13093 && make_cursor_line_fully_visible_p)
13094 {
13095 if (PT == MATRIX_ROW_END_CHARPOS (row)
13096 && !row->ends_at_zv_p
13097 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13098 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13099 else if (row->height > window_box_height (w))
13100 {
13101 /* If we end up in a partially visible line, let's
13102 make it fully visible, except when it's taller
13103 than the window, in which case we can't do much
13104 about it. */
13105 *scroll_step = 1;
13106 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13107 }
13108 else
13109 {
13110 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13111 if (!cursor_row_fully_visible_p (w, 0, 1))
13112 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13113 else
13114 rc = CURSOR_MOVEMENT_SUCCESS;
13115 }
13116 }
13117 else if (scroll_p)
13118 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13119 else
13120 {
13121 do
13122 {
13123 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13124 {
13125 rc = CURSOR_MOVEMENT_SUCCESS;
13126 break;
13127 }
13128 ++row;
13129 }
13130 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13131 && MATRIX_ROW_START_CHARPOS (row) == PT
13132 && cursor_row_p (w, row));
13133 }
13134 }
13135 }
13136
13137 return rc;
13138 }
13139
13140 void
13141 set_vertical_scroll_bar (w)
13142 struct window *w;
13143 {
13144 int start, end, whole;
13145
13146 /* Calculate the start and end positions for the current window.
13147 At some point, it would be nice to choose between scrollbars
13148 which reflect the whole buffer size, with special markers
13149 indicating narrowing, and scrollbars which reflect only the
13150 visible region.
13151
13152 Note that mini-buffers sometimes aren't displaying any text. */
13153 if (!MINI_WINDOW_P (w)
13154 || (w == XWINDOW (minibuf_window)
13155 && NILP (echo_area_buffer[0])))
13156 {
13157 struct buffer *buf = XBUFFER (w->buffer);
13158 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13159 start = marker_position (w->start) - BUF_BEGV (buf);
13160 /* I don't think this is guaranteed to be right. For the
13161 moment, we'll pretend it is. */
13162 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13163
13164 if (end < start)
13165 end = start;
13166 if (whole < (end - start))
13167 whole = end - start;
13168 }
13169 else
13170 start = end = whole = 0;
13171
13172 /* Indicate what this scroll bar ought to be displaying now. */
13173 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13174 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13175 (w, end - start, whole, start);
13176 }
13177
13178
13179 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13180 selected_window is redisplayed.
13181
13182 We can return without actually redisplaying the window if
13183 fonts_changed_p is nonzero. In that case, redisplay_internal will
13184 retry. */
13185
13186 static void
13187 redisplay_window (window, just_this_one_p)
13188 Lisp_Object window;
13189 int just_this_one_p;
13190 {
13191 struct window *w = XWINDOW (window);
13192 struct frame *f = XFRAME (w->frame);
13193 struct buffer *buffer = XBUFFER (w->buffer);
13194 struct buffer *old = current_buffer;
13195 struct text_pos lpoint, opoint, startp;
13196 int update_mode_line;
13197 int tem;
13198 struct it it;
13199 /* Record it now because it's overwritten. */
13200 int current_matrix_up_to_date_p = 0;
13201 int used_current_matrix_p = 0;
13202 /* This is less strict than current_matrix_up_to_date_p.
13203 It indictes that the buffer contents and narrowing are unchanged. */
13204 int buffer_unchanged_p = 0;
13205 int temp_scroll_step = 0;
13206 int count = SPECPDL_INDEX ();
13207 int rc;
13208 int centering_position = -1;
13209 int last_line_misfit = 0;
13210 int beg_unchanged, end_unchanged;
13211
13212 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13213 opoint = lpoint;
13214
13215 /* W must be a leaf window here. */
13216 xassert (!NILP (w->buffer));
13217 #if GLYPH_DEBUG
13218 *w->desired_matrix->method = 0;
13219 #endif
13220
13221 restart:
13222 reconsider_clip_changes (w, buffer);
13223
13224 /* Has the mode line to be updated? */
13225 update_mode_line = (!NILP (w->update_mode_line)
13226 || update_mode_lines
13227 || buffer->clip_changed
13228 || buffer->prevent_redisplay_optimizations_p);
13229
13230 if (MINI_WINDOW_P (w))
13231 {
13232 if (w == XWINDOW (echo_area_window)
13233 && !NILP (echo_area_buffer[0]))
13234 {
13235 if (update_mode_line)
13236 /* We may have to update a tty frame's menu bar or a
13237 tool-bar. Example `M-x C-h C-h C-g'. */
13238 goto finish_menu_bars;
13239 else
13240 /* We've already displayed the echo area glyphs in this window. */
13241 goto finish_scroll_bars;
13242 }
13243 else if ((w != XWINDOW (minibuf_window)
13244 || minibuf_level == 0)
13245 /* When buffer is nonempty, redisplay window normally. */
13246 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13247 /* Quail displays non-mini buffers in minibuffer window.
13248 In that case, redisplay the window normally. */
13249 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13250 {
13251 /* W is a mini-buffer window, but it's not active, so clear
13252 it. */
13253 int yb = window_text_bottom_y (w);
13254 struct glyph_row *row;
13255 int y;
13256
13257 for (y = 0, row = w->desired_matrix->rows;
13258 y < yb;
13259 y += row->height, ++row)
13260 blank_row (w, row, y);
13261 goto finish_scroll_bars;
13262 }
13263
13264 clear_glyph_matrix (w->desired_matrix);
13265 }
13266
13267 /* Otherwise set up data on this window; select its buffer and point
13268 value. */
13269 /* Really select the buffer, for the sake of buffer-local
13270 variables. */
13271 set_buffer_internal_1 (XBUFFER (w->buffer));
13272
13273 current_matrix_up_to_date_p
13274 = (!NILP (w->window_end_valid)
13275 && !current_buffer->clip_changed
13276 && !current_buffer->prevent_redisplay_optimizations_p
13277 && XFASTINT (w->last_modified) >= MODIFF
13278 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13279
13280 /* Run the window-bottom-change-functions
13281 if it is possible that the text on the screen has changed
13282 (either due to modification of the text, or any other reason). */
13283 if (!current_matrix_up_to_date_p
13284 && !NILP (Vwindow_text_change_functions))
13285 {
13286 safe_run_hooks (Qwindow_text_change_functions);
13287 goto restart;
13288 }
13289
13290 beg_unchanged = BEG_UNCHANGED;
13291 end_unchanged = END_UNCHANGED;
13292
13293 SET_TEXT_POS (opoint, PT, PT_BYTE);
13294
13295 specbind (Qinhibit_point_motion_hooks, Qt);
13296
13297 buffer_unchanged_p
13298 = (!NILP (w->window_end_valid)
13299 && !current_buffer->clip_changed
13300 && XFASTINT (w->last_modified) >= MODIFF
13301 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13302
13303 /* When windows_or_buffers_changed is non-zero, we can't rely on
13304 the window end being valid, so set it to nil there. */
13305 if (windows_or_buffers_changed)
13306 {
13307 /* If window starts on a continuation line, maybe adjust the
13308 window start in case the window's width changed. */
13309 if (XMARKER (w->start)->buffer == current_buffer)
13310 compute_window_start_on_continuation_line (w);
13311
13312 w->window_end_valid = Qnil;
13313 }
13314
13315 /* Some sanity checks. */
13316 CHECK_WINDOW_END (w);
13317 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13318 abort ();
13319 if (BYTEPOS (opoint) < CHARPOS (opoint))
13320 abort ();
13321
13322 /* If %c is in mode line, update it if needed. */
13323 if (!NILP (w->column_number_displayed)
13324 /* This alternative quickly identifies a common case
13325 where no change is needed. */
13326 && !(PT == XFASTINT (w->last_point)
13327 && XFASTINT (w->last_modified) >= MODIFF
13328 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13329 && (XFASTINT (w->column_number_displayed)
13330 != (int) current_column ())) /* iftc */
13331 update_mode_line = 1;
13332
13333 /* Count number of windows showing the selected buffer. An indirect
13334 buffer counts as its base buffer. */
13335 if (!just_this_one_p)
13336 {
13337 struct buffer *current_base, *window_base;
13338 current_base = current_buffer;
13339 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13340 if (current_base->base_buffer)
13341 current_base = current_base->base_buffer;
13342 if (window_base->base_buffer)
13343 window_base = window_base->base_buffer;
13344 if (current_base == window_base)
13345 buffer_shared++;
13346 }
13347
13348 /* Point refers normally to the selected window. For any other
13349 window, set up appropriate value. */
13350 if (!EQ (window, selected_window))
13351 {
13352 int new_pt = XMARKER (w->pointm)->charpos;
13353 int new_pt_byte = marker_byte_position (w->pointm);
13354 if (new_pt < BEGV)
13355 {
13356 new_pt = BEGV;
13357 new_pt_byte = BEGV_BYTE;
13358 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13359 }
13360 else if (new_pt > (ZV - 1))
13361 {
13362 new_pt = ZV;
13363 new_pt_byte = ZV_BYTE;
13364 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13365 }
13366
13367 /* We don't use SET_PT so that the point-motion hooks don't run. */
13368 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13369 }
13370
13371 /* If any of the character widths specified in the display table
13372 have changed, invalidate the width run cache. It's true that
13373 this may be a bit late to catch such changes, but the rest of
13374 redisplay goes (non-fatally) haywire when the display table is
13375 changed, so why should we worry about doing any better? */
13376 if (current_buffer->width_run_cache)
13377 {
13378 struct Lisp_Char_Table *disptab = buffer_display_table ();
13379
13380 if (! disptab_matches_widthtab (disptab,
13381 XVECTOR (current_buffer->width_table)))
13382 {
13383 invalidate_region_cache (current_buffer,
13384 current_buffer->width_run_cache,
13385 BEG, Z);
13386 recompute_width_table (current_buffer, disptab);
13387 }
13388 }
13389
13390 /* If window-start is screwed up, choose a new one. */
13391 if (XMARKER (w->start)->buffer != current_buffer)
13392 goto recenter;
13393
13394 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13395
13396 /* If someone specified a new starting point but did not insist,
13397 check whether it can be used. */
13398 if (!NILP (w->optional_new_start)
13399 && CHARPOS (startp) >= BEGV
13400 && CHARPOS (startp) <= ZV)
13401 {
13402 w->optional_new_start = Qnil;
13403 start_display (&it, w, startp);
13404 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13405 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13406 if (IT_CHARPOS (it) == PT)
13407 w->force_start = Qt;
13408 /* IT may overshoot PT if text at PT is invisible. */
13409 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13410 w->force_start = Qt;
13411 }
13412
13413 force_start:
13414
13415 /* Handle case where place to start displaying has been specified,
13416 unless the specified location is outside the accessible range. */
13417 if (!NILP (w->force_start)
13418 || w->frozen_window_start_p)
13419 {
13420 /* We set this later on if we have to adjust point. */
13421 int new_vpos = -1;
13422
13423 w->force_start = Qnil;
13424 w->vscroll = 0;
13425 w->window_end_valid = Qnil;
13426
13427 /* Forget any recorded base line for line number display. */
13428 if (!buffer_unchanged_p)
13429 w->base_line_number = Qnil;
13430
13431 /* Redisplay the mode line. Select the buffer properly for that.
13432 Also, run the hook window-scroll-functions
13433 because we have scrolled. */
13434 /* Note, we do this after clearing force_start because
13435 if there's an error, it is better to forget about force_start
13436 than to get into an infinite loop calling the hook functions
13437 and having them get more errors. */
13438 if (!update_mode_line
13439 || ! NILP (Vwindow_scroll_functions))
13440 {
13441 update_mode_line = 1;
13442 w->update_mode_line = Qt;
13443 startp = run_window_scroll_functions (window, startp);
13444 }
13445
13446 w->last_modified = make_number (0);
13447 w->last_overlay_modified = make_number (0);
13448 if (CHARPOS (startp) < BEGV)
13449 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13450 else if (CHARPOS (startp) > ZV)
13451 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13452
13453 /* Redisplay, then check if cursor has been set during the
13454 redisplay. Give up if new fonts were loaded. */
13455 /* We used to issue a CHECK_MARGINS argument to try_window here,
13456 but this causes scrolling to fail when point begins inside
13457 the scroll margin (bug#148) -- cyd */
13458 if (!try_window (window, startp, 0))
13459 {
13460 w->force_start = Qt;
13461 clear_glyph_matrix (w->desired_matrix);
13462 goto need_larger_matrices;
13463 }
13464
13465 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13466 {
13467 /* If point does not appear, try to move point so it does
13468 appear. The desired matrix has been built above, so we
13469 can use it here. */
13470 new_vpos = window_box_height (w) / 2;
13471 }
13472
13473 if (!cursor_row_fully_visible_p (w, 0, 0))
13474 {
13475 /* Point does appear, but on a line partly visible at end of window.
13476 Move it back to a fully-visible line. */
13477 new_vpos = window_box_height (w);
13478 }
13479
13480 /* If we need to move point for either of the above reasons,
13481 now actually do it. */
13482 if (new_vpos >= 0)
13483 {
13484 struct glyph_row *row;
13485
13486 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13487 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13488 ++row;
13489
13490 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13491 MATRIX_ROW_START_BYTEPOS (row));
13492
13493 if (w != XWINDOW (selected_window))
13494 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13495 else if (current_buffer == old)
13496 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13497
13498 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13499
13500 /* If we are highlighting the region, then we just changed
13501 the region, so redisplay to show it. */
13502 if (!NILP (Vtransient_mark_mode)
13503 && !NILP (current_buffer->mark_active))
13504 {
13505 clear_glyph_matrix (w->desired_matrix);
13506 if (!try_window (window, startp, 0))
13507 goto need_larger_matrices;
13508 }
13509 }
13510
13511 #if GLYPH_DEBUG
13512 debug_method_add (w, "forced window start");
13513 #endif
13514 goto done;
13515 }
13516
13517 /* Handle case where text has not changed, only point, and it has
13518 not moved off the frame, and we are not retrying after hscroll.
13519 (current_matrix_up_to_date_p is nonzero when retrying.) */
13520 if (current_matrix_up_to_date_p
13521 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13522 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13523 {
13524 switch (rc)
13525 {
13526 case CURSOR_MOVEMENT_SUCCESS:
13527 used_current_matrix_p = 1;
13528 goto done;
13529
13530 case CURSOR_MOVEMENT_MUST_SCROLL:
13531 goto try_to_scroll;
13532
13533 default:
13534 abort ();
13535 }
13536 }
13537 /* If current starting point was originally the beginning of a line
13538 but no longer is, find a new starting point. */
13539 else if (!NILP (w->start_at_line_beg)
13540 && !(CHARPOS (startp) <= BEGV
13541 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13542 {
13543 #if GLYPH_DEBUG
13544 debug_method_add (w, "recenter 1");
13545 #endif
13546 goto recenter;
13547 }
13548
13549 /* Try scrolling with try_window_id. Value is > 0 if update has
13550 been done, it is -1 if we know that the same window start will
13551 not work. It is 0 if unsuccessful for some other reason. */
13552 else if ((tem = try_window_id (w)) != 0)
13553 {
13554 #if GLYPH_DEBUG
13555 debug_method_add (w, "try_window_id %d", tem);
13556 #endif
13557
13558 if (fonts_changed_p)
13559 goto need_larger_matrices;
13560 if (tem > 0)
13561 goto done;
13562
13563 /* Otherwise try_window_id has returned -1 which means that we
13564 don't want the alternative below this comment to execute. */
13565 }
13566 else if (CHARPOS (startp) >= BEGV
13567 && CHARPOS (startp) <= ZV
13568 && PT >= CHARPOS (startp)
13569 && (CHARPOS (startp) < ZV
13570 /* Avoid starting at end of buffer. */
13571 || CHARPOS (startp) == BEGV
13572 || (XFASTINT (w->last_modified) >= MODIFF
13573 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13574 {
13575
13576 /* If first window line is a continuation line, and window start
13577 is inside the modified region, but the first change is before
13578 current window start, we must select a new window start.
13579
13580 However, if this is the result of a down-mouse event (e.g. by
13581 extending the mouse-drag-overlay), we don't want to select a
13582 new window start, since that would change the position under
13583 the mouse, resulting in an unwanted mouse-movement rather
13584 than a simple mouse-click. */
13585 if (NILP (w->start_at_line_beg)
13586 && NILP (do_mouse_tracking)
13587 && CHARPOS (startp) > BEGV
13588 && CHARPOS (startp) > BEG + beg_unchanged
13589 && CHARPOS (startp) <= Z - end_unchanged
13590 /* Even if w->start_at_line_beg is nil, a new window may
13591 start at a line_beg, since that's how set_buffer_window
13592 sets it. So, we need to check the return value of
13593 compute_window_start_on_continuation_line. (See also
13594 bug#197). */
13595 && XMARKER (w->start)->buffer == current_buffer
13596 && compute_window_start_on_continuation_line (w))
13597 {
13598 w->force_start = Qt;
13599 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13600 goto force_start;
13601 }
13602
13603 #if GLYPH_DEBUG
13604 debug_method_add (w, "same window start");
13605 #endif
13606
13607 /* Try to redisplay starting at same place as before.
13608 If point has not moved off frame, accept the results. */
13609 if (!current_matrix_up_to_date_p
13610 /* Don't use try_window_reusing_current_matrix in this case
13611 because a window scroll function can have changed the
13612 buffer. */
13613 || !NILP (Vwindow_scroll_functions)
13614 || MINI_WINDOW_P (w)
13615 || !(used_current_matrix_p
13616 = try_window_reusing_current_matrix (w)))
13617 {
13618 IF_DEBUG (debug_method_add (w, "1"));
13619 if (try_window (window, startp, 1) < 0)
13620 /* -1 means we need to scroll.
13621 0 means we need new matrices, but fonts_changed_p
13622 is set in that case, so we will detect it below. */
13623 goto try_to_scroll;
13624 }
13625
13626 if (fonts_changed_p)
13627 goto need_larger_matrices;
13628
13629 if (w->cursor.vpos >= 0)
13630 {
13631 if (!just_this_one_p
13632 || current_buffer->clip_changed
13633 || BEG_UNCHANGED < CHARPOS (startp))
13634 /* Forget any recorded base line for line number display. */
13635 w->base_line_number = Qnil;
13636
13637 if (!cursor_row_fully_visible_p (w, 1, 0))
13638 {
13639 clear_glyph_matrix (w->desired_matrix);
13640 last_line_misfit = 1;
13641 }
13642 /* Drop through and scroll. */
13643 else
13644 goto done;
13645 }
13646 else
13647 clear_glyph_matrix (w->desired_matrix);
13648 }
13649
13650 try_to_scroll:
13651
13652 w->last_modified = make_number (0);
13653 w->last_overlay_modified = make_number (0);
13654
13655 /* Redisplay the mode line. Select the buffer properly for that. */
13656 if (!update_mode_line)
13657 {
13658 update_mode_line = 1;
13659 w->update_mode_line = Qt;
13660 }
13661
13662 /* Try to scroll by specified few lines. */
13663 if ((scroll_conservatively
13664 || scroll_step
13665 || temp_scroll_step
13666 || NUMBERP (current_buffer->scroll_up_aggressively)
13667 || NUMBERP (current_buffer->scroll_down_aggressively))
13668 && !current_buffer->clip_changed
13669 && CHARPOS (startp) >= BEGV
13670 && CHARPOS (startp) <= ZV)
13671 {
13672 /* The function returns -1 if new fonts were loaded, 1 if
13673 successful, 0 if not successful. */
13674 int rc = try_scrolling (window, just_this_one_p,
13675 scroll_conservatively,
13676 scroll_step,
13677 temp_scroll_step, last_line_misfit);
13678 switch (rc)
13679 {
13680 case SCROLLING_SUCCESS:
13681 goto done;
13682
13683 case SCROLLING_NEED_LARGER_MATRICES:
13684 goto need_larger_matrices;
13685
13686 case SCROLLING_FAILED:
13687 break;
13688
13689 default:
13690 abort ();
13691 }
13692 }
13693
13694 /* Finally, just choose place to start which centers point */
13695
13696 recenter:
13697 if (centering_position < 0)
13698 centering_position = window_box_height (w) / 2;
13699
13700 #if GLYPH_DEBUG
13701 debug_method_add (w, "recenter");
13702 #endif
13703
13704 /* w->vscroll = 0; */
13705
13706 /* Forget any previously recorded base line for line number display. */
13707 if (!buffer_unchanged_p)
13708 w->base_line_number = Qnil;
13709
13710 /* Move backward half the height of the window. */
13711 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13712 it.current_y = it.last_visible_y;
13713 move_it_vertically_backward (&it, centering_position);
13714 xassert (IT_CHARPOS (it) >= BEGV);
13715
13716 /* The function move_it_vertically_backward may move over more
13717 than the specified y-distance. If it->w is small, e.g. a
13718 mini-buffer window, we may end up in front of the window's
13719 display area. Start displaying at the start of the line
13720 containing PT in this case. */
13721 if (it.current_y <= 0)
13722 {
13723 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13724 move_it_vertically_backward (&it, 0);
13725 it.current_y = 0;
13726 }
13727
13728 it.current_x = it.hpos = 0;
13729
13730 /* Set startp here explicitly in case that helps avoid an infinite loop
13731 in case the window-scroll-functions functions get errors. */
13732 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13733
13734 /* Run scroll hooks. */
13735 startp = run_window_scroll_functions (window, it.current.pos);
13736
13737 /* Redisplay the window. */
13738 if (!current_matrix_up_to_date_p
13739 || windows_or_buffers_changed
13740 || cursor_type_changed
13741 /* Don't use try_window_reusing_current_matrix in this case
13742 because it can have changed the buffer. */
13743 || !NILP (Vwindow_scroll_functions)
13744 || !just_this_one_p
13745 || MINI_WINDOW_P (w)
13746 || !(used_current_matrix_p
13747 = try_window_reusing_current_matrix (w)))
13748 try_window (window, startp, 0);
13749
13750 /* If new fonts have been loaded (due to fontsets), give up. We
13751 have to start a new redisplay since we need to re-adjust glyph
13752 matrices. */
13753 if (fonts_changed_p)
13754 goto need_larger_matrices;
13755
13756 /* If cursor did not appear assume that the middle of the window is
13757 in the first line of the window. Do it again with the next line.
13758 (Imagine a window of height 100, displaying two lines of height
13759 60. Moving back 50 from it->last_visible_y will end in the first
13760 line.) */
13761 if (w->cursor.vpos < 0)
13762 {
13763 if (!NILP (w->window_end_valid)
13764 && PT >= Z - XFASTINT (w->window_end_pos))
13765 {
13766 clear_glyph_matrix (w->desired_matrix);
13767 move_it_by_lines (&it, 1, 0);
13768 try_window (window, it.current.pos, 0);
13769 }
13770 else if (PT < IT_CHARPOS (it))
13771 {
13772 clear_glyph_matrix (w->desired_matrix);
13773 move_it_by_lines (&it, -1, 0);
13774 try_window (window, it.current.pos, 0);
13775 }
13776 else
13777 {
13778 /* Not much we can do about it. */
13779 }
13780 }
13781
13782 /* Consider the following case: Window starts at BEGV, there is
13783 invisible, intangible text at BEGV, so that display starts at
13784 some point START > BEGV. It can happen that we are called with
13785 PT somewhere between BEGV and START. Try to handle that case. */
13786 if (w->cursor.vpos < 0)
13787 {
13788 struct glyph_row *row = w->current_matrix->rows;
13789 if (row->mode_line_p)
13790 ++row;
13791 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13792 }
13793
13794 if (!cursor_row_fully_visible_p (w, 0, 0))
13795 {
13796 /* If vscroll is enabled, disable it and try again. */
13797 if (w->vscroll)
13798 {
13799 w->vscroll = 0;
13800 clear_glyph_matrix (w->desired_matrix);
13801 goto recenter;
13802 }
13803
13804 /* If centering point failed to make the whole line visible,
13805 put point at the top instead. That has to make the whole line
13806 visible, if it can be done. */
13807 if (centering_position == 0)
13808 goto done;
13809
13810 clear_glyph_matrix (w->desired_matrix);
13811 centering_position = 0;
13812 goto recenter;
13813 }
13814
13815 done:
13816
13817 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13818 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13819 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13820 ? Qt : Qnil);
13821
13822 /* Display the mode line, if we must. */
13823 if ((update_mode_line
13824 /* If window not full width, must redo its mode line
13825 if (a) the window to its side is being redone and
13826 (b) we do a frame-based redisplay. This is a consequence
13827 of how inverted lines are drawn in frame-based redisplay. */
13828 || (!just_this_one_p
13829 && !FRAME_WINDOW_P (f)
13830 && !WINDOW_FULL_WIDTH_P (w))
13831 /* Line number to display. */
13832 || INTEGERP (w->base_line_pos)
13833 /* Column number is displayed and different from the one displayed. */
13834 || (!NILP (w->column_number_displayed)
13835 && (XFASTINT (w->column_number_displayed)
13836 != (int) current_column ()))) /* iftc */
13837 /* This means that the window has a mode line. */
13838 && (WINDOW_WANTS_MODELINE_P (w)
13839 || WINDOW_WANTS_HEADER_LINE_P (w)))
13840 {
13841 display_mode_lines (w);
13842
13843 /* If mode line height has changed, arrange for a thorough
13844 immediate redisplay using the correct mode line height. */
13845 if (WINDOW_WANTS_MODELINE_P (w)
13846 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13847 {
13848 fonts_changed_p = 1;
13849 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13850 = DESIRED_MODE_LINE_HEIGHT (w);
13851 }
13852
13853 /* If top line height has changed, arrange for a thorough
13854 immediate redisplay using the correct mode line height. */
13855 if (WINDOW_WANTS_HEADER_LINE_P (w)
13856 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13857 {
13858 fonts_changed_p = 1;
13859 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13860 = DESIRED_HEADER_LINE_HEIGHT (w);
13861 }
13862
13863 if (fonts_changed_p)
13864 goto need_larger_matrices;
13865 }
13866
13867 if (!line_number_displayed
13868 && !BUFFERP (w->base_line_pos))
13869 {
13870 w->base_line_pos = Qnil;
13871 w->base_line_number = Qnil;
13872 }
13873
13874 finish_menu_bars:
13875
13876 /* When we reach a frame's selected window, redo the frame's menu bar. */
13877 if (update_mode_line
13878 && EQ (FRAME_SELECTED_WINDOW (f), window))
13879 {
13880 int redisplay_menu_p = 0;
13881 int redisplay_tool_bar_p = 0;
13882
13883 if (FRAME_WINDOW_P (f))
13884 {
13885 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
13886 || defined (HAVE_NS) || defined (USE_GTK)
13887 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13888 #else
13889 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13890 #endif
13891 }
13892 else
13893 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13894
13895 if (redisplay_menu_p)
13896 display_menu_bar (w);
13897
13898 #ifdef HAVE_WINDOW_SYSTEM
13899 if (FRAME_WINDOW_P (f))
13900 {
13901 #if defined (USE_GTK) || defined (HAVE_NS)
13902 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13903 #else
13904 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13905 && (FRAME_TOOL_BAR_LINES (f) > 0
13906 || !NILP (Vauto_resize_tool_bars));
13907 #endif
13908
13909 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13910 {
13911 extern int ignore_mouse_drag_p;
13912 ignore_mouse_drag_p = 1;
13913 }
13914 }
13915 #endif
13916 }
13917
13918 #ifdef HAVE_WINDOW_SYSTEM
13919 if (FRAME_WINDOW_P (f)
13920 && update_window_fringes (w, (just_this_one_p
13921 || (!used_current_matrix_p && !overlay_arrow_seen)
13922 || w->pseudo_window_p)))
13923 {
13924 update_begin (f);
13925 BLOCK_INPUT;
13926 if (draw_window_fringes (w, 1))
13927 x_draw_vertical_border (w);
13928 UNBLOCK_INPUT;
13929 update_end (f);
13930 }
13931 #endif /* HAVE_WINDOW_SYSTEM */
13932
13933 /* We go to this label, with fonts_changed_p nonzero,
13934 if it is necessary to try again using larger glyph matrices.
13935 We have to redeem the scroll bar even in this case,
13936 because the loop in redisplay_internal expects that. */
13937 need_larger_matrices:
13938 ;
13939 finish_scroll_bars:
13940
13941 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13942 {
13943 /* Set the thumb's position and size. */
13944 set_vertical_scroll_bar (w);
13945
13946 /* Note that we actually used the scroll bar attached to this
13947 window, so it shouldn't be deleted at the end of redisplay. */
13948 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13949 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13950 }
13951
13952 /* Restore current_buffer and value of point in it. */
13953 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13954 set_buffer_internal_1 (old);
13955 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13956 shorter. This can be caused by log truncation in *Messages*. */
13957 if (CHARPOS (lpoint) <= ZV)
13958 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13959
13960 unbind_to (count, Qnil);
13961 }
13962
13963
13964 /* Build the complete desired matrix of WINDOW with a window start
13965 buffer position POS.
13966
13967 Value is 1 if successful. It is zero if fonts were loaded during
13968 redisplay which makes re-adjusting glyph matrices necessary, and -1
13969 if point would appear in the scroll margins.
13970 (We check that only if CHECK_MARGINS is nonzero. */
13971
13972 int
13973 try_window (window, pos, check_margins)
13974 Lisp_Object window;
13975 struct text_pos pos;
13976 int check_margins;
13977 {
13978 struct window *w = XWINDOW (window);
13979 struct it it;
13980 struct glyph_row *last_text_row = NULL;
13981 struct frame *f = XFRAME (w->frame);
13982
13983 /* Make POS the new window start. */
13984 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13985
13986 /* Mark cursor position as unknown. No overlay arrow seen. */
13987 w->cursor.vpos = -1;
13988 overlay_arrow_seen = 0;
13989
13990 /* Initialize iterator and info to start at POS. */
13991 start_display (&it, w, pos);
13992
13993 /* Display all lines of W. */
13994 while (it.current_y < it.last_visible_y)
13995 {
13996 if (display_line (&it))
13997 last_text_row = it.glyph_row - 1;
13998 if (fonts_changed_p)
13999 return 0;
14000 }
14001
14002 /* Don't let the cursor end in the scroll margins. */
14003 if (check_margins
14004 && !MINI_WINDOW_P (w))
14005 {
14006 int this_scroll_margin;
14007
14008 if (scroll_margin > 0)
14009 {
14010 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14011 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14012 }
14013 else
14014 this_scroll_margin = 0;
14015
14016 if ((w->cursor.y >= 0 /* not vscrolled */
14017 && w->cursor.y < this_scroll_margin
14018 && CHARPOS (pos) > BEGV
14019 && IT_CHARPOS (it) < ZV)
14020 /* rms: considering make_cursor_line_fully_visible_p here
14021 seems to give wrong results. We don't want to recenter
14022 when the last line is partly visible, we want to allow
14023 that case to be handled in the usual way. */
14024 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14025 {
14026 w->cursor.vpos = -1;
14027 clear_glyph_matrix (w->desired_matrix);
14028 return -1;
14029 }
14030 }
14031
14032 /* If bottom moved off end of frame, change mode line percentage. */
14033 if (XFASTINT (w->window_end_pos) <= 0
14034 && Z != IT_CHARPOS (it))
14035 w->update_mode_line = Qt;
14036
14037 /* Set window_end_pos to the offset of the last character displayed
14038 on the window from the end of current_buffer. Set
14039 window_end_vpos to its row number. */
14040 if (last_text_row)
14041 {
14042 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14043 w->window_end_bytepos
14044 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14045 w->window_end_pos
14046 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14047 w->window_end_vpos
14048 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14049 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14050 ->displays_text_p);
14051 }
14052 else
14053 {
14054 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14055 w->window_end_pos = make_number (Z - ZV);
14056 w->window_end_vpos = make_number (0);
14057 }
14058
14059 /* But that is not valid info until redisplay finishes. */
14060 w->window_end_valid = Qnil;
14061 return 1;
14062 }
14063
14064
14065 \f
14066 /************************************************************************
14067 Window redisplay reusing current matrix when buffer has not changed
14068 ************************************************************************/
14069
14070 /* Try redisplay of window W showing an unchanged buffer with a
14071 different window start than the last time it was displayed by
14072 reusing its current matrix. Value is non-zero if successful.
14073 W->start is the new window start. */
14074
14075 static int
14076 try_window_reusing_current_matrix (w)
14077 struct window *w;
14078 {
14079 struct frame *f = XFRAME (w->frame);
14080 struct glyph_row *row, *bottom_row;
14081 struct it it;
14082 struct run run;
14083 struct text_pos start, new_start;
14084 int nrows_scrolled, i;
14085 struct glyph_row *last_text_row;
14086 struct glyph_row *last_reused_text_row;
14087 struct glyph_row *start_row;
14088 int start_vpos, min_y, max_y;
14089
14090 #if GLYPH_DEBUG
14091 if (inhibit_try_window_reusing)
14092 return 0;
14093 #endif
14094
14095 if (/* This function doesn't handle terminal frames. */
14096 !FRAME_WINDOW_P (f)
14097 /* Don't try to reuse the display if windows have been split
14098 or such. */
14099 || windows_or_buffers_changed
14100 || cursor_type_changed)
14101 return 0;
14102
14103 /* Can't do this if region may have changed. */
14104 if ((!NILP (Vtransient_mark_mode)
14105 && !NILP (current_buffer->mark_active))
14106 || !NILP (w->region_showing)
14107 || !NILP (Vshow_trailing_whitespace))
14108 return 0;
14109
14110 /* If top-line visibility has changed, give up. */
14111 if (WINDOW_WANTS_HEADER_LINE_P (w)
14112 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14113 return 0;
14114
14115 /* Give up if old or new display is scrolled vertically. We could
14116 make this function handle this, but right now it doesn't. */
14117 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14118 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14119 return 0;
14120
14121 /* The variable new_start now holds the new window start. The old
14122 start `start' can be determined from the current matrix. */
14123 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14124 start = start_row->start.pos;
14125 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14126
14127 /* Clear the desired matrix for the display below. */
14128 clear_glyph_matrix (w->desired_matrix);
14129
14130 if (CHARPOS (new_start) <= CHARPOS (start))
14131 {
14132 int first_row_y;
14133
14134 /* Don't use this method if the display starts with an ellipsis
14135 displayed for invisible text. It's not easy to handle that case
14136 below, and it's certainly not worth the effort since this is
14137 not a frequent case. */
14138 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14139 return 0;
14140
14141 IF_DEBUG (debug_method_add (w, "twu1"));
14142
14143 /* Display up to a row that can be reused. The variable
14144 last_text_row is set to the last row displayed that displays
14145 text. Note that it.vpos == 0 if or if not there is a
14146 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14147 start_display (&it, w, new_start);
14148 first_row_y = it.current_y;
14149 w->cursor.vpos = -1;
14150 last_text_row = last_reused_text_row = NULL;
14151
14152 while (it.current_y < it.last_visible_y
14153 && !fonts_changed_p)
14154 {
14155 /* If we have reached into the characters in the START row,
14156 that means the line boundaries have changed. So we
14157 can't start copying with the row START. Maybe it will
14158 work to start copying with the following row. */
14159 while (IT_CHARPOS (it) > CHARPOS (start))
14160 {
14161 /* Advance to the next row as the "start". */
14162 start_row++;
14163 start = start_row->start.pos;
14164 /* If there are no more rows to try, or just one, give up. */
14165 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14166 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14167 || CHARPOS (start) == ZV)
14168 {
14169 clear_glyph_matrix (w->desired_matrix);
14170 return 0;
14171 }
14172
14173 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14174 }
14175 /* If we have reached alignment,
14176 we can copy the rest of the rows. */
14177 if (IT_CHARPOS (it) == CHARPOS (start))
14178 break;
14179
14180 if (display_line (&it))
14181 last_text_row = it.glyph_row - 1;
14182 }
14183
14184 /* A value of current_y < last_visible_y means that we stopped
14185 at the previous window start, which in turn means that we
14186 have at least one reusable row. */
14187 if (it.current_y < it.last_visible_y)
14188 {
14189 /* IT.vpos always starts from 0; it counts text lines. */
14190 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14191
14192 /* Find PT if not already found in the lines displayed. */
14193 if (w->cursor.vpos < 0)
14194 {
14195 int dy = it.current_y - start_row->y;
14196
14197 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14198 row = row_containing_pos (w, PT, row, NULL, dy);
14199 if (row)
14200 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14201 dy, nrows_scrolled);
14202 else
14203 {
14204 clear_glyph_matrix (w->desired_matrix);
14205 return 0;
14206 }
14207 }
14208
14209 /* Scroll the display. Do it before the current matrix is
14210 changed. The problem here is that update has not yet
14211 run, i.e. part of the current matrix is not up to date.
14212 scroll_run_hook will clear the cursor, and use the
14213 current matrix to get the height of the row the cursor is
14214 in. */
14215 run.current_y = start_row->y;
14216 run.desired_y = it.current_y;
14217 run.height = it.last_visible_y - it.current_y;
14218
14219 if (run.height > 0 && run.current_y != run.desired_y)
14220 {
14221 update_begin (f);
14222 FRAME_RIF (f)->update_window_begin_hook (w);
14223 FRAME_RIF (f)->clear_window_mouse_face (w);
14224 FRAME_RIF (f)->scroll_run_hook (w, &run);
14225 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14226 update_end (f);
14227 }
14228
14229 /* Shift current matrix down by nrows_scrolled lines. */
14230 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14231 rotate_matrix (w->current_matrix,
14232 start_vpos,
14233 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14234 nrows_scrolled);
14235
14236 /* Disable lines that must be updated. */
14237 for (i = 0; i < nrows_scrolled; ++i)
14238 (start_row + i)->enabled_p = 0;
14239
14240 /* Re-compute Y positions. */
14241 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14242 max_y = it.last_visible_y;
14243 for (row = start_row + nrows_scrolled;
14244 row < bottom_row;
14245 ++row)
14246 {
14247 row->y = it.current_y;
14248 row->visible_height = row->height;
14249
14250 if (row->y < min_y)
14251 row->visible_height -= min_y - row->y;
14252 if (row->y + row->height > max_y)
14253 row->visible_height -= row->y + row->height - max_y;
14254 row->redraw_fringe_bitmaps_p = 1;
14255
14256 it.current_y += row->height;
14257
14258 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14259 last_reused_text_row = row;
14260 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14261 break;
14262 }
14263
14264 /* Disable lines in the current matrix which are now
14265 below the window. */
14266 for (++row; row < bottom_row; ++row)
14267 row->enabled_p = row->mode_line_p = 0;
14268 }
14269
14270 /* Update window_end_pos etc.; last_reused_text_row is the last
14271 reused row from the current matrix containing text, if any.
14272 The value of last_text_row is the last displayed line
14273 containing text. */
14274 if (last_reused_text_row)
14275 {
14276 w->window_end_bytepos
14277 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14278 w->window_end_pos
14279 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14280 w->window_end_vpos
14281 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14282 w->current_matrix));
14283 }
14284 else if (last_text_row)
14285 {
14286 w->window_end_bytepos
14287 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14288 w->window_end_pos
14289 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14290 w->window_end_vpos
14291 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14292 }
14293 else
14294 {
14295 /* This window must be completely empty. */
14296 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14297 w->window_end_pos = make_number (Z - ZV);
14298 w->window_end_vpos = make_number (0);
14299 }
14300 w->window_end_valid = Qnil;
14301
14302 /* Update hint: don't try scrolling again in update_window. */
14303 w->desired_matrix->no_scrolling_p = 1;
14304
14305 #if GLYPH_DEBUG
14306 debug_method_add (w, "try_window_reusing_current_matrix 1");
14307 #endif
14308 return 1;
14309 }
14310 else if (CHARPOS (new_start) > CHARPOS (start))
14311 {
14312 struct glyph_row *pt_row, *row;
14313 struct glyph_row *first_reusable_row;
14314 struct glyph_row *first_row_to_display;
14315 int dy;
14316 int yb = window_text_bottom_y (w);
14317
14318 /* Find the row starting at new_start, if there is one. Don't
14319 reuse a partially visible line at the end. */
14320 first_reusable_row = start_row;
14321 while (first_reusable_row->enabled_p
14322 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14323 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14324 < CHARPOS (new_start)))
14325 ++first_reusable_row;
14326
14327 /* Give up if there is no row to reuse. */
14328 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14329 || !first_reusable_row->enabled_p
14330 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14331 != CHARPOS (new_start)))
14332 return 0;
14333
14334 /* We can reuse fully visible rows beginning with
14335 first_reusable_row to the end of the window. Set
14336 first_row_to_display to the first row that cannot be reused.
14337 Set pt_row to the row containing point, if there is any. */
14338 pt_row = NULL;
14339 for (first_row_to_display = first_reusable_row;
14340 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14341 ++first_row_to_display)
14342 {
14343 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14344 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14345 pt_row = first_row_to_display;
14346 }
14347
14348 /* Start displaying at the start of first_row_to_display. */
14349 xassert (first_row_to_display->y < yb);
14350 init_to_row_start (&it, w, first_row_to_display);
14351
14352 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14353 - start_vpos);
14354 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14355 - nrows_scrolled);
14356 it.current_y = (first_row_to_display->y - first_reusable_row->y
14357 + WINDOW_HEADER_LINE_HEIGHT (w));
14358
14359 /* Display lines beginning with first_row_to_display in the
14360 desired matrix. Set last_text_row to the last row displayed
14361 that displays text. */
14362 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14363 if (pt_row == NULL)
14364 w->cursor.vpos = -1;
14365 last_text_row = NULL;
14366 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14367 if (display_line (&it))
14368 last_text_row = it.glyph_row - 1;
14369
14370 /* If point is in a reused row, adjust y and vpos of the cursor
14371 position. */
14372 if (pt_row)
14373 {
14374 w->cursor.vpos -= nrows_scrolled;
14375 w->cursor.y -= first_reusable_row->y - start_row->y;
14376 }
14377
14378 /* Give up if point isn't in a row displayed or reused. (This
14379 also handles the case where w->cursor.vpos < nrows_scrolled
14380 after the calls to display_line, which can happen with scroll
14381 margins. See bug#1295.) */
14382 if (w->cursor.vpos < 0)
14383 {
14384 clear_glyph_matrix (w->desired_matrix);
14385 return 0;
14386 }
14387
14388 /* Scroll the display. */
14389 run.current_y = first_reusable_row->y;
14390 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14391 run.height = it.last_visible_y - run.current_y;
14392 dy = run.current_y - run.desired_y;
14393
14394 if (run.height)
14395 {
14396 update_begin (f);
14397 FRAME_RIF (f)->update_window_begin_hook (w);
14398 FRAME_RIF (f)->clear_window_mouse_face (w);
14399 FRAME_RIF (f)->scroll_run_hook (w, &run);
14400 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14401 update_end (f);
14402 }
14403
14404 /* Adjust Y positions of reused rows. */
14405 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14406 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14407 max_y = it.last_visible_y;
14408 for (row = first_reusable_row; row < first_row_to_display; ++row)
14409 {
14410 row->y -= dy;
14411 row->visible_height = row->height;
14412 if (row->y < min_y)
14413 row->visible_height -= min_y - row->y;
14414 if (row->y + row->height > max_y)
14415 row->visible_height -= row->y + row->height - max_y;
14416 row->redraw_fringe_bitmaps_p = 1;
14417 }
14418
14419 /* Scroll the current matrix. */
14420 xassert (nrows_scrolled > 0);
14421 rotate_matrix (w->current_matrix,
14422 start_vpos,
14423 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14424 -nrows_scrolled);
14425
14426 /* Disable rows not reused. */
14427 for (row -= nrows_scrolled; row < bottom_row; ++row)
14428 row->enabled_p = 0;
14429
14430 /* Point may have moved to a different line, so we cannot assume that
14431 the previous cursor position is valid; locate the correct row. */
14432 if (pt_row)
14433 {
14434 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14435 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14436 row++)
14437 {
14438 w->cursor.vpos++;
14439 w->cursor.y = row->y;
14440 }
14441 if (row < bottom_row)
14442 {
14443 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14444 struct glyph *end = glyph + row->used[TEXT_AREA];
14445
14446 for (; glyph < end
14447 && (!BUFFERP (glyph->object)
14448 || glyph->charpos < PT);
14449 glyph++)
14450 {
14451 w->cursor.hpos++;
14452 w->cursor.x += glyph->pixel_width;
14453 }
14454 }
14455 }
14456
14457 /* Adjust window end. A null value of last_text_row means that
14458 the window end is in reused rows which in turn means that
14459 only its vpos can have changed. */
14460 if (last_text_row)
14461 {
14462 w->window_end_bytepos
14463 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14464 w->window_end_pos
14465 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14466 w->window_end_vpos
14467 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14468 }
14469 else
14470 {
14471 w->window_end_vpos
14472 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14473 }
14474
14475 w->window_end_valid = Qnil;
14476 w->desired_matrix->no_scrolling_p = 1;
14477
14478 #if GLYPH_DEBUG
14479 debug_method_add (w, "try_window_reusing_current_matrix 2");
14480 #endif
14481 return 1;
14482 }
14483
14484 return 0;
14485 }
14486
14487
14488 \f
14489 /************************************************************************
14490 Window redisplay reusing current matrix when buffer has changed
14491 ************************************************************************/
14492
14493 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14494 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14495 int *, int *));
14496 static struct glyph_row *
14497 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14498 struct glyph_row *));
14499
14500
14501 /* Return the last row in MATRIX displaying text. If row START is
14502 non-null, start searching with that row. IT gives the dimensions
14503 of the display. Value is null if matrix is empty; otherwise it is
14504 a pointer to the row found. */
14505
14506 static struct glyph_row *
14507 find_last_row_displaying_text (matrix, it, start)
14508 struct glyph_matrix *matrix;
14509 struct it *it;
14510 struct glyph_row *start;
14511 {
14512 struct glyph_row *row, *row_found;
14513
14514 /* Set row_found to the last row in IT->w's current matrix
14515 displaying text. The loop looks funny but think of partially
14516 visible lines. */
14517 row_found = NULL;
14518 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14519 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14520 {
14521 xassert (row->enabled_p);
14522 row_found = row;
14523 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14524 break;
14525 ++row;
14526 }
14527
14528 return row_found;
14529 }
14530
14531
14532 /* Return the last row in the current matrix of W that is not affected
14533 by changes at the start of current_buffer that occurred since W's
14534 current matrix was built. Value is null if no such row exists.
14535
14536 BEG_UNCHANGED us the number of characters unchanged at the start of
14537 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14538 first changed character in current_buffer. Characters at positions <
14539 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14540 when the current matrix was built. */
14541
14542 static struct glyph_row *
14543 find_last_unchanged_at_beg_row (w)
14544 struct window *w;
14545 {
14546 int first_changed_pos = BEG + BEG_UNCHANGED;
14547 struct glyph_row *row;
14548 struct glyph_row *row_found = NULL;
14549 int yb = window_text_bottom_y (w);
14550
14551 /* Find the last row displaying unchanged text. */
14552 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14553 MATRIX_ROW_DISPLAYS_TEXT_P (row)
14554 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
14555 ++row)
14556 {
14557 if (/* If row ends before first_changed_pos, it is unchanged,
14558 except in some case. */
14559 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14560 /* When row ends in ZV and we write at ZV it is not
14561 unchanged. */
14562 && !row->ends_at_zv_p
14563 /* When first_changed_pos is the end of a continued line,
14564 row is not unchanged because it may be no longer
14565 continued. */
14566 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14567 && (row->continued_p
14568 || row->exact_window_width_line_p)))
14569 row_found = row;
14570
14571 /* Stop if last visible row. */
14572 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14573 break;
14574 }
14575
14576 return row_found;
14577 }
14578
14579
14580 /* Find the first glyph row in the current matrix of W that is not
14581 affected by changes at the end of current_buffer since the
14582 time W's current matrix was built.
14583
14584 Return in *DELTA the number of chars by which buffer positions in
14585 unchanged text at the end of current_buffer must be adjusted.
14586
14587 Return in *DELTA_BYTES the corresponding number of bytes.
14588
14589 Value is null if no such row exists, i.e. all rows are affected by
14590 changes. */
14591
14592 static struct glyph_row *
14593 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14594 struct window *w;
14595 int *delta, *delta_bytes;
14596 {
14597 struct glyph_row *row;
14598 struct glyph_row *row_found = NULL;
14599
14600 *delta = *delta_bytes = 0;
14601
14602 /* Display must not have been paused, otherwise the current matrix
14603 is not up to date. */
14604 eassert (!NILP (w->window_end_valid));
14605
14606 /* A value of window_end_pos >= END_UNCHANGED means that the window
14607 end is in the range of changed text. If so, there is no
14608 unchanged row at the end of W's current matrix. */
14609 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14610 return NULL;
14611
14612 /* Set row to the last row in W's current matrix displaying text. */
14613 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14614
14615 /* If matrix is entirely empty, no unchanged row exists. */
14616 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14617 {
14618 /* The value of row is the last glyph row in the matrix having a
14619 meaningful buffer position in it. The end position of row
14620 corresponds to window_end_pos. This allows us to translate
14621 buffer positions in the current matrix to current buffer
14622 positions for characters not in changed text. */
14623 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14624 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14625 int last_unchanged_pos, last_unchanged_pos_old;
14626 struct glyph_row *first_text_row
14627 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14628
14629 *delta = Z - Z_old;
14630 *delta_bytes = Z_BYTE - Z_BYTE_old;
14631
14632 /* Set last_unchanged_pos to the buffer position of the last
14633 character in the buffer that has not been changed. Z is the
14634 index + 1 of the last character in current_buffer, i.e. by
14635 subtracting END_UNCHANGED we get the index of the last
14636 unchanged character, and we have to add BEG to get its buffer
14637 position. */
14638 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14639 last_unchanged_pos_old = last_unchanged_pos - *delta;
14640
14641 /* Search backward from ROW for a row displaying a line that
14642 starts at a minimum position >= last_unchanged_pos_old. */
14643 for (; row > first_text_row; --row)
14644 {
14645 /* This used to abort, but it can happen.
14646 It is ok to just stop the search instead here. KFS. */
14647 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14648 break;
14649
14650 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14651 row_found = row;
14652 }
14653 }
14654
14655 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
14656
14657 return row_found;
14658 }
14659
14660
14661 /* Make sure that glyph rows in the current matrix of window W
14662 reference the same glyph memory as corresponding rows in the
14663 frame's frame matrix. This function is called after scrolling W's
14664 current matrix on a terminal frame in try_window_id and
14665 try_window_reusing_current_matrix. */
14666
14667 static void
14668 sync_frame_with_window_matrix_rows (w)
14669 struct window *w;
14670 {
14671 struct frame *f = XFRAME (w->frame);
14672 struct glyph_row *window_row, *window_row_end, *frame_row;
14673
14674 /* Preconditions: W must be a leaf window and full-width. Its frame
14675 must have a frame matrix. */
14676 xassert (NILP (w->hchild) && NILP (w->vchild));
14677 xassert (WINDOW_FULL_WIDTH_P (w));
14678 xassert (!FRAME_WINDOW_P (f));
14679
14680 /* If W is a full-width window, glyph pointers in W's current matrix
14681 have, by definition, to be the same as glyph pointers in the
14682 corresponding frame matrix. Note that frame matrices have no
14683 marginal areas (see build_frame_matrix). */
14684 window_row = w->current_matrix->rows;
14685 window_row_end = window_row + w->current_matrix->nrows;
14686 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14687 while (window_row < window_row_end)
14688 {
14689 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14690 struct glyph *end = window_row->glyphs[LAST_AREA];
14691
14692 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14693 frame_row->glyphs[TEXT_AREA] = start;
14694 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14695 frame_row->glyphs[LAST_AREA] = end;
14696
14697 /* Disable frame rows whose corresponding window rows have
14698 been disabled in try_window_id. */
14699 if (!window_row->enabled_p)
14700 frame_row->enabled_p = 0;
14701
14702 ++window_row, ++frame_row;
14703 }
14704 }
14705
14706
14707 /* Find the glyph row in window W containing CHARPOS. Consider all
14708 rows between START and END (not inclusive). END null means search
14709 all rows to the end of the display area of W. Value is the row
14710 containing CHARPOS or null. */
14711
14712 struct glyph_row *
14713 row_containing_pos (w, charpos, start, end, dy)
14714 struct window *w;
14715 int charpos;
14716 struct glyph_row *start, *end;
14717 int dy;
14718 {
14719 struct glyph_row *row = start;
14720 int last_y;
14721
14722 /* If we happen to start on a header-line, skip that. */
14723 if (row->mode_line_p)
14724 ++row;
14725
14726 if ((end && row >= end) || !row->enabled_p)
14727 return NULL;
14728
14729 last_y = window_text_bottom_y (w) - dy;
14730
14731 while (1)
14732 {
14733 /* Give up if we have gone too far. */
14734 if (end && row >= end)
14735 return NULL;
14736 /* This formerly returned if they were equal.
14737 I think that both quantities are of a "last plus one" type;
14738 if so, when they are equal, the row is within the screen. -- rms. */
14739 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14740 return NULL;
14741
14742 /* If it is in this row, return this row. */
14743 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14744 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14745 /* The end position of a row equals the start
14746 position of the next row. If CHARPOS is there, we
14747 would rather display it in the next line, except
14748 when this line ends in ZV. */
14749 && !row->ends_at_zv_p
14750 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14751 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14752 return row;
14753 ++row;
14754 }
14755 }
14756
14757
14758 /* Try to redisplay window W by reusing its existing display. W's
14759 current matrix must be up to date when this function is called,
14760 i.e. window_end_valid must not be nil.
14761
14762 Value is
14763
14764 1 if display has been updated
14765 0 if otherwise unsuccessful
14766 -1 if redisplay with same window start is known not to succeed
14767
14768 The following steps are performed:
14769
14770 1. Find the last row in the current matrix of W that is not
14771 affected by changes at the start of current_buffer. If no such row
14772 is found, give up.
14773
14774 2. Find the first row in W's current matrix that is not affected by
14775 changes at the end of current_buffer. Maybe there is no such row.
14776
14777 3. Display lines beginning with the row + 1 found in step 1 to the
14778 row found in step 2 or, if step 2 didn't find a row, to the end of
14779 the window.
14780
14781 4. If cursor is not known to appear on the window, give up.
14782
14783 5. If display stopped at the row found in step 2, scroll the
14784 display and current matrix as needed.
14785
14786 6. Maybe display some lines at the end of W, if we must. This can
14787 happen under various circumstances, like a partially visible line
14788 becoming fully visible, or because newly displayed lines are displayed
14789 in smaller font sizes.
14790
14791 7. Update W's window end information. */
14792
14793 static int
14794 try_window_id (w)
14795 struct window *w;
14796 {
14797 struct frame *f = XFRAME (w->frame);
14798 struct glyph_matrix *current_matrix = w->current_matrix;
14799 struct glyph_matrix *desired_matrix = w->desired_matrix;
14800 struct glyph_row *last_unchanged_at_beg_row;
14801 struct glyph_row *first_unchanged_at_end_row;
14802 struct glyph_row *row;
14803 struct glyph_row *bottom_row;
14804 int bottom_vpos;
14805 struct it it;
14806 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14807 struct text_pos start_pos;
14808 struct run run;
14809 int first_unchanged_at_end_vpos = 0;
14810 struct glyph_row *last_text_row, *last_text_row_at_end;
14811 struct text_pos start;
14812 int first_changed_charpos, last_changed_charpos;
14813
14814 #if GLYPH_DEBUG
14815 if (inhibit_try_window_id)
14816 return 0;
14817 #endif
14818
14819 /* This is handy for debugging. */
14820 #if 0
14821 #define GIVE_UP(X) \
14822 do { \
14823 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14824 return 0; \
14825 } while (0)
14826 #else
14827 #define GIVE_UP(X) return 0
14828 #endif
14829
14830 SET_TEXT_POS_FROM_MARKER (start, w->start);
14831
14832 /* Don't use this for mini-windows because these can show
14833 messages and mini-buffers, and we don't handle that here. */
14834 if (MINI_WINDOW_P (w))
14835 GIVE_UP (1);
14836
14837 /* This flag is used to prevent redisplay optimizations. */
14838 if (windows_or_buffers_changed || cursor_type_changed)
14839 GIVE_UP (2);
14840
14841 /* Verify that narrowing has not changed.
14842 Also verify that we were not told to prevent redisplay optimizations.
14843 It would be nice to further
14844 reduce the number of cases where this prevents try_window_id. */
14845 if (current_buffer->clip_changed
14846 || current_buffer->prevent_redisplay_optimizations_p)
14847 GIVE_UP (3);
14848
14849 /* Window must either use window-based redisplay or be full width. */
14850 if (!FRAME_WINDOW_P (f)
14851 && (!FRAME_LINE_INS_DEL_OK (f)
14852 || !WINDOW_FULL_WIDTH_P (w)))
14853 GIVE_UP (4);
14854
14855 /* Give up if point is not known NOT to appear in W. */
14856 if (PT < CHARPOS (start))
14857 GIVE_UP (5);
14858
14859 /* Another way to prevent redisplay optimizations. */
14860 if (XFASTINT (w->last_modified) == 0)
14861 GIVE_UP (6);
14862
14863 /* Verify that window is not hscrolled. */
14864 if (XFASTINT (w->hscroll) != 0)
14865 GIVE_UP (7);
14866
14867 /* Verify that display wasn't paused. */
14868 if (NILP (w->window_end_valid))
14869 GIVE_UP (8);
14870
14871 /* Can't use this if highlighting a region because a cursor movement
14872 will do more than just set the cursor. */
14873 if (!NILP (Vtransient_mark_mode)
14874 && !NILP (current_buffer->mark_active))
14875 GIVE_UP (9);
14876
14877 /* Likewise if highlighting trailing whitespace. */
14878 if (!NILP (Vshow_trailing_whitespace))
14879 GIVE_UP (11);
14880
14881 /* Likewise if showing a region. */
14882 if (!NILP (w->region_showing))
14883 GIVE_UP (10);
14884
14885 /* Can use this if overlay arrow position and or string have changed. */
14886 if (overlay_arrows_changed_p ())
14887 GIVE_UP (12);
14888
14889 /* When word-wrap is on, adding a space to the first word of a
14890 wrapped line can change the wrap position, altering the line
14891 above it. It might be worthwhile to handle this more
14892 intelligently, but for now just redisplay from scratch. */
14893 if (!NILP (XBUFFER (w->buffer)->word_wrap))
14894 GIVE_UP (21);
14895
14896 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14897 only if buffer has really changed. The reason is that the gap is
14898 initially at Z for freshly visited files. The code below would
14899 set end_unchanged to 0 in that case. */
14900 if (MODIFF > SAVE_MODIFF
14901 /* This seems to happen sometimes after saving a buffer. */
14902 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14903 {
14904 if (GPT - BEG < BEG_UNCHANGED)
14905 BEG_UNCHANGED = GPT - BEG;
14906 if (Z - GPT < END_UNCHANGED)
14907 END_UNCHANGED = Z - GPT;
14908 }
14909
14910 /* The position of the first and last character that has been changed. */
14911 first_changed_charpos = BEG + BEG_UNCHANGED;
14912 last_changed_charpos = Z - END_UNCHANGED;
14913
14914 /* If window starts after a line end, and the last change is in
14915 front of that newline, then changes don't affect the display.
14916 This case happens with stealth-fontification. Note that although
14917 the display is unchanged, glyph positions in the matrix have to
14918 be adjusted, of course. */
14919 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14920 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14921 && ((last_changed_charpos < CHARPOS (start)
14922 && CHARPOS (start) == BEGV)
14923 || (last_changed_charpos < CHARPOS (start) - 1
14924 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14925 {
14926 int Z_old, delta, Z_BYTE_old, delta_bytes;
14927 struct glyph_row *r0;
14928
14929 /* Compute how many chars/bytes have been added to or removed
14930 from the buffer. */
14931 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14932 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14933 delta = Z - Z_old;
14934 delta_bytes = Z_BYTE - Z_BYTE_old;
14935
14936 /* Give up if PT is not in the window. Note that it already has
14937 been checked at the start of try_window_id that PT is not in
14938 front of the window start. */
14939 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14940 GIVE_UP (13);
14941
14942 /* If window start is unchanged, we can reuse the whole matrix
14943 as is, after adjusting glyph positions. No need to compute
14944 the window end again, since its offset from Z hasn't changed. */
14945 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14946 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14947 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14948 /* PT must not be in a partially visible line. */
14949 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14950 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14951 {
14952 /* Adjust positions in the glyph matrix. */
14953 if (delta || delta_bytes)
14954 {
14955 struct glyph_row *r1
14956 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14957 increment_matrix_positions (w->current_matrix,
14958 MATRIX_ROW_VPOS (r0, current_matrix),
14959 MATRIX_ROW_VPOS (r1, current_matrix),
14960 delta, delta_bytes);
14961 }
14962
14963 /* Set the cursor. */
14964 row = row_containing_pos (w, PT, r0, NULL, 0);
14965 if (row)
14966 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14967 else
14968 abort ();
14969 return 1;
14970 }
14971 }
14972
14973 /* Handle the case that changes are all below what is displayed in
14974 the window, and that PT is in the window. This shortcut cannot
14975 be taken if ZV is visible in the window, and text has been added
14976 there that is visible in the window. */
14977 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14978 /* ZV is not visible in the window, or there are no
14979 changes at ZV, actually. */
14980 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14981 || first_changed_charpos == last_changed_charpos))
14982 {
14983 struct glyph_row *r0;
14984
14985 /* Give up if PT is not in the window. Note that it already has
14986 been checked at the start of try_window_id that PT is not in
14987 front of the window start. */
14988 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14989 GIVE_UP (14);
14990
14991 /* If window start is unchanged, we can reuse the whole matrix
14992 as is, without changing glyph positions since no text has
14993 been added/removed in front of the window end. */
14994 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14995 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14996 /* PT must not be in a partially visible line. */
14997 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14998 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14999 {
15000 /* We have to compute the window end anew since text
15001 can have been added/removed after it. */
15002 w->window_end_pos
15003 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15004 w->window_end_bytepos
15005 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15006
15007 /* Set the cursor. */
15008 row = row_containing_pos (w, PT, r0, NULL, 0);
15009 if (row)
15010 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15011 else
15012 abort ();
15013 return 2;
15014 }
15015 }
15016
15017 /* Give up if window start is in the changed area.
15018
15019 The condition used to read
15020
15021 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15022
15023 but why that was tested escapes me at the moment. */
15024 if (CHARPOS (start) >= first_changed_charpos
15025 && CHARPOS (start) <= last_changed_charpos)
15026 GIVE_UP (15);
15027
15028 /* Check that window start agrees with the start of the first glyph
15029 row in its current matrix. Check this after we know the window
15030 start is not in changed text, otherwise positions would not be
15031 comparable. */
15032 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15033 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
15034 GIVE_UP (16);
15035
15036 /* Give up if the window ends in strings. Overlay strings
15037 at the end are difficult to handle, so don't try. */
15038 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15039 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15040 GIVE_UP (20);
15041
15042 /* Compute the position at which we have to start displaying new
15043 lines. Some of the lines at the top of the window might be
15044 reusable because they are not displaying changed text. Find the
15045 last row in W's current matrix not affected by changes at the
15046 start of current_buffer. Value is null if changes start in the
15047 first line of window. */
15048 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15049 if (last_unchanged_at_beg_row)
15050 {
15051 /* Avoid starting to display in the moddle of a character, a TAB
15052 for instance. This is easier than to set up the iterator
15053 exactly, and it's not a frequent case, so the additional
15054 effort wouldn't really pay off. */
15055 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15056 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15057 && last_unchanged_at_beg_row > w->current_matrix->rows)
15058 --last_unchanged_at_beg_row;
15059
15060 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15061 GIVE_UP (17);
15062
15063 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15064 GIVE_UP (18);
15065 start_pos = it.current.pos;
15066
15067 /* Start displaying new lines in the desired matrix at the same
15068 vpos we would use in the current matrix, i.e. below
15069 last_unchanged_at_beg_row. */
15070 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15071 current_matrix);
15072 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15073 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15074
15075 xassert (it.hpos == 0 && it.current_x == 0);
15076 }
15077 else
15078 {
15079 /* There are no reusable lines at the start of the window.
15080 Start displaying in the first text line. */
15081 start_display (&it, w, start);
15082 it.vpos = it.first_vpos;
15083 start_pos = it.current.pos;
15084 }
15085
15086 /* Find the first row that is not affected by changes at the end of
15087 the buffer. Value will be null if there is no unchanged row, in
15088 which case we must redisplay to the end of the window. delta
15089 will be set to the value by which buffer positions beginning with
15090 first_unchanged_at_end_row have to be adjusted due to text
15091 changes. */
15092 first_unchanged_at_end_row
15093 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15094 IF_DEBUG (debug_delta = delta);
15095 IF_DEBUG (debug_delta_bytes = delta_bytes);
15096
15097 /* Set stop_pos to the buffer position up to which we will have to
15098 display new lines. If first_unchanged_at_end_row != NULL, this
15099 is the buffer position of the start of the line displayed in that
15100 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15101 that we don't stop at a buffer position. */
15102 stop_pos = 0;
15103 if (first_unchanged_at_end_row)
15104 {
15105 xassert (last_unchanged_at_beg_row == NULL
15106 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15107
15108 /* If this is a continuation line, move forward to the next one
15109 that isn't. Changes in lines above affect this line.
15110 Caution: this may move first_unchanged_at_end_row to a row
15111 not displaying text. */
15112 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15113 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15114 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15115 < it.last_visible_y))
15116 ++first_unchanged_at_end_row;
15117
15118 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15119 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15120 >= it.last_visible_y))
15121 first_unchanged_at_end_row = NULL;
15122 else
15123 {
15124 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15125 + delta);
15126 first_unchanged_at_end_vpos
15127 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15128 xassert (stop_pos >= Z - END_UNCHANGED);
15129 }
15130 }
15131 else if (last_unchanged_at_beg_row == NULL)
15132 GIVE_UP (19);
15133
15134
15135 #if GLYPH_DEBUG
15136
15137 /* Either there is no unchanged row at the end, or the one we have
15138 now displays text. This is a necessary condition for the window
15139 end pos calculation at the end of this function. */
15140 xassert (first_unchanged_at_end_row == NULL
15141 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15142
15143 debug_last_unchanged_at_beg_vpos
15144 = (last_unchanged_at_beg_row
15145 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15146 : -1);
15147 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15148
15149 #endif /* GLYPH_DEBUG != 0 */
15150
15151
15152 /* Display new lines. Set last_text_row to the last new line
15153 displayed which has text on it, i.e. might end up as being the
15154 line where the window_end_vpos is. */
15155 w->cursor.vpos = -1;
15156 last_text_row = NULL;
15157 overlay_arrow_seen = 0;
15158 while (it.current_y < it.last_visible_y
15159 && !fonts_changed_p
15160 && (first_unchanged_at_end_row == NULL
15161 || IT_CHARPOS (it) < stop_pos))
15162 {
15163 if (display_line (&it))
15164 last_text_row = it.glyph_row - 1;
15165 }
15166
15167 if (fonts_changed_p)
15168 return -1;
15169
15170
15171 /* Compute differences in buffer positions, y-positions etc. for
15172 lines reused at the bottom of the window. Compute what we can
15173 scroll. */
15174 if (first_unchanged_at_end_row
15175 /* No lines reused because we displayed everything up to the
15176 bottom of the window. */
15177 && it.current_y < it.last_visible_y)
15178 {
15179 dvpos = (it.vpos
15180 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15181 current_matrix));
15182 dy = it.current_y - first_unchanged_at_end_row->y;
15183 run.current_y = first_unchanged_at_end_row->y;
15184 run.desired_y = run.current_y + dy;
15185 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15186 }
15187 else
15188 {
15189 delta = delta_bytes = dvpos = dy
15190 = run.current_y = run.desired_y = run.height = 0;
15191 first_unchanged_at_end_row = NULL;
15192 }
15193 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15194
15195
15196 /* Find the cursor if not already found. We have to decide whether
15197 PT will appear on this window (it sometimes doesn't, but this is
15198 not a very frequent case.) This decision has to be made before
15199 the current matrix is altered. A value of cursor.vpos < 0 means
15200 that PT is either in one of the lines beginning at
15201 first_unchanged_at_end_row or below the window. Don't care for
15202 lines that might be displayed later at the window end; as
15203 mentioned, this is not a frequent case. */
15204 if (w->cursor.vpos < 0)
15205 {
15206 /* Cursor in unchanged rows at the top? */
15207 if (PT < CHARPOS (start_pos)
15208 && last_unchanged_at_beg_row)
15209 {
15210 row = row_containing_pos (w, PT,
15211 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15212 last_unchanged_at_beg_row + 1, 0);
15213 if (row)
15214 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15215 }
15216
15217 /* Start from first_unchanged_at_end_row looking for PT. */
15218 else if (first_unchanged_at_end_row)
15219 {
15220 row = row_containing_pos (w, PT - delta,
15221 first_unchanged_at_end_row, NULL, 0);
15222 if (row)
15223 set_cursor_from_row (w, row, w->current_matrix, delta,
15224 delta_bytes, dy, dvpos);
15225 }
15226
15227 /* Give up if cursor was not found. */
15228 if (w->cursor.vpos < 0)
15229 {
15230 clear_glyph_matrix (w->desired_matrix);
15231 return -1;
15232 }
15233 }
15234
15235 /* Don't let the cursor end in the scroll margins. */
15236 {
15237 int this_scroll_margin, cursor_height;
15238
15239 this_scroll_margin = max (0, scroll_margin);
15240 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15241 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15242 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15243
15244 if ((w->cursor.y < this_scroll_margin
15245 && CHARPOS (start) > BEGV)
15246 /* Old redisplay didn't take scroll margin into account at the bottom,
15247 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15248 || (w->cursor.y + (make_cursor_line_fully_visible_p
15249 ? cursor_height + this_scroll_margin
15250 : 1)) > it.last_visible_y)
15251 {
15252 w->cursor.vpos = -1;
15253 clear_glyph_matrix (w->desired_matrix);
15254 return -1;
15255 }
15256 }
15257
15258 /* Scroll the display. Do it before changing the current matrix so
15259 that xterm.c doesn't get confused about where the cursor glyph is
15260 found. */
15261 if (dy && run.height)
15262 {
15263 update_begin (f);
15264
15265 if (FRAME_WINDOW_P (f))
15266 {
15267 FRAME_RIF (f)->update_window_begin_hook (w);
15268 FRAME_RIF (f)->clear_window_mouse_face (w);
15269 FRAME_RIF (f)->scroll_run_hook (w, &run);
15270 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15271 }
15272 else
15273 {
15274 /* Terminal frame. In this case, dvpos gives the number of
15275 lines to scroll by; dvpos < 0 means scroll up. */
15276 int first_unchanged_at_end_vpos
15277 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15278 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15279 int end = (WINDOW_TOP_EDGE_LINE (w)
15280 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15281 + window_internal_height (w));
15282
15283 /* Perform the operation on the screen. */
15284 if (dvpos > 0)
15285 {
15286 /* Scroll last_unchanged_at_beg_row to the end of the
15287 window down dvpos lines. */
15288 set_terminal_window (f, end);
15289
15290 /* On dumb terminals delete dvpos lines at the end
15291 before inserting dvpos empty lines. */
15292 if (!FRAME_SCROLL_REGION_OK (f))
15293 ins_del_lines (f, end - dvpos, -dvpos);
15294
15295 /* Insert dvpos empty lines in front of
15296 last_unchanged_at_beg_row. */
15297 ins_del_lines (f, from, dvpos);
15298 }
15299 else if (dvpos < 0)
15300 {
15301 /* Scroll up last_unchanged_at_beg_vpos to the end of
15302 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15303 set_terminal_window (f, end);
15304
15305 /* Delete dvpos lines in front of
15306 last_unchanged_at_beg_vpos. ins_del_lines will set
15307 the cursor to the given vpos and emit |dvpos| delete
15308 line sequences. */
15309 ins_del_lines (f, from + dvpos, dvpos);
15310
15311 /* On a dumb terminal insert dvpos empty lines at the
15312 end. */
15313 if (!FRAME_SCROLL_REGION_OK (f))
15314 ins_del_lines (f, end + dvpos, -dvpos);
15315 }
15316
15317 set_terminal_window (f, 0);
15318 }
15319
15320 update_end (f);
15321 }
15322
15323 /* Shift reused rows of the current matrix to the right position.
15324 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15325 text. */
15326 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15327 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15328 if (dvpos < 0)
15329 {
15330 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15331 bottom_vpos, dvpos);
15332 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15333 bottom_vpos, 0);
15334 }
15335 else if (dvpos > 0)
15336 {
15337 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15338 bottom_vpos, dvpos);
15339 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15340 first_unchanged_at_end_vpos + dvpos, 0);
15341 }
15342
15343 /* For frame-based redisplay, make sure that current frame and window
15344 matrix are in sync with respect to glyph memory. */
15345 if (!FRAME_WINDOW_P (f))
15346 sync_frame_with_window_matrix_rows (w);
15347
15348 /* Adjust buffer positions in reused rows. */
15349 if (delta || delta_bytes)
15350 increment_matrix_positions (current_matrix,
15351 first_unchanged_at_end_vpos + dvpos,
15352 bottom_vpos, delta, delta_bytes);
15353
15354 /* Adjust Y positions. */
15355 if (dy)
15356 shift_glyph_matrix (w, current_matrix,
15357 first_unchanged_at_end_vpos + dvpos,
15358 bottom_vpos, dy);
15359
15360 if (first_unchanged_at_end_row)
15361 {
15362 first_unchanged_at_end_row += dvpos;
15363 if (first_unchanged_at_end_row->y >= it.last_visible_y
15364 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15365 first_unchanged_at_end_row = NULL;
15366 }
15367
15368 /* If scrolling up, there may be some lines to display at the end of
15369 the window. */
15370 last_text_row_at_end = NULL;
15371 if (dy < 0)
15372 {
15373 /* Scrolling up can leave for example a partially visible line
15374 at the end of the window to be redisplayed. */
15375 /* Set last_row to the glyph row in the current matrix where the
15376 window end line is found. It has been moved up or down in
15377 the matrix by dvpos. */
15378 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15379 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15380
15381 /* If last_row is the window end line, it should display text. */
15382 xassert (last_row->displays_text_p);
15383
15384 /* If window end line was partially visible before, begin
15385 displaying at that line. Otherwise begin displaying with the
15386 line following it. */
15387 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
15388 {
15389 init_to_row_start (&it, w, last_row);
15390 it.vpos = last_vpos;
15391 it.current_y = last_row->y;
15392 }
15393 else
15394 {
15395 init_to_row_end (&it, w, last_row);
15396 it.vpos = 1 + last_vpos;
15397 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
15398 ++last_row;
15399 }
15400
15401 /* We may start in a continuation line. If so, we have to
15402 get the right continuation_lines_width and current_x. */
15403 it.continuation_lines_width = last_row->continuation_lines_width;
15404 it.hpos = it.current_x = 0;
15405
15406 /* Display the rest of the lines at the window end. */
15407 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15408 while (it.current_y < it.last_visible_y
15409 && !fonts_changed_p)
15410 {
15411 /* Is it always sure that the display agrees with lines in
15412 the current matrix? I don't think so, so we mark rows
15413 displayed invalid in the current matrix by setting their
15414 enabled_p flag to zero. */
15415 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15416 if (display_line (&it))
15417 last_text_row_at_end = it.glyph_row - 1;
15418 }
15419 }
15420
15421 /* Update window_end_pos and window_end_vpos. */
15422 if (first_unchanged_at_end_row
15423 && !last_text_row_at_end)
15424 {
15425 /* Window end line if one of the preserved rows from the current
15426 matrix. Set row to the last row displaying text in current
15427 matrix starting at first_unchanged_at_end_row, after
15428 scrolling. */
15429 xassert (first_unchanged_at_end_row->displays_text_p);
15430 row = find_last_row_displaying_text (w->current_matrix, &it,
15431 first_unchanged_at_end_row);
15432 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15433
15434 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15435 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15436 w->window_end_vpos
15437 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15438 xassert (w->window_end_bytepos >= 0);
15439 IF_DEBUG (debug_method_add (w, "A"));
15440 }
15441 else if (last_text_row_at_end)
15442 {
15443 w->window_end_pos
15444 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15445 w->window_end_bytepos
15446 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15447 w->window_end_vpos
15448 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15449 xassert (w->window_end_bytepos >= 0);
15450 IF_DEBUG (debug_method_add (w, "B"));
15451 }
15452 else if (last_text_row)
15453 {
15454 /* We have displayed either to the end of the window or at the
15455 end of the window, i.e. the last row with text is to be found
15456 in the desired matrix. */
15457 w->window_end_pos
15458 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15459 w->window_end_bytepos
15460 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15461 w->window_end_vpos
15462 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15463 xassert (w->window_end_bytepos >= 0);
15464 }
15465 else if (first_unchanged_at_end_row == NULL
15466 && last_text_row == NULL
15467 && last_text_row_at_end == NULL)
15468 {
15469 /* Displayed to end of window, but no line containing text was
15470 displayed. Lines were deleted at the end of the window. */
15471 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15472 int vpos = XFASTINT (w->window_end_vpos);
15473 struct glyph_row *current_row = current_matrix->rows + vpos;
15474 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15475
15476 for (row = NULL;
15477 row == NULL && vpos >= first_vpos;
15478 --vpos, --current_row, --desired_row)
15479 {
15480 if (desired_row->enabled_p)
15481 {
15482 if (desired_row->displays_text_p)
15483 row = desired_row;
15484 }
15485 else if (current_row->displays_text_p)
15486 row = current_row;
15487 }
15488
15489 xassert (row != NULL);
15490 w->window_end_vpos = make_number (vpos + 1);
15491 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15492 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15493 xassert (w->window_end_bytepos >= 0);
15494 IF_DEBUG (debug_method_add (w, "C"));
15495 }
15496 else
15497 abort ();
15498
15499 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15500 debug_end_vpos = XFASTINT (w->window_end_vpos));
15501
15502 /* Record that display has not been completed. */
15503 w->window_end_valid = Qnil;
15504 w->desired_matrix->no_scrolling_p = 1;
15505 return 3;
15506
15507 #undef GIVE_UP
15508 }
15509
15510
15511 \f
15512 /***********************************************************************
15513 More debugging support
15514 ***********************************************************************/
15515
15516 #if GLYPH_DEBUG
15517
15518 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15519 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15520 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15521
15522
15523 /* Dump the contents of glyph matrix MATRIX on stderr.
15524
15525 GLYPHS 0 means don't show glyph contents.
15526 GLYPHS 1 means show glyphs in short form
15527 GLYPHS > 1 means show glyphs in long form. */
15528
15529 void
15530 dump_glyph_matrix (matrix, glyphs)
15531 struct glyph_matrix *matrix;
15532 int glyphs;
15533 {
15534 int i;
15535 for (i = 0; i < matrix->nrows; ++i)
15536 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15537 }
15538
15539
15540 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15541 the glyph row and area where the glyph comes from. */
15542
15543 void
15544 dump_glyph (row, glyph, area)
15545 struct glyph_row *row;
15546 struct glyph *glyph;
15547 int area;
15548 {
15549 if (glyph->type == CHAR_GLYPH)
15550 {
15551 fprintf (stderr,
15552 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15553 glyph - row->glyphs[TEXT_AREA],
15554 'C',
15555 glyph->charpos,
15556 (BUFFERP (glyph->object)
15557 ? 'B'
15558 : (STRINGP (glyph->object)
15559 ? 'S'
15560 : '-')),
15561 glyph->pixel_width,
15562 glyph->u.ch,
15563 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15564 ? glyph->u.ch
15565 : '.'),
15566 glyph->face_id,
15567 glyph->left_box_line_p,
15568 glyph->right_box_line_p);
15569 }
15570 else if (glyph->type == STRETCH_GLYPH)
15571 {
15572 fprintf (stderr,
15573 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15574 glyph - row->glyphs[TEXT_AREA],
15575 'S',
15576 glyph->charpos,
15577 (BUFFERP (glyph->object)
15578 ? 'B'
15579 : (STRINGP (glyph->object)
15580 ? 'S'
15581 : '-')),
15582 glyph->pixel_width,
15583 0,
15584 '.',
15585 glyph->face_id,
15586 glyph->left_box_line_p,
15587 glyph->right_box_line_p);
15588 }
15589 else if (glyph->type == IMAGE_GLYPH)
15590 {
15591 fprintf (stderr,
15592 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15593 glyph - row->glyphs[TEXT_AREA],
15594 'I',
15595 glyph->charpos,
15596 (BUFFERP (glyph->object)
15597 ? 'B'
15598 : (STRINGP (glyph->object)
15599 ? 'S'
15600 : '-')),
15601 glyph->pixel_width,
15602 glyph->u.img_id,
15603 '.',
15604 glyph->face_id,
15605 glyph->left_box_line_p,
15606 glyph->right_box_line_p);
15607 }
15608 else if (glyph->type == COMPOSITE_GLYPH)
15609 {
15610 fprintf (stderr,
15611 " %5d %4c %6d %c %3d 0x%05x",
15612 glyph - row->glyphs[TEXT_AREA],
15613 '+',
15614 glyph->charpos,
15615 (BUFFERP (glyph->object)
15616 ? 'B'
15617 : (STRINGP (glyph->object)
15618 ? 'S'
15619 : '-')),
15620 glyph->pixel_width,
15621 glyph->u.cmp.id);
15622 if (glyph->u.cmp.automatic)
15623 fprintf (stderr,
15624 "[%d-%d]",
15625 glyph->u.cmp.from, glyph->u.cmp.to);
15626 fprintf (stderr, " . %4d %1.1d%1.1d\n",
15627 glyph->face_id,
15628 glyph->left_box_line_p,
15629 glyph->right_box_line_p);
15630 }
15631 }
15632
15633
15634 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15635 GLYPHS 0 means don't show glyph contents.
15636 GLYPHS 1 means show glyphs in short form
15637 GLYPHS > 1 means show glyphs in long form. */
15638
15639 void
15640 dump_glyph_row (row, vpos, glyphs)
15641 struct glyph_row *row;
15642 int vpos, glyphs;
15643 {
15644 if (glyphs != 1)
15645 {
15646 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15647 fprintf (stderr, "======================================================================\n");
15648
15649 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15650 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15651 vpos,
15652 MATRIX_ROW_START_CHARPOS (row),
15653 MATRIX_ROW_END_CHARPOS (row),
15654 row->used[TEXT_AREA],
15655 row->contains_overlapping_glyphs_p,
15656 row->enabled_p,
15657 row->truncated_on_left_p,
15658 row->truncated_on_right_p,
15659 row->continued_p,
15660 MATRIX_ROW_CONTINUATION_LINE_P (row),
15661 row->displays_text_p,
15662 row->ends_at_zv_p,
15663 row->fill_line_p,
15664 row->ends_in_middle_of_char_p,
15665 row->starts_in_middle_of_char_p,
15666 row->mouse_face_p,
15667 row->x,
15668 row->y,
15669 row->pixel_width,
15670 row->height,
15671 row->visible_height,
15672 row->ascent,
15673 row->phys_ascent);
15674 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15675 row->end.overlay_string_index,
15676 row->continuation_lines_width);
15677 fprintf (stderr, "%9d %5d\n",
15678 CHARPOS (row->start.string_pos),
15679 CHARPOS (row->end.string_pos));
15680 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15681 row->end.dpvec_index);
15682 }
15683
15684 if (glyphs > 1)
15685 {
15686 int area;
15687
15688 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15689 {
15690 struct glyph *glyph = row->glyphs[area];
15691 struct glyph *glyph_end = glyph + row->used[area];
15692
15693 /* Glyph for a line end in text. */
15694 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15695 ++glyph_end;
15696
15697 if (glyph < glyph_end)
15698 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15699
15700 for (; glyph < glyph_end; ++glyph)
15701 dump_glyph (row, glyph, area);
15702 }
15703 }
15704 else if (glyphs == 1)
15705 {
15706 int area;
15707
15708 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15709 {
15710 char *s = (char *) alloca (row->used[area] + 1);
15711 int i;
15712
15713 for (i = 0; i < row->used[area]; ++i)
15714 {
15715 struct glyph *glyph = row->glyphs[area] + i;
15716 if (glyph->type == CHAR_GLYPH
15717 && glyph->u.ch < 0x80
15718 && glyph->u.ch >= ' ')
15719 s[i] = glyph->u.ch;
15720 else
15721 s[i] = '.';
15722 }
15723
15724 s[i] = '\0';
15725 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15726 }
15727 }
15728 }
15729
15730
15731 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15732 Sdump_glyph_matrix, 0, 1, "p",
15733 doc: /* Dump the current matrix of the selected window to stderr.
15734 Shows contents of glyph row structures. With non-nil
15735 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15736 glyphs in short form, otherwise show glyphs in long form. */)
15737 (glyphs)
15738 Lisp_Object glyphs;
15739 {
15740 struct window *w = XWINDOW (selected_window);
15741 struct buffer *buffer = XBUFFER (w->buffer);
15742
15743 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15744 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15745 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15746 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15747 fprintf (stderr, "=============================================\n");
15748 dump_glyph_matrix (w->current_matrix,
15749 NILP (glyphs) ? 0 : XINT (glyphs));
15750 return Qnil;
15751 }
15752
15753
15754 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15755 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15756 ()
15757 {
15758 struct frame *f = XFRAME (selected_frame);
15759 dump_glyph_matrix (f->current_matrix, 1);
15760 return Qnil;
15761 }
15762
15763
15764 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15765 doc: /* Dump glyph row ROW to stderr.
15766 GLYPH 0 means don't dump glyphs.
15767 GLYPH 1 means dump glyphs in short form.
15768 GLYPH > 1 or omitted means dump glyphs in long form. */)
15769 (row, glyphs)
15770 Lisp_Object row, glyphs;
15771 {
15772 struct glyph_matrix *matrix;
15773 int vpos;
15774
15775 CHECK_NUMBER (row);
15776 matrix = XWINDOW (selected_window)->current_matrix;
15777 vpos = XINT (row);
15778 if (vpos >= 0 && vpos < matrix->nrows)
15779 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15780 vpos,
15781 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15782 return Qnil;
15783 }
15784
15785
15786 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15787 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15788 GLYPH 0 means don't dump glyphs.
15789 GLYPH 1 means dump glyphs in short form.
15790 GLYPH > 1 or omitted means dump glyphs in long form. */)
15791 (row, glyphs)
15792 Lisp_Object row, glyphs;
15793 {
15794 struct frame *sf = SELECTED_FRAME ();
15795 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15796 int vpos;
15797
15798 CHECK_NUMBER (row);
15799 vpos = XINT (row);
15800 if (vpos >= 0 && vpos < m->nrows)
15801 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15802 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15803 return Qnil;
15804 }
15805
15806
15807 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15808 doc: /* Toggle tracing of redisplay.
15809 With ARG, turn tracing on if and only if ARG is positive. */)
15810 (arg)
15811 Lisp_Object arg;
15812 {
15813 if (NILP (arg))
15814 trace_redisplay_p = !trace_redisplay_p;
15815 else
15816 {
15817 arg = Fprefix_numeric_value (arg);
15818 trace_redisplay_p = XINT (arg) > 0;
15819 }
15820
15821 return Qnil;
15822 }
15823
15824
15825 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15826 doc: /* Like `format', but print result to stderr.
15827 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15828 (nargs, args)
15829 int nargs;
15830 Lisp_Object *args;
15831 {
15832 Lisp_Object s = Fformat (nargs, args);
15833 fprintf (stderr, "%s", SDATA (s));
15834 return Qnil;
15835 }
15836
15837 #endif /* GLYPH_DEBUG */
15838
15839
15840 \f
15841 /***********************************************************************
15842 Building Desired Matrix Rows
15843 ***********************************************************************/
15844
15845 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15846 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15847
15848 static struct glyph_row *
15849 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15850 struct window *w;
15851 Lisp_Object overlay_arrow_string;
15852 {
15853 struct frame *f = XFRAME (WINDOW_FRAME (w));
15854 struct buffer *buffer = XBUFFER (w->buffer);
15855 struct buffer *old = current_buffer;
15856 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15857 int arrow_len = SCHARS (overlay_arrow_string);
15858 const unsigned char *arrow_end = arrow_string + arrow_len;
15859 const unsigned char *p;
15860 struct it it;
15861 int multibyte_p;
15862 int n_glyphs_before;
15863
15864 set_buffer_temp (buffer);
15865 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15866 it.glyph_row->used[TEXT_AREA] = 0;
15867 SET_TEXT_POS (it.position, 0, 0);
15868
15869 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15870 p = arrow_string;
15871 while (p < arrow_end)
15872 {
15873 Lisp_Object face, ilisp;
15874
15875 /* Get the next character. */
15876 if (multibyte_p)
15877 it.c = string_char_and_length (p, arrow_len, &it.len);
15878 else
15879 it.c = *p, it.len = 1;
15880 p += it.len;
15881
15882 /* Get its face. */
15883 ilisp = make_number (p - arrow_string);
15884 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15885 it.face_id = compute_char_face (f, it.c, face);
15886
15887 /* Compute its width, get its glyphs. */
15888 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15889 SET_TEXT_POS (it.position, -1, -1);
15890 PRODUCE_GLYPHS (&it);
15891
15892 /* If this character doesn't fit any more in the line, we have
15893 to remove some glyphs. */
15894 if (it.current_x > it.last_visible_x)
15895 {
15896 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15897 break;
15898 }
15899 }
15900
15901 set_buffer_temp (old);
15902 return it.glyph_row;
15903 }
15904
15905
15906 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15907 glyphs are only inserted for terminal frames since we can't really
15908 win with truncation glyphs when partially visible glyphs are
15909 involved. Which glyphs to insert is determined by
15910 produce_special_glyphs. */
15911
15912 static void
15913 insert_left_trunc_glyphs (it)
15914 struct it *it;
15915 {
15916 struct it truncate_it;
15917 struct glyph *from, *end, *to, *toend;
15918
15919 xassert (!FRAME_WINDOW_P (it->f));
15920
15921 /* Get the truncation glyphs. */
15922 truncate_it = *it;
15923 truncate_it.current_x = 0;
15924 truncate_it.face_id = DEFAULT_FACE_ID;
15925 truncate_it.glyph_row = &scratch_glyph_row;
15926 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15927 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15928 truncate_it.object = make_number (0);
15929 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15930
15931 /* Overwrite glyphs from IT with truncation glyphs. */
15932 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15933 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15934 to = it->glyph_row->glyphs[TEXT_AREA];
15935 toend = to + it->glyph_row->used[TEXT_AREA];
15936
15937 while (from < end)
15938 *to++ = *from++;
15939
15940 /* There may be padding glyphs left over. Overwrite them too. */
15941 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15942 {
15943 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15944 while (from < end)
15945 *to++ = *from++;
15946 }
15947
15948 if (to > toend)
15949 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15950 }
15951
15952
15953 /* Compute the pixel height and width of IT->glyph_row.
15954
15955 Most of the time, ascent and height of a display line will be equal
15956 to the max_ascent and max_height values of the display iterator
15957 structure. This is not the case if
15958
15959 1. We hit ZV without displaying anything. In this case, max_ascent
15960 and max_height will be zero.
15961
15962 2. We have some glyphs that don't contribute to the line height.
15963 (The glyph row flag contributes_to_line_height_p is for future
15964 pixmap extensions).
15965
15966 The first case is easily covered by using default values because in
15967 these cases, the line height does not really matter, except that it
15968 must not be zero. */
15969
15970 static void
15971 compute_line_metrics (it)
15972 struct it *it;
15973 {
15974 struct glyph_row *row = it->glyph_row;
15975 int area, i;
15976
15977 if (FRAME_WINDOW_P (it->f))
15978 {
15979 int i, min_y, max_y;
15980
15981 /* The line may consist of one space only, that was added to
15982 place the cursor on it. If so, the row's height hasn't been
15983 computed yet. */
15984 if (row->height == 0)
15985 {
15986 if (it->max_ascent + it->max_descent == 0)
15987 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15988 row->ascent = it->max_ascent;
15989 row->height = it->max_ascent + it->max_descent;
15990 row->phys_ascent = it->max_phys_ascent;
15991 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15992 row->extra_line_spacing = it->max_extra_line_spacing;
15993 }
15994
15995 /* Compute the width of this line. */
15996 row->pixel_width = row->x;
15997 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15998 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15999
16000 xassert (row->pixel_width >= 0);
16001 xassert (row->ascent >= 0 && row->height > 0);
16002
16003 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16004 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16005
16006 /* If first line's physical ascent is larger than its logical
16007 ascent, use the physical ascent, and make the row taller.
16008 This makes accented characters fully visible. */
16009 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16010 && row->phys_ascent > row->ascent)
16011 {
16012 row->height += row->phys_ascent - row->ascent;
16013 row->ascent = row->phys_ascent;
16014 }
16015
16016 /* Compute how much of the line is visible. */
16017 row->visible_height = row->height;
16018
16019 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16020 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16021
16022 if (row->y < min_y)
16023 row->visible_height -= min_y - row->y;
16024 if (row->y + row->height > max_y)
16025 row->visible_height -= row->y + row->height - max_y;
16026 }
16027 else
16028 {
16029 row->pixel_width = row->used[TEXT_AREA];
16030 if (row->continued_p)
16031 row->pixel_width -= it->continuation_pixel_width;
16032 else if (row->truncated_on_right_p)
16033 row->pixel_width -= it->truncation_pixel_width;
16034 row->ascent = row->phys_ascent = 0;
16035 row->height = row->phys_height = row->visible_height = 1;
16036 row->extra_line_spacing = 0;
16037 }
16038
16039 /* Compute a hash code for this row. */
16040 row->hash = 0;
16041 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16042 for (i = 0; i < row->used[area]; ++i)
16043 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16044 + row->glyphs[area][i].u.val
16045 + row->glyphs[area][i].face_id
16046 + row->glyphs[area][i].padding_p
16047 + (row->glyphs[area][i].type << 2));
16048
16049 it->max_ascent = it->max_descent = 0;
16050 it->max_phys_ascent = it->max_phys_descent = 0;
16051 }
16052
16053
16054 /* Append one space to the glyph row of iterator IT if doing a
16055 window-based redisplay. The space has the same face as
16056 IT->face_id. Value is non-zero if a space was added.
16057
16058 This function is called to make sure that there is always one glyph
16059 at the end of a glyph row that the cursor can be set on under
16060 window-systems. (If there weren't such a glyph we would not know
16061 how wide and tall a box cursor should be displayed).
16062
16063 At the same time this space let's a nicely handle clearing to the
16064 end of the line if the row ends in italic text. */
16065
16066 static int
16067 append_space_for_newline (it, default_face_p)
16068 struct it *it;
16069 int default_face_p;
16070 {
16071 if (FRAME_WINDOW_P (it->f))
16072 {
16073 int n = it->glyph_row->used[TEXT_AREA];
16074
16075 if (it->glyph_row->glyphs[TEXT_AREA] + n
16076 < it->glyph_row->glyphs[1 + TEXT_AREA])
16077 {
16078 /* Save some values that must not be changed.
16079 Must save IT->c and IT->len because otherwise
16080 ITERATOR_AT_END_P wouldn't work anymore after
16081 append_space_for_newline has been called. */
16082 enum display_element_type saved_what = it->what;
16083 int saved_c = it->c, saved_len = it->len;
16084 int saved_x = it->current_x;
16085 int saved_face_id = it->face_id;
16086 struct text_pos saved_pos;
16087 Lisp_Object saved_object;
16088 struct face *face;
16089
16090 saved_object = it->object;
16091 saved_pos = it->position;
16092
16093 it->what = IT_CHARACTER;
16094 bzero (&it->position, sizeof it->position);
16095 it->object = make_number (0);
16096 it->c = ' ';
16097 it->len = 1;
16098
16099 if (default_face_p)
16100 it->face_id = DEFAULT_FACE_ID;
16101 else if (it->face_before_selective_p)
16102 it->face_id = it->saved_face_id;
16103 face = FACE_FROM_ID (it->f, it->face_id);
16104 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16105
16106 PRODUCE_GLYPHS (it);
16107
16108 it->override_ascent = -1;
16109 it->constrain_row_ascent_descent_p = 0;
16110 it->current_x = saved_x;
16111 it->object = saved_object;
16112 it->position = saved_pos;
16113 it->what = saved_what;
16114 it->face_id = saved_face_id;
16115 it->len = saved_len;
16116 it->c = saved_c;
16117 return 1;
16118 }
16119 }
16120
16121 return 0;
16122 }
16123
16124
16125 /* Extend the face of the last glyph in the text area of IT->glyph_row
16126 to the end of the display line. Called from display_line.
16127 If the glyph row is empty, add a space glyph to it so that we
16128 know the face to draw. Set the glyph row flag fill_line_p. */
16129
16130 static void
16131 extend_face_to_end_of_line (it)
16132 struct it *it;
16133 {
16134 struct face *face;
16135 struct frame *f = it->f;
16136
16137 /* If line is already filled, do nothing. */
16138 if (it->current_x >= it->last_visible_x)
16139 return;
16140
16141 /* Face extension extends the background and box of IT->face_id
16142 to the end of the line. If the background equals the background
16143 of the frame, we don't have to do anything. */
16144 if (it->face_before_selective_p)
16145 face = FACE_FROM_ID (it->f, it->saved_face_id);
16146 else
16147 face = FACE_FROM_ID (f, it->face_id);
16148
16149 if (FRAME_WINDOW_P (f)
16150 && it->glyph_row->displays_text_p
16151 && face->box == FACE_NO_BOX
16152 && face->background == FRAME_BACKGROUND_PIXEL (f)
16153 && !face->stipple)
16154 return;
16155
16156 /* Set the glyph row flag indicating that the face of the last glyph
16157 in the text area has to be drawn to the end of the text area. */
16158 it->glyph_row->fill_line_p = 1;
16159
16160 /* If current character of IT is not ASCII, make sure we have the
16161 ASCII face. This will be automatically undone the next time
16162 get_next_display_element returns a multibyte character. Note
16163 that the character will always be single byte in unibyte text. */
16164 if (!ASCII_CHAR_P (it->c))
16165 {
16166 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16167 }
16168
16169 if (FRAME_WINDOW_P (f))
16170 {
16171 /* If the row is empty, add a space with the current face of IT,
16172 so that we know which face to draw. */
16173 if (it->glyph_row->used[TEXT_AREA] == 0)
16174 {
16175 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16176 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16177 it->glyph_row->used[TEXT_AREA] = 1;
16178 }
16179 }
16180 else
16181 {
16182 /* Save some values that must not be changed. */
16183 int saved_x = it->current_x;
16184 struct text_pos saved_pos;
16185 Lisp_Object saved_object;
16186 enum display_element_type saved_what = it->what;
16187 int saved_face_id = it->face_id;
16188
16189 saved_object = it->object;
16190 saved_pos = it->position;
16191
16192 it->what = IT_CHARACTER;
16193 bzero (&it->position, sizeof it->position);
16194 it->object = make_number (0);
16195 it->c = ' ';
16196 it->len = 1;
16197 it->face_id = face->id;
16198
16199 PRODUCE_GLYPHS (it);
16200
16201 while (it->current_x <= it->last_visible_x)
16202 PRODUCE_GLYPHS (it);
16203
16204 /* Don't count these blanks really. It would let us insert a left
16205 truncation glyph below and make us set the cursor on them, maybe. */
16206 it->current_x = saved_x;
16207 it->object = saved_object;
16208 it->position = saved_pos;
16209 it->what = saved_what;
16210 it->face_id = saved_face_id;
16211 }
16212 }
16213
16214
16215 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16216 trailing whitespace. */
16217
16218 static int
16219 trailing_whitespace_p (charpos)
16220 int charpos;
16221 {
16222 int bytepos = CHAR_TO_BYTE (charpos);
16223 int c = 0;
16224
16225 while (bytepos < ZV_BYTE
16226 && (c = FETCH_CHAR (bytepos),
16227 c == ' ' || c == '\t'))
16228 ++bytepos;
16229
16230 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16231 {
16232 if (bytepos != PT_BYTE)
16233 return 1;
16234 }
16235 return 0;
16236 }
16237
16238
16239 /* Highlight trailing whitespace, if any, in ROW. */
16240
16241 void
16242 highlight_trailing_whitespace (f, row)
16243 struct frame *f;
16244 struct glyph_row *row;
16245 {
16246 int used = row->used[TEXT_AREA];
16247
16248 if (used)
16249 {
16250 struct glyph *start = row->glyphs[TEXT_AREA];
16251 struct glyph *glyph = start + used - 1;
16252
16253 /* Skip over glyphs inserted to display the cursor at the
16254 end of a line, for extending the face of the last glyph
16255 to the end of the line on terminals, and for truncation
16256 and continuation glyphs. */
16257 while (glyph >= start
16258 && glyph->type == CHAR_GLYPH
16259 && INTEGERP (glyph->object))
16260 --glyph;
16261
16262 /* If last glyph is a space or stretch, and it's trailing
16263 whitespace, set the face of all trailing whitespace glyphs in
16264 IT->glyph_row to `trailing-whitespace'. */
16265 if (glyph >= start
16266 && BUFFERP (glyph->object)
16267 && (glyph->type == STRETCH_GLYPH
16268 || (glyph->type == CHAR_GLYPH
16269 && glyph->u.ch == ' '))
16270 && trailing_whitespace_p (glyph->charpos))
16271 {
16272 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16273 if (face_id < 0)
16274 return;
16275
16276 while (glyph >= start
16277 && BUFFERP (glyph->object)
16278 && (glyph->type == STRETCH_GLYPH
16279 || (glyph->type == CHAR_GLYPH
16280 && glyph->u.ch == ' ')))
16281 (glyph--)->face_id = face_id;
16282 }
16283 }
16284 }
16285
16286
16287 /* Value is non-zero if glyph row ROW in window W should be
16288 used to hold the cursor. */
16289
16290 static int
16291 cursor_row_p (w, row)
16292 struct window *w;
16293 struct glyph_row *row;
16294 {
16295 int cursor_row_p = 1;
16296
16297 if (PT == MATRIX_ROW_END_CHARPOS (row))
16298 {
16299 /* Suppose the row ends on a string.
16300 Unless the row is continued, that means it ends on a newline
16301 in the string. If it's anything other than a display string
16302 (e.g. a before-string from an overlay), we don't want the
16303 cursor there. (This heuristic seems to give the optimal
16304 behavior for the various types of multi-line strings.) */
16305 if (CHARPOS (row->end.string_pos) >= 0)
16306 {
16307 if (row->continued_p)
16308 cursor_row_p = 1;
16309 else
16310 {
16311 /* Check for `display' property. */
16312 struct glyph *beg = row->glyphs[TEXT_AREA];
16313 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
16314 struct glyph *glyph;
16315
16316 cursor_row_p = 0;
16317 for (glyph = end; glyph >= beg; --glyph)
16318 if (STRINGP (glyph->object))
16319 {
16320 Lisp_Object prop
16321 = Fget_char_property (make_number (PT),
16322 Qdisplay, Qnil);
16323 cursor_row_p =
16324 (!NILP (prop)
16325 && display_prop_string_p (prop, glyph->object));
16326 break;
16327 }
16328 }
16329 }
16330 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16331 {
16332 /* If the row ends in middle of a real character,
16333 and the line is continued, we want the cursor here.
16334 That's because MATRIX_ROW_END_CHARPOS would equal
16335 PT if PT is before the character. */
16336 if (!row->ends_in_ellipsis_p)
16337 cursor_row_p = row->continued_p;
16338 else
16339 /* If the row ends in an ellipsis, then
16340 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
16341 We want that position to be displayed after the ellipsis. */
16342 cursor_row_p = 0;
16343 }
16344 /* If the row ends at ZV, display the cursor at the end of that
16345 row instead of at the start of the row below. */
16346 else if (row->ends_at_zv_p)
16347 cursor_row_p = 1;
16348 else
16349 cursor_row_p = 0;
16350 }
16351
16352 return cursor_row_p;
16353 }
16354
16355 \f
16356
16357 /* Push the display property PROP so that it will be rendered at the
16358 current position in IT. */
16359
16360 static void
16361 push_display_prop (struct it *it, Lisp_Object prop)
16362 {
16363 push_it (it);
16364
16365 /* Never display a cursor on the prefix. */
16366 it->avoid_cursor_p = 1;
16367
16368 if (STRINGP (prop))
16369 {
16370 if (SCHARS (prop) == 0)
16371 {
16372 pop_it (it);
16373 return;
16374 }
16375
16376 it->string = prop;
16377 it->multibyte_p = STRING_MULTIBYTE (it->string);
16378 it->current.overlay_string_index = -1;
16379 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
16380 it->end_charpos = it->string_nchars = SCHARS (it->string);
16381 it->method = GET_FROM_STRING;
16382 it->stop_charpos = 0;
16383 }
16384 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
16385 {
16386 it->method = GET_FROM_STRETCH;
16387 it->object = prop;
16388 }
16389 #ifdef HAVE_WINDOW_SYSTEM
16390 else if (IMAGEP (prop))
16391 {
16392 it->what = IT_IMAGE;
16393 it->image_id = lookup_image (it->f, prop);
16394 it->method = GET_FROM_IMAGE;
16395 }
16396 #endif /* HAVE_WINDOW_SYSTEM */
16397 else
16398 {
16399 pop_it (it); /* bogus display property, give up */
16400 return;
16401 }
16402 }
16403
16404 /* Return the character-property PROP at the current position in IT. */
16405
16406 static Lisp_Object
16407 get_it_property (it, prop)
16408 struct it *it;
16409 Lisp_Object prop;
16410 {
16411 Lisp_Object position;
16412
16413 if (STRINGP (it->object))
16414 position = make_number (IT_STRING_CHARPOS (*it));
16415 else if (BUFFERP (it->object))
16416 position = make_number (IT_CHARPOS (*it));
16417 else
16418 return Qnil;
16419
16420 return Fget_char_property (position, prop, it->object);
16421 }
16422
16423 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
16424
16425 static void
16426 handle_line_prefix (struct it *it)
16427 {
16428 Lisp_Object prefix;
16429 if (it->continuation_lines_width > 0)
16430 {
16431 prefix = get_it_property (it, Qwrap_prefix);
16432 if (NILP (prefix))
16433 prefix = Vwrap_prefix;
16434 }
16435 else
16436 {
16437 prefix = get_it_property (it, Qline_prefix);
16438 if (NILP (prefix))
16439 prefix = Vline_prefix;
16440 }
16441 if (! NILP (prefix))
16442 {
16443 push_display_prop (it, prefix);
16444 /* If the prefix is wider than the window, and we try to wrap
16445 it, it would acquire its own wrap prefix, and so on till the
16446 iterator stack overflows. So, don't wrap the prefix. */
16447 it->line_wrap = TRUNCATE;
16448 }
16449 }
16450
16451 \f
16452
16453 /* Construct the glyph row IT->glyph_row in the desired matrix of
16454 IT->w from text at the current position of IT. See dispextern.h
16455 for an overview of struct it. Value is non-zero if
16456 IT->glyph_row displays text, as opposed to a line displaying ZV
16457 only. */
16458
16459 static int
16460 display_line (it)
16461 struct it *it;
16462 {
16463 struct glyph_row *row = it->glyph_row;
16464 Lisp_Object overlay_arrow_string;
16465 struct it wrap_it;
16466 int may_wrap = 0, wrap_x;
16467 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
16468 int wrap_row_phys_ascent, wrap_row_phys_height;
16469 int wrap_row_extra_line_spacing;
16470
16471 /* We always start displaying at hpos zero even if hscrolled. */
16472 xassert (it->hpos == 0 && it->current_x == 0);
16473
16474 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
16475 >= it->w->desired_matrix->nrows)
16476 {
16477 it->w->nrows_scale_factor++;
16478 fonts_changed_p = 1;
16479 return 0;
16480 }
16481
16482 /* Is IT->w showing the region? */
16483 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
16484
16485 /* Clear the result glyph row and enable it. */
16486 prepare_desired_row (row);
16487
16488 row->y = it->current_y;
16489 row->start = it->start;
16490 row->continuation_lines_width = it->continuation_lines_width;
16491 row->displays_text_p = 1;
16492 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
16493 it->starts_in_middle_of_char_p = 0;
16494
16495 /* Arrange the overlays nicely for our purposes. Usually, we call
16496 display_line on only one line at a time, in which case this
16497 can't really hurt too much, or we call it on lines which appear
16498 one after another in the buffer, in which case all calls to
16499 recenter_overlay_lists but the first will be pretty cheap. */
16500 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16501
16502 /* Move over display elements that are not visible because we are
16503 hscrolled. This may stop at an x-position < IT->first_visible_x
16504 if the first glyph is partially visible or if we hit a line end. */
16505 if (it->current_x < it->first_visible_x)
16506 {
16507 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16508 MOVE_TO_POS | MOVE_TO_X);
16509 }
16510 else
16511 {
16512 /* We only do this when not calling `move_it_in_display_line_to'
16513 above, because move_it_in_display_line_to calls
16514 handle_line_prefix itself. */
16515 handle_line_prefix (it);
16516 }
16517
16518 /* Get the initial row height. This is either the height of the
16519 text hscrolled, if there is any, or zero. */
16520 row->ascent = it->max_ascent;
16521 row->height = it->max_ascent + it->max_descent;
16522 row->phys_ascent = it->max_phys_ascent;
16523 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16524 row->extra_line_spacing = it->max_extra_line_spacing;
16525
16526 /* Loop generating characters. The loop is left with IT on the next
16527 character to display. */
16528 while (1)
16529 {
16530 int n_glyphs_before, hpos_before, x_before;
16531 int x, i, nglyphs;
16532 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16533
16534 /* Retrieve the next thing to display. Value is zero if end of
16535 buffer reached. */
16536 if (!get_next_display_element (it))
16537 {
16538 /* Maybe add a space at the end of this line that is used to
16539 display the cursor there under X. Set the charpos of the
16540 first glyph of blank lines not corresponding to any text
16541 to -1. */
16542 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16543 row->exact_window_width_line_p = 1;
16544 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16545 || row->used[TEXT_AREA] == 0)
16546 {
16547 row->glyphs[TEXT_AREA]->charpos = -1;
16548 row->displays_text_p = 0;
16549
16550 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16551 && (!MINI_WINDOW_P (it->w)
16552 || (minibuf_level && EQ (it->window, minibuf_window))))
16553 row->indicate_empty_line_p = 1;
16554 }
16555
16556 it->continuation_lines_width = 0;
16557 row->ends_at_zv_p = 1;
16558 break;
16559 }
16560
16561 /* Now, get the metrics of what we want to display. This also
16562 generates glyphs in `row' (which is IT->glyph_row). */
16563 n_glyphs_before = row->used[TEXT_AREA];
16564 x = it->current_x;
16565
16566 /* Remember the line height so far in case the next element doesn't
16567 fit on the line. */
16568 if (it->line_wrap != TRUNCATE)
16569 {
16570 ascent = it->max_ascent;
16571 descent = it->max_descent;
16572 phys_ascent = it->max_phys_ascent;
16573 phys_descent = it->max_phys_descent;
16574
16575 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
16576 {
16577 if (IT_DISPLAYING_WHITESPACE (it))
16578 may_wrap = 1;
16579 else if (may_wrap)
16580 {
16581 wrap_it = *it;
16582 wrap_x = x;
16583 wrap_row_used = row->used[TEXT_AREA];
16584 wrap_row_ascent = row->ascent;
16585 wrap_row_height = row->height;
16586 wrap_row_phys_ascent = row->phys_ascent;
16587 wrap_row_phys_height = row->phys_height;
16588 wrap_row_extra_line_spacing = row->extra_line_spacing;
16589 may_wrap = 0;
16590 }
16591 }
16592 }
16593
16594 PRODUCE_GLYPHS (it);
16595
16596 /* If this display element was in marginal areas, continue with
16597 the next one. */
16598 if (it->area != TEXT_AREA)
16599 {
16600 row->ascent = max (row->ascent, it->max_ascent);
16601 row->height = max (row->height, it->max_ascent + it->max_descent);
16602 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16603 row->phys_height = max (row->phys_height,
16604 it->max_phys_ascent + it->max_phys_descent);
16605 row->extra_line_spacing = max (row->extra_line_spacing,
16606 it->max_extra_line_spacing);
16607 set_iterator_to_next (it, 1);
16608 continue;
16609 }
16610
16611 /* Does the display element fit on the line? If we truncate
16612 lines, we should draw past the right edge of the window. If
16613 we don't truncate, we want to stop so that we can display the
16614 continuation glyph before the right margin. If lines are
16615 continued, there are two possible strategies for characters
16616 resulting in more than 1 glyph (e.g. tabs): Display as many
16617 glyphs as possible in this line and leave the rest for the
16618 continuation line, or display the whole element in the next
16619 line. Original redisplay did the former, so we do it also. */
16620 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16621 hpos_before = it->hpos;
16622 x_before = x;
16623
16624 if (/* Not a newline. */
16625 nglyphs > 0
16626 /* Glyphs produced fit entirely in the line. */
16627 && it->current_x < it->last_visible_x)
16628 {
16629 it->hpos += nglyphs;
16630 row->ascent = max (row->ascent, it->max_ascent);
16631 row->height = max (row->height, it->max_ascent + it->max_descent);
16632 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16633 row->phys_height = max (row->phys_height,
16634 it->max_phys_ascent + it->max_phys_descent);
16635 row->extra_line_spacing = max (row->extra_line_spacing,
16636 it->max_extra_line_spacing);
16637 if (it->current_x - it->pixel_width < it->first_visible_x)
16638 row->x = x - it->first_visible_x;
16639 }
16640 else
16641 {
16642 int new_x;
16643 struct glyph *glyph;
16644
16645 for (i = 0; i < nglyphs; ++i, x = new_x)
16646 {
16647 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16648 new_x = x + glyph->pixel_width;
16649
16650 if (/* Lines are continued. */
16651 it->line_wrap != TRUNCATE
16652 && (/* Glyph doesn't fit on the line. */
16653 new_x > it->last_visible_x
16654 /* Or it fits exactly on a window system frame. */
16655 || (new_x == it->last_visible_x
16656 && FRAME_WINDOW_P (it->f))))
16657 {
16658 /* End of a continued line. */
16659
16660 if (it->hpos == 0
16661 || (new_x == it->last_visible_x
16662 && FRAME_WINDOW_P (it->f)))
16663 {
16664 /* Current glyph is the only one on the line or
16665 fits exactly on the line. We must continue
16666 the line because we can't draw the cursor
16667 after the glyph. */
16668 row->continued_p = 1;
16669 it->current_x = new_x;
16670 it->continuation_lines_width += new_x;
16671 ++it->hpos;
16672 if (i == nglyphs - 1)
16673 {
16674 /* If line-wrap is on, check if a previous
16675 wrap point was found. */
16676 if (wrap_row_used > 0
16677 /* Even if there is a previous wrap
16678 point, continue the line here as
16679 usual, if (i) the previous character
16680 was a space or tab AND (ii) the
16681 current character is not. */
16682 && (!may_wrap
16683 || IT_DISPLAYING_WHITESPACE (it)))
16684 goto back_to_wrap;
16685
16686 set_iterator_to_next (it, 1);
16687 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16688 {
16689 if (!get_next_display_element (it))
16690 {
16691 row->exact_window_width_line_p = 1;
16692 it->continuation_lines_width = 0;
16693 row->continued_p = 0;
16694 row->ends_at_zv_p = 1;
16695 }
16696 else if (ITERATOR_AT_END_OF_LINE_P (it))
16697 {
16698 row->continued_p = 0;
16699 row->exact_window_width_line_p = 1;
16700 }
16701 }
16702 }
16703 }
16704 else if (CHAR_GLYPH_PADDING_P (*glyph)
16705 && !FRAME_WINDOW_P (it->f))
16706 {
16707 /* A padding glyph that doesn't fit on this line.
16708 This means the whole character doesn't fit
16709 on the line. */
16710 row->used[TEXT_AREA] = n_glyphs_before;
16711
16712 /* Fill the rest of the row with continuation
16713 glyphs like in 20.x. */
16714 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16715 < row->glyphs[1 + TEXT_AREA])
16716 produce_special_glyphs (it, IT_CONTINUATION);
16717
16718 row->continued_p = 1;
16719 it->current_x = x_before;
16720 it->continuation_lines_width += x_before;
16721
16722 /* Restore the height to what it was before the
16723 element not fitting on the line. */
16724 it->max_ascent = ascent;
16725 it->max_descent = descent;
16726 it->max_phys_ascent = phys_ascent;
16727 it->max_phys_descent = phys_descent;
16728 }
16729 else if (wrap_row_used > 0)
16730 {
16731 back_to_wrap:
16732 *it = wrap_it;
16733 it->continuation_lines_width += wrap_x;
16734 row->used[TEXT_AREA] = wrap_row_used;
16735 row->ascent = wrap_row_ascent;
16736 row->height = wrap_row_height;
16737 row->phys_ascent = wrap_row_phys_ascent;
16738 row->phys_height = wrap_row_phys_height;
16739 row->extra_line_spacing = wrap_row_extra_line_spacing;
16740 row->continued_p = 1;
16741 row->ends_at_zv_p = 0;
16742 row->exact_window_width_line_p = 0;
16743 it->continuation_lines_width += x;
16744
16745 /* Make sure that a non-default face is extended
16746 up to the right margin of the window. */
16747 extend_face_to_end_of_line (it);
16748 }
16749 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16750 {
16751 /* A TAB that extends past the right edge of the
16752 window. This produces a single glyph on
16753 window system frames. We leave the glyph in
16754 this row and let it fill the row, but don't
16755 consume the TAB. */
16756 it->continuation_lines_width += it->last_visible_x;
16757 row->ends_in_middle_of_char_p = 1;
16758 row->continued_p = 1;
16759 glyph->pixel_width = it->last_visible_x - x;
16760 it->starts_in_middle_of_char_p = 1;
16761 }
16762 else
16763 {
16764 /* Something other than a TAB that draws past
16765 the right edge of the window. Restore
16766 positions to values before the element. */
16767 row->used[TEXT_AREA] = n_glyphs_before + i;
16768
16769 /* Display continuation glyphs. */
16770 if (!FRAME_WINDOW_P (it->f))
16771 produce_special_glyphs (it, IT_CONTINUATION);
16772 row->continued_p = 1;
16773
16774 it->current_x = x_before;
16775 it->continuation_lines_width += x;
16776 extend_face_to_end_of_line (it);
16777
16778 if (nglyphs > 1 && i > 0)
16779 {
16780 row->ends_in_middle_of_char_p = 1;
16781 it->starts_in_middle_of_char_p = 1;
16782 }
16783
16784 /* Restore the height to what it was before the
16785 element not fitting on the line. */
16786 it->max_ascent = ascent;
16787 it->max_descent = descent;
16788 it->max_phys_ascent = phys_ascent;
16789 it->max_phys_descent = phys_descent;
16790 }
16791
16792 break;
16793 }
16794 else if (new_x > it->first_visible_x)
16795 {
16796 /* Increment number of glyphs actually displayed. */
16797 ++it->hpos;
16798
16799 if (x < it->first_visible_x)
16800 /* Glyph is partially visible, i.e. row starts at
16801 negative X position. */
16802 row->x = x - it->first_visible_x;
16803 }
16804 else
16805 {
16806 /* Glyph is completely off the left margin of the
16807 window. This should not happen because of the
16808 move_it_in_display_line at the start of this
16809 function, unless the text display area of the
16810 window is empty. */
16811 xassert (it->first_visible_x <= it->last_visible_x);
16812 }
16813 }
16814
16815 row->ascent = max (row->ascent, it->max_ascent);
16816 row->height = max (row->height, it->max_ascent + it->max_descent);
16817 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16818 row->phys_height = max (row->phys_height,
16819 it->max_phys_ascent + it->max_phys_descent);
16820 row->extra_line_spacing = max (row->extra_line_spacing,
16821 it->max_extra_line_spacing);
16822
16823 /* End of this display line if row is continued. */
16824 if (row->continued_p || row->ends_at_zv_p)
16825 break;
16826 }
16827
16828 at_end_of_line:
16829 /* Is this a line end? If yes, we're also done, after making
16830 sure that a non-default face is extended up to the right
16831 margin of the window. */
16832 if (ITERATOR_AT_END_OF_LINE_P (it))
16833 {
16834 int used_before = row->used[TEXT_AREA];
16835
16836 row->ends_in_newline_from_string_p = STRINGP (it->object);
16837
16838 /* Add a space at the end of the line that is used to
16839 display the cursor there. */
16840 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16841 append_space_for_newline (it, 0);
16842
16843 /* Extend the face to the end of the line. */
16844 extend_face_to_end_of_line (it);
16845
16846 /* Make sure we have the position. */
16847 if (used_before == 0)
16848 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16849
16850 /* Consume the line end. This skips over invisible lines. */
16851 set_iterator_to_next (it, 1);
16852 it->continuation_lines_width = 0;
16853 break;
16854 }
16855
16856 /* Proceed with next display element. Note that this skips
16857 over lines invisible because of selective display. */
16858 set_iterator_to_next (it, 1);
16859
16860 /* If we truncate lines, we are done when the last displayed
16861 glyphs reach past the right margin of the window. */
16862 if (it->line_wrap == TRUNCATE
16863 && (FRAME_WINDOW_P (it->f)
16864 ? (it->current_x >= it->last_visible_x)
16865 : (it->current_x > it->last_visible_x)))
16866 {
16867 /* Maybe add truncation glyphs. */
16868 if (!FRAME_WINDOW_P (it->f))
16869 {
16870 int i, n;
16871
16872 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16873 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16874 break;
16875
16876 for (n = row->used[TEXT_AREA]; i < n; ++i)
16877 {
16878 row->used[TEXT_AREA] = i;
16879 produce_special_glyphs (it, IT_TRUNCATION);
16880 }
16881 }
16882 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16883 {
16884 /* Don't truncate if we can overflow newline into fringe. */
16885 if (!get_next_display_element (it))
16886 {
16887 it->continuation_lines_width = 0;
16888 row->ends_at_zv_p = 1;
16889 row->exact_window_width_line_p = 1;
16890 break;
16891 }
16892 if (ITERATOR_AT_END_OF_LINE_P (it))
16893 {
16894 row->exact_window_width_line_p = 1;
16895 goto at_end_of_line;
16896 }
16897 }
16898
16899 row->truncated_on_right_p = 1;
16900 it->continuation_lines_width = 0;
16901 reseat_at_next_visible_line_start (it, 0);
16902 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16903 it->hpos = hpos_before;
16904 it->current_x = x_before;
16905 break;
16906 }
16907 }
16908
16909 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16910 at the left window margin. */
16911 if (it->first_visible_x
16912 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16913 {
16914 if (!FRAME_WINDOW_P (it->f))
16915 insert_left_trunc_glyphs (it);
16916 row->truncated_on_left_p = 1;
16917 }
16918
16919 /* If the start of this line is the overlay arrow-position, then
16920 mark this glyph row as the one containing the overlay arrow.
16921 This is clearly a mess with variable size fonts. It would be
16922 better to let it be displayed like cursors under X. */
16923 if ((row->displays_text_p || !overlay_arrow_seen)
16924 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16925 !NILP (overlay_arrow_string)))
16926 {
16927 /* Overlay arrow in window redisplay is a fringe bitmap. */
16928 if (STRINGP (overlay_arrow_string))
16929 {
16930 struct glyph_row *arrow_row
16931 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16932 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16933 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16934 struct glyph *p = row->glyphs[TEXT_AREA];
16935 struct glyph *p2, *end;
16936
16937 /* Copy the arrow glyphs. */
16938 while (glyph < arrow_end)
16939 *p++ = *glyph++;
16940
16941 /* Throw away padding glyphs. */
16942 p2 = p;
16943 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16944 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16945 ++p2;
16946 if (p2 > p)
16947 {
16948 while (p2 < end)
16949 *p++ = *p2++;
16950 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16951 }
16952 }
16953 else
16954 {
16955 xassert (INTEGERP (overlay_arrow_string));
16956 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16957 }
16958 overlay_arrow_seen = 1;
16959 }
16960
16961 /* Compute pixel dimensions of this line. */
16962 compute_line_metrics (it);
16963
16964 /* Remember the position at which this line ends. */
16965 row->end = it->current;
16966
16967 /* Record whether this row ends inside an ellipsis. */
16968 row->ends_in_ellipsis_p
16969 = (it->method == GET_FROM_DISPLAY_VECTOR
16970 && it->ellipsis_p);
16971
16972 /* Save fringe bitmaps in this row. */
16973 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16974 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16975 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16976 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16977
16978 it->left_user_fringe_bitmap = 0;
16979 it->left_user_fringe_face_id = 0;
16980 it->right_user_fringe_bitmap = 0;
16981 it->right_user_fringe_face_id = 0;
16982
16983 /* Maybe set the cursor. */
16984 if (it->w->cursor.vpos < 0
16985 && PT >= MATRIX_ROW_START_CHARPOS (row)
16986 && PT <= MATRIX_ROW_END_CHARPOS (row)
16987 && cursor_row_p (it->w, row))
16988 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16989
16990 /* Highlight trailing whitespace. */
16991 if (!NILP (Vshow_trailing_whitespace))
16992 highlight_trailing_whitespace (it->f, it->glyph_row);
16993
16994 /* Prepare for the next line. This line starts horizontally at (X
16995 HPOS) = (0 0). Vertical positions are incremented. As a
16996 convenience for the caller, IT->glyph_row is set to the next
16997 row to be used. */
16998 it->current_x = it->hpos = 0;
16999 it->current_y += row->height;
17000 ++it->vpos;
17001 ++it->glyph_row;
17002 it->start = it->current;
17003 return row->displays_text_p;
17004 }
17005
17006
17007 \f
17008 /***********************************************************************
17009 Menu Bar
17010 ***********************************************************************/
17011
17012 /* Redisplay the menu bar in the frame for window W.
17013
17014 The menu bar of X frames that don't have X toolkit support is
17015 displayed in a special window W->frame->menu_bar_window.
17016
17017 The menu bar of terminal frames is treated specially as far as
17018 glyph matrices are concerned. Menu bar lines are not part of
17019 windows, so the update is done directly on the frame matrix rows
17020 for the menu bar. */
17021
17022 static void
17023 display_menu_bar (w)
17024 struct window *w;
17025 {
17026 struct frame *f = XFRAME (WINDOW_FRAME (w));
17027 struct it it;
17028 Lisp_Object items;
17029 int i;
17030
17031 /* Don't do all this for graphical frames. */
17032 #ifdef HAVE_NTGUI
17033 if (FRAME_W32_P (f))
17034 return;
17035 #endif
17036 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
17037 if (FRAME_X_P (f))
17038 return;
17039 #endif
17040
17041 #ifdef HAVE_NS
17042 if (FRAME_NS_P (f))
17043 return;
17044 #endif /* HAVE_NS */
17045
17046 #ifdef USE_X_TOOLKIT
17047 xassert (!FRAME_WINDOW_P (f));
17048 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
17049 it.first_visible_x = 0;
17050 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
17051 #else /* not USE_X_TOOLKIT */
17052 if (FRAME_WINDOW_P (f))
17053 {
17054 /* Menu bar lines are displayed in the desired matrix of the
17055 dummy window menu_bar_window. */
17056 struct window *menu_w;
17057 xassert (WINDOWP (f->menu_bar_window));
17058 menu_w = XWINDOW (f->menu_bar_window);
17059 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
17060 MENU_FACE_ID);
17061 it.first_visible_x = 0;
17062 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
17063 }
17064 else
17065 {
17066 /* This is a TTY frame, i.e. character hpos/vpos are used as
17067 pixel x/y. */
17068 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
17069 MENU_FACE_ID);
17070 it.first_visible_x = 0;
17071 it.last_visible_x = FRAME_COLS (f);
17072 }
17073 #endif /* not USE_X_TOOLKIT */
17074
17075 if (! mode_line_inverse_video)
17076 /* Force the menu-bar to be displayed in the default face. */
17077 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
17078
17079 /* Clear all rows of the menu bar. */
17080 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
17081 {
17082 struct glyph_row *row = it.glyph_row + i;
17083 clear_glyph_row (row);
17084 row->enabled_p = 1;
17085 row->full_width_p = 1;
17086 }
17087
17088 /* Display all items of the menu bar. */
17089 items = FRAME_MENU_BAR_ITEMS (it.f);
17090 for (i = 0; i < XVECTOR (items)->size; i += 4)
17091 {
17092 Lisp_Object string;
17093
17094 /* Stop at nil string. */
17095 string = AREF (items, i + 1);
17096 if (NILP (string))
17097 break;
17098
17099 /* Remember where item was displayed. */
17100 ASET (items, i + 3, make_number (it.hpos));
17101
17102 /* Display the item, pad with one space. */
17103 if (it.current_x < it.last_visible_x)
17104 display_string (NULL, string, Qnil, 0, 0, &it,
17105 SCHARS (string) + 1, 0, 0, -1);
17106 }
17107
17108 /* Fill out the line with spaces. */
17109 if (it.current_x < it.last_visible_x)
17110 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
17111
17112 /* Compute the total height of the lines. */
17113 compute_line_metrics (&it);
17114 }
17115
17116
17117 \f
17118 /***********************************************************************
17119 Mode Line
17120 ***********************************************************************/
17121
17122 /* Redisplay mode lines in the window tree whose root is WINDOW. If
17123 FORCE is non-zero, redisplay mode lines unconditionally.
17124 Otherwise, redisplay only mode lines that are garbaged. Value is
17125 the number of windows whose mode lines were redisplayed. */
17126
17127 static int
17128 redisplay_mode_lines (window, force)
17129 Lisp_Object window;
17130 int force;
17131 {
17132 int nwindows = 0;
17133
17134 while (!NILP (window))
17135 {
17136 struct window *w = XWINDOW (window);
17137
17138 if (WINDOWP (w->hchild))
17139 nwindows += redisplay_mode_lines (w->hchild, force);
17140 else if (WINDOWP (w->vchild))
17141 nwindows += redisplay_mode_lines (w->vchild, force);
17142 else if (force
17143 || FRAME_GARBAGED_P (XFRAME (w->frame))
17144 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
17145 {
17146 struct text_pos lpoint;
17147 struct buffer *old = current_buffer;
17148
17149 /* Set the window's buffer for the mode line display. */
17150 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17151 set_buffer_internal_1 (XBUFFER (w->buffer));
17152
17153 /* Point refers normally to the selected window. For any
17154 other window, set up appropriate value. */
17155 if (!EQ (window, selected_window))
17156 {
17157 struct text_pos pt;
17158
17159 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
17160 if (CHARPOS (pt) < BEGV)
17161 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17162 else if (CHARPOS (pt) > (ZV - 1))
17163 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
17164 else
17165 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
17166 }
17167
17168 /* Display mode lines. */
17169 clear_glyph_matrix (w->desired_matrix);
17170 if (display_mode_lines (w))
17171 {
17172 ++nwindows;
17173 w->must_be_updated_p = 1;
17174 }
17175
17176 /* Restore old settings. */
17177 set_buffer_internal_1 (old);
17178 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17179 }
17180
17181 window = w->next;
17182 }
17183
17184 return nwindows;
17185 }
17186
17187
17188 /* Display the mode and/or top line of window W. Value is the number
17189 of mode lines displayed. */
17190
17191 static int
17192 display_mode_lines (w)
17193 struct window *w;
17194 {
17195 Lisp_Object old_selected_window, old_selected_frame;
17196 int n = 0;
17197
17198 old_selected_frame = selected_frame;
17199 selected_frame = w->frame;
17200 old_selected_window = selected_window;
17201 XSETWINDOW (selected_window, w);
17202
17203 /* These will be set while the mode line specs are processed. */
17204 line_number_displayed = 0;
17205 w->column_number_displayed = Qnil;
17206
17207 if (WINDOW_WANTS_MODELINE_P (w))
17208 {
17209 struct window *sel_w = XWINDOW (old_selected_window);
17210
17211 /* Select mode line face based on the real selected window. */
17212 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
17213 current_buffer->mode_line_format);
17214 ++n;
17215 }
17216
17217 if (WINDOW_WANTS_HEADER_LINE_P (w))
17218 {
17219 display_mode_line (w, HEADER_LINE_FACE_ID,
17220 current_buffer->header_line_format);
17221 ++n;
17222 }
17223
17224 selected_frame = old_selected_frame;
17225 selected_window = old_selected_window;
17226 return n;
17227 }
17228
17229
17230 /* Display mode or top line of window W. FACE_ID specifies which line
17231 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
17232 FORMAT is the mode line format to display. Value is the pixel
17233 height of the mode line displayed. */
17234
17235 static int
17236 display_mode_line (w, face_id, format)
17237 struct window *w;
17238 enum face_id face_id;
17239 Lisp_Object format;
17240 {
17241 struct it it;
17242 struct face *face;
17243 int count = SPECPDL_INDEX ();
17244
17245 init_iterator (&it, w, -1, -1, NULL, face_id);
17246 /* Don't extend on a previously drawn mode-line.
17247 This may happen if called from pos_visible_p. */
17248 it.glyph_row->enabled_p = 0;
17249 prepare_desired_row (it.glyph_row);
17250
17251 it.glyph_row->mode_line_p = 1;
17252
17253 if (! mode_line_inverse_video)
17254 /* Force the mode-line to be displayed in the default face. */
17255 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
17256
17257 record_unwind_protect (unwind_format_mode_line,
17258 format_mode_line_unwind_data (NULL, Qnil, 0));
17259
17260 mode_line_target = MODE_LINE_DISPLAY;
17261
17262 /* Temporarily make frame's keyboard the current kboard so that
17263 kboard-local variables in the mode_line_format will get the right
17264 values. */
17265 push_kboard (FRAME_KBOARD (it.f));
17266 record_unwind_save_match_data ();
17267 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17268 pop_kboard ();
17269
17270 unbind_to (count, Qnil);
17271
17272 /* Fill up with spaces. */
17273 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
17274
17275 compute_line_metrics (&it);
17276 it.glyph_row->full_width_p = 1;
17277 it.glyph_row->continued_p = 0;
17278 it.glyph_row->truncated_on_left_p = 0;
17279 it.glyph_row->truncated_on_right_p = 0;
17280
17281 /* Make a 3D mode-line have a shadow at its right end. */
17282 face = FACE_FROM_ID (it.f, face_id);
17283 extend_face_to_end_of_line (&it);
17284 if (face->box != FACE_NO_BOX)
17285 {
17286 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
17287 + it.glyph_row->used[TEXT_AREA] - 1);
17288 last->right_box_line_p = 1;
17289 }
17290
17291 return it.glyph_row->height;
17292 }
17293
17294 /* Move element ELT in LIST to the front of LIST.
17295 Return the updated list. */
17296
17297 static Lisp_Object
17298 move_elt_to_front (elt, list)
17299 Lisp_Object elt, list;
17300 {
17301 register Lisp_Object tail, prev;
17302 register Lisp_Object tem;
17303
17304 tail = list;
17305 prev = Qnil;
17306 while (CONSP (tail))
17307 {
17308 tem = XCAR (tail);
17309
17310 if (EQ (elt, tem))
17311 {
17312 /* Splice out the link TAIL. */
17313 if (NILP (prev))
17314 list = XCDR (tail);
17315 else
17316 Fsetcdr (prev, XCDR (tail));
17317
17318 /* Now make it the first. */
17319 Fsetcdr (tail, list);
17320 return tail;
17321 }
17322 else
17323 prev = tail;
17324 tail = XCDR (tail);
17325 QUIT;
17326 }
17327
17328 /* Not found--return unchanged LIST. */
17329 return list;
17330 }
17331
17332 /* Contribute ELT to the mode line for window IT->w. How it
17333 translates into text depends on its data type.
17334
17335 IT describes the display environment in which we display, as usual.
17336
17337 DEPTH is the depth in recursion. It is used to prevent
17338 infinite recursion here.
17339
17340 FIELD_WIDTH is the number of characters the display of ELT should
17341 occupy in the mode line, and PRECISION is the maximum number of
17342 characters to display from ELT's representation. See
17343 display_string for details.
17344
17345 Returns the hpos of the end of the text generated by ELT.
17346
17347 PROPS is a property list to add to any string we encounter.
17348
17349 If RISKY is nonzero, remove (disregard) any properties in any string
17350 we encounter, and ignore :eval and :propertize.
17351
17352 The global variable `mode_line_target' determines whether the
17353 output is passed to `store_mode_line_noprop',
17354 `store_mode_line_string', or `display_string'. */
17355
17356 static int
17357 display_mode_element (it, depth, field_width, precision, elt, props, risky)
17358 struct it *it;
17359 int depth;
17360 int field_width, precision;
17361 Lisp_Object elt, props;
17362 int risky;
17363 {
17364 int n = 0, field, prec;
17365 int literal = 0;
17366
17367 tail_recurse:
17368 if (depth > 100)
17369 elt = build_string ("*too-deep*");
17370
17371 depth++;
17372
17373 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
17374 {
17375 case Lisp_String:
17376 {
17377 /* A string: output it and check for %-constructs within it. */
17378 unsigned char c;
17379 int offset = 0;
17380
17381 if (SCHARS (elt) > 0
17382 && (!NILP (props) || risky))
17383 {
17384 Lisp_Object oprops, aelt;
17385 oprops = Ftext_properties_at (make_number (0), elt);
17386
17387 /* If the starting string's properties are not what
17388 we want, translate the string. Also, if the string
17389 is risky, do that anyway. */
17390
17391 if (NILP (Fequal (props, oprops)) || risky)
17392 {
17393 /* If the starting string has properties,
17394 merge the specified ones onto the existing ones. */
17395 if (! NILP (oprops) && !risky)
17396 {
17397 Lisp_Object tem;
17398
17399 oprops = Fcopy_sequence (oprops);
17400 tem = props;
17401 while (CONSP (tem))
17402 {
17403 oprops = Fplist_put (oprops, XCAR (tem),
17404 XCAR (XCDR (tem)));
17405 tem = XCDR (XCDR (tem));
17406 }
17407 props = oprops;
17408 }
17409
17410 aelt = Fassoc (elt, mode_line_proptrans_alist);
17411 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
17412 {
17413 /* AELT is what we want. Move it to the front
17414 without consing. */
17415 elt = XCAR (aelt);
17416 mode_line_proptrans_alist
17417 = move_elt_to_front (aelt, mode_line_proptrans_alist);
17418 }
17419 else
17420 {
17421 Lisp_Object tem;
17422
17423 /* If AELT has the wrong props, it is useless.
17424 so get rid of it. */
17425 if (! NILP (aelt))
17426 mode_line_proptrans_alist
17427 = Fdelq (aelt, mode_line_proptrans_alist);
17428
17429 elt = Fcopy_sequence (elt);
17430 Fset_text_properties (make_number (0), Flength (elt),
17431 props, elt);
17432 /* Add this item to mode_line_proptrans_alist. */
17433 mode_line_proptrans_alist
17434 = Fcons (Fcons (elt, props),
17435 mode_line_proptrans_alist);
17436 /* Truncate mode_line_proptrans_alist
17437 to at most 50 elements. */
17438 tem = Fnthcdr (make_number (50),
17439 mode_line_proptrans_alist);
17440 if (! NILP (tem))
17441 XSETCDR (tem, Qnil);
17442 }
17443 }
17444 }
17445
17446 offset = 0;
17447
17448 if (literal)
17449 {
17450 prec = precision - n;
17451 switch (mode_line_target)
17452 {
17453 case MODE_LINE_NOPROP:
17454 case MODE_LINE_TITLE:
17455 n += store_mode_line_noprop (SDATA (elt), -1, prec);
17456 break;
17457 case MODE_LINE_STRING:
17458 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
17459 break;
17460 case MODE_LINE_DISPLAY:
17461 n += display_string (NULL, elt, Qnil, 0, 0, it,
17462 0, prec, 0, STRING_MULTIBYTE (elt));
17463 break;
17464 }
17465
17466 break;
17467 }
17468
17469 /* Handle the non-literal case. */
17470
17471 while ((precision <= 0 || n < precision)
17472 && SREF (elt, offset) != 0
17473 && (mode_line_target != MODE_LINE_DISPLAY
17474 || it->current_x < it->last_visible_x))
17475 {
17476 int last_offset = offset;
17477
17478 /* Advance to end of string or next format specifier. */
17479 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
17480 ;
17481
17482 if (offset - 1 != last_offset)
17483 {
17484 int nchars, nbytes;
17485
17486 /* Output to end of string or up to '%'. Field width
17487 is length of string. Don't output more than
17488 PRECISION allows us. */
17489 offset--;
17490
17491 prec = c_string_width (SDATA (elt) + last_offset,
17492 offset - last_offset, precision - n,
17493 &nchars, &nbytes);
17494
17495 switch (mode_line_target)
17496 {
17497 case MODE_LINE_NOPROP:
17498 case MODE_LINE_TITLE:
17499 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
17500 break;
17501 case MODE_LINE_STRING:
17502 {
17503 int bytepos = last_offset;
17504 int charpos = string_byte_to_char (elt, bytepos);
17505 int endpos = (precision <= 0
17506 ? string_byte_to_char (elt, offset)
17507 : charpos + nchars);
17508
17509 n += store_mode_line_string (NULL,
17510 Fsubstring (elt, make_number (charpos),
17511 make_number (endpos)),
17512 0, 0, 0, Qnil);
17513 }
17514 break;
17515 case MODE_LINE_DISPLAY:
17516 {
17517 int bytepos = last_offset;
17518 int charpos = string_byte_to_char (elt, bytepos);
17519
17520 if (precision <= 0)
17521 nchars = string_byte_to_char (elt, offset) - charpos;
17522 n += display_string (NULL, elt, Qnil, 0, charpos,
17523 it, 0, nchars, 0,
17524 STRING_MULTIBYTE (elt));
17525 }
17526 break;
17527 }
17528 }
17529 else /* c == '%' */
17530 {
17531 int percent_position = offset;
17532
17533 /* Get the specified minimum width. Zero means
17534 don't pad. */
17535 field = 0;
17536 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
17537 field = field * 10 + c - '0';
17538
17539 /* Don't pad beyond the total padding allowed. */
17540 if (field_width - n > 0 && field > field_width - n)
17541 field = field_width - n;
17542
17543 /* Note that either PRECISION <= 0 or N < PRECISION. */
17544 prec = precision - n;
17545
17546 if (c == 'M')
17547 n += display_mode_element (it, depth, field, prec,
17548 Vglobal_mode_string, props,
17549 risky);
17550 else if (c != 0)
17551 {
17552 int multibyte;
17553 int bytepos, charpos;
17554 unsigned char *spec;
17555
17556 bytepos = percent_position;
17557 charpos = (STRING_MULTIBYTE (elt)
17558 ? string_byte_to_char (elt, bytepos)
17559 : bytepos);
17560 spec
17561 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17562
17563 switch (mode_line_target)
17564 {
17565 case MODE_LINE_NOPROP:
17566 case MODE_LINE_TITLE:
17567 n += store_mode_line_noprop (spec, field, prec);
17568 break;
17569 case MODE_LINE_STRING:
17570 {
17571 int len = strlen (spec);
17572 Lisp_Object tem = make_string (spec, len);
17573 props = Ftext_properties_at (make_number (charpos), elt);
17574 /* Should only keep face property in props */
17575 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17576 }
17577 break;
17578 case MODE_LINE_DISPLAY:
17579 {
17580 int nglyphs_before, nwritten;
17581
17582 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17583 nwritten = display_string (spec, Qnil, elt,
17584 charpos, 0, it,
17585 field, prec, 0,
17586 multibyte);
17587
17588 /* Assign to the glyphs written above the
17589 string where the `%x' came from, position
17590 of the `%'. */
17591 if (nwritten > 0)
17592 {
17593 struct glyph *glyph
17594 = (it->glyph_row->glyphs[TEXT_AREA]
17595 + nglyphs_before);
17596 int i;
17597
17598 for (i = 0; i < nwritten; ++i)
17599 {
17600 glyph[i].object = elt;
17601 glyph[i].charpos = charpos;
17602 }
17603
17604 n += nwritten;
17605 }
17606 }
17607 break;
17608 }
17609 }
17610 else /* c == 0 */
17611 break;
17612 }
17613 }
17614 }
17615 break;
17616
17617 case Lisp_Symbol:
17618 /* A symbol: process the value of the symbol recursively
17619 as if it appeared here directly. Avoid error if symbol void.
17620 Special case: if value of symbol is a string, output the string
17621 literally. */
17622 {
17623 register Lisp_Object tem;
17624
17625 /* If the variable is not marked as risky to set
17626 then its contents are risky to use. */
17627 if (NILP (Fget (elt, Qrisky_local_variable)))
17628 risky = 1;
17629
17630 tem = Fboundp (elt);
17631 if (!NILP (tem))
17632 {
17633 tem = Fsymbol_value (elt);
17634 /* If value is a string, output that string literally:
17635 don't check for % within it. */
17636 if (STRINGP (tem))
17637 literal = 1;
17638
17639 if (!EQ (tem, elt))
17640 {
17641 /* Give up right away for nil or t. */
17642 elt = tem;
17643 goto tail_recurse;
17644 }
17645 }
17646 }
17647 break;
17648
17649 case Lisp_Cons:
17650 {
17651 register Lisp_Object car, tem;
17652
17653 /* A cons cell: five distinct cases.
17654 If first element is :eval or :propertize, do something special.
17655 If first element is a string or a cons, process all the elements
17656 and effectively concatenate them.
17657 If first element is a negative number, truncate displaying cdr to
17658 at most that many characters. If positive, pad (with spaces)
17659 to at least that many characters.
17660 If first element is a symbol, process the cadr or caddr recursively
17661 according to whether the symbol's value is non-nil or nil. */
17662 car = XCAR (elt);
17663 if (EQ (car, QCeval))
17664 {
17665 /* An element of the form (:eval FORM) means evaluate FORM
17666 and use the result as mode line elements. */
17667
17668 if (risky)
17669 break;
17670
17671 if (CONSP (XCDR (elt)))
17672 {
17673 Lisp_Object spec;
17674 spec = safe_eval (XCAR (XCDR (elt)));
17675 n += display_mode_element (it, depth, field_width - n,
17676 precision - n, spec, props,
17677 risky);
17678 }
17679 }
17680 else if (EQ (car, QCpropertize))
17681 {
17682 /* An element of the form (:propertize ELT PROPS...)
17683 means display ELT but applying properties PROPS. */
17684
17685 if (risky)
17686 break;
17687
17688 if (CONSP (XCDR (elt)))
17689 n += display_mode_element (it, depth, field_width - n,
17690 precision - n, XCAR (XCDR (elt)),
17691 XCDR (XCDR (elt)), risky);
17692 }
17693 else if (SYMBOLP (car))
17694 {
17695 tem = Fboundp (car);
17696 elt = XCDR (elt);
17697 if (!CONSP (elt))
17698 goto invalid;
17699 /* elt is now the cdr, and we know it is a cons cell.
17700 Use its car if CAR has a non-nil value. */
17701 if (!NILP (tem))
17702 {
17703 tem = Fsymbol_value (car);
17704 if (!NILP (tem))
17705 {
17706 elt = XCAR (elt);
17707 goto tail_recurse;
17708 }
17709 }
17710 /* Symbol's value is nil (or symbol is unbound)
17711 Get the cddr of the original list
17712 and if possible find the caddr and use that. */
17713 elt = XCDR (elt);
17714 if (NILP (elt))
17715 break;
17716 else if (!CONSP (elt))
17717 goto invalid;
17718 elt = XCAR (elt);
17719 goto tail_recurse;
17720 }
17721 else if (INTEGERP (car))
17722 {
17723 register int lim = XINT (car);
17724 elt = XCDR (elt);
17725 if (lim < 0)
17726 {
17727 /* Negative int means reduce maximum width. */
17728 if (precision <= 0)
17729 precision = -lim;
17730 else
17731 precision = min (precision, -lim);
17732 }
17733 else if (lim > 0)
17734 {
17735 /* Padding specified. Don't let it be more than
17736 current maximum. */
17737 if (precision > 0)
17738 lim = min (precision, lim);
17739
17740 /* If that's more padding than already wanted, queue it.
17741 But don't reduce padding already specified even if
17742 that is beyond the current truncation point. */
17743 field_width = max (lim, field_width);
17744 }
17745 goto tail_recurse;
17746 }
17747 else if (STRINGP (car) || CONSP (car))
17748 {
17749 register int limit = 50;
17750 /* Limit is to protect against circular lists. */
17751 while (CONSP (elt)
17752 && --limit > 0
17753 && (precision <= 0 || n < precision))
17754 {
17755 n += display_mode_element (it, depth,
17756 /* Do padding only after the last
17757 element in the list. */
17758 (! CONSP (XCDR (elt))
17759 ? field_width - n
17760 : 0),
17761 precision - n, XCAR (elt),
17762 props, risky);
17763 elt = XCDR (elt);
17764 }
17765 }
17766 }
17767 break;
17768
17769 default:
17770 invalid:
17771 elt = build_string ("*invalid*");
17772 goto tail_recurse;
17773 }
17774
17775 /* Pad to FIELD_WIDTH. */
17776 if (field_width > 0 && n < field_width)
17777 {
17778 switch (mode_line_target)
17779 {
17780 case MODE_LINE_NOPROP:
17781 case MODE_LINE_TITLE:
17782 n += store_mode_line_noprop ("", field_width - n, 0);
17783 break;
17784 case MODE_LINE_STRING:
17785 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17786 break;
17787 case MODE_LINE_DISPLAY:
17788 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17789 0, 0, 0);
17790 break;
17791 }
17792 }
17793
17794 return n;
17795 }
17796
17797 /* Store a mode-line string element in mode_line_string_list.
17798
17799 If STRING is non-null, display that C string. Otherwise, the Lisp
17800 string LISP_STRING is displayed.
17801
17802 FIELD_WIDTH is the minimum number of output glyphs to produce.
17803 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17804 with spaces. FIELD_WIDTH <= 0 means don't pad.
17805
17806 PRECISION is the maximum number of characters to output from
17807 STRING. PRECISION <= 0 means don't truncate the string.
17808
17809 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17810 properties to the string.
17811
17812 PROPS are the properties to add to the string.
17813 The mode_line_string_face face property is always added to the string.
17814 */
17815
17816 static int
17817 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17818 char *string;
17819 Lisp_Object lisp_string;
17820 int copy_string;
17821 int field_width;
17822 int precision;
17823 Lisp_Object props;
17824 {
17825 int len;
17826 int n = 0;
17827
17828 if (string != NULL)
17829 {
17830 len = strlen (string);
17831 if (precision > 0 && len > precision)
17832 len = precision;
17833 lisp_string = make_string (string, len);
17834 if (NILP (props))
17835 props = mode_line_string_face_prop;
17836 else if (!NILP (mode_line_string_face))
17837 {
17838 Lisp_Object face = Fplist_get (props, Qface);
17839 props = Fcopy_sequence (props);
17840 if (NILP (face))
17841 face = mode_line_string_face;
17842 else
17843 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17844 props = Fplist_put (props, Qface, face);
17845 }
17846 Fadd_text_properties (make_number (0), make_number (len),
17847 props, lisp_string);
17848 }
17849 else
17850 {
17851 len = XFASTINT (Flength (lisp_string));
17852 if (precision > 0 && len > precision)
17853 {
17854 len = precision;
17855 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17856 precision = -1;
17857 }
17858 if (!NILP (mode_line_string_face))
17859 {
17860 Lisp_Object face;
17861 if (NILP (props))
17862 props = Ftext_properties_at (make_number (0), lisp_string);
17863 face = Fplist_get (props, Qface);
17864 if (NILP (face))
17865 face = mode_line_string_face;
17866 else
17867 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17868 props = Fcons (Qface, Fcons (face, Qnil));
17869 if (copy_string)
17870 lisp_string = Fcopy_sequence (lisp_string);
17871 }
17872 if (!NILP (props))
17873 Fadd_text_properties (make_number (0), make_number (len),
17874 props, lisp_string);
17875 }
17876
17877 if (len > 0)
17878 {
17879 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17880 n += len;
17881 }
17882
17883 if (field_width > len)
17884 {
17885 field_width -= len;
17886 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17887 if (!NILP (props))
17888 Fadd_text_properties (make_number (0), make_number (field_width),
17889 props, lisp_string);
17890 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17891 n += field_width;
17892 }
17893
17894 return n;
17895 }
17896
17897
17898 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17899 1, 4, 0,
17900 doc: /* Format a string out of a mode line format specification.
17901 First arg FORMAT specifies the mode line format (see `mode-line-format'
17902 for details) to use.
17903
17904 Optional second arg FACE specifies the face property to put
17905 on all characters for which no face is specified.
17906 The value t means whatever face the window's mode line currently uses
17907 \(either `mode-line' or `mode-line-inactive', depending).
17908 A value of nil means the default is no face property.
17909 If FACE is an integer, the value string has no text properties.
17910
17911 Optional third and fourth args WINDOW and BUFFER specify the window
17912 and buffer to use as the context for the formatting (defaults
17913 are the selected window and the window's buffer). */)
17914 (format, face, window, buffer)
17915 Lisp_Object format, face, window, buffer;
17916 {
17917 struct it it;
17918 int len;
17919 struct window *w;
17920 struct buffer *old_buffer = NULL;
17921 int face_id = -1;
17922 int no_props = INTEGERP (face);
17923 int count = SPECPDL_INDEX ();
17924 Lisp_Object str;
17925 int string_start = 0;
17926
17927 if (NILP (window))
17928 window = selected_window;
17929 CHECK_WINDOW (window);
17930 w = XWINDOW (window);
17931
17932 if (NILP (buffer))
17933 buffer = w->buffer;
17934 CHECK_BUFFER (buffer);
17935
17936 /* Make formatting the modeline a non-op when noninteractive, otherwise
17937 there will be problems later caused by a partially initialized frame. */
17938 if (NILP (format) || noninteractive)
17939 return empty_unibyte_string;
17940
17941 if (no_props)
17942 face = Qnil;
17943
17944 if (!NILP (face))
17945 {
17946 if (EQ (face, Qt))
17947 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17948 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
17949 }
17950
17951 if (face_id < 0)
17952 face_id = DEFAULT_FACE_ID;
17953
17954 if (XBUFFER (buffer) != current_buffer)
17955 old_buffer = current_buffer;
17956
17957 /* Save things including mode_line_proptrans_alist,
17958 and set that to nil so that we don't alter the outer value. */
17959 record_unwind_protect (unwind_format_mode_line,
17960 format_mode_line_unwind_data
17961 (old_buffer, selected_window, 1));
17962 mode_line_proptrans_alist = Qnil;
17963
17964 Fselect_window (window, Qt);
17965 if (old_buffer)
17966 set_buffer_internal_1 (XBUFFER (buffer));
17967
17968 init_iterator (&it, w, -1, -1, NULL, face_id);
17969
17970 if (no_props)
17971 {
17972 mode_line_target = MODE_LINE_NOPROP;
17973 mode_line_string_face_prop = Qnil;
17974 mode_line_string_list = Qnil;
17975 string_start = MODE_LINE_NOPROP_LEN (0);
17976 }
17977 else
17978 {
17979 mode_line_target = MODE_LINE_STRING;
17980 mode_line_string_list = Qnil;
17981 mode_line_string_face = face;
17982 mode_line_string_face_prop
17983 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17984 }
17985
17986 push_kboard (FRAME_KBOARD (it.f));
17987 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17988 pop_kboard ();
17989
17990 if (no_props)
17991 {
17992 len = MODE_LINE_NOPROP_LEN (string_start);
17993 str = make_string (mode_line_noprop_buf + string_start, len);
17994 }
17995 else
17996 {
17997 mode_line_string_list = Fnreverse (mode_line_string_list);
17998 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17999 empty_unibyte_string);
18000 }
18001
18002 unbind_to (count, Qnil);
18003 return str;
18004 }
18005
18006 /* Write a null-terminated, right justified decimal representation of
18007 the positive integer D to BUF using a minimal field width WIDTH. */
18008
18009 static void
18010 pint2str (buf, width, d)
18011 register char *buf;
18012 register int width;
18013 register int d;
18014 {
18015 register char *p = buf;
18016
18017 if (d <= 0)
18018 *p++ = '0';
18019 else
18020 {
18021 while (d > 0)
18022 {
18023 *p++ = d % 10 + '0';
18024 d /= 10;
18025 }
18026 }
18027
18028 for (width -= (int) (p - buf); width > 0; --width)
18029 *p++ = ' ';
18030 *p-- = '\0';
18031 while (p > buf)
18032 {
18033 d = *buf;
18034 *buf++ = *p;
18035 *p-- = d;
18036 }
18037 }
18038
18039 /* Write a null-terminated, right justified decimal and "human
18040 readable" representation of the nonnegative integer D to BUF using
18041 a minimal field width WIDTH. D should be smaller than 999.5e24. */
18042
18043 static const char power_letter[] =
18044 {
18045 0, /* not used */
18046 'k', /* kilo */
18047 'M', /* mega */
18048 'G', /* giga */
18049 'T', /* tera */
18050 'P', /* peta */
18051 'E', /* exa */
18052 'Z', /* zetta */
18053 'Y' /* yotta */
18054 };
18055
18056 static void
18057 pint2hrstr (buf, width, d)
18058 char *buf;
18059 int width;
18060 int d;
18061 {
18062 /* We aim to represent the nonnegative integer D as
18063 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
18064 int quotient = d;
18065 int remainder = 0;
18066 /* -1 means: do not use TENTHS. */
18067 int tenths = -1;
18068 int exponent = 0;
18069
18070 /* Length of QUOTIENT.TENTHS as a string. */
18071 int length;
18072
18073 char * psuffix;
18074 char * p;
18075
18076 if (1000 <= quotient)
18077 {
18078 /* Scale to the appropriate EXPONENT. */
18079 do
18080 {
18081 remainder = quotient % 1000;
18082 quotient /= 1000;
18083 exponent++;
18084 }
18085 while (1000 <= quotient);
18086
18087 /* Round to nearest and decide whether to use TENTHS or not. */
18088 if (quotient <= 9)
18089 {
18090 tenths = remainder / 100;
18091 if (50 <= remainder % 100)
18092 {
18093 if (tenths < 9)
18094 tenths++;
18095 else
18096 {
18097 quotient++;
18098 if (quotient == 10)
18099 tenths = -1;
18100 else
18101 tenths = 0;
18102 }
18103 }
18104 }
18105 else
18106 if (500 <= remainder)
18107 {
18108 if (quotient < 999)
18109 quotient++;
18110 else
18111 {
18112 quotient = 1;
18113 exponent++;
18114 tenths = 0;
18115 }
18116 }
18117 }
18118
18119 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
18120 if (tenths == -1 && quotient <= 99)
18121 if (quotient <= 9)
18122 length = 1;
18123 else
18124 length = 2;
18125 else
18126 length = 3;
18127 p = psuffix = buf + max (width, length);
18128
18129 /* Print EXPONENT. */
18130 if (exponent)
18131 *psuffix++ = power_letter[exponent];
18132 *psuffix = '\0';
18133
18134 /* Print TENTHS. */
18135 if (tenths >= 0)
18136 {
18137 *--p = '0' + tenths;
18138 *--p = '.';
18139 }
18140
18141 /* Print QUOTIENT. */
18142 do
18143 {
18144 int digit = quotient % 10;
18145 *--p = '0' + digit;
18146 }
18147 while ((quotient /= 10) != 0);
18148
18149 /* Print leading spaces. */
18150 while (buf < p)
18151 *--p = ' ';
18152 }
18153
18154 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
18155 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
18156 type of CODING_SYSTEM. Return updated pointer into BUF. */
18157
18158 static unsigned char invalid_eol_type[] = "(*invalid*)";
18159
18160 static char *
18161 decode_mode_spec_coding (coding_system, buf, eol_flag)
18162 Lisp_Object coding_system;
18163 register char *buf;
18164 int eol_flag;
18165 {
18166 Lisp_Object val;
18167 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
18168 const unsigned char *eol_str;
18169 int eol_str_len;
18170 /* The EOL conversion we are using. */
18171 Lisp_Object eoltype;
18172
18173 val = CODING_SYSTEM_SPEC (coding_system);
18174 eoltype = Qnil;
18175
18176 if (!VECTORP (val)) /* Not yet decided. */
18177 {
18178 if (multibyte)
18179 *buf++ = '-';
18180 if (eol_flag)
18181 eoltype = eol_mnemonic_undecided;
18182 /* Don't mention EOL conversion if it isn't decided. */
18183 }
18184 else
18185 {
18186 Lisp_Object attrs;
18187 Lisp_Object eolvalue;
18188
18189 attrs = AREF (val, 0);
18190 eolvalue = AREF (val, 2);
18191
18192 if (multibyte)
18193 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
18194
18195 if (eol_flag)
18196 {
18197 /* The EOL conversion that is normal on this system. */
18198
18199 if (NILP (eolvalue)) /* Not yet decided. */
18200 eoltype = eol_mnemonic_undecided;
18201 else if (VECTORP (eolvalue)) /* Not yet decided. */
18202 eoltype = eol_mnemonic_undecided;
18203 else /* eolvalue is Qunix, Qdos, or Qmac. */
18204 eoltype = (EQ (eolvalue, Qunix)
18205 ? eol_mnemonic_unix
18206 : (EQ (eolvalue, Qdos) == 1
18207 ? eol_mnemonic_dos : eol_mnemonic_mac));
18208 }
18209 }
18210
18211 if (eol_flag)
18212 {
18213 /* Mention the EOL conversion if it is not the usual one. */
18214 if (STRINGP (eoltype))
18215 {
18216 eol_str = SDATA (eoltype);
18217 eol_str_len = SBYTES (eoltype);
18218 }
18219 else if (CHARACTERP (eoltype))
18220 {
18221 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
18222 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
18223 eol_str = tmp;
18224 }
18225 else
18226 {
18227 eol_str = invalid_eol_type;
18228 eol_str_len = sizeof (invalid_eol_type) - 1;
18229 }
18230 bcopy (eol_str, buf, eol_str_len);
18231 buf += eol_str_len;
18232 }
18233
18234 return buf;
18235 }
18236
18237 /* Return a string for the output of a mode line %-spec for window W,
18238 generated by character C. PRECISION >= 0 means don't return a
18239 string longer than that value. FIELD_WIDTH > 0 means pad the
18240 string returned with spaces to that value. Return 1 in *MULTIBYTE
18241 if the result is multibyte text.
18242
18243 Note we operate on the current buffer for most purposes,
18244 the exception being w->base_line_pos. */
18245
18246 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
18247
18248 static char *
18249 decode_mode_spec (w, c, field_width, precision, multibyte)
18250 struct window *w;
18251 register int c;
18252 int field_width, precision;
18253 int *multibyte;
18254 {
18255 Lisp_Object obj;
18256 struct frame *f = XFRAME (WINDOW_FRAME (w));
18257 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
18258 struct buffer *b = current_buffer;
18259
18260 obj = Qnil;
18261 *multibyte = 0;
18262
18263 switch (c)
18264 {
18265 case '*':
18266 if (!NILP (b->read_only))
18267 return "%";
18268 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18269 return "*";
18270 return "-";
18271
18272 case '+':
18273 /* This differs from %* only for a modified read-only buffer. */
18274 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18275 return "*";
18276 if (!NILP (b->read_only))
18277 return "%";
18278 return "-";
18279
18280 case '&':
18281 /* This differs from %* in ignoring read-only-ness. */
18282 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18283 return "*";
18284 return "-";
18285
18286 case '%':
18287 return "%";
18288
18289 case '[':
18290 {
18291 int i;
18292 char *p;
18293
18294 if (command_loop_level > 5)
18295 return "[[[... ";
18296 p = decode_mode_spec_buf;
18297 for (i = 0; i < command_loop_level; i++)
18298 *p++ = '[';
18299 *p = 0;
18300 return decode_mode_spec_buf;
18301 }
18302
18303 case ']':
18304 {
18305 int i;
18306 char *p;
18307
18308 if (command_loop_level > 5)
18309 return " ...]]]";
18310 p = decode_mode_spec_buf;
18311 for (i = 0; i < command_loop_level; i++)
18312 *p++ = ']';
18313 *p = 0;
18314 return decode_mode_spec_buf;
18315 }
18316
18317 case '-':
18318 {
18319 register int i;
18320
18321 /* Let lots_of_dashes be a string of infinite length. */
18322 if (mode_line_target == MODE_LINE_NOPROP ||
18323 mode_line_target == MODE_LINE_STRING)
18324 return "--";
18325 if (field_width <= 0
18326 || field_width > sizeof (lots_of_dashes))
18327 {
18328 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
18329 decode_mode_spec_buf[i] = '-';
18330 decode_mode_spec_buf[i] = '\0';
18331 return decode_mode_spec_buf;
18332 }
18333 else
18334 return lots_of_dashes;
18335 }
18336
18337 case 'b':
18338 obj = b->name;
18339 break;
18340
18341 case 'c':
18342 /* %c and %l are ignored in `frame-title-format'.
18343 (In redisplay_internal, the frame title is drawn _before_ the
18344 windows are updated, so the stuff which depends on actual
18345 window contents (such as %l) may fail to render properly, or
18346 even crash emacs.) */
18347 if (mode_line_target == MODE_LINE_TITLE)
18348 return "";
18349 else
18350 {
18351 int col = (int) current_column (); /* iftc */
18352 w->column_number_displayed = make_number (col);
18353 pint2str (decode_mode_spec_buf, field_width, col);
18354 return decode_mode_spec_buf;
18355 }
18356
18357 case 'e':
18358 #ifndef SYSTEM_MALLOC
18359 {
18360 if (NILP (Vmemory_full))
18361 return "";
18362 else
18363 return "!MEM FULL! ";
18364 }
18365 #else
18366 return "";
18367 #endif
18368
18369 case 'F':
18370 /* %F displays the frame name. */
18371 if (!NILP (f->title))
18372 return (char *) SDATA (f->title);
18373 if (f->explicit_name || ! FRAME_WINDOW_P (f))
18374 return (char *) SDATA (f->name);
18375 return "Emacs";
18376
18377 case 'f':
18378 obj = b->filename;
18379 break;
18380
18381 case 'i':
18382 {
18383 int size = ZV - BEGV;
18384 pint2str (decode_mode_spec_buf, field_width, size);
18385 return decode_mode_spec_buf;
18386 }
18387
18388 case 'I':
18389 {
18390 int size = ZV - BEGV;
18391 pint2hrstr (decode_mode_spec_buf, field_width, size);
18392 return decode_mode_spec_buf;
18393 }
18394
18395 case 'l':
18396 {
18397 int startpos, startpos_byte, line, linepos, linepos_byte;
18398 int topline, nlines, junk, height;
18399
18400 /* %c and %l are ignored in `frame-title-format'. */
18401 if (mode_line_target == MODE_LINE_TITLE)
18402 return "";
18403
18404 startpos = XMARKER (w->start)->charpos;
18405 startpos_byte = marker_byte_position (w->start);
18406 height = WINDOW_TOTAL_LINES (w);
18407
18408 /* If we decided that this buffer isn't suitable for line numbers,
18409 don't forget that too fast. */
18410 if (EQ (w->base_line_pos, w->buffer))
18411 goto no_value;
18412 /* But do forget it, if the window shows a different buffer now. */
18413 else if (BUFFERP (w->base_line_pos))
18414 w->base_line_pos = Qnil;
18415
18416 /* If the buffer is very big, don't waste time. */
18417 if (INTEGERP (Vline_number_display_limit)
18418 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
18419 {
18420 w->base_line_pos = Qnil;
18421 w->base_line_number = Qnil;
18422 goto no_value;
18423 }
18424
18425 if (INTEGERP (w->base_line_number)
18426 && INTEGERP (w->base_line_pos)
18427 && XFASTINT (w->base_line_pos) <= startpos)
18428 {
18429 line = XFASTINT (w->base_line_number);
18430 linepos = XFASTINT (w->base_line_pos);
18431 linepos_byte = buf_charpos_to_bytepos (b, linepos);
18432 }
18433 else
18434 {
18435 line = 1;
18436 linepos = BUF_BEGV (b);
18437 linepos_byte = BUF_BEGV_BYTE (b);
18438 }
18439
18440 /* Count lines from base line to window start position. */
18441 nlines = display_count_lines (linepos, linepos_byte,
18442 startpos_byte,
18443 startpos, &junk);
18444
18445 topline = nlines + line;
18446
18447 /* Determine a new base line, if the old one is too close
18448 or too far away, or if we did not have one.
18449 "Too close" means it's plausible a scroll-down would
18450 go back past it. */
18451 if (startpos == BUF_BEGV (b))
18452 {
18453 w->base_line_number = make_number (topline);
18454 w->base_line_pos = make_number (BUF_BEGV (b));
18455 }
18456 else if (nlines < height + 25 || nlines > height * 3 + 50
18457 || linepos == BUF_BEGV (b))
18458 {
18459 int limit = BUF_BEGV (b);
18460 int limit_byte = BUF_BEGV_BYTE (b);
18461 int position;
18462 int distance = (height * 2 + 30) * line_number_display_limit_width;
18463
18464 if (startpos - distance > limit)
18465 {
18466 limit = startpos - distance;
18467 limit_byte = CHAR_TO_BYTE (limit);
18468 }
18469
18470 nlines = display_count_lines (startpos, startpos_byte,
18471 limit_byte,
18472 - (height * 2 + 30),
18473 &position);
18474 /* If we couldn't find the lines we wanted within
18475 line_number_display_limit_width chars per line,
18476 give up on line numbers for this window. */
18477 if (position == limit_byte && limit == startpos - distance)
18478 {
18479 w->base_line_pos = w->buffer;
18480 w->base_line_number = Qnil;
18481 goto no_value;
18482 }
18483
18484 w->base_line_number = make_number (topline - nlines);
18485 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
18486 }
18487
18488 /* Now count lines from the start pos to point. */
18489 nlines = display_count_lines (startpos, startpos_byte,
18490 PT_BYTE, PT, &junk);
18491
18492 /* Record that we did display the line number. */
18493 line_number_displayed = 1;
18494
18495 /* Make the string to show. */
18496 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
18497 return decode_mode_spec_buf;
18498 no_value:
18499 {
18500 char* p = decode_mode_spec_buf;
18501 int pad = field_width - 2;
18502 while (pad-- > 0)
18503 *p++ = ' ';
18504 *p++ = '?';
18505 *p++ = '?';
18506 *p = '\0';
18507 return decode_mode_spec_buf;
18508 }
18509 }
18510 break;
18511
18512 case 'm':
18513 obj = b->mode_name;
18514 break;
18515
18516 case 'n':
18517 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
18518 return " Narrow";
18519 break;
18520
18521 case 'p':
18522 {
18523 int pos = marker_position (w->start);
18524 int total = BUF_ZV (b) - BUF_BEGV (b);
18525
18526 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
18527 {
18528 if (pos <= BUF_BEGV (b))
18529 return "All";
18530 else
18531 return "Bottom";
18532 }
18533 else if (pos <= BUF_BEGV (b))
18534 return "Top";
18535 else
18536 {
18537 if (total > 1000000)
18538 /* Do it differently for a large value, to avoid overflow. */
18539 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18540 else
18541 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
18542 /* We can't normally display a 3-digit number,
18543 so get us a 2-digit number that is close. */
18544 if (total == 100)
18545 total = 99;
18546 sprintf (decode_mode_spec_buf, "%2d%%", total);
18547 return decode_mode_spec_buf;
18548 }
18549 }
18550
18551 /* Display percentage of size above the bottom of the screen. */
18552 case 'P':
18553 {
18554 int toppos = marker_position (w->start);
18555 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18556 int total = BUF_ZV (b) - BUF_BEGV (b);
18557
18558 if (botpos >= BUF_ZV (b))
18559 {
18560 if (toppos <= BUF_BEGV (b))
18561 return "All";
18562 else
18563 return "Bottom";
18564 }
18565 else
18566 {
18567 if (total > 1000000)
18568 /* Do it differently for a large value, to avoid overflow. */
18569 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18570 else
18571 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18572 /* We can't normally display a 3-digit number,
18573 so get us a 2-digit number that is close. */
18574 if (total == 100)
18575 total = 99;
18576 if (toppos <= BUF_BEGV (b))
18577 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18578 else
18579 sprintf (decode_mode_spec_buf, "%2d%%", total);
18580 return decode_mode_spec_buf;
18581 }
18582 }
18583
18584 case 's':
18585 /* status of process */
18586 obj = Fget_buffer_process (Fcurrent_buffer ());
18587 if (NILP (obj))
18588 return "no process";
18589 #ifdef subprocesses
18590 obj = Fsymbol_name (Fprocess_status (obj));
18591 #endif
18592 break;
18593
18594 case '@':
18595 {
18596 Lisp_Object val;
18597 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18598 if (NILP (val))
18599 return "-";
18600 else
18601 return "@";
18602 }
18603
18604 case 't': /* indicate TEXT or BINARY */
18605 #ifdef MODE_LINE_BINARY_TEXT
18606 return MODE_LINE_BINARY_TEXT (b);
18607 #else
18608 return "T";
18609 #endif
18610
18611 case 'z':
18612 /* coding-system (not including end-of-line format) */
18613 case 'Z':
18614 /* coding-system (including end-of-line type) */
18615 {
18616 int eol_flag = (c == 'Z');
18617 char *p = decode_mode_spec_buf;
18618
18619 if (! FRAME_WINDOW_P (f))
18620 {
18621 /* No need to mention EOL here--the terminal never needs
18622 to do EOL conversion. */
18623 p = decode_mode_spec_coding (CODING_ID_NAME
18624 (FRAME_KEYBOARD_CODING (f)->id),
18625 p, 0);
18626 p = decode_mode_spec_coding (CODING_ID_NAME
18627 (FRAME_TERMINAL_CODING (f)->id),
18628 p, 0);
18629 }
18630 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18631 p, eol_flag);
18632
18633 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18634 #ifdef subprocesses
18635 obj = Fget_buffer_process (Fcurrent_buffer ());
18636 if (PROCESSP (obj))
18637 {
18638 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18639 p, eol_flag);
18640 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18641 p, eol_flag);
18642 }
18643 #endif /* subprocesses */
18644 #endif /* 0 */
18645 *p = 0;
18646 return decode_mode_spec_buf;
18647 }
18648 }
18649
18650 if (STRINGP (obj))
18651 {
18652 *multibyte = STRING_MULTIBYTE (obj);
18653 return (char *) SDATA (obj);
18654 }
18655 else
18656 return "";
18657 }
18658
18659
18660 /* Count up to COUNT lines starting from START / START_BYTE.
18661 But don't go beyond LIMIT_BYTE.
18662 Return the number of lines thus found (always nonnegative).
18663
18664 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18665
18666 static int
18667 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18668 int start, start_byte, limit_byte, count;
18669 int *byte_pos_ptr;
18670 {
18671 register unsigned char *cursor;
18672 unsigned char *base;
18673
18674 register int ceiling;
18675 register unsigned char *ceiling_addr;
18676 int orig_count = count;
18677
18678 /* If we are not in selective display mode,
18679 check only for newlines. */
18680 int selective_display = (!NILP (current_buffer->selective_display)
18681 && !INTEGERP (current_buffer->selective_display));
18682
18683 if (count > 0)
18684 {
18685 while (start_byte < limit_byte)
18686 {
18687 ceiling = BUFFER_CEILING_OF (start_byte);
18688 ceiling = min (limit_byte - 1, ceiling);
18689 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18690 base = (cursor = BYTE_POS_ADDR (start_byte));
18691 while (1)
18692 {
18693 if (selective_display)
18694 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18695 ;
18696 else
18697 while (*cursor != '\n' && ++cursor != ceiling_addr)
18698 ;
18699
18700 if (cursor != ceiling_addr)
18701 {
18702 if (--count == 0)
18703 {
18704 start_byte += cursor - base + 1;
18705 *byte_pos_ptr = start_byte;
18706 return orig_count;
18707 }
18708 else
18709 if (++cursor == ceiling_addr)
18710 break;
18711 }
18712 else
18713 break;
18714 }
18715 start_byte += cursor - base;
18716 }
18717 }
18718 else
18719 {
18720 while (start_byte > limit_byte)
18721 {
18722 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18723 ceiling = max (limit_byte, ceiling);
18724 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18725 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18726 while (1)
18727 {
18728 if (selective_display)
18729 while (--cursor != ceiling_addr
18730 && *cursor != '\n' && *cursor != 015)
18731 ;
18732 else
18733 while (--cursor != ceiling_addr && *cursor != '\n')
18734 ;
18735
18736 if (cursor != ceiling_addr)
18737 {
18738 if (++count == 0)
18739 {
18740 start_byte += cursor - base + 1;
18741 *byte_pos_ptr = start_byte;
18742 /* When scanning backwards, we should
18743 not count the newline posterior to which we stop. */
18744 return - orig_count - 1;
18745 }
18746 }
18747 else
18748 break;
18749 }
18750 /* Here we add 1 to compensate for the last decrement
18751 of CURSOR, which took it past the valid range. */
18752 start_byte += cursor - base + 1;
18753 }
18754 }
18755
18756 *byte_pos_ptr = limit_byte;
18757
18758 if (count < 0)
18759 return - orig_count + count;
18760 return orig_count - count;
18761
18762 }
18763
18764
18765 \f
18766 /***********************************************************************
18767 Displaying strings
18768 ***********************************************************************/
18769
18770 /* Display a NUL-terminated string, starting with index START.
18771
18772 If STRING is non-null, display that C string. Otherwise, the Lisp
18773 string LISP_STRING is displayed.
18774
18775 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18776 FACE_STRING. Display STRING or LISP_STRING with the face at
18777 FACE_STRING_POS in FACE_STRING:
18778
18779 Display the string in the environment given by IT, but use the
18780 standard display table, temporarily.
18781
18782 FIELD_WIDTH is the minimum number of output glyphs to produce.
18783 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18784 with spaces. If STRING has more characters, more than FIELD_WIDTH
18785 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18786
18787 PRECISION is the maximum number of characters to output from
18788 STRING. PRECISION < 0 means don't truncate the string.
18789
18790 This is roughly equivalent to printf format specifiers:
18791
18792 FIELD_WIDTH PRECISION PRINTF
18793 ----------------------------------------
18794 -1 -1 %s
18795 -1 10 %.10s
18796 10 -1 %10s
18797 20 10 %20.10s
18798
18799 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18800 display them, and < 0 means obey the current buffer's value of
18801 enable_multibyte_characters.
18802
18803 Value is the number of columns displayed. */
18804
18805 static int
18806 display_string (string, lisp_string, face_string, face_string_pos,
18807 start, it, field_width, precision, max_x, multibyte)
18808 unsigned char *string;
18809 Lisp_Object lisp_string;
18810 Lisp_Object face_string;
18811 EMACS_INT face_string_pos;
18812 EMACS_INT start;
18813 struct it *it;
18814 int field_width, precision, max_x;
18815 int multibyte;
18816 {
18817 int hpos_at_start = it->hpos;
18818 int saved_face_id = it->face_id;
18819 struct glyph_row *row = it->glyph_row;
18820
18821 /* Initialize the iterator IT for iteration over STRING beginning
18822 with index START. */
18823 reseat_to_string (it, string, lisp_string, start,
18824 precision, field_width, multibyte);
18825
18826 /* If displaying STRING, set up the face of the iterator
18827 from LISP_STRING, if that's given. */
18828 if (STRINGP (face_string))
18829 {
18830 EMACS_INT endptr;
18831 struct face *face;
18832
18833 it->face_id
18834 = face_at_string_position (it->w, face_string, face_string_pos,
18835 0, it->region_beg_charpos,
18836 it->region_end_charpos,
18837 &endptr, it->base_face_id, 0);
18838 face = FACE_FROM_ID (it->f, it->face_id);
18839 it->face_box_p = face->box != FACE_NO_BOX;
18840 }
18841
18842 /* Set max_x to the maximum allowed X position. Don't let it go
18843 beyond the right edge of the window. */
18844 if (max_x <= 0)
18845 max_x = it->last_visible_x;
18846 else
18847 max_x = min (max_x, it->last_visible_x);
18848
18849 /* Skip over display elements that are not visible. because IT->w is
18850 hscrolled. */
18851 if (it->current_x < it->first_visible_x)
18852 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18853 MOVE_TO_POS | MOVE_TO_X);
18854
18855 row->ascent = it->max_ascent;
18856 row->height = it->max_ascent + it->max_descent;
18857 row->phys_ascent = it->max_phys_ascent;
18858 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18859 row->extra_line_spacing = it->max_extra_line_spacing;
18860
18861 /* This condition is for the case that we are called with current_x
18862 past last_visible_x. */
18863 while (it->current_x < max_x)
18864 {
18865 int x_before, x, n_glyphs_before, i, nglyphs;
18866
18867 /* Get the next display element. */
18868 if (!get_next_display_element (it))
18869 break;
18870
18871 /* Produce glyphs. */
18872 x_before = it->current_x;
18873 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18874 PRODUCE_GLYPHS (it);
18875
18876 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18877 i = 0;
18878 x = x_before;
18879 while (i < nglyphs)
18880 {
18881 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18882
18883 if (it->line_wrap != TRUNCATE
18884 && x + glyph->pixel_width > max_x)
18885 {
18886 /* End of continued line or max_x reached. */
18887 if (CHAR_GLYPH_PADDING_P (*glyph))
18888 {
18889 /* A wide character is unbreakable. */
18890 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18891 it->current_x = x_before;
18892 }
18893 else
18894 {
18895 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18896 it->current_x = x;
18897 }
18898 break;
18899 }
18900 else if (x + glyph->pixel_width >= it->first_visible_x)
18901 {
18902 /* Glyph is at least partially visible. */
18903 ++it->hpos;
18904 if (x < it->first_visible_x)
18905 it->glyph_row->x = x - it->first_visible_x;
18906 }
18907 else
18908 {
18909 /* Glyph is off the left margin of the display area.
18910 Should not happen. */
18911 abort ();
18912 }
18913
18914 row->ascent = max (row->ascent, it->max_ascent);
18915 row->height = max (row->height, it->max_ascent + it->max_descent);
18916 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18917 row->phys_height = max (row->phys_height,
18918 it->max_phys_ascent + it->max_phys_descent);
18919 row->extra_line_spacing = max (row->extra_line_spacing,
18920 it->max_extra_line_spacing);
18921 x += glyph->pixel_width;
18922 ++i;
18923 }
18924
18925 /* Stop if max_x reached. */
18926 if (i < nglyphs)
18927 break;
18928
18929 /* Stop at line ends. */
18930 if (ITERATOR_AT_END_OF_LINE_P (it))
18931 {
18932 it->continuation_lines_width = 0;
18933 break;
18934 }
18935
18936 set_iterator_to_next (it, 1);
18937
18938 /* Stop if truncating at the right edge. */
18939 if (it->line_wrap == TRUNCATE
18940 && it->current_x >= it->last_visible_x)
18941 {
18942 /* Add truncation mark, but don't do it if the line is
18943 truncated at a padding space. */
18944 if (IT_CHARPOS (*it) < it->string_nchars)
18945 {
18946 if (!FRAME_WINDOW_P (it->f))
18947 {
18948 int i, n;
18949
18950 if (it->current_x > it->last_visible_x)
18951 {
18952 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18953 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18954 break;
18955 for (n = row->used[TEXT_AREA]; i < n; ++i)
18956 {
18957 row->used[TEXT_AREA] = i;
18958 produce_special_glyphs (it, IT_TRUNCATION);
18959 }
18960 }
18961 produce_special_glyphs (it, IT_TRUNCATION);
18962 }
18963 it->glyph_row->truncated_on_right_p = 1;
18964 }
18965 break;
18966 }
18967 }
18968
18969 /* Maybe insert a truncation at the left. */
18970 if (it->first_visible_x
18971 && IT_CHARPOS (*it) > 0)
18972 {
18973 if (!FRAME_WINDOW_P (it->f))
18974 insert_left_trunc_glyphs (it);
18975 it->glyph_row->truncated_on_left_p = 1;
18976 }
18977
18978 it->face_id = saved_face_id;
18979
18980 /* Value is number of columns displayed. */
18981 return it->hpos - hpos_at_start;
18982 }
18983
18984
18985 \f
18986 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18987 appears as an element of LIST or as the car of an element of LIST.
18988 If PROPVAL is a list, compare each element against LIST in that
18989 way, and return 1/2 if any element of PROPVAL is found in LIST.
18990 Otherwise return 0. This function cannot quit.
18991 The return value is 2 if the text is invisible but with an ellipsis
18992 and 1 if it's invisible and without an ellipsis. */
18993
18994 int
18995 invisible_p (propval, list)
18996 register Lisp_Object propval;
18997 Lisp_Object list;
18998 {
18999 register Lisp_Object tail, proptail;
19000
19001 for (tail = list; CONSP (tail); tail = XCDR (tail))
19002 {
19003 register Lisp_Object tem;
19004 tem = XCAR (tail);
19005 if (EQ (propval, tem))
19006 return 1;
19007 if (CONSP (tem) && EQ (propval, XCAR (tem)))
19008 return NILP (XCDR (tem)) ? 1 : 2;
19009 }
19010
19011 if (CONSP (propval))
19012 {
19013 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
19014 {
19015 Lisp_Object propelt;
19016 propelt = XCAR (proptail);
19017 for (tail = list; CONSP (tail); tail = XCDR (tail))
19018 {
19019 register Lisp_Object tem;
19020 tem = XCAR (tail);
19021 if (EQ (propelt, tem))
19022 return 1;
19023 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
19024 return NILP (XCDR (tem)) ? 1 : 2;
19025 }
19026 }
19027 }
19028
19029 return 0;
19030 }
19031
19032 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
19033 doc: /* Non-nil if the property makes the text invisible.
19034 POS-OR-PROP can be a marker or number, in which case it is taken to be
19035 a position in the current buffer and the value of the `invisible' property
19036 is checked; or it can be some other value, which is then presumed to be the
19037 value of the `invisible' property of the text of interest.
19038 The non-nil value returned can be t for truly invisible text or something
19039 else if the text is replaced by an ellipsis. */)
19040 (pos_or_prop)
19041 Lisp_Object pos_or_prop;
19042 {
19043 Lisp_Object prop
19044 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
19045 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
19046 : pos_or_prop);
19047 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
19048 return (invis == 0 ? Qnil
19049 : invis == 1 ? Qt
19050 : make_number (invis));
19051 }
19052
19053 /* Calculate a width or height in pixels from a specification using
19054 the following elements:
19055
19056 SPEC ::=
19057 NUM - a (fractional) multiple of the default font width/height
19058 (NUM) - specifies exactly NUM pixels
19059 UNIT - a fixed number of pixels, see below.
19060 ELEMENT - size of a display element in pixels, see below.
19061 (NUM . SPEC) - equals NUM * SPEC
19062 (+ SPEC SPEC ...) - add pixel values
19063 (- SPEC SPEC ...) - subtract pixel values
19064 (- SPEC) - negate pixel value
19065
19066 NUM ::=
19067 INT or FLOAT - a number constant
19068 SYMBOL - use symbol's (buffer local) variable binding.
19069
19070 UNIT ::=
19071 in - pixels per inch *)
19072 mm - pixels per 1/1000 meter *)
19073 cm - pixels per 1/100 meter *)
19074 width - width of current font in pixels.
19075 height - height of current font in pixels.
19076
19077 *) using the ratio(s) defined in display-pixels-per-inch.
19078
19079 ELEMENT ::=
19080
19081 left-fringe - left fringe width in pixels
19082 right-fringe - right fringe width in pixels
19083
19084 left-margin - left margin width in pixels
19085 right-margin - right margin width in pixels
19086
19087 scroll-bar - scroll-bar area width in pixels
19088
19089 Examples:
19090
19091 Pixels corresponding to 5 inches:
19092 (5 . in)
19093
19094 Total width of non-text areas on left side of window (if scroll-bar is on left):
19095 '(space :width (+ left-fringe left-margin scroll-bar))
19096
19097 Align to first text column (in header line):
19098 '(space :align-to 0)
19099
19100 Align to middle of text area minus half the width of variable `my-image'
19101 containing a loaded image:
19102 '(space :align-to (0.5 . (- text my-image)))
19103
19104 Width of left margin minus width of 1 character in the default font:
19105 '(space :width (- left-margin 1))
19106
19107 Width of left margin minus width of 2 characters in the current font:
19108 '(space :width (- left-margin (2 . width)))
19109
19110 Center 1 character over left-margin (in header line):
19111 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
19112
19113 Different ways to express width of left fringe plus left margin minus one pixel:
19114 '(space :width (- (+ left-fringe left-margin) (1)))
19115 '(space :width (+ left-fringe left-margin (- (1))))
19116 '(space :width (+ left-fringe left-margin (-1)))
19117
19118 */
19119
19120 #define NUMVAL(X) \
19121 ((INTEGERP (X) || FLOATP (X)) \
19122 ? XFLOATINT (X) \
19123 : - 1)
19124
19125 int
19126 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
19127 double *res;
19128 struct it *it;
19129 Lisp_Object prop;
19130 struct font *font;
19131 int width_p, *align_to;
19132 {
19133 double pixels;
19134
19135 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
19136 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
19137
19138 if (NILP (prop))
19139 return OK_PIXELS (0);
19140
19141 xassert (FRAME_LIVE_P (it->f));
19142
19143 if (SYMBOLP (prop))
19144 {
19145 if (SCHARS (SYMBOL_NAME (prop)) == 2)
19146 {
19147 char *unit = SDATA (SYMBOL_NAME (prop));
19148
19149 if (unit[0] == 'i' && unit[1] == 'n')
19150 pixels = 1.0;
19151 else if (unit[0] == 'm' && unit[1] == 'm')
19152 pixels = 25.4;
19153 else if (unit[0] == 'c' && unit[1] == 'm')
19154 pixels = 2.54;
19155 else
19156 pixels = 0;
19157 if (pixels > 0)
19158 {
19159 double ppi;
19160 #ifdef HAVE_WINDOW_SYSTEM
19161 if (FRAME_WINDOW_P (it->f)
19162 && (ppi = (width_p
19163 ? FRAME_X_DISPLAY_INFO (it->f)->resx
19164 : FRAME_X_DISPLAY_INFO (it->f)->resy),
19165 ppi > 0))
19166 return OK_PIXELS (ppi / pixels);
19167 #endif
19168
19169 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
19170 || (CONSP (Vdisplay_pixels_per_inch)
19171 && (ppi = (width_p
19172 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
19173 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
19174 ppi > 0)))
19175 return OK_PIXELS (ppi / pixels);
19176
19177 return 0;
19178 }
19179 }
19180
19181 #ifdef HAVE_WINDOW_SYSTEM
19182 if (EQ (prop, Qheight))
19183 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
19184 if (EQ (prop, Qwidth))
19185 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
19186 #else
19187 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
19188 return OK_PIXELS (1);
19189 #endif
19190
19191 if (EQ (prop, Qtext))
19192 return OK_PIXELS (width_p
19193 ? window_box_width (it->w, TEXT_AREA)
19194 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
19195
19196 if (align_to && *align_to < 0)
19197 {
19198 *res = 0;
19199 if (EQ (prop, Qleft))
19200 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
19201 if (EQ (prop, Qright))
19202 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
19203 if (EQ (prop, Qcenter))
19204 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
19205 + window_box_width (it->w, TEXT_AREA) / 2);
19206 if (EQ (prop, Qleft_fringe))
19207 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19208 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
19209 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
19210 if (EQ (prop, Qright_fringe))
19211 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19212 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
19213 : window_box_right_offset (it->w, TEXT_AREA));
19214 if (EQ (prop, Qleft_margin))
19215 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
19216 if (EQ (prop, Qright_margin))
19217 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
19218 if (EQ (prop, Qscroll_bar))
19219 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
19220 ? 0
19221 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
19222 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19223 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19224 : 0)));
19225 }
19226 else
19227 {
19228 if (EQ (prop, Qleft_fringe))
19229 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
19230 if (EQ (prop, Qright_fringe))
19231 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
19232 if (EQ (prop, Qleft_margin))
19233 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
19234 if (EQ (prop, Qright_margin))
19235 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
19236 if (EQ (prop, Qscroll_bar))
19237 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
19238 }
19239
19240 prop = Fbuffer_local_value (prop, it->w->buffer);
19241 }
19242
19243 if (INTEGERP (prop) || FLOATP (prop))
19244 {
19245 int base_unit = (width_p
19246 ? FRAME_COLUMN_WIDTH (it->f)
19247 : FRAME_LINE_HEIGHT (it->f));
19248 return OK_PIXELS (XFLOATINT (prop) * base_unit);
19249 }
19250
19251 if (CONSP (prop))
19252 {
19253 Lisp_Object car = XCAR (prop);
19254 Lisp_Object cdr = XCDR (prop);
19255
19256 if (SYMBOLP (car))
19257 {
19258 #ifdef HAVE_WINDOW_SYSTEM
19259 if (FRAME_WINDOW_P (it->f)
19260 && valid_image_p (prop))
19261 {
19262 int id = lookup_image (it->f, prop);
19263 struct image *img = IMAGE_FROM_ID (it->f, id);
19264
19265 return OK_PIXELS (width_p ? img->width : img->height);
19266 }
19267 #endif
19268 if (EQ (car, Qplus) || EQ (car, Qminus))
19269 {
19270 int first = 1;
19271 double px;
19272
19273 pixels = 0;
19274 while (CONSP (cdr))
19275 {
19276 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
19277 font, width_p, align_to))
19278 return 0;
19279 if (first)
19280 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
19281 else
19282 pixels += px;
19283 cdr = XCDR (cdr);
19284 }
19285 if (EQ (car, Qminus))
19286 pixels = -pixels;
19287 return OK_PIXELS (pixels);
19288 }
19289
19290 car = Fbuffer_local_value (car, it->w->buffer);
19291 }
19292
19293 if (INTEGERP (car) || FLOATP (car))
19294 {
19295 double fact;
19296 pixels = XFLOATINT (car);
19297 if (NILP (cdr))
19298 return OK_PIXELS (pixels);
19299 if (calc_pixel_width_or_height (&fact, it, cdr,
19300 font, width_p, align_to))
19301 return OK_PIXELS (pixels * fact);
19302 return 0;
19303 }
19304
19305 return 0;
19306 }
19307
19308 return 0;
19309 }
19310
19311 \f
19312 /***********************************************************************
19313 Glyph Display
19314 ***********************************************************************/
19315
19316 #ifdef HAVE_WINDOW_SYSTEM
19317
19318 #if GLYPH_DEBUG
19319
19320 void
19321 dump_glyph_string (s)
19322 struct glyph_string *s;
19323 {
19324 fprintf (stderr, "glyph string\n");
19325 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
19326 s->x, s->y, s->width, s->height);
19327 fprintf (stderr, " ybase = %d\n", s->ybase);
19328 fprintf (stderr, " hl = %d\n", s->hl);
19329 fprintf (stderr, " left overhang = %d, right = %d\n",
19330 s->left_overhang, s->right_overhang);
19331 fprintf (stderr, " nchars = %d\n", s->nchars);
19332 fprintf (stderr, " extends to end of line = %d\n",
19333 s->extends_to_end_of_line_p);
19334 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
19335 fprintf (stderr, " bg width = %d\n", s->background_width);
19336 }
19337
19338 #endif /* GLYPH_DEBUG */
19339
19340 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
19341 of XChar2b structures for S; it can't be allocated in
19342 init_glyph_string because it must be allocated via `alloca'. W
19343 is the window on which S is drawn. ROW and AREA are the glyph row
19344 and area within the row from which S is constructed. START is the
19345 index of the first glyph structure covered by S. HL is a
19346 face-override for drawing S. */
19347
19348 #ifdef HAVE_NTGUI
19349 #define OPTIONAL_HDC(hdc) hdc,
19350 #define DECLARE_HDC(hdc) HDC hdc;
19351 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
19352 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
19353 #endif
19354
19355 #ifndef OPTIONAL_HDC
19356 #define OPTIONAL_HDC(hdc)
19357 #define DECLARE_HDC(hdc)
19358 #define ALLOCATE_HDC(hdc, f)
19359 #define RELEASE_HDC(hdc, f)
19360 #endif
19361
19362 static void
19363 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
19364 struct glyph_string *s;
19365 DECLARE_HDC (hdc)
19366 XChar2b *char2b;
19367 struct window *w;
19368 struct glyph_row *row;
19369 enum glyph_row_area area;
19370 int start;
19371 enum draw_glyphs_face hl;
19372 {
19373 bzero (s, sizeof *s);
19374 s->w = w;
19375 s->f = XFRAME (w->frame);
19376 #ifdef HAVE_NTGUI
19377 s->hdc = hdc;
19378 #endif
19379 s->display = FRAME_X_DISPLAY (s->f);
19380 s->window = FRAME_X_WINDOW (s->f);
19381 s->char2b = char2b;
19382 s->hl = hl;
19383 s->row = row;
19384 s->area = area;
19385 s->first_glyph = row->glyphs[area] + start;
19386 s->height = row->height;
19387 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
19388
19389 /* Display the internal border below the tool-bar window. */
19390 if (WINDOWP (s->f->tool_bar_window)
19391 && s->w == XWINDOW (s->f->tool_bar_window))
19392 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
19393
19394 s->ybase = s->y + row->ascent;
19395 }
19396
19397
19398 /* Append the list of glyph strings with head H and tail T to the list
19399 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
19400
19401 static INLINE void
19402 append_glyph_string_lists (head, tail, h, t)
19403 struct glyph_string **head, **tail;
19404 struct glyph_string *h, *t;
19405 {
19406 if (h)
19407 {
19408 if (*head)
19409 (*tail)->next = h;
19410 else
19411 *head = h;
19412 h->prev = *tail;
19413 *tail = t;
19414 }
19415 }
19416
19417
19418 /* Prepend the list of glyph strings with head H and tail T to the
19419 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
19420 result. */
19421
19422 static INLINE void
19423 prepend_glyph_string_lists (head, tail, h, t)
19424 struct glyph_string **head, **tail;
19425 struct glyph_string *h, *t;
19426 {
19427 if (h)
19428 {
19429 if (*head)
19430 (*head)->prev = t;
19431 else
19432 *tail = t;
19433 t->next = *head;
19434 *head = h;
19435 }
19436 }
19437
19438
19439 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
19440 Set *HEAD and *TAIL to the resulting list. */
19441
19442 static INLINE void
19443 append_glyph_string (head, tail, s)
19444 struct glyph_string **head, **tail;
19445 struct glyph_string *s;
19446 {
19447 s->next = s->prev = NULL;
19448 append_glyph_string_lists (head, tail, s, s);
19449 }
19450
19451
19452 /* Get face and two-byte form of character C in face FACE_ID on frame
19453 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19454 means we want to display multibyte text. DISPLAY_P non-zero means
19455 make sure that X resources for the face returned are allocated.
19456 Value is a pointer to a realized face that is ready for display if
19457 DISPLAY_P is non-zero. */
19458
19459 static INLINE struct face *
19460 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19461 struct frame *f;
19462 int c, face_id;
19463 XChar2b *char2b;
19464 int multibyte_p, display_p;
19465 {
19466 struct face *face = FACE_FROM_ID (f, face_id);
19467
19468 if (face->font)
19469 {
19470 unsigned code = face->font->driver->encode_char (face->font, c);
19471
19472 if (code != FONT_INVALID_CODE)
19473 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19474 else
19475 STORE_XCHAR2B (char2b, 0, 0);
19476 }
19477
19478 /* Make sure X resources of the face are allocated. */
19479 #ifdef HAVE_X_WINDOWS
19480 if (display_p)
19481 #endif
19482 {
19483 xassert (face != NULL);
19484 PREPARE_FACE_FOR_DISPLAY (f, face);
19485 }
19486
19487 return face;
19488 }
19489
19490
19491 /* Get face and two-byte form of character glyph GLYPH on frame F.
19492 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
19493 a pointer to a realized face that is ready for display. */
19494
19495 static INLINE struct face *
19496 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19497 struct frame *f;
19498 struct glyph *glyph;
19499 XChar2b *char2b;
19500 int *two_byte_p;
19501 {
19502 struct face *face;
19503
19504 xassert (glyph->type == CHAR_GLYPH);
19505 face = FACE_FROM_ID (f, glyph->face_id);
19506
19507 if (two_byte_p)
19508 *two_byte_p = 0;
19509
19510 if (face->font)
19511 {
19512 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
19513
19514 if (code != FONT_INVALID_CODE)
19515 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19516 else
19517 STORE_XCHAR2B (char2b, 0, 0);
19518 }
19519
19520 /* Make sure X resources of the face are allocated. */
19521 xassert (face != NULL);
19522 PREPARE_FACE_FOR_DISPLAY (f, face);
19523 return face;
19524 }
19525
19526
19527 /* Fill glyph string S with composition components specified by S->cmp.
19528
19529 BASE_FACE is the base face of the composition.
19530 S->cmp_from is the index of the first component for S.
19531
19532 OVERLAPS non-zero means S should draw the foreground only, and use
19533 its physical height for clipping. See also draw_glyphs.
19534
19535 Value is the index of a component not in S. */
19536
19537 static int
19538 fill_composite_glyph_string (s, base_face, overlaps)
19539 struct glyph_string *s;
19540 struct face *base_face;
19541 int overlaps;
19542 {
19543 int i;
19544 /* For all glyphs of this composition, starting at the offset
19545 S->cmp_from, until we reach the end of the definition or encounter a
19546 glyph that requires the different face, add it to S. */
19547 struct face *face;
19548
19549 xassert (s);
19550
19551 s->for_overlaps = overlaps;
19552 s->face = NULL;
19553 s->font = NULL;
19554 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
19555 {
19556 int c = COMPOSITION_GLYPH (s->cmp, i);
19557
19558 if (c != '\t')
19559 {
19560 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
19561 -1, Qnil);
19562
19563 face = get_char_face_and_encoding (s->f, c, face_id,
19564 s->char2b + i, 1, 1);
19565 if (face)
19566 {
19567 if (! s->face)
19568 {
19569 s->face = face;
19570 s->font = s->face->font;
19571 }
19572 else if (s->face != face)
19573 break;
19574 }
19575 }
19576 ++s->nchars;
19577 }
19578 s->cmp_to = i;
19579
19580 /* All glyph strings for the same composition has the same width,
19581 i.e. the width set for the first component of the composition. */
19582 s->width = s->first_glyph->pixel_width;
19583
19584 /* If the specified font could not be loaded, use the frame's
19585 default font, but record the fact that we couldn't load it in
19586 the glyph string so that we can draw rectangles for the
19587 characters of the glyph string. */
19588 if (s->font == NULL)
19589 {
19590 s->font_not_found_p = 1;
19591 s->font = FRAME_FONT (s->f);
19592 }
19593
19594 /* Adjust base line for subscript/superscript text. */
19595 s->ybase += s->first_glyph->voffset;
19596
19597 /* This glyph string must always be drawn with 16-bit functions. */
19598 s->two_byte_p = 1;
19599
19600 return s->cmp_to;
19601 }
19602
19603 static int
19604 fill_gstring_glyph_string (s, face_id, start, end, overlaps)
19605 struct glyph_string *s;
19606 int face_id;
19607 int start, end, overlaps;
19608 {
19609 struct glyph *glyph, *last;
19610 Lisp_Object lgstring;
19611 int i;
19612
19613 s->for_overlaps = overlaps;
19614 glyph = s->row->glyphs[s->area] + start;
19615 last = s->row->glyphs[s->area] + end;
19616 s->cmp_id = glyph->u.cmp.id;
19617 s->cmp_from = glyph->u.cmp.from;
19618 s->cmp_to = glyph->u.cmp.to + 1;
19619 s->face = FACE_FROM_ID (s->f, face_id);
19620 lgstring = composition_gstring_from_id (s->cmp_id);
19621 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
19622 glyph++;
19623 while (glyph < last
19624 && glyph->u.cmp.automatic
19625 && glyph->u.cmp.id == s->cmp_id
19626 && s->cmp_to == glyph->u.cmp.from)
19627 s->cmp_to = (glyph++)->u.cmp.to + 1;
19628
19629 for (i = s->cmp_from; i < s->cmp_to; i++)
19630 {
19631 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
19632 unsigned code = LGLYPH_CODE (lglyph);
19633
19634 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
19635 }
19636 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
19637 return glyph - s->row->glyphs[s->area];
19638 }
19639
19640
19641 /* Fill glyph string S from a sequence of character glyphs.
19642
19643 FACE_ID is the face id of the string. START is the index of the
19644 first glyph to consider, END is the index of the last + 1.
19645 OVERLAPS non-zero means S should draw the foreground only, and use
19646 its physical height for clipping. See also draw_glyphs.
19647
19648 Value is the index of the first glyph not in S. */
19649
19650 static int
19651 fill_glyph_string (s, face_id, start, end, overlaps)
19652 struct glyph_string *s;
19653 int face_id;
19654 int start, end, overlaps;
19655 {
19656 struct glyph *glyph, *last;
19657 int voffset;
19658 int glyph_not_available_p;
19659
19660 xassert (s->f == XFRAME (s->w->frame));
19661 xassert (s->nchars == 0);
19662 xassert (start >= 0 && end > start);
19663
19664 s->for_overlaps = overlaps;
19665 glyph = s->row->glyphs[s->area] + start;
19666 last = s->row->glyphs[s->area] + end;
19667 voffset = glyph->voffset;
19668 s->padding_p = glyph->padding_p;
19669 glyph_not_available_p = glyph->glyph_not_available_p;
19670
19671 while (glyph < last
19672 && glyph->type == CHAR_GLYPH
19673 && glyph->voffset == voffset
19674 /* Same face id implies same font, nowadays. */
19675 && glyph->face_id == face_id
19676 && glyph->glyph_not_available_p == glyph_not_available_p)
19677 {
19678 int two_byte_p;
19679
19680 s->face = get_glyph_face_and_encoding (s->f, glyph,
19681 s->char2b + s->nchars,
19682 &two_byte_p);
19683 s->two_byte_p = two_byte_p;
19684 ++s->nchars;
19685 xassert (s->nchars <= end - start);
19686 s->width += glyph->pixel_width;
19687 if (glyph++->padding_p != s->padding_p)
19688 break;
19689 }
19690
19691 s->font = s->face->font;
19692
19693 /* If the specified font could not be loaded, use the frame's font,
19694 but record the fact that we couldn't load it in
19695 S->font_not_found_p so that we can draw rectangles for the
19696 characters of the glyph string. */
19697 if (s->font == NULL || glyph_not_available_p)
19698 {
19699 s->font_not_found_p = 1;
19700 s->font = FRAME_FONT (s->f);
19701 }
19702
19703 /* Adjust base line for subscript/superscript text. */
19704 s->ybase += voffset;
19705
19706 xassert (s->face && s->face->gc);
19707 return glyph - s->row->glyphs[s->area];
19708 }
19709
19710
19711 /* Fill glyph string S from image glyph S->first_glyph. */
19712
19713 static void
19714 fill_image_glyph_string (s)
19715 struct glyph_string *s;
19716 {
19717 xassert (s->first_glyph->type == IMAGE_GLYPH);
19718 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19719 xassert (s->img);
19720 s->slice = s->first_glyph->slice;
19721 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19722 s->font = s->face->font;
19723 s->width = s->first_glyph->pixel_width;
19724
19725 /* Adjust base line for subscript/superscript text. */
19726 s->ybase += s->first_glyph->voffset;
19727 }
19728
19729
19730 /* Fill glyph string S from a sequence of stretch glyphs.
19731
19732 ROW is the glyph row in which the glyphs are found, AREA is the
19733 area within the row. START is the index of the first glyph to
19734 consider, END is the index of the last + 1.
19735
19736 Value is the index of the first glyph not in S. */
19737
19738 static int
19739 fill_stretch_glyph_string (s, row, area, start, end)
19740 struct glyph_string *s;
19741 struct glyph_row *row;
19742 enum glyph_row_area area;
19743 int start, end;
19744 {
19745 struct glyph *glyph, *last;
19746 int voffset, face_id;
19747
19748 xassert (s->first_glyph->type == STRETCH_GLYPH);
19749
19750 glyph = s->row->glyphs[s->area] + start;
19751 last = s->row->glyphs[s->area] + end;
19752 face_id = glyph->face_id;
19753 s->face = FACE_FROM_ID (s->f, face_id);
19754 s->font = s->face->font;
19755 s->width = glyph->pixel_width;
19756 s->nchars = 1;
19757 voffset = glyph->voffset;
19758
19759 for (++glyph;
19760 (glyph < last
19761 && glyph->type == STRETCH_GLYPH
19762 && glyph->voffset == voffset
19763 && glyph->face_id == face_id);
19764 ++glyph)
19765 s->width += glyph->pixel_width;
19766
19767 /* Adjust base line for subscript/superscript text. */
19768 s->ybase += voffset;
19769
19770 /* The case that face->gc == 0 is handled when drawing the glyph
19771 string by calling PREPARE_FACE_FOR_DISPLAY. */
19772 xassert (s->face);
19773 return glyph - s->row->glyphs[s->area];
19774 }
19775
19776 static struct font_metrics *
19777 get_per_char_metric (f, font, char2b)
19778 struct frame *f;
19779 struct font *font;
19780 XChar2b *char2b;
19781 {
19782 static struct font_metrics metrics;
19783 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
19784
19785 if (! font || code == FONT_INVALID_CODE)
19786 return NULL;
19787 font->driver->text_extents (font, &code, 1, &metrics);
19788 return &metrics;
19789 }
19790
19791 /* EXPORT for RIF:
19792 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19793 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19794 assumed to be zero. */
19795
19796 void
19797 x_get_glyph_overhangs (glyph, f, left, right)
19798 struct glyph *glyph;
19799 struct frame *f;
19800 int *left, *right;
19801 {
19802 *left = *right = 0;
19803
19804 if (glyph->type == CHAR_GLYPH)
19805 {
19806 struct face *face;
19807 XChar2b char2b;
19808 struct font_metrics *pcm;
19809
19810 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19811 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
19812 {
19813 if (pcm->rbearing > pcm->width)
19814 *right = pcm->rbearing - pcm->width;
19815 if (pcm->lbearing < 0)
19816 *left = -pcm->lbearing;
19817 }
19818 }
19819 else if (glyph->type == COMPOSITE_GLYPH)
19820 {
19821 if (! glyph->u.cmp.automatic)
19822 {
19823 struct composition *cmp = composition_table[glyph->u.cmp.id];
19824
19825 if (cmp->rbearing > cmp->pixel_width)
19826 *right = cmp->rbearing - cmp->pixel_width;
19827 if (cmp->lbearing < 0)
19828 *left = - cmp->lbearing;
19829 }
19830 else
19831 {
19832 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
19833 struct font_metrics metrics;
19834
19835 composition_gstring_width (gstring, glyph->u.cmp.from,
19836 glyph->u.cmp.to + 1, &metrics);
19837 if (metrics.rbearing > metrics.width)
19838 *right = metrics.rbearing - metrics.width;
19839 if (metrics.lbearing < 0)
19840 *left = - metrics.lbearing;
19841 }
19842 }
19843 }
19844
19845
19846 /* Return the index of the first glyph preceding glyph string S that
19847 is overwritten by S because of S's left overhang. Value is -1
19848 if no glyphs are overwritten. */
19849
19850 static int
19851 left_overwritten (s)
19852 struct glyph_string *s;
19853 {
19854 int k;
19855
19856 if (s->left_overhang)
19857 {
19858 int x = 0, i;
19859 struct glyph *glyphs = s->row->glyphs[s->area];
19860 int first = s->first_glyph - glyphs;
19861
19862 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19863 x -= glyphs[i].pixel_width;
19864
19865 k = i + 1;
19866 }
19867 else
19868 k = -1;
19869
19870 return k;
19871 }
19872
19873
19874 /* Return the index of the first glyph preceding glyph string S that
19875 is overwriting S because of its right overhang. Value is -1 if no
19876 glyph in front of S overwrites S. */
19877
19878 static int
19879 left_overwriting (s)
19880 struct glyph_string *s;
19881 {
19882 int i, k, x;
19883 struct glyph *glyphs = s->row->glyphs[s->area];
19884 int first = s->first_glyph - glyphs;
19885
19886 k = -1;
19887 x = 0;
19888 for (i = first - 1; i >= 0; --i)
19889 {
19890 int left, right;
19891 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19892 if (x + right > 0)
19893 k = i;
19894 x -= glyphs[i].pixel_width;
19895 }
19896
19897 return k;
19898 }
19899
19900
19901 /* Return the index of the last glyph following glyph string S that is
19902 overwritten by S because of S's right overhang. Value is -1 if
19903 no such glyph is found. */
19904
19905 static int
19906 right_overwritten (s)
19907 struct glyph_string *s;
19908 {
19909 int k = -1;
19910
19911 if (s->right_overhang)
19912 {
19913 int x = 0, i;
19914 struct glyph *glyphs = s->row->glyphs[s->area];
19915 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19916 int end = s->row->used[s->area];
19917
19918 for (i = first; i < end && s->right_overhang > x; ++i)
19919 x += glyphs[i].pixel_width;
19920
19921 k = i;
19922 }
19923
19924 return k;
19925 }
19926
19927
19928 /* Return the index of the last glyph following glyph string S that
19929 overwrites S because of its left overhang. Value is negative
19930 if no such glyph is found. */
19931
19932 static int
19933 right_overwriting (s)
19934 struct glyph_string *s;
19935 {
19936 int i, k, x;
19937 int end = s->row->used[s->area];
19938 struct glyph *glyphs = s->row->glyphs[s->area];
19939 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19940
19941 k = -1;
19942 x = 0;
19943 for (i = first; i < end; ++i)
19944 {
19945 int left, right;
19946 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19947 if (x - left < 0)
19948 k = i;
19949 x += glyphs[i].pixel_width;
19950 }
19951
19952 return k;
19953 }
19954
19955
19956 /* Set background width of glyph string S. START is the index of the
19957 first glyph following S. LAST_X is the right-most x-position + 1
19958 in the drawing area. */
19959
19960 static INLINE void
19961 set_glyph_string_background_width (s, start, last_x)
19962 struct glyph_string *s;
19963 int start;
19964 int last_x;
19965 {
19966 /* If the face of this glyph string has to be drawn to the end of
19967 the drawing area, set S->extends_to_end_of_line_p. */
19968
19969 if (start == s->row->used[s->area]
19970 && s->area == TEXT_AREA
19971 && ((s->row->fill_line_p
19972 && (s->hl == DRAW_NORMAL_TEXT
19973 || s->hl == DRAW_IMAGE_RAISED
19974 || s->hl == DRAW_IMAGE_SUNKEN))
19975 || s->hl == DRAW_MOUSE_FACE))
19976 s->extends_to_end_of_line_p = 1;
19977
19978 /* If S extends its face to the end of the line, set its
19979 background_width to the distance to the right edge of the drawing
19980 area. */
19981 if (s->extends_to_end_of_line_p)
19982 s->background_width = last_x - s->x + 1;
19983 else
19984 s->background_width = s->width;
19985 }
19986
19987
19988 /* Compute overhangs and x-positions for glyph string S and its
19989 predecessors, or successors. X is the starting x-position for S.
19990 BACKWARD_P non-zero means process predecessors. */
19991
19992 static void
19993 compute_overhangs_and_x (s, x, backward_p)
19994 struct glyph_string *s;
19995 int x;
19996 int backward_p;
19997 {
19998 if (backward_p)
19999 {
20000 while (s)
20001 {
20002 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20003 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20004 x -= s->width;
20005 s->x = x;
20006 s = s->prev;
20007 }
20008 }
20009 else
20010 {
20011 while (s)
20012 {
20013 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20014 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20015 s->x = x;
20016 x += s->width;
20017 s = s->next;
20018 }
20019 }
20020 }
20021
20022
20023
20024 /* The following macros are only called from draw_glyphs below.
20025 They reference the following parameters of that function directly:
20026 `w', `row', `area', and `overlap_p'
20027 as well as the following local variables:
20028 `s', `f', and `hdc' (in W32) */
20029
20030 #ifdef HAVE_NTGUI
20031 /* On W32, silently add local `hdc' variable to argument list of
20032 init_glyph_string. */
20033 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20034 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20035 #else
20036 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20037 init_glyph_string (s, char2b, w, row, area, start, hl)
20038 #endif
20039
20040 /* Add a glyph string for a stretch glyph to the list of strings
20041 between HEAD and TAIL. START is the index of the stretch glyph in
20042 row area AREA of glyph row ROW. END is the index of the last glyph
20043 in that glyph row area. X is the current output position assigned
20044 to the new glyph string constructed. HL overrides that face of the
20045 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20046 is the right-most x-position of the drawing area. */
20047
20048 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
20049 and below -- keep them on one line. */
20050 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20051 do \
20052 { \
20053 s = (struct glyph_string *) alloca (sizeof *s); \
20054 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
20055 START = fill_stretch_glyph_string (s, row, area, START, END); \
20056 append_glyph_string (&HEAD, &TAIL, s); \
20057 s->x = (X); \
20058 } \
20059 while (0)
20060
20061
20062 /* Add a glyph string for an image glyph to the list of strings
20063 between HEAD and TAIL. START is the index of the image glyph in
20064 row area AREA of glyph row ROW. END is the index of the last glyph
20065 in that glyph row area. X is the current output position assigned
20066 to the new glyph string constructed. HL overrides that face of the
20067 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20068 is the right-most x-position of the drawing area. */
20069
20070 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20071 do \
20072 { \
20073 s = (struct glyph_string *) alloca (sizeof *s); \
20074 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
20075 fill_image_glyph_string (s); \
20076 append_glyph_string (&HEAD, &TAIL, s); \
20077 ++START; \
20078 s->x = (X); \
20079 } \
20080 while (0)
20081
20082
20083 /* Add a glyph string for a sequence of character glyphs to the list
20084 of strings between HEAD and TAIL. START is the index of the first
20085 glyph in row area AREA of glyph row ROW that is part of the new
20086 glyph string. END is the index of the last glyph in that glyph row
20087 area. X is the current output position assigned to the new glyph
20088 string constructed. HL overrides that face of the glyph; e.g. it
20089 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
20090 right-most x-position of the drawing area. */
20091
20092 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
20093 do \
20094 { \
20095 int face_id; \
20096 XChar2b *char2b; \
20097 \
20098 face_id = (row)->glyphs[area][START].face_id; \
20099 \
20100 s = (struct glyph_string *) alloca (sizeof *s); \
20101 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
20102 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20103 append_glyph_string (&HEAD, &TAIL, s); \
20104 s->x = (X); \
20105 START = fill_glyph_string (s, face_id, START, END, overlaps); \
20106 } \
20107 while (0)
20108
20109
20110 /* Add a glyph string for a composite sequence to the list of strings
20111 between HEAD and TAIL. START is the index of the first glyph in
20112 row area AREA of glyph row ROW that is part of the new glyph
20113 string. END is the index of the last glyph in that glyph row area.
20114 X is the current output position assigned to the new glyph string
20115 constructed. HL overrides that face of the glyph; e.g. it is
20116 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
20117 x-position of the drawing area. */
20118
20119 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20120 do { \
20121 int face_id = (row)->glyphs[area][START].face_id; \
20122 struct face *base_face = FACE_FROM_ID (f, face_id); \
20123 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
20124 struct composition *cmp = composition_table[cmp_id]; \
20125 XChar2b *char2b; \
20126 struct glyph_string *first_s; \
20127 int n; \
20128 \
20129 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
20130 \
20131 /* Make glyph_strings for each glyph sequence that is drawable by \
20132 the same face, and append them to HEAD/TAIL. */ \
20133 for (n = 0; n < cmp->glyph_len;) \
20134 { \
20135 s = (struct glyph_string *) alloca (sizeof *s); \
20136 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20137 append_glyph_string (&(HEAD), &(TAIL), s); \
20138 s->cmp = cmp; \
20139 s->cmp_from = n; \
20140 s->x = (X); \
20141 if (n == 0) \
20142 first_s = s; \
20143 n = fill_composite_glyph_string (s, base_face, overlaps); \
20144 } \
20145 \
20146 ++START; \
20147 s = first_s; \
20148 } while (0)
20149
20150
20151 /* Add a glyph string for a glyph-string sequence to the list of strings
20152 between HEAD and TAIL. */
20153
20154 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20155 do { \
20156 int face_id; \
20157 XChar2b *char2b; \
20158 Lisp_Object gstring; \
20159 \
20160 face_id = (row)->glyphs[area][START].face_id; \
20161 gstring = (composition_gstring_from_id \
20162 ((row)->glyphs[area][START].u.cmp.id)); \
20163 s = (struct glyph_string *) alloca (sizeof *s); \
20164 char2b = (XChar2b *) alloca ((sizeof *char2b) \
20165 * LGSTRING_GLYPH_LEN (gstring)); \
20166 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20167 append_glyph_string (&(HEAD), &(TAIL), s); \
20168 s->x = (X); \
20169 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
20170 } while (0)
20171
20172
20173 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
20174 of AREA of glyph row ROW on window W between indices START and END.
20175 HL overrides the face for drawing glyph strings, e.g. it is
20176 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
20177 x-positions of the drawing area.
20178
20179 This is an ugly monster macro construct because we must use alloca
20180 to allocate glyph strings (because draw_glyphs can be called
20181 asynchronously). */
20182
20183 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
20184 do \
20185 { \
20186 HEAD = TAIL = NULL; \
20187 while (START < END) \
20188 { \
20189 struct glyph *first_glyph = (row)->glyphs[area] + START; \
20190 switch (first_glyph->type) \
20191 { \
20192 case CHAR_GLYPH: \
20193 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
20194 HL, X, LAST_X); \
20195 break; \
20196 \
20197 case COMPOSITE_GLYPH: \
20198 if (first_glyph->u.cmp.automatic) \
20199 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
20200 HL, X, LAST_X); \
20201 else \
20202 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
20203 HL, X, LAST_X); \
20204 break; \
20205 \
20206 case STRETCH_GLYPH: \
20207 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
20208 HL, X, LAST_X); \
20209 break; \
20210 \
20211 case IMAGE_GLYPH: \
20212 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
20213 HL, X, LAST_X); \
20214 break; \
20215 \
20216 default: \
20217 abort (); \
20218 } \
20219 \
20220 if (s) \
20221 { \
20222 set_glyph_string_background_width (s, START, LAST_X); \
20223 (X) += s->width; \
20224 } \
20225 } \
20226 } while (0)
20227
20228
20229 /* Draw glyphs between START and END in AREA of ROW on window W,
20230 starting at x-position X. X is relative to AREA in W. HL is a
20231 face-override with the following meaning:
20232
20233 DRAW_NORMAL_TEXT draw normally
20234 DRAW_CURSOR draw in cursor face
20235 DRAW_MOUSE_FACE draw in mouse face.
20236 DRAW_INVERSE_VIDEO draw in mode line face
20237 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
20238 DRAW_IMAGE_RAISED draw an image with a raised relief around it
20239
20240 If OVERLAPS is non-zero, draw only the foreground of characters and
20241 clip to the physical height of ROW. Non-zero value also defines
20242 the overlapping part to be drawn:
20243
20244 OVERLAPS_PRED overlap with preceding rows
20245 OVERLAPS_SUCC overlap with succeeding rows
20246 OVERLAPS_BOTH overlap with both preceding/succeeding rows
20247 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
20248
20249 Value is the x-position reached, relative to AREA of W. */
20250
20251 static int
20252 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
20253 struct window *w;
20254 int x;
20255 struct glyph_row *row;
20256 enum glyph_row_area area;
20257 EMACS_INT start, end;
20258 enum draw_glyphs_face hl;
20259 int overlaps;
20260 {
20261 struct glyph_string *head, *tail;
20262 struct glyph_string *s;
20263 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
20264 int i, j, x_reached, last_x, area_left = 0;
20265 struct frame *f = XFRAME (WINDOW_FRAME (w));
20266 DECLARE_HDC (hdc);
20267
20268 ALLOCATE_HDC (hdc, f);
20269
20270 /* Let's rather be paranoid than getting a SEGV. */
20271 end = min (end, row->used[area]);
20272 start = max (0, start);
20273 start = min (end, start);
20274
20275 /* Translate X to frame coordinates. Set last_x to the right
20276 end of the drawing area. */
20277 if (row->full_width_p)
20278 {
20279 /* X is relative to the left edge of W, without scroll bars
20280 or fringes. */
20281 area_left = WINDOW_LEFT_EDGE_X (w);
20282 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
20283 }
20284 else
20285 {
20286 area_left = window_box_left (w, area);
20287 last_x = area_left + window_box_width (w, area);
20288 }
20289 x += area_left;
20290
20291 /* Build a doubly-linked list of glyph_string structures between
20292 head and tail from what we have to draw. Note that the macro
20293 BUILD_GLYPH_STRINGS will modify its start parameter. That's
20294 the reason we use a separate variable `i'. */
20295 i = start;
20296 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
20297 if (tail)
20298 x_reached = tail->x + tail->background_width;
20299 else
20300 x_reached = x;
20301
20302 /* If there are any glyphs with lbearing < 0 or rbearing > width in
20303 the row, redraw some glyphs in front or following the glyph
20304 strings built above. */
20305 if (head && !overlaps && row->contains_overlapping_glyphs_p)
20306 {
20307 struct glyph_string *h, *t;
20308 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20309 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
20310 int dummy_x = 0;
20311
20312 /* If mouse highlighting is on, we may need to draw adjacent
20313 glyphs using mouse-face highlighting. */
20314 if (area == TEXT_AREA && row->mouse_face_p)
20315 {
20316 struct glyph_row *mouse_beg_row, *mouse_end_row;
20317
20318 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20319 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20320
20321 if (row >= mouse_beg_row && row <= mouse_end_row)
20322 {
20323 check_mouse_face = 1;
20324 mouse_beg_col = (row == mouse_beg_row)
20325 ? dpyinfo->mouse_face_beg_col : 0;
20326 mouse_end_col = (row == mouse_end_row)
20327 ? dpyinfo->mouse_face_end_col
20328 : row->used[TEXT_AREA];
20329 }
20330 }
20331
20332 /* Compute overhangs for all glyph strings. */
20333 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
20334 for (s = head; s; s = s->next)
20335 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
20336
20337 /* Prepend glyph strings for glyphs in front of the first glyph
20338 string that are overwritten because of the first glyph
20339 string's left overhang. The background of all strings
20340 prepended must be drawn because the first glyph string
20341 draws over it. */
20342 i = left_overwritten (head);
20343 if (i >= 0)
20344 {
20345 enum draw_glyphs_face overlap_hl;
20346
20347 /* If this row contains mouse highlighting, attempt to draw
20348 the overlapped glyphs with the correct highlight. This
20349 code fails if the overlap encompasses more than one glyph
20350 and mouse-highlight spans only some of these glyphs.
20351 However, making it work perfectly involves a lot more
20352 code, and I don't know if the pathological case occurs in
20353 practice, so we'll stick to this for now. --- cyd */
20354 if (check_mouse_face
20355 && mouse_beg_col < start && mouse_end_col > i)
20356 overlap_hl = DRAW_MOUSE_FACE;
20357 else
20358 overlap_hl = DRAW_NORMAL_TEXT;
20359
20360 j = i;
20361 BUILD_GLYPH_STRINGS (j, start, h, t,
20362 overlap_hl, dummy_x, last_x);
20363 compute_overhangs_and_x (t, head->x, 1);
20364 prepend_glyph_string_lists (&head, &tail, h, t);
20365 clip_head = head;
20366 }
20367
20368 /* Prepend glyph strings for glyphs in front of the first glyph
20369 string that overwrite that glyph string because of their
20370 right overhang. For these strings, only the foreground must
20371 be drawn, because it draws over the glyph string at `head'.
20372 The background must not be drawn because this would overwrite
20373 right overhangs of preceding glyphs for which no glyph
20374 strings exist. */
20375 i = left_overwriting (head);
20376 if (i >= 0)
20377 {
20378 enum draw_glyphs_face overlap_hl;
20379
20380 if (check_mouse_face
20381 && mouse_beg_col < start && mouse_end_col > i)
20382 overlap_hl = DRAW_MOUSE_FACE;
20383 else
20384 overlap_hl = DRAW_NORMAL_TEXT;
20385
20386 clip_head = head;
20387 BUILD_GLYPH_STRINGS (i, start, h, t,
20388 overlap_hl, dummy_x, last_x);
20389 for (s = h; s; s = s->next)
20390 s->background_filled_p = 1;
20391 compute_overhangs_and_x (t, head->x, 1);
20392 prepend_glyph_string_lists (&head, &tail, h, t);
20393 }
20394
20395 /* Append glyphs strings for glyphs following the last glyph
20396 string tail that are overwritten by tail. The background of
20397 these strings has to be drawn because tail's foreground draws
20398 over it. */
20399 i = right_overwritten (tail);
20400 if (i >= 0)
20401 {
20402 enum draw_glyphs_face overlap_hl;
20403
20404 if (check_mouse_face
20405 && mouse_beg_col < i && mouse_end_col > end)
20406 overlap_hl = DRAW_MOUSE_FACE;
20407 else
20408 overlap_hl = DRAW_NORMAL_TEXT;
20409
20410 BUILD_GLYPH_STRINGS (end, i, h, t,
20411 overlap_hl, x, last_x);
20412 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20413 append_glyph_string_lists (&head, &tail, h, t);
20414 clip_tail = tail;
20415 }
20416
20417 /* Append glyph strings for glyphs following the last glyph
20418 string tail that overwrite tail. The foreground of such
20419 glyphs has to be drawn because it writes into the background
20420 of tail. The background must not be drawn because it could
20421 paint over the foreground of following glyphs. */
20422 i = right_overwriting (tail);
20423 if (i >= 0)
20424 {
20425 enum draw_glyphs_face overlap_hl;
20426 if (check_mouse_face
20427 && mouse_beg_col < i && mouse_end_col > end)
20428 overlap_hl = DRAW_MOUSE_FACE;
20429 else
20430 overlap_hl = DRAW_NORMAL_TEXT;
20431
20432 clip_tail = tail;
20433 i++; /* We must include the Ith glyph. */
20434 BUILD_GLYPH_STRINGS (end, i, h, t,
20435 overlap_hl, x, last_x);
20436 for (s = h; s; s = s->next)
20437 s->background_filled_p = 1;
20438 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20439 append_glyph_string_lists (&head, &tail, h, t);
20440 }
20441 if (clip_head || clip_tail)
20442 for (s = head; s; s = s->next)
20443 {
20444 s->clip_head = clip_head;
20445 s->clip_tail = clip_tail;
20446 }
20447 }
20448
20449 /* Draw all strings. */
20450 for (s = head; s; s = s->next)
20451 FRAME_RIF (f)->draw_glyph_string (s);
20452
20453 #ifndef HAVE_NS
20454 /* When focus a sole frame and move horizontally, this sets on_p to 0
20455 causing a failure to erase prev cursor position. */
20456 if (area == TEXT_AREA
20457 && !row->full_width_p
20458 /* When drawing overlapping rows, only the glyph strings'
20459 foreground is drawn, which doesn't erase a cursor
20460 completely. */
20461 && !overlaps)
20462 {
20463 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
20464 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
20465 : (tail ? tail->x + tail->background_width : x));
20466 x0 -= area_left;
20467 x1 -= area_left;
20468
20469 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
20470 row->y, MATRIX_ROW_BOTTOM_Y (row));
20471 }
20472 #endif
20473
20474 /* Value is the x-position up to which drawn, relative to AREA of W.
20475 This doesn't include parts drawn because of overhangs. */
20476 if (row->full_width_p)
20477 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
20478 else
20479 x_reached -= area_left;
20480
20481 RELEASE_HDC (hdc, f);
20482
20483 return x_reached;
20484 }
20485
20486 /* Expand row matrix if too narrow. Don't expand if area
20487 is not present. */
20488
20489 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
20490 { \
20491 if (!fonts_changed_p \
20492 && (it->glyph_row->glyphs[area] \
20493 < it->glyph_row->glyphs[area + 1])) \
20494 { \
20495 it->w->ncols_scale_factor++; \
20496 fonts_changed_p = 1; \
20497 } \
20498 }
20499
20500 /* Store one glyph for IT->char_to_display in IT->glyph_row.
20501 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20502
20503 static INLINE void
20504 append_glyph (it)
20505 struct it *it;
20506 {
20507 struct glyph *glyph;
20508 enum glyph_row_area area = it->area;
20509
20510 xassert (it->glyph_row);
20511 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
20512
20513 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20514 if (glyph < it->glyph_row->glyphs[area + 1])
20515 {
20516 glyph->charpos = CHARPOS (it->position);
20517 glyph->object = it->object;
20518 if (it->pixel_width > 0)
20519 {
20520 glyph->pixel_width = it->pixel_width;
20521 glyph->padding_p = 0;
20522 }
20523 else
20524 {
20525 /* Assure at least 1-pixel width. Otherwise, cursor can't
20526 be displayed correctly. */
20527 glyph->pixel_width = 1;
20528 glyph->padding_p = 1;
20529 }
20530 glyph->ascent = it->ascent;
20531 glyph->descent = it->descent;
20532 glyph->voffset = it->voffset;
20533 glyph->type = CHAR_GLYPH;
20534 glyph->avoid_cursor_p = it->avoid_cursor_p;
20535 glyph->multibyte_p = it->multibyte_p;
20536 glyph->left_box_line_p = it->start_of_box_run_p;
20537 glyph->right_box_line_p = it->end_of_box_run_p;
20538 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20539 || it->phys_descent > it->descent);
20540 glyph->glyph_not_available_p = it->glyph_not_available_p;
20541 glyph->face_id = it->face_id;
20542 glyph->u.ch = it->char_to_display;
20543 glyph->slice = null_glyph_slice;
20544 glyph->font_type = FONT_TYPE_UNKNOWN;
20545 ++it->glyph_row->used[area];
20546 }
20547 else
20548 IT_EXPAND_MATRIX_WIDTH (it, area);
20549 }
20550
20551 /* Store one glyph for the composition IT->cmp_it.id in
20552 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
20553 non-null. */
20554
20555 static INLINE void
20556 append_composite_glyph (it)
20557 struct it *it;
20558 {
20559 struct glyph *glyph;
20560 enum glyph_row_area area = it->area;
20561
20562 xassert (it->glyph_row);
20563
20564 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20565 if (glyph < it->glyph_row->glyphs[area + 1])
20566 {
20567 glyph->charpos = CHARPOS (it->position);
20568 glyph->object = it->object;
20569 glyph->pixel_width = it->pixel_width;
20570 glyph->ascent = it->ascent;
20571 glyph->descent = it->descent;
20572 glyph->voffset = it->voffset;
20573 glyph->type = COMPOSITE_GLYPH;
20574 if (it->cmp_it.ch < 0)
20575 {
20576 glyph->u.cmp.automatic = 0;
20577 glyph->u.cmp.id = it->cmp_it.id;
20578 }
20579 else
20580 {
20581 glyph->u.cmp.automatic = 1;
20582 glyph->u.cmp.id = it->cmp_it.id;
20583 glyph->u.cmp.from = it->cmp_it.from;
20584 glyph->u.cmp.to = it->cmp_it.to - 1;
20585 }
20586 glyph->avoid_cursor_p = it->avoid_cursor_p;
20587 glyph->multibyte_p = it->multibyte_p;
20588 glyph->left_box_line_p = it->start_of_box_run_p;
20589 glyph->right_box_line_p = it->end_of_box_run_p;
20590 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20591 || it->phys_descent > it->descent);
20592 glyph->padding_p = 0;
20593 glyph->glyph_not_available_p = 0;
20594 glyph->face_id = it->face_id;
20595 glyph->slice = null_glyph_slice;
20596 glyph->font_type = FONT_TYPE_UNKNOWN;
20597 ++it->glyph_row->used[area];
20598 }
20599 else
20600 IT_EXPAND_MATRIX_WIDTH (it, area);
20601 }
20602
20603
20604 /* Change IT->ascent and IT->height according to the setting of
20605 IT->voffset. */
20606
20607 static INLINE void
20608 take_vertical_position_into_account (it)
20609 struct it *it;
20610 {
20611 if (it->voffset)
20612 {
20613 if (it->voffset < 0)
20614 /* Increase the ascent so that we can display the text higher
20615 in the line. */
20616 it->ascent -= it->voffset;
20617 else
20618 /* Increase the descent so that we can display the text lower
20619 in the line. */
20620 it->descent += it->voffset;
20621 }
20622 }
20623
20624
20625 /* Produce glyphs/get display metrics for the image IT is loaded with.
20626 See the description of struct display_iterator in dispextern.h for
20627 an overview of struct display_iterator. */
20628
20629 static void
20630 produce_image_glyph (it)
20631 struct it *it;
20632 {
20633 struct image *img;
20634 struct face *face;
20635 int glyph_ascent, crop;
20636 struct glyph_slice slice;
20637
20638 xassert (it->what == IT_IMAGE);
20639
20640 face = FACE_FROM_ID (it->f, it->face_id);
20641 xassert (face);
20642 /* Make sure X resources of the face is loaded. */
20643 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20644
20645 if (it->image_id < 0)
20646 {
20647 /* Fringe bitmap. */
20648 it->ascent = it->phys_ascent = 0;
20649 it->descent = it->phys_descent = 0;
20650 it->pixel_width = 0;
20651 it->nglyphs = 0;
20652 return;
20653 }
20654
20655 img = IMAGE_FROM_ID (it->f, it->image_id);
20656 xassert (img);
20657 /* Make sure X resources of the image is loaded. */
20658 prepare_image_for_display (it->f, img);
20659
20660 slice.x = slice.y = 0;
20661 slice.width = img->width;
20662 slice.height = img->height;
20663
20664 if (INTEGERP (it->slice.x))
20665 slice.x = XINT (it->slice.x);
20666 else if (FLOATP (it->slice.x))
20667 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
20668
20669 if (INTEGERP (it->slice.y))
20670 slice.y = XINT (it->slice.y);
20671 else if (FLOATP (it->slice.y))
20672 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
20673
20674 if (INTEGERP (it->slice.width))
20675 slice.width = XINT (it->slice.width);
20676 else if (FLOATP (it->slice.width))
20677 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
20678
20679 if (INTEGERP (it->slice.height))
20680 slice.height = XINT (it->slice.height);
20681 else if (FLOATP (it->slice.height))
20682 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
20683
20684 if (slice.x >= img->width)
20685 slice.x = img->width;
20686 if (slice.y >= img->height)
20687 slice.y = img->height;
20688 if (slice.x + slice.width >= img->width)
20689 slice.width = img->width - slice.x;
20690 if (slice.y + slice.height > img->height)
20691 slice.height = img->height - slice.y;
20692
20693 if (slice.width == 0 || slice.height == 0)
20694 return;
20695
20696 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20697
20698 it->descent = slice.height - glyph_ascent;
20699 if (slice.y == 0)
20700 it->descent += img->vmargin;
20701 if (slice.y + slice.height == img->height)
20702 it->descent += img->vmargin;
20703 it->phys_descent = it->descent;
20704
20705 it->pixel_width = slice.width;
20706 if (slice.x == 0)
20707 it->pixel_width += img->hmargin;
20708 if (slice.x + slice.width == img->width)
20709 it->pixel_width += img->hmargin;
20710
20711 /* It's quite possible for images to have an ascent greater than
20712 their height, so don't get confused in that case. */
20713 if (it->descent < 0)
20714 it->descent = 0;
20715
20716 it->nglyphs = 1;
20717
20718 if (face->box != FACE_NO_BOX)
20719 {
20720 if (face->box_line_width > 0)
20721 {
20722 if (slice.y == 0)
20723 it->ascent += face->box_line_width;
20724 if (slice.y + slice.height == img->height)
20725 it->descent += face->box_line_width;
20726 }
20727
20728 if (it->start_of_box_run_p && slice.x == 0)
20729 it->pixel_width += eabs (face->box_line_width);
20730 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20731 it->pixel_width += eabs (face->box_line_width);
20732 }
20733
20734 take_vertical_position_into_account (it);
20735
20736 /* Automatically crop wide image glyphs at right edge so we can
20737 draw the cursor on same display row. */
20738 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20739 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20740 {
20741 it->pixel_width -= crop;
20742 slice.width -= crop;
20743 }
20744
20745 if (it->glyph_row)
20746 {
20747 struct glyph *glyph;
20748 enum glyph_row_area area = it->area;
20749
20750 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20751 if (glyph < it->glyph_row->glyphs[area + 1])
20752 {
20753 glyph->charpos = CHARPOS (it->position);
20754 glyph->object = it->object;
20755 glyph->pixel_width = it->pixel_width;
20756 glyph->ascent = glyph_ascent;
20757 glyph->descent = it->descent;
20758 glyph->voffset = it->voffset;
20759 glyph->type = IMAGE_GLYPH;
20760 glyph->avoid_cursor_p = it->avoid_cursor_p;
20761 glyph->multibyte_p = it->multibyte_p;
20762 glyph->left_box_line_p = it->start_of_box_run_p;
20763 glyph->right_box_line_p = it->end_of_box_run_p;
20764 glyph->overlaps_vertically_p = 0;
20765 glyph->padding_p = 0;
20766 glyph->glyph_not_available_p = 0;
20767 glyph->face_id = it->face_id;
20768 glyph->u.img_id = img->id;
20769 glyph->slice = slice;
20770 glyph->font_type = FONT_TYPE_UNKNOWN;
20771 ++it->glyph_row->used[area];
20772 }
20773 else
20774 IT_EXPAND_MATRIX_WIDTH (it, area);
20775 }
20776 }
20777
20778
20779 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20780 of the glyph, WIDTH and HEIGHT are the width and height of the
20781 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20782
20783 static void
20784 append_stretch_glyph (it, object, width, height, ascent)
20785 struct it *it;
20786 Lisp_Object object;
20787 int width, height;
20788 int ascent;
20789 {
20790 struct glyph *glyph;
20791 enum glyph_row_area area = it->area;
20792
20793 xassert (ascent >= 0 && ascent <= height);
20794
20795 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20796 if (glyph < it->glyph_row->glyphs[area + 1])
20797 {
20798 glyph->charpos = CHARPOS (it->position);
20799 glyph->object = object;
20800 glyph->pixel_width = width;
20801 glyph->ascent = ascent;
20802 glyph->descent = height - ascent;
20803 glyph->voffset = it->voffset;
20804 glyph->type = STRETCH_GLYPH;
20805 glyph->avoid_cursor_p = it->avoid_cursor_p;
20806 glyph->multibyte_p = it->multibyte_p;
20807 glyph->left_box_line_p = it->start_of_box_run_p;
20808 glyph->right_box_line_p = it->end_of_box_run_p;
20809 glyph->overlaps_vertically_p = 0;
20810 glyph->padding_p = 0;
20811 glyph->glyph_not_available_p = 0;
20812 glyph->face_id = it->face_id;
20813 glyph->u.stretch.ascent = ascent;
20814 glyph->u.stretch.height = height;
20815 glyph->slice = null_glyph_slice;
20816 glyph->font_type = FONT_TYPE_UNKNOWN;
20817 ++it->glyph_row->used[area];
20818 }
20819 else
20820 IT_EXPAND_MATRIX_WIDTH (it, area);
20821 }
20822
20823
20824 /* Produce a stretch glyph for iterator IT. IT->object is the value
20825 of the glyph property displayed. The value must be a list
20826 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20827 being recognized:
20828
20829 1. `:width WIDTH' specifies that the space should be WIDTH *
20830 canonical char width wide. WIDTH may be an integer or floating
20831 point number.
20832
20833 2. `:relative-width FACTOR' specifies that the width of the stretch
20834 should be computed from the width of the first character having the
20835 `glyph' property, and should be FACTOR times that width.
20836
20837 3. `:align-to HPOS' specifies that the space should be wide enough
20838 to reach HPOS, a value in canonical character units.
20839
20840 Exactly one of the above pairs must be present.
20841
20842 4. `:height HEIGHT' specifies that the height of the stretch produced
20843 should be HEIGHT, measured in canonical character units.
20844
20845 5. `:relative-height FACTOR' specifies that the height of the
20846 stretch should be FACTOR times the height of the characters having
20847 the glyph property.
20848
20849 Either none or exactly one of 4 or 5 must be present.
20850
20851 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20852 of the stretch should be used for the ascent of the stretch.
20853 ASCENT must be in the range 0 <= ASCENT <= 100. */
20854
20855 static void
20856 produce_stretch_glyph (it)
20857 struct it *it;
20858 {
20859 /* (space :width WIDTH :height HEIGHT ...) */
20860 Lisp_Object prop, plist;
20861 int width = 0, height = 0, align_to = -1;
20862 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20863 int ascent = 0;
20864 double tem;
20865 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20866 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20867
20868 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20869
20870 /* List should start with `space'. */
20871 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20872 plist = XCDR (it->object);
20873
20874 /* Compute the width of the stretch. */
20875 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20876 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20877 {
20878 /* Absolute width `:width WIDTH' specified and valid. */
20879 zero_width_ok_p = 1;
20880 width = (int)tem;
20881 }
20882 else if (prop = Fplist_get (plist, QCrelative_width),
20883 NUMVAL (prop) > 0)
20884 {
20885 /* Relative width `:relative-width FACTOR' specified and valid.
20886 Compute the width of the characters having the `glyph'
20887 property. */
20888 struct it it2;
20889 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20890
20891 it2 = *it;
20892 if (it->multibyte_p)
20893 {
20894 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20895 - IT_BYTEPOS (*it));
20896 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20897 }
20898 else
20899 it2.c = *p, it2.len = 1;
20900
20901 it2.glyph_row = NULL;
20902 it2.what = IT_CHARACTER;
20903 x_produce_glyphs (&it2);
20904 width = NUMVAL (prop) * it2.pixel_width;
20905 }
20906 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20907 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20908 {
20909 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20910 align_to = (align_to < 0
20911 ? 0
20912 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20913 else if (align_to < 0)
20914 align_to = window_box_left_offset (it->w, TEXT_AREA);
20915 width = max (0, (int)tem + align_to - it->current_x);
20916 zero_width_ok_p = 1;
20917 }
20918 else
20919 /* Nothing specified -> width defaults to canonical char width. */
20920 width = FRAME_COLUMN_WIDTH (it->f);
20921
20922 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20923 width = 1;
20924
20925 /* Compute height. */
20926 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20927 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20928 {
20929 height = (int)tem;
20930 zero_height_ok_p = 1;
20931 }
20932 else if (prop = Fplist_get (plist, QCrelative_height),
20933 NUMVAL (prop) > 0)
20934 height = FONT_HEIGHT (font) * NUMVAL (prop);
20935 else
20936 height = FONT_HEIGHT (font);
20937
20938 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20939 height = 1;
20940
20941 /* Compute percentage of height used for ascent. If
20942 `:ascent ASCENT' is present and valid, use that. Otherwise,
20943 derive the ascent from the font in use. */
20944 if (prop = Fplist_get (plist, QCascent),
20945 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20946 ascent = height * NUMVAL (prop) / 100.0;
20947 else if (!NILP (prop)
20948 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20949 ascent = min (max (0, (int)tem), height);
20950 else
20951 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20952
20953 if (width > 0 && it->line_wrap != TRUNCATE
20954 && it->current_x + width > it->last_visible_x)
20955 width = it->last_visible_x - it->current_x - 1;
20956
20957 if (width > 0 && height > 0 && it->glyph_row)
20958 {
20959 Lisp_Object object = it->stack[it->sp - 1].string;
20960 if (!STRINGP (object))
20961 object = it->w->buffer;
20962 append_stretch_glyph (it, object, width, height, ascent);
20963 }
20964
20965 it->pixel_width = width;
20966 it->ascent = it->phys_ascent = ascent;
20967 it->descent = it->phys_descent = height - it->ascent;
20968 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20969
20970 take_vertical_position_into_account (it);
20971 }
20972
20973 /* Calculate line-height and line-spacing properties.
20974 An integer value specifies explicit pixel value.
20975 A float value specifies relative value to current face height.
20976 A cons (float . face-name) specifies relative value to
20977 height of specified face font.
20978
20979 Returns height in pixels, or nil. */
20980
20981
20982 static Lisp_Object
20983 calc_line_height_property (it, val, font, boff, override)
20984 struct it *it;
20985 Lisp_Object val;
20986 struct font *font;
20987 int boff, override;
20988 {
20989 Lisp_Object face_name = Qnil;
20990 int ascent, descent, height;
20991
20992 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20993 return val;
20994
20995 if (CONSP (val))
20996 {
20997 face_name = XCAR (val);
20998 val = XCDR (val);
20999 if (!NUMBERP (val))
21000 val = make_number (1);
21001 if (NILP (face_name))
21002 {
21003 height = it->ascent + it->descent;
21004 goto scale;
21005 }
21006 }
21007
21008 if (NILP (face_name))
21009 {
21010 font = FRAME_FONT (it->f);
21011 boff = FRAME_BASELINE_OFFSET (it->f);
21012 }
21013 else if (EQ (face_name, Qt))
21014 {
21015 override = 0;
21016 }
21017 else
21018 {
21019 int face_id;
21020 struct face *face;
21021
21022 face_id = lookup_named_face (it->f, face_name, 0);
21023 if (face_id < 0)
21024 return make_number (-1);
21025
21026 face = FACE_FROM_ID (it->f, face_id);
21027 font = face->font;
21028 if (font == NULL)
21029 return make_number (-1);
21030 boff = font->baseline_offset;
21031 if (font->vertical_centering)
21032 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21033 }
21034
21035 ascent = FONT_BASE (font) + boff;
21036 descent = FONT_DESCENT (font) - boff;
21037
21038 if (override)
21039 {
21040 it->override_ascent = ascent;
21041 it->override_descent = descent;
21042 it->override_boff = boff;
21043 }
21044
21045 height = ascent + descent;
21046
21047 scale:
21048 if (FLOATP (val))
21049 height = (int)(XFLOAT_DATA (val) * height);
21050 else if (INTEGERP (val))
21051 height *= XINT (val);
21052
21053 return make_number (height);
21054 }
21055
21056
21057 /* RIF:
21058 Produce glyphs/get display metrics for the display element IT is
21059 loaded with. See the description of struct it in dispextern.h
21060 for an overview of struct it. */
21061
21062 void
21063 x_produce_glyphs (it)
21064 struct it *it;
21065 {
21066 int extra_line_spacing = it->extra_line_spacing;
21067
21068 it->glyph_not_available_p = 0;
21069
21070 if (it->what == IT_CHARACTER)
21071 {
21072 XChar2b char2b;
21073 struct font *font;
21074 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21075 struct font_metrics *pcm;
21076 int font_not_found_p;
21077 int boff; /* baseline offset */
21078 /* We may change it->multibyte_p upon unibyte<->multibyte
21079 conversion. So, save the current value now and restore it
21080 later.
21081
21082 Note: It seems that we don't have to record multibyte_p in
21083 struct glyph because the character code itself tells if or
21084 not the character is multibyte. Thus, in the future, we must
21085 consider eliminating the field `multibyte_p' in the struct
21086 glyph. */
21087 int saved_multibyte_p = it->multibyte_p;
21088
21089 /* Maybe translate single-byte characters to multibyte, or the
21090 other way. */
21091 it->char_to_display = it->c;
21092 if (!ASCII_BYTE_P (it->c)
21093 && ! it->multibyte_p)
21094 {
21095 if (SINGLE_BYTE_CHAR_P (it->c)
21096 && unibyte_display_via_language_environment)
21097 it->char_to_display = unibyte_char_to_multibyte (it->c);
21098 if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
21099 {
21100 it->multibyte_p = 1;
21101 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
21102 -1, Qnil);
21103 face = FACE_FROM_ID (it->f, it->face_id);
21104 }
21105 }
21106
21107 /* Get font to use. Encode IT->char_to_display. */
21108 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
21109 &char2b, it->multibyte_p, 0);
21110 font = face->font;
21111
21112 /* When no suitable font found, use the default font. */
21113 font_not_found_p = font == NULL;
21114 if (font_not_found_p)
21115 {
21116 font = FRAME_FONT (it->f);
21117 boff = FRAME_BASELINE_OFFSET (it->f);
21118 }
21119 else
21120 {
21121 boff = font->baseline_offset;
21122 if (font->vertical_centering)
21123 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21124 }
21125
21126 if (it->char_to_display >= ' '
21127 && (!it->multibyte_p || it->char_to_display < 128))
21128 {
21129 /* Either unibyte or ASCII. */
21130 int stretched_p;
21131
21132 it->nglyphs = 1;
21133
21134 pcm = get_per_char_metric (it->f, font, &char2b);
21135
21136 if (it->override_ascent >= 0)
21137 {
21138 it->ascent = it->override_ascent;
21139 it->descent = it->override_descent;
21140 boff = it->override_boff;
21141 }
21142 else
21143 {
21144 it->ascent = FONT_BASE (font) + boff;
21145 it->descent = FONT_DESCENT (font) - boff;
21146 }
21147
21148 if (pcm)
21149 {
21150 it->phys_ascent = pcm->ascent + boff;
21151 it->phys_descent = pcm->descent - boff;
21152 it->pixel_width = pcm->width;
21153 }
21154 else
21155 {
21156 it->glyph_not_available_p = 1;
21157 it->phys_ascent = it->ascent;
21158 it->phys_descent = it->descent;
21159 it->pixel_width = FONT_WIDTH (font);
21160 }
21161
21162 if (it->constrain_row_ascent_descent_p)
21163 {
21164 if (it->descent > it->max_descent)
21165 {
21166 it->ascent += it->descent - it->max_descent;
21167 it->descent = it->max_descent;
21168 }
21169 if (it->ascent > it->max_ascent)
21170 {
21171 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
21172 it->ascent = it->max_ascent;
21173 }
21174 it->phys_ascent = min (it->phys_ascent, it->ascent);
21175 it->phys_descent = min (it->phys_descent, it->descent);
21176 extra_line_spacing = 0;
21177 }
21178
21179 /* If this is a space inside a region of text with
21180 `space-width' property, change its width. */
21181 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
21182 if (stretched_p)
21183 it->pixel_width *= XFLOATINT (it->space_width);
21184
21185 /* If face has a box, add the box thickness to the character
21186 height. If character has a box line to the left and/or
21187 right, add the box line width to the character's width. */
21188 if (face->box != FACE_NO_BOX)
21189 {
21190 int thick = face->box_line_width;
21191
21192 if (thick > 0)
21193 {
21194 it->ascent += thick;
21195 it->descent += thick;
21196 }
21197 else
21198 thick = -thick;
21199
21200 if (it->start_of_box_run_p)
21201 it->pixel_width += thick;
21202 if (it->end_of_box_run_p)
21203 it->pixel_width += thick;
21204 }
21205
21206 /* If face has an overline, add the height of the overline
21207 (1 pixel) and a 1 pixel margin to the character height. */
21208 if (face->overline_p)
21209 it->ascent += overline_margin;
21210
21211 if (it->constrain_row_ascent_descent_p)
21212 {
21213 if (it->ascent > it->max_ascent)
21214 it->ascent = it->max_ascent;
21215 if (it->descent > it->max_descent)
21216 it->descent = it->max_descent;
21217 }
21218
21219 take_vertical_position_into_account (it);
21220
21221 /* If we have to actually produce glyphs, do it. */
21222 if (it->glyph_row)
21223 {
21224 if (stretched_p)
21225 {
21226 /* Translate a space with a `space-width' property
21227 into a stretch glyph. */
21228 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
21229 / FONT_HEIGHT (font));
21230 append_stretch_glyph (it, it->object, it->pixel_width,
21231 it->ascent + it->descent, ascent);
21232 }
21233 else
21234 append_glyph (it);
21235
21236 /* If characters with lbearing or rbearing are displayed
21237 in this line, record that fact in a flag of the
21238 glyph row. This is used to optimize X output code. */
21239 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
21240 it->glyph_row->contains_overlapping_glyphs_p = 1;
21241 }
21242 if (! stretched_p && it->pixel_width == 0)
21243 /* We assure that all visible glyphs have at least 1-pixel
21244 width. */
21245 it->pixel_width = 1;
21246 }
21247 else if (it->char_to_display == '\n')
21248 {
21249 /* A newline has no width but we need the height of the line.
21250 But if previous part of the line set a height, don't
21251 increase that height */
21252
21253 Lisp_Object height;
21254 Lisp_Object total_height = Qnil;
21255
21256 it->override_ascent = -1;
21257 it->pixel_width = 0;
21258 it->nglyphs = 0;
21259
21260 height = get_it_property(it, Qline_height);
21261 /* Split (line-height total-height) list */
21262 if (CONSP (height)
21263 && CONSP (XCDR (height))
21264 && NILP (XCDR (XCDR (height))))
21265 {
21266 total_height = XCAR (XCDR (height));
21267 height = XCAR (height);
21268 }
21269 height = calc_line_height_property(it, height, font, boff, 1);
21270
21271 if (it->override_ascent >= 0)
21272 {
21273 it->ascent = it->override_ascent;
21274 it->descent = it->override_descent;
21275 boff = it->override_boff;
21276 }
21277 else
21278 {
21279 it->ascent = FONT_BASE (font) + boff;
21280 it->descent = FONT_DESCENT (font) - boff;
21281 }
21282
21283 if (EQ (height, Qt))
21284 {
21285 if (it->descent > it->max_descent)
21286 {
21287 it->ascent += it->descent - it->max_descent;
21288 it->descent = it->max_descent;
21289 }
21290 if (it->ascent > it->max_ascent)
21291 {
21292 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
21293 it->ascent = it->max_ascent;
21294 }
21295 it->phys_ascent = min (it->phys_ascent, it->ascent);
21296 it->phys_descent = min (it->phys_descent, it->descent);
21297 it->constrain_row_ascent_descent_p = 1;
21298 extra_line_spacing = 0;
21299 }
21300 else
21301 {
21302 Lisp_Object spacing;
21303
21304 it->phys_ascent = it->ascent;
21305 it->phys_descent = it->descent;
21306
21307 if ((it->max_ascent > 0 || it->max_descent > 0)
21308 && face->box != FACE_NO_BOX
21309 && face->box_line_width > 0)
21310 {
21311 it->ascent += face->box_line_width;
21312 it->descent += face->box_line_width;
21313 }
21314 if (!NILP (height)
21315 && XINT (height) > it->ascent + it->descent)
21316 it->ascent = XINT (height) - it->descent;
21317
21318 if (!NILP (total_height))
21319 spacing = calc_line_height_property(it, total_height, font, boff, 0);
21320 else
21321 {
21322 spacing = get_it_property(it, Qline_spacing);
21323 spacing = calc_line_height_property(it, spacing, font, boff, 0);
21324 }
21325 if (INTEGERP (spacing))
21326 {
21327 extra_line_spacing = XINT (spacing);
21328 if (!NILP (total_height))
21329 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
21330 }
21331 }
21332 }
21333 else if (it->char_to_display == '\t')
21334 {
21335 if (font->space_width > 0)
21336 {
21337 int tab_width = it->tab_width * font->space_width;
21338 int x = it->current_x + it->continuation_lines_width;
21339 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
21340
21341 /* If the distance from the current position to the next tab
21342 stop is less than a space character width, use the
21343 tab stop after that. */
21344 if (next_tab_x - x < font->space_width)
21345 next_tab_x += tab_width;
21346
21347 it->pixel_width = next_tab_x - x;
21348 it->nglyphs = 1;
21349 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
21350 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
21351
21352 if (it->glyph_row)
21353 {
21354 append_stretch_glyph (it, it->object, it->pixel_width,
21355 it->ascent + it->descent, it->ascent);
21356 }
21357 }
21358 else
21359 {
21360 it->pixel_width = 0;
21361 it->nglyphs = 1;
21362 }
21363 }
21364 else
21365 {
21366 /* A multi-byte character. Assume that the display width of the
21367 character is the width of the character multiplied by the
21368 width of the font. */
21369
21370 /* If we found a font, this font should give us the right
21371 metrics. If we didn't find a font, use the frame's
21372 default font and calculate the width of the character by
21373 multiplying the width of font by the width of the
21374 character. */
21375
21376 pcm = get_per_char_metric (it->f, font, &char2b);
21377
21378 if (font_not_found_p || !pcm)
21379 {
21380 int char_width = CHAR_WIDTH (it->char_to_display);
21381
21382 if (char_width == 0)
21383 /* This is a non spacing character. But, as we are
21384 going to display an empty box, the box must occupy
21385 at least one column. */
21386 char_width = 1;
21387 it->glyph_not_available_p = 1;
21388 it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
21389 it->phys_ascent = FONT_BASE (font) + boff;
21390 it->phys_descent = FONT_DESCENT (font) - boff;
21391 }
21392 else
21393 {
21394 it->pixel_width = pcm->width;
21395 it->phys_ascent = pcm->ascent + boff;
21396 it->phys_descent = pcm->descent - boff;
21397 if (it->glyph_row
21398 && (pcm->lbearing < 0
21399 || pcm->rbearing > pcm->width))
21400 it->glyph_row->contains_overlapping_glyphs_p = 1;
21401 }
21402 it->nglyphs = 1;
21403 it->ascent = FONT_BASE (font) + boff;
21404 it->descent = FONT_DESCENT (font) - boff;
21405 if (face->box != FACE_NO_BOX)
21406 {
21407 int thick = face->box_line_width;
21408
21409 if (thick > 0)
21410 {
21411 it->ascent += thick;
21412 it->descent += thick;
21413 }
21414 else
21415 thick = - thick;
21416
21417 if (it->start_of_box_run_p)
21418 it->pixel_width += thick;
21419 if (it->end_of_box_run_p)
21420 it->pixel_width += thick;
21421 }
21422
21423 /* If face has an overline, add the height of the overline
21424 (1 pixel) and a 1 pixel margin to the character height. */
21425 if (face->overline_p)
21426 it->ascent += overline_margin;
21427
21428 take_vertical_position_into_account (it);
21429
21430 if (it->ascent < 0)
21431 it->ascent = 0;
21432 if (it->descent < 0)
21433 it->descent = 0;
21434
21435 if (it->glyph_row)
21436 append_glyph (it);
21437 if (it->pixel_width == 0)
21438 /* We assure that all visible glyphs have at least 1-pixel
21439 width. */
21440 it->pixel_width = 1;
21441 }
21442 it->multibyte_p = saved_multibyte_p;
21443 }
21444 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
21445 {
21446 /* A static compositoin.
21447
21448 Note: A composition is represented as one glyph in the
21449 glyph matrix. There are no padding glyphs.
21450
21451 Important is that pixel_width, ascent, and descent are the
21452 values of what is drawn by draw_glyphs (i.e. the values of
21453 the overall glyphs composed). */
21454 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21455 int boff; /* baseline offset */
21456 struct composition *cmp = composition_table[it->cmp_it.id];
21457 int glyph_len = cmp->glyph_len;
21458 struct font *font = face->font;
21459
21460 it->nglyphs = 1;
21461
21462 /* If we have not yet calculated pixel size data of glyphs of
21463 the composition for the current face font, calculate them
21464 now. Theoretically, we have to check all fonts for the
21465 glyphs, but that requires much time and memory space. So,
21466 here we check only the font of the first glyph. This leads
21467 to incorrect display, but it's very rare, and C-l (recenter)
21468 can correct the display anyway. */
21469 if (! cmp->font || cmp->font != font)
21470 {
21471 /* Ascent and descent of the font of the first character
21472 of this composition (adjusted by baseline offset).
21473 Ascent and descent of overall glyphs should not be less
21474 than them respectively. */
21475 int font_ascent, font_descent, font_height;
21476 /* Bounding box of the overall glyphs. */
21477 int leftmost, rightmost, lowest, highest;
21478 int lbearing, rbearing;
21479 int i, width, ascent, descent;
21480 int left_padded = 0, right_padded = 0;
21481 int c;
21482 XChar2b char2b;
21483 struct font_metrics *pcm;
21484 int font_not_found_p;
21485 int pos;
21486
21487 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
21488 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
21489 break;
21490 if (glyph_len < cmp->glyph_len)
21491 right_padded = 1;
21492 for (i = 0; i < glyph_len; i++)
21493 {
21494 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
21495 break;
21496 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21497 }
21498 if (i > 0)
21499 left_padded = 1;
21500
21501 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
21502 : IT_CHARPOS (*it));
21503 /* When no suitable font found, use the default font. */
21504 font_not_found_p = font == NULL;
21505 if (font_not_found_p)
21506 {
21507 face = face->ascii_face;
21508 font = face->font;
21509 }
21510 boff = font->baseline_offset;
21511 if (font->vertical_centering)
21512 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21513 font_ascent = FONT_BASE (font) + boff;
21514 font_descent = FONT_DESCENT (font) - boff;
21515 font_height = FONT_HEIGHT (font);
21516
21517 cmp->font = (void *) font;
21518
21519 pcm = NULL;
21520 if (! font_not_found_p)
21521 {
21522 get_char_face_and_encoding (it->f, c, it->face_id,
21523 &char2b, it->multibyte_p, 0);
21524 pcm = get_per_char_metric (it->f, font, &char2b);
21525 }
21526
21527 /* Initialize the bounding box. */
21528 if (pcm)
21529 {
21530 width = pcm->width;
21531 ascent = pcm->ascent;
21532 descent = pcm->descent;
21533 lbearing = pcm->lbearing;
21534 rbearing = pcm->rbearing;
21535 }
21536 else
21537 {
21538 width = FONT_WIDTH (font);
21539 ascent = FONT_BASE (font);
21540 descent = FONT_DESCENT (font);
21541 lbearing = 0;
21542 rbearing = width;
21543 }
21544
21545 rightmost = width;
21546 leftmost = 0;
21547 lowest = - descent + boff;
21548 highest = ascent + boff;
21549
21550 if (! font_not_found_p
21551 && font->default_ascent
21552 && CHAR_TABLE_P (Vuse_default_ascent)
21553 && !NILP (Faref (Vuse_default_ascent,
21554 make_number (it->char_to_display))))
21555 highest = font->default_ascent + boff;
21556
21557 /* Draw the first glyph at the normal position. It may be
21558 shifted to right later if some other glyphs are drawn
21559 at the left. */
21560 cmp->offsets[i * 2] = 0;
21561 cmp->offsets[i * 2 + 1] = boff;
21562 cmp->lbearing = lbearing;
21563 cmp->rbearing = rbearing;
21564
21565 /* Set cmp->offsets for the remaining glyphs. */
21566 for (i++; i < glyph_len; i++)
21567 {
21568 int left, right, btm, top;
21569 int ch = COMPOSITION_GLYPH (cmp, i);
21570 int face_id;
21571 struct face *this_face;
21572 int this_boff;
21573
21574 if (ch == '\t')
21575 ch = ' ';
21576 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
21577 this_face = FACE_FROM_ID (it->f, face_id);
21578 font = this_face->font;
21579
21580 if (font == NULL)
21581 pcm = NULL;
21582 else
21583 {
21584 this_boff = font->baseline_offset;
21585 if (font->vertical_centering)
21586 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21587 get_char_face_and_encoding (it->f, ch, face_id,
21588 &char2b, it->multibyte_p, 0);
21589 pcm = get_per_char_metric (it->f, font, &char2b);
21590 }
21591 if (! pcm)
21592 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21593 else
21594 {
21595 width = pcm->width;
21596 ascent = pcm->ascent;
21597 descent = pcm->descent;
21598 lbearing = pcm->lbearing;
21599 rbearing = pcm->rbearing;
21600 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21601 {
21602 /* Relative composition with or without
21603 alternate chars. */
21604 left = (leftmost + rightmost - width) / 2;
21605 btm = - descent + boff;
21606 if (font->relative_compose
21607 && (! CHAR_TABLE_P (Vignore_relative_composition)
21608 || NILP (Faref (Vignore_relative_composition,
21609 make_number (ch)))))
21610 {
21611
21612 if (- descent >= font->relative_compose)
21613 /* One extra pixel between two glyphs. */
21614 btm = highest + 1;
21615 else if (ascent <= 0)
21616 /* One extra pixel between two glyphs. */
21617 btm = lowest - 1 - ascent - descent;
21618 }
21619 }
21620 else
21621 {
21622 /* A composition rule is specified by an integer
21623 value that encodes global and new reference
21624 points (GREF and NREF). GREF and NREF are
21625 specified by numbers as below:
21626
21627 0---1---2 -- ascent
21628 | |
21629 | |
21630 | |
21631 9--10--11 -- center
21632 | |
21633 ---3---4---5--- baseline
21634 | |
21635 6---7---8 -- descent
21636 */
21637 int rule = COMPOSITION_RULE (cmp, i);
21638 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
21639
21640 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
21641 grefx = gref % 3, nrefx = nref % 3;
21642 grefy = gref / 3, nrefy = nref / 3;
21643 if (xoff)
21644 xoff = font_height * (xoff - 128) / 256;
21645 if (yoff)
21646 yoff = font_height * (yoff - 128) / 256;
21647
21648 left = (leftmost
21649 + grefx * (rightmost - leftmost) / 2
21650 - nrefx * width / 2
21651 + xoff);
21652
21653 btm = ((grefy == 0 ? highest
21654 : grefy == 1 ? 0
21655 : grefy == 2 ? lowest
21656 : (highest + lowest) / 2)
21657 - (nrefy == 0 ? ascent + descent
21658 : nrefy == 1 ? descent - boff
21659 : nrefy == 2 ? 0
21660 : (ascent + descent) / 2)
21661 + yoff);
21662 }
21663
21664 cmp->offsets[i * 2] = left;
21665 cmp->offsets[i * 2 + 1] = btm + descent;
21666
21667 /* Update the bounding box of the overall glyphs. */
21668 if (width > 0)
21669 {
21670 right = left + width;
21671 if (left < leftmost)
21672 leftmost = left;
21673 if (right > rightmost)
21674 rightmost = right;
21675 }
21676 top = btm + descent + ascent;
21677 if (top > highest)
21678 highest = top;
21679 if (btm < lowest)
21680 lowest = btm;
21681
21682 if (cmp->lbearing > left + lbearing)
21683 cmp->lbearing = left + lbearing;
21684 if (cmp->rbearing < left + rbearing)
21685 cmp->rbearing = left + rbearing;
21686 }
21687 }
21688
21689 /* If there are glyphs whose x-offsets are negative,
21690 shift all glyphs to the right and make all x-offsets
21691 non-negative. */
21692 if (leftmost < 0)
21693 {
21694 for (i = 0; i < cmp->glyph_len; i++)
21695 cmp->offsets[i * 2] -= leftmost;
21696 rightmost -= leftmost;
21697 cmp->lbearing -= leftmost;
21698 cmp->rbearing -= leftmost;
21699 }
21700
21701 if (left_padded && cmp->lbearing < 0)
21702 {
21703 for (i = 0; i < cmp->glyph_len; i++)
21704 cmp->offsets[i * 2] -= cmp->lbearing;
21705 rightmost -= cmp->lbearing;
21706 cmp->rbearing -= cmp->lbearing;
21707 cmp->lbearing = 0;
21708 }
21709 if (right_padded && rightmost < cmp->rbearing)
21710 {
21711 rightmost = cmp->rbearing;
21712 }
21713
21714 cmp->pixel_width = rightmost;
21715 cmp->ascent = highest;
21716 cmp->descent = - lowest;
21717 if (cmp->ascent < font_ascent)
21718 cmp->ascent = font_ascent;
21719 if (cmp->descent < font_descent)
21720 cmp->descent = font_descent;
21721 }
21722
21723 if (it->glyph_row
21724 && (cmp->lbearing < 0
21725 || cmp->rbearing > cmp->pixel_width))
21726 it->glyph_row->contains_overlapping_glyphs_p = 1;
21727
21728 it->pixel_width = cmp->pixel_width;
21729 it->ascent = it->phys_ascent = cmp->ascent;
21730 it->descent = it->phys_descent = cmp->descent;
21731 if (face->box != FACE_NO_BOX)
21732 {
21733 int thick = face->box_line_width;
21734
21735 if (thick > 0)
21736 {
21737 it->ascent += thick;
21738 it->descent += thick;
21739 }
21740 else
21741 thick = - thick;
21742
21743 if (it->start_of_box_run_p)
21744 it->pixel_width += thick;
21745 if (it->end_of_box_run_p)
21746 it->pixel_width += thick;
21747 }
21748
21749 /* If face has an overline, add the height of the overline
21750 (1 pixel) and a 1 pixel margin to the character height. */
21751 if (face->overline_p)
21752 it->ascent += overline_margin;
21753
21754 take_vertical_position_into_account (it);
21755 if (it->ascent < 0)
21756 it->ascent = 0;
21757 if (it->descent < 0)
21758 it->descent = 0;
21759
21760 if (it->glyph_row)
21761 append_composite_glyph (it);
21762 }
21763 else if (it->what == IT_COMPOSITION)
21764 {
21765 /* A dynamic (automatic) composition. */
21766 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21767 Lisp_Object gstring;
21768 struct font_metrics metrics;
21769
21770 gstring = composition_gstring_from_id (it->cmp_it.id);
21771 it->pixel_width
21772 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
21773 &metrics);
21774 if (it->glyph_row
21775 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
21776 it->glyph_row->contains_overlapping_glyphs_p = 1;
21777 it->ascent = it->phys_ascent = metrics.ascent;
21778 it->descent = it->phys_descent = metrics.descent;
21779 if (face->box != FACE_NO_BOX)
21780 {
21781 int thick = face->box_line_width;
21782
21783 if (thick > 0)
21784 {
21785 it->ascent += thick;
21786 it->descent += thick;
21787 }
21788 else
21789 thick = - thick;
21790
21791 if (it->start_of_box_run_p)
21792 it->pixel_width += thick;
21793 if (it->end_of_box_run_p)
21794 it->pixel_width += thick;
21795 }
21796 /* If face has an overline, add the height of the overline
21797 (1 pixel) and a 1 pixel margin to the character height. */
21798 if (face->overline_p)
21799 it->ascent += overline_margin;
21800 take_vertical_position_into_account (it);
21801 if (it->ascent < 0)
21802 it->ascent = 0;
21803 if (it->descent < 0)
21804 it->descent = 0;
21805
21806 if (it->glyph_row)
21807 append_composite_glyph (it);
21808 }
21809 else if (it->what == IT_IMAGE)
21810 produce_image_glyph (it);
21811 else if (it->what == IT_STRETCH)
21812 produce_stretch_glyph (it);
21813
21814 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21815 because this isn't true for images with `:ascent 100'. */
21816 xassert (it->ascent >= 0 && it->descent >= 0);
21817 if (it->area == TEXT_AREA)
21818 it->current_x += it->pixel_width;
21819
21820 if (extra_line_spacing > 0)
21821 {
21822 it->descent += extra_line_spacing;
21823 if (extra_line_spacing > it->max_extra_line_spacing)
21824 it->max_extra_line_spacing = extra_line_spacing;
21825 }
21826
21827 it->max_ascent = max (it->max_ascent, it->ascent);
21828 it->max_descent = max (it->max_descent, it->descent);
21829 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21830 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21831 }
21832
21833 /* EXPORT for RIF:
21834 Output LEN glyphs starting at START at the nominal cursor position.
21835 Advance the nominal cursor over the text. The global variable
21836 updated_window contains the window being updated, updated_row is
21837 the glyph row being updated, and updated_area is the area of that
21838 row being updated. */
21839
21840 void
21841 x_write_glyphs (start, len)
21842 struct glyph *start;
21843 int len;
21844 {
21845 int x, hpos;
21846
21847 xassert (updated_window && updated_row);
21848 BLOCK_INPUT;
21849
21850 /* Write glyphs. */
21851
21852 hpos = start - updated_row->glyphs[updated_area];
21853 x = draw_glyphs (updated_window, output_cursor.x,
21854 updated_row, updated_area,
21855 hpos, hpos + len,
21856 DRAW_NORMAL_TEXT, 0);
21857
21858 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21859 if (updated_area == TEXT_AREA
21860 && updated_window->phys_cursor_on_p
21861 && updated_window->phys_cursor.vpos == output_cursor.vpos
21862 && updated_window->phys_cursor.hpos >= hpos
21863 && updated_window->phys_cursor.hpos < hpos + len)
21864 updated_window->phys_cursor_on_p = 0;
21865
21866 UNBLOCK_INPUT;
21867
21868 /* Advance the output cursor. */
21869 output_cursor.hpos += len;
21870 output_cursor.x = x;
21871 }
21872
21873
21874 /* EXPORT for RIF:
21875 Insert LEN glyphs from START at the nominal cursor position. */
21876
21877 void
21878 x_insert_glyphs (start, len)
21879 struct glyph *start;
21880 int len;
21881 {
21882 struct frame *f;
21883 struct window *w;
21884 int line_height, shift_by_width, shifted_region_width;
21885 struct glyph_row *row;
21886 struct glyph *glyph;
21887 int frame_x, frame_y;
21888 EMACS_INT hpos;
21889
21890 xassert (updated_window && updated_row);
21891 BLOCK_INPUT;
21892 w = updated_window;
21893 f = XFRAME (WINDOW_FRAME (w));
21894
21895 /* Get the height of the line we are in. */
21896 row = updated_row;
21897 line_height = row->height;
21898
21899 /* Get the width of the glyphs to insert. */
21900 shift_by_width = 0;
21901 for (glyph = start; glyph < start + len; ++glyph)
21902 shift_by_width += glyph->pixel_width;
21903
21904 /* Get the width of the region to shift right. */
21905 shifted_region_width = (window_box_width (w, updated_area)
21906 - output_cursor.x
21907 - shift_by_width);
21908
21909 /* Shift right. */
21910 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21911 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21912
21913 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21914 line_height, shift_by_width);
21915
21916 /* Write the glyphs. */
21917 hpos = start - row->glyphs[updated_area];
21918 draw_glyphs (w, output_cursor.x, row, updated_area,
21919 hpos, hpos + len,
21920 DRAW_NORMAL_TEXT, 0);
21921
21922 /* Advance the output cursor. */
21923 output_cursor.hpos += len;
21924 output_cursor.x += shift_by_width;
21925 UNBLOCK_INPUT;
21926 }
21927
21928
21929 /* EXPORT for RIF:
21930 Erase the current text line from the nominal cursor position
21931 (inclusive) to pixel column TO_X (exclusive). The idea is that
21932 everything from TO_X onward is already erased.
21933
21934 TO_X is a pixel position relative to updated_area of
21935 updated_window. TO_X == -1 means clear to the end of this area. */
21936
21937 void
21938 x_clear_end_of_line (to_x)
21939 int to_x;
21940 {
21941 struct frame *f;
21942 struct window *w = updated_window;
21943 int max_x, min_y, max_y;
21944 int from_x, from_y, to_y;
21945
21946 xassert (updated_window && updated_row);
21947 f = XFRAME (w->frame);
21948
21949 if (updated_row->full_width_p)
21950 max_x = WINDOW_TOTAL_WIDTH (w);
21951 else
21952 max_x = window_box_width (w, updated_area);
21953 max_y = window_text_bottom_y (w);
21954
21955 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21956 of window. For TO_X > 0, truncate to end of drawing area. */
21957 if (to_x == 0)
21958 return;
21959 else if (to_x < 0)
21960 to_x = max_x;
21961 else
21962 to_x = min (to_x, max_x);
21963
21964 to_y = min (max_y, output_cursor.y + updated_row->height);
21965
21966 /* Notice if the cursor will be cleared by this operation. */
21967 if (!updated_row->full_width_p)
21968 notice_overwritten_cursor (w, updated_area,
21969 output_cursor.x, -1,
21970 updated_row->y,
21971 MATRIX_ROW_BOTTOM_Y (updated_row));
21972
21973 from_x = output_cursor.x;
21974
21975 /* Translate to frame coordinates. */
21976 if (updated_row->full_width_p)
21977 {
21978 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21979 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21980 }
21981 else
21982 {
21983 int area_left = window_box_left (w, updated_area);
21984 from_x += area_left;
21985 to_x += area_left;
21986 }
21987
21988 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21989 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21990 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21991
21992 /* Prevent inadvertently clearing to end of the X window. */
21993 if (to_x > from_x && to_y > from_y)
21994 {
21995 BLOCK_INPUT;
21996 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21997 to_x - from_x, to_y - from_y);
21998 UNBLOCK_INPUT;
21999 }
22000 }
22001
22002 #endif /* HAVE_WINDOW_SYSTEM */
22003
22004
22005 \f
22006 /***********************************************************************
22007 Cursor types
22008 ***********************************************************************/
22009
22010 /* Value is the internal representation of the specified cursor type
22011 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
22012 of the bar cursor. */
22013
22014 static enum text_cursor_kinds
22015 get_specified_cursor_type (arg, width)
22016 Lisp_Object arg;
22017 int *width;
22018 {
22019 enum text_cursor_kinds type;
22020
22021 if (NILP (arg))
22022 return NO_CURSOR;
22023
22024 if (EQ (arg, Qbox))
22025 return FILLED_BOX_CURSOR;
22026
22027 if (EQ (arg, Qhollow))
22028 return HOLLOW_BOX_CURSOR;
22029
22030 if (EQ (arg, Qbar))
22031 {
22032 *width = 2;
22033 return BAR_CURSOR;
22034 }
22035
22036 if (CONSP (arg)
22037 && EQ (XCAR (arg), Qbar)
22038 && INTEGERP (XCDR (arg))
22039 && XINT (XCDR (arg)) >= 0)
22040 {
22041 *width = XINT (XCDR (arg));
22042 return BAR_CURSOR;
22043 }
22044
22045 if (EQ (arg, Qhbar))
22046 {
22047 *width = 2;
22048 return HBAR_CURSOR;
22049 }
22050
22051 if (CONSP (arg)
22052 && EQ (XCAR (arg), Qhbar)
22053 && INTEGERP (XCDR (arg))
22054 && XINT (XCDR (arg)) >= 0)
22055 {
22056 *width = XINT (XCDR (arg));
22057 return HBAR_CURSOR;
22058 }
22059
22060 /* Treat anything unknown as "hollow box cursor".
22061 It was bad to signal an error; people have trouble fixing
22062 .Xdefaults with Emacs, when it has something bad in it. */
22063 type = HOLLOW_BOX_CURSOR;
22064
22065 return type;
22066 }
22067
22068 /* Set the default cursor types for specified frame. */
22069 void
22070 set_frame_cursor_types (f, arg)
22071 struct frame *f;
22072 Lisp_Object arg;
22073 {
22074 int width;
22075 Lisp_Object tem;
22076
22077 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
22078 FRAME_CURSOR_WIDTH (f) = width;
22079
22080 /* By default, set up the blink-off state depending on the on-state. */
22081
22082 tem = Fassoc (arg, Vblink_cursor_alist);
22083 if (!NILP (tem))
22084 {
22085 FRAME_BLINK_OFF_CURSOR (f)
22086 = get_specified_cursor_type (XCDR (tem), &width);
22087 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
22088 }
22089 else
22090 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
22091 }
22092
22093
22094 /* Return the cursor we want to be displayed in window W. Return
22095 width of bar/hbar cursor through WIDTH arg. Return with
22096 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
22097 (i.e. if the `system caret' should track this cursor).
22098
22099 In a mini-buffer window, we want the cursor only to appear if we
22100 are reading input from this window. For the selected window, we
22101 want the cursor type given by the frame parameter or buffer local
22102 setting of cursor-type. If explicitly marked off, draw no cursor.
22103 In all other cases, we want a hollow box cursor. */
22104
22105 static enum text_cursor_kinds
22106 get_window_cursor_type (w, glyph, width, active_cursor)
22107 struct window *w;
22108 struct glyph *glyph;
22109 int *width;
22110 int *active_cursor;
22111 {
22112 struct frame *f = XFRAME (w->frame);
22113 struct buffer *b = XBUFFER (w->buffer);
22114 int cursor_type = DEFAULT_CURSOR;
22115 Lisp_Object alt_cursor;
22116 int non_selected = 0;
22117
22118 *active_cursor = 1;
22119
22120 /* Echo area */
22121 if (cursor_in_echo_area
22122 && FRAME_HAS_MINIBUF_P (f)
22123 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
22124 {
22125 if (w == XWINDOW (echo_area_window))
22126 {
22127 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
22128 {
22129 *width = FRAME_CURSOR_WIDTH (f);
22130 return FRAME_DESIRED_CURSOR (f);
22131 }
22132 else
22133 return get_specified_cursor_type (b->cursor_type, width);
22134 }
22135
22136 *active_cursor = 0;
22137 non_selected = 1;
22138 }
22139
22140 /* Detect a nonselected window or nonselected frame. */
22141 else if (w != XWINDOW (f->selected_window)
22142 #ifdef HAVE_WINDOW_SYSTEM
22143 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
22144 #endif
22145 )
22146 {
22147 *active_cursor = 0;
22148
22149 if (MINI_WINDOW_P (w) && minibuf_level == 0)
22150 return NO_CURSOR;
22151
22152 non_selected = 1;
22153 }
22154
22155 /* Never display a cursor in a window in which cursor-type is nil. */
22156 if (NILP (b->cursor_type))
22157 return NO_CURSOR;
22158
22159 /* Get the normal cursor type for this window. */
22160 if (EQ (b->cursor_type, Qt))
22161 {
22162 cursor_type = FRAME_DESIRED_CURSOR (f);
22163 *width = FRAME_CURSOR_WIDTH (f);
22164 }
22165 else
22166 cursor_type = get_specified_cursor_type (b->cursor_type, width);
22167
22168 /* Use cursor-in-non-selected-windows instead
22169 for non-selected window or frame. */
22170 if (non_selected)
22171 {
22172 alt_cursor = b->cursor_in_non_selected_windows;
22173 if (!EQ (Qt, alt_cursor))
22174 return get_specified_cursor_type (alt_cursor, width);
22175 /* t means modify the normal cursor type. */
22176 if (cursor_type == FILLED_BOX_CURSOR)
22177 cursor_type = HOLLOW_BOX_CURSOR;
22178 else if (cursor_type == BAR_CURSOR && *width > 1)
22179 --*width;
22180 return cursor_type;
22181 }
22182
22183 /* Use normal cursor if not blinked off. */
22184 if (!w->cursor_off_p)
22185 {
22186 #ifdef HAVE_WINDOW_SYSTEM
22187 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22188 {
22189 if (cursor_type == FILLED_BOX_CURSOR)
22190 {
22191 /* Using a block cursor on large images can be very annoying.
22192 So use a hollow cursor for "large" images.
22193 If image is not transparent (no mask), also use hollow cursor. */
22194 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22195 if (img != NULL && IMAGEP (img->spec))
22196 {
22197 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
22198 where N = size of default frame font size.
22199 This should cover most of the "tiny" icons people may use. */
22200 if (!img->mask
22201 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
22202 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
22203 cursor_type = HOLLOW_BOX_CURSOR;
22204 }
22205 }
22206 else if (cursor_type != NO_CURSOR)
22207 {
22208 /* Display current only supports BOX and HOLLOW cursors for images.
22209 So for now, unconditionally use a HOLLOW cursor when cursor is
22210 not a solid box cursor. */
22211 cursor_type = HOLLOW_BOX_CURSOR;
22212 }
22213 }
22214 #endif
22215 return cursor_type;
22216 }
22217
22218 /* Cursor is blinked off, so determine how to "toggle" it. */
22219
22220 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
22221 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
22222 return get_specified_cursor_type (XCDR (alt_cursor), width);
22223
22224 /* Then see if frame has specified a specific blink off cursor type. */
22225 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
22226 {
22227 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
22228 return FRAME_BLINK_OFF_CURSOR (f);
22229 }
22230
22231 #if 0
22232 /* Some people liked having a permanently visible blinking cursor,
22233 while others had very strong opinions against it. So it was
22234 decided to remove it. KFS 2003-09-03 */
22235
22236 /* Finally perform built-in cursor blinking:
22237 filled box <-> hollow box
22238 wide [h]bar <-> narrow [h]bar
22239 narrow [h]bar <-> no cursor
22240 other type <-> no cursor */
22241
22242 if (cursor_type == FILLED_BOX_CURSOR)
22243 return HOLLOW_BOX_CURSOR;
22244
22245 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
22246 {
22247 *width = 1;
22248 return cursor_type;
22249 }
22250 #endif
22251
22252 return NO_CURSOR;
22253 }
22254
22255
22256 #ifdef HAVE_WINDOW_SYSTEM
22257
22258 /* Notice when the text cursor of window W has been completely
22259 overwritten by a drawing operation that outputs glyphs in AREA
22260 starting at X0 and ending at X1 in the line starting at Y0 and
22261 ending at Y1. X coordinates are area-relative. X1 < 0 means all
22262 the rest of the line after X0 has been written. Y coordinates
22263 are window-relative. */
22264
22265 static void
22266 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
22267 struct window *w;
22268 enum glyph_row_area area;
22269 int x0, y0, x1, y1;
22270 {
22271 int cx0, cx1, cy0, cy1;
22272 struct glyph_row *row;
22273
22274 if (!w->phys_cursor_on_p)
22275 return;
22276 if (area != TEXT_AREA)
22277 return;
22278
22279 if (w->phys_cursor.vpos < 0
22280 || w->phys_cursor.vpos >= w->current_matrix->nrows
22281 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
22282 !(row->enabled_p && row->displays_text_p)))
22283 return;
22284
22285 if (row->cursor_in_fringe_p)
22286 {
22287 row->cursor_in_fringe_p = 0;
22288 draw_fringe_bitmap (w, row, 0);
22289 w->phys_cursor_on_p = 0;
22290 return;
22291 }
22292
22293 cx0 = w->phys_cursor.x;
22294 cx1 = cx0 + w->phys_cursor_width;
22295 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
22296 return;
22297
22298 /* The cursor image will be completely removed from the
22299 screen if the output area intersects the cursor area in
22300 y-direction. When we draw in [y0 y1[, and some part of
22301 the cursor is at y < y0, that part must have been drawn
22302 before. When scrolling, the cursor is erased before
22303 actually scrolling, so we don't come here. When not
22304 scrolling, the rows above the old cursor row must have
22305 changed, and in this case these rows must have written
22306 over the cursor image.
22307
22308 Likewise if part of the cursor is below y1, with the
22309 exception of the cursor being in the first blank row at
22310 the buffer and window end because update_text_area
22311 doesn't draw that row. (Except when it does, but
22312 that's handled in update_text_area.) */
22313
22314 cy0 = w->phys_cursor.y;
22315 cy1 = cy0 + w->phys_cursor_height;
22316 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
22317 return;
22318
22319 w->phys_cursor_on_p = 0;
22320 }
22321
22322 #endif /* HAVE_WINDOW_SYSTEM */
22323
22324 \f
22325 /************************************************************************
22326 Mouse Face
22327 ************************************************************************/
22328
22329 #ifdef HAVE_WINDOW_SYSTEM
22330
22331 /* EXPORT for RIF:
22332 Fix the display of area AREA of overlapping row ROW in window W
22333 with respect to the overlapping part OVERLAPS. */
22334
22335 void
22336 x_fix_overlapping_area (w, row, area, overlaps)
22337 struct window *w;
22338 struct glyph_row *row;
22339 enum glyph_row_area area;
22340 int overlaps;
22341 {
22342 int i, x;
22343
22344 BLOCK_INPUT;
22345
22346 x = 0;
22347 for (i = 0; i < row->used[area];)
22348 {
22349 if (row->glyphs[area][i].overlaps_vertically_p)
22350 {
22351 int start = i, start_x = x;
22352
22353 do
22354 {
22355 x += row->glyphs[area][i].pixel_width;
22356 ++i;
22357 }
22358 while (i < row->used[area]
22359 && row->glyphs[area][i].overlaps_vertically_p);
22360
22361 draw_glyphs (w, start_x, row, area,
22362 start, i,
22363 DRAW_NORMAL_TEXT, overlaps);
22364 }
22365 else
22366 {
22367 x += row->glyphs[area][i].pixel_width;
22368 ++i;
22369 }
22370 }
22371
22372 UNBLOCK_INPUT;
22373 }
22374
22375
22376 /* EXPORT:
22377 Draw the cursor glyph of window W in glyph row ROW. See the
22378 comment of draw_glyphs for the meaning of HL. */
22379
22380 void
22381 draw_phys_cursor_glyph (w, row, hl)
22382 struct window *w;
22383 struct glyph_row *row;
22384 enum draw_glyphs_face hl;
22385 {
22386 /* If cursor hpos is out of bounds, don't draw garbage. This can
22387 happen in mini-buffer windows when switching between echo area
22388 glyphs and mini-buffer. */
22389 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
22390 {
22391 int on_p = w->phys_cursor_on_p;
22392 int x1;
22393 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
22394 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
22395 hl, 0);
22396 w->phys_cursor_on_p = on_p;
22397
22398 if (hl == DRAW_CURSOR)
22399 w->phys_cursor_width = x1 - w->phys_cursor.x;
22400 /* When we erase the cursor, and ROW is overlapped by other
22401 rows, make sure that these overlapping parts of other rows
22402 are redrawn. */
22403 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
22404 {
22405 w->phys_cursor_width = x1 - w->phys_cursor.x;
22406
22407 if (row > w->current_matrix->rows
22408 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
22409 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
22410 OVERLAPS_ERASED_CURSOR);
22411
22412 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
22413 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
22414 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
22415 OVERLAPS_ERASED_CURSOR);
22416 }
22417 }
22418 }
22419
22420
22421 /* EXPORT:
22422 Erase the image of a cursor of window W from the screen. */
22423
22424 void
22425 erase_phys_cursor (w)
22426 struct window *w;
22427 {
22428 struct frame *f = XFRAME (w->frame);
22429 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22430 int hpos = w->phys_cursor.hpos;
22431 int vpos = w->phys_cursor.vpos;
22432 int mouse_face_here_p = 0;
22433 struct glyph_matrix *active_glyphs = w->current_matrix;
22434 struct glyph_row *cursor_row;
22435 struct glyph *cursor_glyph;
22436 enum draw_glyphs_face hl;
22437
22438 /* No cursor displayed or row invalidated => nothing to do on the
22439 screen. */
22440 if (w->phys_cursor_type == NO_CURSOR)
22441 goto mark_cursor_off;
22442
22443 /* VPOS >= active_glyphs->nrows means that window has been resized.
22444 Don't bother to erase the cursor. */
22445 if (vpos >= active_glyphs->nrows)
22446 goto mark_cursor_off;
22447
22448 /* If row containing cursor is marked invalid, there is nothing we
22449 can do. */
22450 cursor_row = MATRIX_ROW (active_glyphs, vpos);
22451 if (!cursor_row->enabled_p)
22452 goto mark_cursor_off;
22453
22454 /* If line spacing is > 0, old cursor may only be partially visible in
22455 window after split-window. So adjust visible height. */
22456 cursor_row->visible_height = min (cursor_row->visible_height,
22457 window_text_bottom_y (w) - cursor_row->y);
22458
22459 /* If row is completely invisible, don't attempt to delete a cursor which
22460 isn't there. This can happen if cursor is at top of a window, and
22461 we switch to a buffer with a header line in that window. */
22462 if (cursor_row->visible_height <= 0)
22463 goto mark_cursor_off;
22464
22465 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
22466 if (cursor_row->cursor_in_fringe_p)
22467 {
22468 cursor_row->cursor_in_fringe_p = 0;
22469 draw_fringe_bitmap (w, cursor_row, 0);
22470 goto mark_cursor_off;
22471 }
22472
22473 /* This can happen when the new row is shorter than the old one.
22474 In this case, either draw_glyphs or clear_end_of_line
22475 should have cleared the cursor. Note that we wouldn't be
22476 able to erase the cursor in this case because we don't have a
22477 cursor glyph at hand. */
22478 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
22479 goto mark_cursor_off;
22480
22481 /* If the cursor is in the mouse face area, redisplay that when
22482 we clear the cursor. */
22483 if (! NILP (dpyinfo->mouse_face_window)
22484 && w == XWINDOW (dpyinfo->mouse_face_window)
22485 && (vpos > dpyinfo->mouse_face_beg_row
22486 || (vpos == dpyinfo->mouse_face_beg_row
22487 && hpos >= dpyinfo->mouse_face_beg_col))
22488 && (vpos < dpyinfo->mouse_face_end_row
22489 || (vpos == dpyinfo->mouse_face_end_row
22490 && hpos < dpyinfo->mouse_face_end_col))
22491 /* Don't redraw the cursor's spot in mouse face if it is at the
22492 end of a line (on a newline). The cursor appears there, but
22493 mouse highlighting does not. */
22494 && cursor_row->used[TEXT_AREA] > hpos)
22495 mouse_face_here_p = 1;
22496
22497 /* Maybe clear the display under the cursor. */
22498 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
22499 {
22500 int x, y, left_x;
22501 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
22502 int width;
22503
22504 cursor_glyph = get_phys_cursor_glyph (w);
22505 if (cursor_glyph == NULL)
22506 goto mark_cursor_off;
22507
22508 width = cursor_glyph->pixel_width;
22509 left_x = window_box_left_offset (w, TEXT_AREA);
22510 x = w->phys_cursor.x;
22511 if (x < left_x)
22512 width -= left_x - x;
22513 width = min (width, window_box_width (w, TEXT_AREA) - x);
22514 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
22515 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
22516
22517 if (width > 0)
22518 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
22519 }
22520
22521 /* Erase the cursor by redrawing the character underneath it. */
22522 if (mouse_face_here_p)
22523 hl = DRAW_MOUSE_FACE;
22524 else
22525 hl = DRAW_NORMAL_TEXT;
22526 draw_phys_cursor_glyph (w, cursor_row, hl);
22527
22528 mark_cursor_off:
22529 w->phys_cursor_on_p = 0;
22530 w->phys_cursor_type = NO_CURSOR;
22531 }
22532
22533
22534 /* EXPORT:
22535 Display or clear cursor of window W. If ON is zero, clear the
22536 cursor. If it is non-zero, display the cursor. If ON is nonzero,
22537 where to put the cursor is specified by HPOS, VPOS, X and Y. */
22538
22539 void
22540 display_and_set_cursor (w, on, hpos, vpos, x, y)
22541 struct window *w;
22542 int on, hpos, vpos, x, y;
22543 {
22544 struct frame *f = XFRAME (w->frame);
22545 int new_cursor_type;
22546 int new_cursor_width;
22547 int active_cursor;
22548 struct glyph_row *glyph_row;
22549 struct glyph *glyph;
22550
22551 /* This is pointless on invisible frames, and dangerous on garbaged
22552 windows and frames; in the latter case, the frame or window may
22553 be in the midst of changing its size, and x and y may be off the
22554 window. */
22555 if (! FRAME_VISIBLE_P (f)
22556 || FRAME_GARBAGED_P (f)
22557 || vpos >= w->current_matrix->nrows
22558 || hpos >= w->current_matrix->matrix_w)
22559 return;
22560
22561 /* If cursor is off and we want it off, return quickly. */
22562 if (!on && !w->phys_cursor_on_p)
22563 return;
22564
22565 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
22566 /* If cursor row is not enabled, we don't really know where to
22567 display the cursor. */
22568 if (!glyph_row->enabled_p)
22569 {
22570 w->phys_cursor_on_p = 0;
22571 return;
22572 }
22573
22574 glyph = NULL;
22575 if (!glyph_row->exact_window_width_line_p
22576 || hpos < glyph_row->used[TEXT_AREA])
22577 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
22578
22579 xassert (interrupt_input_blocked);
22580
22581 /* Set new_cursor_type to the cursor we want to be displayed. */
22582 new_cursor_type = get_window_cursor_type (w, glyph,
22583 &new_cursor_width, &active_cursor);
22584
22585 /* If cursor is currently being shown and we don't want it to be or
22586 it is in the wrong place, or the cursor type is not what we want,
22587 erase it. */
22588 if (w->phys_cursor_on_p
22589 && (!on
22590 || w->phys_cursor.x != x
22591 || w->phys_cursor.y != y
22592 || new_cursor_type != w->phys_cursor_type
22593 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
22594 && new_cursor_width != w->phys_cursor_width)))
22595 erase_phys_cursor (w);
22596
22597 /* Don't check phys_cursor_on_p here because that flag is only set
22598 to zero in some cases where we know that the cursor has been
22599 completely erased, to avoid the extra work of erasing the cursor
22600 twice. In other words, phys_cursor_on_p can be 1 and the cursor
22601 still not be visible, or it has only been partly erased. */
22602 if (on)
22603 {
22604 w->phys_cursor_ascent = glyph_row->ascent;
22605 w->phys_cursor_height = glyph_row->height;
22606
22607 /* Set phys_cursor_.* before x_draw_.* is called because some
22608 of them may need the information. */
22609 w->phys_cursor.x = x;
22610 w->phys_cursor.y = glyph_row->y;
22611 w->phys_cursor.hpos = hpos;
22612 w->phys_cursor.vpos = vpos;
22613 }
22614
22615 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
22616 new_cursor_type, new_cursor_width,
22617 on, active_cursor);
22618 }
22619
22620
22621 /* Switch the display of W's cursor on or off, according to the value
22622 of ON. */
22623
22624 #ifndef HAVE_NS
22625 static
22626 #endif
22627 void
22628 update_window_cursor (w, on)
22629 struct window *w;
22630 int on;
22631 {
22632 /* Don't update cursor in windows whose frame is in the process
22633 of being deleted. */
22634 if (w->current_matrix)
22635 {
22636 BLOCK_INPUT;
22637 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
22638 w->phys_cursor.x, w->phys_cursor.y);
22639 UNBLOCK_INPUT;
22640 }
22641 }
22642
22643
22644 /* Call update_window_cursor with parameter ON_P on all leaf windows
22645 in the window tree rooted at W. */
22646
22647 static void
22648 update_cursor_in_window_tree (w, on_p)
22649 struct window *w;
22650 int on_p;
22651 {
22652 while (w)
22653 {
22654 if (!NILP (w->hchild))
22655 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
22656 else if (!NILP (w->vchild))
22657 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
22658 else
22659 update_window_cursor (w, on_p);
22660
22661 w = NILP (w->next) ? 0 : XWINDOW (w->next);
22662 }
22663 }
22664
22665
22666 /* EXPORT:
22667 Display the cursor on window W, or clear it, according to ON_P.
22668 Don't change the cursor's position. */
22669
22670 void
22671 x_update_cursor (f, on_p)
22672 struct frame *f;
22673 int on_p;
22674 {
22675 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
22676 }
22677
22678
22679 /* EXPORT:
22680 Clear the cursor of window W to background color, and mark the
22681 cursor as not shown. This is used when the text where the cursor
22682 is is about to be rewritten. */
22683
22684 void
22685 x_clear_cursor (w)
22686 struct window *w;
22687 {
22688 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
22689 update_window_cursor (w, 0);
22690 }
22691
22692
22693 /* EXPORT:
22694 Display the active region described by mouse_face_* according to DRAW. */
22695
22696 void
22697 show_mouse_face (dpyinfo, draw)
22698 Display_Info *dpyinfo;
22699 enum draw_glyphs_face draw;
22700 {
22701 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
22702 struct frame *f = XFRAME (WINDOW_FRAME (w));
22703
22704 if (/* If window is in the process of being destroyed, don't bother
22705 to do anything. */
22706 w->current_matrix != NULL
22707 /* Don't update mouse highlight if hidden */
22708 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
22709 /* Recognize when we are called to operate on rows that don't exist
22710 anymore. This can happen when a window is split. */
22711 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
22712 {
22713 int phys_cursor_on_p = w->phys_cursor_on_p;
22714 struct glyph_row *row, *first, *last;
22715
22716 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
22717 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
22718
22719 for (row = first; row <= last && row->enabled_p; ++row)
22720 {
22721 int start_hpos, end_hpos, start_x;
22722
22723 /* For all but the first row, the highlight starts at column 0. */
22724 if (row == first)
22725 {
22726 start_hpos = dpyinfo->mouse_face_beg_col;
22727 start_x = dpyinfo->mouse_face_beg_x;
22728 }
22729 else
22730 {
22731 start_hpos = 0;
22732 start_x = 0;
22733 }
22734
22735 if (row == last)
22736 end_hpos = dpyinfo->mouse_face_end_col;
22737 else
22738 {
22739 end_hpos = row->used[TEXT_AREA];
22740 if (draw == DRAW_NORMAL_TEXT)
22741 row->fill_line_p = 1; /* Clear to end of line */
22742 }
22743
22744 if (end_hpos > start_hpos)
22745 {
22746 draw_glyphs (w, start_x, row, TEXT_AREA,
22747 start_hpos, end_hpos,
22748 draw, 0);
22749
22750 row->mouse_face_p
22751 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
22752 }
22753 }
22754
22755 /* When we've written over the cursor, arrange for it to
22756 be displayed again. */
22757 if (phys_cursor_on_p && !w->phys_cursor_on_p)
22758 {
22759 BLOCK_INPUT;
22760 display_and_set_cursor (w, 1,
22761 w->phys_cursor.hpos, w->phys_cursor.vpos,
22762 w->phys_cursor.x, w->phys_cursor.y);
22763 UNBLOCK_INPUT;
22764 }
22765 }
22766
22767 /* Change the mouse cursor. */
22768 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22769 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22770 else if (draw == DRAW_MOUSE_FACE)
22771 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22772 else
22773 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22774 }
22775
22776 /* EXPORT:
22777 Clear out the mouse-highlighted active region.
22778 Redraw it un-highlighted first. Value is non-zero if mouse
22779 face was actually drawn unhighlighted. */
22780
22781 int
22782 clear_mouse_face (dpyinfo)
22783 Display_Info *dpyinfo;
22784 {
22785 int cleared = 0;
22786
22787 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22788 {
22789 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22790 cleared = 1;
22791 }
22792
22793 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22794 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22795 dpyinfo->mouse_face_window = Qnil;
22796 dpyinfo->mouse_face_overlay = Qnil;
22797 return cleared;
22798 }
22799
22800
22801 /* EXPORT:
22802 Non-zero if physical cursor of window W is within mouse face. */
22803
22804 int
22805 cursor_in_mouse_face_p (w)
22806 struct window *w;
22807 {
22808 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22809 int in_mouse_face = 0;
22810
22811 if (WINDOWP (dpyinfo->mouse_face_window)
22812 && XWINDOW (dpyinfo->mouse_face_window) == w)
22813 {
22814 int hpos = w->phys_cursor.hpos;
22815 int vpos = w->phys_cursor.vpos;
22816
22817 if (vpos >= dpyinfo->mouse_face_beg_row
22818 && vpos <= dpyinfo->mouse_face_end_row
22819 && (vpos > dpyinfo->mouse_face_beg_row
22820 || hpos >= dpyinfo->mouse_face_beg_col)
22821 && (vpos < dpyinfo->mouse_face_end_row
22822 || hpos < dpyinfo->mouse_face_end_col
22823 || dpyinfo->mouse_face_past_end))
22824 in_mouse_face = 1;
22825 }
22826
22827 return in_mouse_face;
22828 }
22829
22830
22831
22832 \f
22833 /* This function sets the mouse_face_* elements of DPYINFO, assuming
22834 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
22835 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
22836 for the overlay or run of text properties specifying the mouse
22837 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
22838 before-string and after-string that must also be highlighted.
22839 DISPLAY_STRING, if non-nil, is a display string that may cover some
22840 or all of the highlighted text. */
22841
22842 static void
22843 mouse_face_from_buffer_pos (Lisp_Object window,
22844 Display_Info *dpyinfo,
22845 EMACS_INT mouse_charpos,
22846 EMACS_INT start_charpos,
22847 EMACS_INT end_charpos,
22848 Lisp_Object before_string,
22849 Lisp_Object after_string,
22850 Lisp_Object display_string)
22851 {
22852 struct window *w = XWINDOW (window);
22853 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22854 struct glyph_row *row;
22855 struct glyph *glyph, *end;
22856 EMACS_INT ignore;
22857 int x;
22858
22859 xassert (NILP (display_string) || STRINGP (display_string));
22860 xassert (NILP (before_string) || STRINGP (before_string));
22861 xassert (NILP (after_string) || STRINGP (after_string));
22862
22863 /* Find the first highlighted glyph. */
22864 if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
22865 {
22866 dpyinfo->mouse_face_beg_col = 0;
22867 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
22868 dpyinfo->mouse_face_beg_x = first->x;
22869 dpyinfo->mouse_face_beg_y = first->y;
22870 }
22871 else
22872 {
22873 row = row_containing_pos (w, start_charpos, first, NULL, 0);
22874 if (row == NULL)
22875 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22876
22877 /* If the before-string or display-string contains newlines,
22878 row_containing_pos skips to its last row. Move back. */
22879 if (!NILP (before_string) || !NILP (display_string))
22880 {
22881 struct glyph_row *prev;
22882 while ((prev = row - 1, prev >= first)
22883 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
22884 && prev->used[TEXT_AREA] > 0)
22885 {
22886 struct glyph *beg = prev->glyphs[TEXT_AREA];
22887 glyph = beg + prev->used[TEXT_AREA];
22888 while (--glyph >= beg && INTEGERP (glyph->object));
22889 if (glyph < beg
22890 || !(EQ (glyph->object, before_string)
22891 || EQ (glyph->object, display_string)))
22892 break;
22893 row = prev;
22894 }
22895 }
22896
22897 glyph = row->glyphs[TEXT_AREA];
22898 end = glyph + row->used[TEXT_AREA];
22899 x = row->x;
22900 dpyinfo->mouse_face_beg_y = row->y;
22901 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
22902
22903 /* Skip truncation glyphs at the start of the glyph row. */
22904 if (row->displays_text_p)
22905 for (; glyph < end
22906 && INTEGERP (glyph->object)
22907 && glyph->charpos < 0;
22908 ++glyph)
22909 x += glyph->pixel_width;
22910
22911 /* Scan the glyph row, stopping before BEFORE_STRING or
22912 DISPLAY_STRING or START_CHARPOS. */
22913 for (; glyph < end
22914 && !INTEGERP (glyph->object)
22915 && !EQ (glyph->object, before_string)
22916 && !EQ (glyph->object, display_string)
22917 && !(BUFFERP (glyph->object)
22918 && glyph->charpos >= start_charpos);
22919 ++glyph)
22920 x += glyph->pixel_width;
22921
22922 dpyinfo->mouse_face_beg_x = x;
22923 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
22924 }
22925
22926 /* Find the last highlighted glyph. */
22927 row = row_containing_pos (w, end_charpos, first, NULL, 0);
22928 if (row == NULL)
22929 {
22930 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22931 dpyinfo->mouse_face_past_end = 1;
22932 }
22933 else if (!NILP (after_string))
22934 {
22935 /* If the after-string has newlines, advance to its last row. */
22936 struct glyph_row *next;
22937 struct glyph_row *last
22938 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22939
22940 for (next = row + 1;
22941 next <= last
22942 && next->used[TEXT_AREA] > 0
22943 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
22944 ++next)
22945 row = next;
22946 }
22947
22948 glyph = row->glyphs[TEXT_AREA];
22949 end = glyph + row->used[TEXT_AREA];
22950 x = row->x;
22951 dpyinfo->mouse_face_end_y = row->y;
22952 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
22953
22954 /* Skip truncation glyphs at the start of the row. */
22955 if (row->displays_text_p)
22956 for (; glyph < end
22957 && INTEGERP (glyph->object)
22958 && glyph->charpos < 0;
22959 ++glyph)
22960 x += glyph->pixel_width;
22961
22962 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
22963 AFTER_STRING. */
22964 for (; glyph < end
22965 && !INTEGERP (glyph->object)
22966 && !EQ (glyph->object, after_string)
22967 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
22968 ++glyph)
22969 x += glyph->pixel_width;
22970
22971 /* If we found AFTER_STRING, consume it and stop. */
22972 if (EQ (glyph->object, after_string))
22973 {
22974 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
22975 x += glyph->pixel_width;
22976 }
22977 else
22978 {
22979 /* If there's no after-string, we must check if we overshot,
22980 which might be the case if we stopped after a string glyph.
22981 That glyph may belong to a before-string or display-string
22982 associated with the end position, which must not be
22983 highlighted. */
22984 Lisp_Object prev_object;
22985 int pos;
22986
22987 while (glyph > row->glyphs[TEXT_AREA])
22988 {
22989 prev_object = (glyph - 1)->object;
22990 if (!STRINGP (prev_object) || EQ (prev_object, display_string))
22991 break;
22992
22993 pos = string_buffer_position (w, prev_object, end_charpos);
22994 if (pos && pos < end_charpos)
22995 break;
22996
22997 for (; glyph > row->glyphs[TEXT_AREA]
22998 && EQ ((glyph - 1)->object, prev_object);
22999 --glyph)
23000 x -= (glyph - 1)->pixel_width;
23001 }
23002 }
23003
23004 dpyinfo->mouse_face_end_x = x;
23005 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
23006 dpyinfo->mouse_face_window = window;
23007 dpyinfo->mouse_face_face_id
23008 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
23009 mouse_charpos + 1,
23010 !dpyinfo->mouse_face_hidden, -1);
23011 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23012 }
23013
23014
23015 /* Find the position of the glyph for position POS in OBJECT in
23016 window W's current matrix, and return in *X, *Y the pixel
23017 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
23018
23019 RIGHT_P non-zero means return the position of the right edge of the
23020 glyph, RIGHT_P zero means return the left edge position.
23021
23022 If no glyph for POS exists in the matrix, return the position of
23023 the glyph with the next smaller position that is in the matrix, if
23024 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
23025 exists in the matrix, return the position of the glyph with the
23026 next larger position in OBJECT.
23027
23028 Value is non-zero if a glyph was found. */
23029
23030 static int
23031 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
23032 struct window *w;
23033 EMACS_INT pos;
23034 Lisp_Object object;
23035 int *hpos, *vpos, *x, *y;
23036 int right_p;
23037 {
23038 int yb = window_text_bottom_y (w);
23039 struct glyph_row *r;
23040 struct glyph *best_glyph = NULL;
23041 struct glyph_row *best_row = NULL;
23042 int best_x = 0;
23043
23044 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23045 r->enabled_p && r->y < yb;
23046 ++r)
23047 {
23048 struct glyph *g = r->glyphs[TEXT_AREA];
23049 struct glyph *e = g + r->used[TEXT_AREA];
23050 int gx;
23051
23052 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
23053 if (EQ (g->object, object))
23054 {
23055 if (g->charpos == pos)
23056 {
23057 best_glyph = g;
23058 best_x = gx;
23059 best_row = r;
23060 goto found;
23061 }
23062 else if (best_glyph == NULL
23063 || ((eabs (g->charpos - pos)
23064 < eabs (best_glyph->charpos - pos))
23065 && (right_p
23066 ? g->charpos < pos
23067 : g->charpos > pos)))
23068 {
23069 best_glyph = g;
23070 best_x = gx;
23071 best_row = r;
23072 }
23073 }
23074 }
23075
23076 found:
23077
23078 if (best_glyph)
23079 {
23080 *x = best_x;
23081 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
23082
23083 if (right_p)
23084 {
23085 *x += best_glyph->pixel_width;
23086 ++*hpos;
23087 }
23088
23089 *y = best_row->y;
23090 *vpos = best_row - w->current_matrix->rows;
23091 }
23092
23093 return best_glyph != NULL;
23094 }
23095
23096
23097 /* See if position X, Y is within a hot-spot of an image. */
23098
23099 static int
23100 on_hot_spot_p (hot_spot, x, y)
23101 Lisp_Object hot_spot;
23102 int x, y;
23103 {
23104 if (!CONSP (hot_spot))
23105 return 0;
23106
23107 if (EQ (XCAR (hot_spot), Qrect))
23108 {
23109 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
23110 Lisp_Object rect = XCDR (hot_spot);
23111 Lisp_Object tem;
23112 if (!CONSP (rect))
23113 return 0;
23114 if (!CONSP (XCAR (rect)))
23115 return 0;
23116 if (!CONSP (XCDR (rect)))
23117 return 0;
23118 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
23119 return 0;
23120 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
23121 return 0;
23122 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
23123 return 0;
23124 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
23125 return 0;
23126 return 1;
23127 }
23128 else if (EQ (XCAR (hot_spot), Qcircle))
23129 {
23130 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
23131 Lisp_Object circ = XCDR (hot_spot);
23132 Lisp_Object lr, lx0, ly0;
23133 if (CONSP (circ)
23134 && CONSP (XCAR (circ))
23135 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
23136 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
23137 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
23138 {
23139 double r = XFLOATINT (lr);
23140 double dx = XINT (lx0) - x;
23141 double dy = XINT (ly0) - y;
23142 return (dx * dx + dy * dy <= r * r);
23143 }
23144 }
23145 else if (EQ (XCAR (hot_spot), Qpoly))
23146 {
23147 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
23148 if (VECTORP (XCDR (hot_spot)))
23149 {
23150 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
23151 Lisp_Object *poly = v->contents;
23152 int n = v->size;
23153 int i;
23154 int inside = 0;
23155 Lisp_Object lx, ly;
23156 int x0, y0;
23157
23158 /* Need an even number of coordinates, and at least 3 edges. */
23159 if (n < 6 || n & 1)
23160 return 0;
23161
23162 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
23163 If count is odd, we are inside polygon. Pixels on edges
23164 may or may not be included depending on actual geometry of the
23165 polygon. */
23166 if ((lx = poly[n-2], !INTEGERP (lx))
23167 || (ly = poly[n-1], !INTEGERP (lx)))
23168 return 0;
23169 x0 = XINT (lx), y0 = XINT (ly);
23170 for (i = 0; i < n; i += 2)
23171 {
23172 int x1 = x0, y1 = y0;
23173 if ((lx = poly[i], !INTEGERP (lx))
23174 || (ly = poly[i+1], !INTEGERP (ly)))
23175 return 0;
23176 x0 = XINT (lx), y0 = XINT (ly);
23177
23178 /* Does this segment cross the X line? */
23179 if (x0 >= x)
23180 {
23181 if (x1 >= x)
23182 continue;
23183 }
23184 else if (x1 < x)
23185 continue;
23186 if (y > y0 && y > y1)
23187 continue;
23188 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
23189 inside = !inside;
23190 }
23191 return inside;
23192 }
23193 }
23194 return 0;
23195 }
23196
23197 Lisp_Object
23198 find_hot_spot (map, x, y)
23199 Lisp_Object map;
23200 int x, y;
23201 {
23202 while (CONSP (map))
23203 {
23204 if (CONSP (XCAR (map))
23205 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
23206 return XCAR (map);
23207 map = XCDR (map);
23208 }
23209
23210 return Qnil;
23211 }
23212
23213 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
23214 3, 3, 0,
23215 doc: /* Lookup in image map MAP coordinates X and Y.
23216 An image map is an alist where each element has the format (AREA ID PLIST).
23217 An AREA is specified as either a rectangle, a circle, or a polygon:
23218 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
23219 pixel coordinates of the upper left and bottom right corners.
23220 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
23221 and the radius of the circle; r may be a float or integer.
23222 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
23223 vector describes one corner in the polygon.
23224 Returns the alist element for the first matching AREA in MAP. */)
23225 (map, x, y)
23226 Lisp_Object map;
23227 Lisp_Object x, y;
23228 {
23229 if (NILP (map))
23230 return Qnil;
23231
23232 CHECK_NUMBER (x);
23233 CHECK_NUMBER (y);
23234
23235 return find_hot_spot (map, XINT (x), XINT (y));
23236 }
23237
23238
23239 /* Display frame CURSOR, optionally using shape defined by POINTER. */
23240 static void
23241 define_frame_cursor1 (f, cursor, pointer)
23242 struct frame *f;
23243 Cursor cursor;
23244 Lisp_Object pointer;
23245 {
23246 /* Do not change cursor shape while dragging mouse. */
23247 if (!NILP (do_mouse_tracking))
23248 return;
23249
23250 if (!NILP (pointer))
23251 {
23252 if (EQ (pointer, Qarrow))
23253 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23254 else if (EQ (pointer, Qhand))
23255 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
23256 else if (EQ (pointer, Qtext))
23257 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23258 else if (EQ (pointer, intern ("hdrag")))
23259 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23260 #ifdef HAVE_X_WINDOWS
23261 else if (EQ (pointer, intern ("vdrag")))
23262 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
23263 #endif
23264 else if (EQ (pointer, intern ("hourglass")))
23265 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
23266 else if (EQ (pointer, Qmodeline))
23267 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
23268 else
23269 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23270 }
23271
23272 if (cursor != No_Cursor)
23273 FRAME_RIF (f)->define_frame_cursor (f, cursor);
23274 }
23275
23276 /* Take proper action when mouse has moved to the mode or header line
23277 or marginal area AREA of window W, x-position X and y-position Y.
23278 X is relative to the start of the text display area of W, so the
23279 width of bitmap areas and scroll bars must be subtracted to get a
23280 position relative to the start of the mode line. */
23281
23282 static void
23283 note_mode_line_or_margin_highlight (window, x, y, area)
23284 Lisp_Object window;
23285 int x, y;
23286 enum window_part area;
23287 {
23288 struct window *w = XWINDOW (window);
23289 struct frame *f = XFRAME (w->frame);
23290 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23291 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23292 Lisp_Object pointer = Qnil;
23293 int charpos, dx, dy, width, height;
23294 Lisp_Object string, object = Qnil;
23295 Lisp_Object pos, help;
23296
23297 Lisp_Object mouse_face;
23298 int original_x_pixel = x;
23299 struct glyph * glyph = NULL, * row_start_glyph = NULL;
23300 struct glyph_row *row;
23301
23302 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
23303 {
23304 int x0;
23305 struct glyph *end;
23306
23307 string = mode_line_string (w, area, &x, &y, &charpos,
23308 &object, &dx, &dy, &width, &height);
23309
23310 row = (area == ON_MODE_LINE
23311 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
23312 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
23313
23314 /* Find glyph */
23315 if (row->mode_line_p && row->enabled_p)
23316 {
23317 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
23318 end = glyph + row->used[TEXT_AREA];
23319
23320 for (x0 = original_x_pixel;
23321 glyph < end && x0 >= glyph->pixel_width;
23322 ++glyph)
23323 x0 -= glyph->pixel_width;
23324
23325 if (glyph >= end)
23326 glyph = NULL;
23327 }
23328 }
23329 else
23330 {
23331 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
23332 string = marginal_area_string (w, area, &x, &y, &charpos,
23333 &object, &dx, &dy, &width, &height);
23334 }
23335
23336 help = Qnil;
23337
23338 if (IMAGEP (object))
23339 {
23340 Lisp_Object image_map, hotspot;
23341 if ((image_map = Fplist_get (XCDR (object), QCmap),
23342 !NILP (image_map))
23343 && (hotspot = find_hot_spot (image_map, dx, dy),
23344 CONSP (hotspot))
23345 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23346 {
23347 Lisp_Object area_id, plist;
23348
23349 area_id = XCAR (hotspot);
23350 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23351 If so, we could look for mouse-enter, mouse-leave
23352 properties in PLIST (and do something...). */
23353 hotspot = XCDR (hotspot);
23354 if (CONSP (hotspot)
23355 && (plist = XCAR (hotspot), CONSP (plist)))
23356 {
23357 pointer = Fplist_get (plist, Qpointer);
23358 if (NILP (pointer))
23359 pointer = Qhand;
23360 help = Fplist_get (plist, Qhelp_echo);
23361 if (!NILP (help))
23362 {
23363 help_echo_string = help;
23364 /* Is this correct? ++kfs */
23365 XSETWINDOW (help_echo_window, w);
23366 help_echo_object = w->buffer;
23367 help_echo_pos = charpos;
23368 }
23369 }
23370 }
23371 if (NILP (pointer))
23372 pointer = Fplist_get (XCDR (object), QCpointer);
23373 }
23374
23375 if (STRINGP (string))
23376 {
23377 pos = make_number (charpos);
23378 /* If we're on a string with `help-echo' text property, arrange
23379 for the help to be displayed. This is done by setting the
23380 global variable help_echo_string to the help string. */
23381 if (NILP (help))
23382 {
23383 help = Fget_text_property (pos, Qhelp_echo, string);
23384 if (!NILP (help))
23385 {
23386 help_echo_string = help;
23387 XSETWINDOW (help_echo_window, w);
23388 help_echo_object = string;
23389 help_echo_pos = charpos;
23390 }
23391 }
23392
23393 if (NILP (pointer))
23394 pointer = Fget_text_property (pos, Qpointer, string);
23395
23396 /* Change the mouse pointer according to what is under X/Y. */
23397 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
23398 {
23399 Lisp_Object map;
23400 map = Fget_text_property (pos, Qlocal_map, string);
23401 if (!KEYMAPP (map))
23402 map = Fget_text_property (pos, Qkeymap, string);
23403 if (!KEYMAPP (map))
23404 cursor = dpyinfo->vertical_scroll_bar_cursor;
23405 }
23406
23407 /* Change the mouse face according to what is under X/Y. */
23408 mouse_face = Fget_text_property (pos, Qmouse_face, string);
23409 if (!NILP (mouse_face)
23410 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23411 && glyph)
23412 {
23413 Lisp_Object b, e;
23414
23415 struct glyph * tmp_glyph;
23416
23417 int gpos;
23418 int gseq_length;
23419 int total_pixel_width;
23420 EMACS_INT ignore;
23421
23422 int vpos, hpos;
23423
23424 b = Fprevious_single_property_change (make_number (charpos + 1),
23425 Qmouse_face, string, Qnil);
23426 if (NILP (b))
23427 b = make_number (0);
23428
23429 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
23430 if (NILP (e))
23431 e = make_number (SCHARS (string));
23432
23433 /* Calculate the position(glyph position: GPOS) of GLYPH in
23434 displayed string. GPOS is different from CHARPOS.
23435
23436 CHARPOS is the position of glyph in internal string
23437 object. A mode line string format has structures which
23438 is converted to a flatten by emacs lisp interpreter.
23439 The internal string is an element of the structures.
23440 The displayed string is the flatten string. */
23441 gpos = 0;
23442 if (glyph > row_start_glyph)
23443 {
23444 tmp_glyph = glyph - 1;
23445 while (tmp_glyph >= row_start_glyph
23446 && tmp_glyph->charpos >= XINT (b)
23447 && EQ (tmp_glyph->object, glyph->object))
23448 {
23449 tmp_glyph--;
23450 gpos++;
23451 }
23452 }
23453
23454 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
23455 displayed string holding GLYPH.
23456
23457 GSEQ_LENGTH is different from SCHARS (STRING).
23458 SCHARS (STRING) returns the length of the internal string. */
23459 for (tmp_glyph = glyph, gseq_length = gpos;
23460 tmp_glyph->charpos < XINT (e);
23461 tmp_glyph++, gseq_length++)
23462 {
23463 if (!EQ (tmp_glyph->object, glyph->object))
23464 break;
23465 }
23466
23467 total_pixel_width = 0;
23468 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
23469 total_pixel_width += tmp_glyph->pixel_width;
23470
23471 /* Pre calculation of re-rendering position */
23472 vpos = (x - gpos);
23473 hpos = (area == ON_MODE_LINE
23474 ? (w->current_matrix)->nrows - 1
23475 : 0);
23476
23477 /* If the re-rendering position is included in the last
23478 re-rendering area, we should do nothing. */
23479 if ( EQ (window, dpyinfo->mouse_face_window)
23480 && dpyinfo->mouse_face_beg_col <= vpos
23481 && vpos < dpyinfo->mouse_face_end_col
23482 && dpyinfo->mouse_face_beg_row == hpos )
23483 return;
23484
23485 if (clear_mouse_face (dpyinfo))
23486 cursor = No_Cursor;
23487
23488 dpyinfo->mouse_face_beg_col = vpos;
23489 dpyinfo->mouse_face_beg_row = hpos;
23490
23491 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
23492 dpyinfo->mouse_face_beg_y = 0;
23493
23494 dpyinfo->mouse_face_end_col = vpos + gseq_length;
23495 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
23496
23497 dpyinfo->mouse_face_end_x = 0;
23498 dpyinfo->mouse_face_end_y = 0;
23499
23500 dpyinfo->mouse_face_past_end = 0;
23501 dpyinfo->mouse_face_window = window;
23502
23503 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
23504 charpos,
23505 0, 0, 0, &ignore,
23506 glyph->face_id, 1);
23507 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23508
23509 if (NILP (pointer))
23510 pointer = Qhand;
23511 }
23512 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23513 clear_mouse_face (dpyinfo);
23514 }
23515 define_frame_cursor1 (f, cursor, pointer);
23516 }
23517
23518
23519 /* EXPORT:
23520 Take proper action when the mouse has moved to position X, Y on
23521 frame F as regards highlighting characters that have mouse-face
23522 properties. Also de-highlighting chars where the mouse was before.
23523 X and Y can be negative or out of range. */
23524
23525 void
23526 note_mouse_highlight (f, x, y)
23527 struct frame *f;
23528 int x, y;
23529 {
23530 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23531 enum window_part part;
23532 Lisp_Object window;
23533 struct window *w;
23534 Cursor cursor = No_Cursor;
23535 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
23536 struct buffer *b;
23537
23538 /* When a menu is active, don't highlight because this looks odd. */
23539 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
23540 if (popup_activated ())
23541 return;
23542 #endif
23543
23544 if (NILP (Vmouse_highlight)
23545 || !f->glyphs_initialized_p)
23546 return;
23547
23548 dpyinfo->mouse_face_mouse_x = x;
23549 dpyinfo->mouse_face_mouse_y = y;
23550 dpyinfo->mouse_face_mouse_frame = f;
23551
23552 if (dpyinfo->mouse_face_defer)
23553 return;
23554
23555 if (gc_in_progress)
23556 {
23557 dpyinfo->mouse_face_deferred_gc = 1;
23558 return;
23559 }
23560
23561 /* Which window is that in? */
23562 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
23563
23564 /* If we were displaying active text in another window, clear that.
23565 Also clear if we move out of text area in same window. */
23566 if (! EQ (window, dpyinfo->mouse_face_window)
23567 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
23568 && !NILP (dpyinfo->mouse_face_window)))
23569 clear_mouse_face (dpyinfo);
23570
23571 /* Not on a window -> return. */
23572 if (!WINDOWP (window))
23573 return;
23574
23575 /* Reset help_echo_string. It will get recomputed below. */
23576 help_echo_string = Qnil;
23577
23578 /* Convert to window-relative pixel coordinates. */
23579 w = XWINDOW (window);
23580 frame_to_window_pixel_xy (w, &x, &y);
23581
23582 /* Handle tool-bar window differently since it doesn't display a
23583 buffer. */
23584 if (EQ (window, f->tool_bar_window))
23585 {
23586 note_tool_bar_highlight (f, x, y);
23587 return;
23588 }
23589
23590 /* Mouse is on the mode, header line or margin? */
23591 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
23592 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
23593 {
23594 note_mode_line_or_margin_highlight (window, x, y, part);
23595 return;
23596 }
23597
23598 if (part == ON_VERTICAL_BORDER)
23599 {
23600 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23601 help_echo_string = build_string ("drag-mouse-1: resize");
23602 }
23603 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
23604 || part == ON_SCROLL_BAR)
23605 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23606 else
23607 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23608
23609 /* Are we in a window whose display is up to date?
23610 And verify the buffer's text has not changed. */
23611 b = XBUFFER (w->buffer);
23612 if (part == ON_TEXT
23613 && EQ (w->window_end_valid, w->buffer)
23614 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
23615 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
23616 {
23617 int hpos, vpos, pos, i, dx, dy, area;
23618 struct glyph *glyph;
23619 Lisp_Object object;
23620 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
23621 Lisp_Object *overlay_vec = NULL;
23622 int noverlays;
23623 struct buffer *obuf;
23624 int obegv, ozv, same_region;
23625
23626 /* Find the glyph under X/Y. */
23627 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
23628
23629 /* Look for :pointer property on image. */
23630 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23631 {
23632 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23633 if (img != NULL && IMAGEP (img->spec))
23634 {
23635 Lisp_Object image_map, hotspot;
23636 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
23637 !NILP (image_map))
23638 && (hotspot = find_hot_spot (image_map,
23639 glyph->slice.x + dx,
23640 glyph->slice.y + dy),
23641 CONSP (hotspot))
23642 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23643 {
23644 Lisp_Object area_id, plist;
23645
23646 area_id = XCAR (hotspot);
23647 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23648 If so, we could look for mouse-enter, mouse-leave
23649 properties in PLIST (and do something...). */
23650 hotspot = XCDR (hotspot);
23651 if (CONSP (hotspot)
23652 && (plist = XCAR (hotspot), CONSP (plist)))
23653 {
23654 pointer = Fplist_get (plist, Qpointer);
23655 if (NILP (pointer))
23656 pointer = Qhand;
23657 help_echo_string = Fplist_get (plist, Qhelp_echo);
23658 if (!NILP (help_echo_string))
23659 {
23660 help_echo_window = window;
23661 help_echo_object = glyph->object;
23662 help_echo_pos = glyph->charpos;
23663 }
23664 }
23665 }
23666 if (NILP (pointer))
23667 pointer = Fplist_get (XCDR (img->spec), QCpointer);
23668 }
23669 }
23670
23671 /* Clear mouse face if X/Y not over text. */
23672 if (glyph == NULL
23673 || area != TEXT_AREA
23674 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
23675 {
23676 if (clear_mouse_face (dpyinfo))
23677 cursor = No_Cursor;
23678 if (NILP (pointer))
23679 {
23680 if (area != TEXT_AREA)
23681 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23682 else
23683 pointer = Vvoid_text_area_pointer;
23684 }
23685 goto set_cursor;
23686 }
23687
23688 pos = glyph->charpos;
23689 object = glyph->object;
23690 if (!STRINGP (object) && !BUFFERP (object))
23691 goto set_cursor;
23692
23693 /* If we get an out-of-range value, return now; avoid an error. */
23694 if (BUFFERP (object) && pos > BUF_Z (b))
23695 goto set_cursor;
23696
23697 /* Make the window's buffer temporarily current for
23698 overlays_at and compute_char_face. */
23699 obuf = current_buffer;
23700 current_buffer = b;
23701 obegv = BEGV;
23702 ozv = ZV;
23703 BEGV = BEG;
23704 ZV = Z;
23705
23706 /* Is this char mouse-active or does it have help-echo? */
23707 position = make_number (pos);
23708
23709 if (BUFFERP (object))
23710 {
23711 /* Put all the overlays we want in a vector in overlay_vec. */
23712 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
23713 /* Sort overlays into increasing priority order. */
23714 noverlays = sort_overlays (overlay_vec, noverlays, w);
23715 }
23716 else
23717 noverlays = 0;
23718
23719 same_region = (EQ (window, dpyinfo->mouse_face_window)
23720 && vpos >= dpyinfo->mouse_face_beg_row
23721 && vpos <= dpyinfo->mouse_face_end_row
23722 && (vpos > dpyinfo->mouse_face_beg_row
23723 || hpos >= dpyinfo->mouse_face_beg_col)
23724 && (vpos < dpyinfo->mouse_face_end_row
23725 || hpos < dpyinfo->mouse_face_end_col
23726 || dpyinfo->mouse_face_past_end));
23727
23728 if (same_region)
23729 cursor = No_Cursor;
23730
23731 /* Check mouse-face highlighting. */
23732 if (! same_region
23733 /* If there exists an overlay with mouse-face overlapping
23734 the one we are currently highlighting, we have to
23735 check if we enter the overlapping overlay, and then
23736 highlight only that. */
23737 || (OVERLAYP (dpyinfo->mouse_face_overlay)
23738 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
23739 {
23740 /* Find the highest priority overlay with a mouse-face. */
23741 overlay = Qnil;
23742 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
23743 {
23744 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
23745 if (!NILP (mouse_face))
23746 overlay = overlay_vec[i];
23747 }
23748
23749 /* If we're highlighting the same overlay as before, there's
23750 no need to do that again. */
23751 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
23752 goto check_help_echo;
23753 dpyinfo->mouse_face_overlay = overlay;
23754
23755 /* Clear the display of the old active region, if any. */
23756 if (clear_mouse_face (dpyinfo))
23757 cursor = No_Cursor;
23758
23759 /* If no overlay applies, get a text property. */
23760 if (NILP (overlay))
23761 mouse_face = Fget_text_property (position, Qmouse_face, object);
23762
23763 /* Next, compute the bounds of the mouse highlighting and
23764 display it. */
23765 if (!NILP (mouse_face) && STRINGP (object))
23766 {
23767 /* The mouse-highlighting comes from a display string
23768 with a mouse-face. */
23769 Lisp_Object b, e;
23770 EMACS_INT ignore;
23771
23772 b = Fprevious_single_property_change
23773 (make_number (pos + 1), Qmouse_face, object, Qnil);
23774 e = Fnext_single_property_change
23775 (position, Qmouse_face, object, Qnil);
23776 if (NILP (b))
23777 b = make_number (0);
23778 if (NILP (e))
23779 e = make_number (SCHARS (object) - 1);
23780
23781 fast_find_string_pos (w, XINT (b), object,
23782 &dpyinfo->mouse_face_beg_col,
23783 &dpyinfo->mouse_face_beg_row,
23784 &dpyinfo->mouse_face_beg_x,
23785 &dpyinfo->mouse_face_beg_y, 0);
23786 fast_find_string_pos (w, XINT (e), object,
23787 &dpyinfo->mouse_face_end_col,
23788 &dpyinfo->mouse_face_end_row,
23789 &dpyinfo->mouse_face_end_x,
23790 &dpyinfo->mouse_face_end_y, 1);
23791 dpyinfo->mouse_face_past_end = 0;
23792 dpyinfo->mouse_face_window = window;
23793 dpyinfo->mouse_face_face_id
23794 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23795 glyph->face_id, 1);
23796 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23797 cursor = No_Cursor;
23798 }
23799 else
23800 {
23801 /* The mouse-highlighting, if any, comes from an overlay
23802 or text property in the buffer. */
23803 Lisp_Object buffer, display_string;
23804
23805 if (STRINGP (object))
23806 {
23807 /* If we are on a display string with no mouse-face,
23808 check if the text under it has one. */
23809 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23810 int start = MATRIX_ROW_START_CHARPOS (r);
23811 pos = string_buffer_position (w, object, start);
23812 if (pos > 0)
23813 {
23814 mouse_face = get_char_property_and_overlay
23815 (make_number (pos), Qmouse_face, w->buffer, &overlay);
23816 buffer = w->buffer;
23817 display_string = object;
23818 }
23819 }
23820 else
23821 {
23822 buffer = object;
23823 display_string = Qnil;
23824 }
23825
23826 if (!NILP (mouse_face))
23827 {
23828 Lisp_Object before, after;
23829 Lisp_Object before_string, after_string;
23830
23831 if (NILP (overlay))
23832 {
23833 /* Handle the text property case. */
23834 before = Fprevious_single_property_change
23835 (make_number (pos + 1), Qmouse_face, buffer,
23836 Fmarker_position (w->start));
23837 after = Fnext_single_property_change
23838 (make_number (pos), Qmouse_face, buffer,
23839 make_number (BUF_Z (XBUFFER (buffer))
23840 - XFASTINT (w->window_end_pos)));
23841 before_string = after_string = Qnil;
23842 }
23843 else
23844 {
23845 /* Handle the overlay case. */
23846 before = Foverlay_start (overlay);
23847 after = Foverlay_end (overlay);
23848 before_string = Foverlay_get (overlay, Qbefore_string);
23849 after_string = Foverlay_get (overlay, Qafter_string);
23850
23851 if (!STRINGP (before_string)) before_string = Qnil;
23852 if (!STRINGP (after_string)) after_string = Qnil;
23853 }
23854
23855 mouse_face_from_buffer_pos (window, dpyinfo, pos,
23856 XFASTINT (before),
23857 XFASTINT (after),
23858 before_string, after_string,
23859 display_string);
23860 cursor = No_Cursor;
23861 }
23862 }
23863 }
23864
23865 check_help_echo:
23866
23867 /* Look for a `help-echo' property. */
23868 if (NILP (help_echo_string)) {
23869 Lisp_Object help, overlay;
23870
23871 /* Check overlays first. */
23872 help = overlay = Qnil;
23873 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23874 {
23875 overlay = overlay_vec[i];
23876 help = Foverlay_get (overlay, Qhelp_echo);
23877 }
23878
23879 if (!NILP (help))
23880 {
23881 help_echo_string = help;
23882 help_echo_window = window;
23883 help_echo_object = overlay;
23884 help_echo_pos = pos;
23885 }
23886 else
23887 {
23888 Lisp_Object object = glyph->object;
23889 int charpos = glyph->charpos;
23890
23891 /* Try text properties. */
23892 if (STRINGP (object)
23893 && charpos >= 0
23894 && charpos < SCHARS (object))
23895 {
23896 help = Fget_text_property (make_number (charpos),
23897 Qhelp_echo, object);
23898 if (NILP (help))
23899 {
23900 /* If the string itself doesn't specify a help-echo,
23901 see if the buffer text ``under'' it does. */
23902 struct glyph_row *r
23903 = MATRIX_ROW (w->current_matrix, vpos);
23904 int start = MATRIX_ROW_START_CHARPOS (r);
23905 int pos = string_buffer_position (w, object, start);
23906 if (pos > 0)
23907 {
23908 help = Fget_char_property (make_number (pos),
23909 Qhelp_echo, w->buffer);
23910 if (!NILP (help))
23911 {
23912 charpos = pos;
23913 object = w->buffer;
23914 }
23915 }
23916 }
23917 }
23918 else if (BUFFERP (object)
23919 && charpos >= BEGV
23920 && charpos < ZV)
23921 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23922 object);
23923
23924 if (!NILP (help))
23925 {
23926 help_echo_string = help;
23927 help_echo_window = window;
23928 help_echo_object = object;
23929 help_echo_pos = charpos;
23930 }
23931 }
23932 }
23933
23934 /* Look for a `pointer' property. */
23935 if (NILP (pointer))
23936 {
23937 /* Check overlays first. */
23938 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23939 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23940
23941 if (NILP (pointer))
23942 {
23943 Lisp_Object object = glyph->object;
23944 int charpos = glyph->charpos;
23945
23946 /* Try text properties. */
23947 if (STRINGP (object)
23948 && charpos >= 0
23949 && charpos < SCHARS (object))
23950 {
23951 pointer = Fget_text_property (make_number (charpos),
23952 Qpointer, object);
23953 if (NILP (pointer))
23954 {
23955 /* If the string itself doesn't specify a pointer,
23956 see if the buffer text ``under'' it does. */
23957 struct glyph_row *r
23958 = MATRIX_ROW (w->current_matrix, vpos);
23959 int start = MATRIX_ROW_START_CHARPOS (r);
23960 int pos = string_buffer_position (w, object, start);
23961 if (pos > 0)
23962 pointer = Fget_char_property (make_number (pos),
23963 Qpointer, w->buffer);
23964 }
23965 }
23966 else if (BUFFERP (object)
23967 && charpos >= BEGV
23968 && charpos < ZV)
23969 pointer = Fget_text_property (make_number (charpos),
23970 Qpointer, object);
23971 }
23972 }
23973
23974 BEGV = obegv;
23975 ZV = ozv;
23976 current_buffer = obuf;
23977 }
23978
23979 set_cursor:
23980
23981 define_frame_cursor1 (f, cursor, pointer);
23982 }
23983
23984
23985 /* EXPORT for RIF:
23986 Clear any mouse-face on window W. This function is part of the
23987 redisplay interface, and is called from try_window_id and similar
23988 functions to ensure the mouse-highlight is off. */
23989
23990 void
23991 x_clear_window_mouse_face (w)
23992 struct window *w;
23993 {
23994 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23995 Lisp_Object window;
23996
23997 BLOCK_INPUT;
23998 XSETWINDOW (window, w);
23999 if (EQ (window, dpyinfo->mouse_face_window))
24000 clear_mouse_face (dpyinfo);
24001 UNBLOCK_INPUT;
24002 }
24003
24004
24005 /* EXPORT:
24006 Just discard the mouse face information for frame F, if any.
24007 This is used when the size of F is changed. */
24008
24009 void
24010 cancel_mouse_face (f)
24011 struct frame *f;
24012 {
24013 Lisp_Object window;
24014 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24015
24016 window = dpyinfo->mouse_face_window;
24017 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
24018 {
24019 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
24020 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
24021 dpyinfo->mouse_face_window = Qnil;
24022 }
24023 }
24024
24025
24026 #endif /* HAVE_WINDOW_SYSTEM */
24027
24028 \f
24029 /***********************************************************************
24030 Exposure Events
24031 ***********************************************************************/
24032
24033 #ifdef HAVE_WINDOW_SYSTEM
24034
24035 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
24036 which intersects rectangle R. R is in window-relative coordinates. */
24037
24038 static void
24039 expose_area (w, row, r, area)
24040 struct window *w;
24041 struct glyph_row *row;
24042 XRectangle *r;
24043 enum glyph_row_area area;
24044 {
24045 struct glyph *first = row->glyphs[area];
24046 struct glyph *end = row->glyphs[area] + row->used[area];
24047 struct glyph *last;
24048 int first_x, start_x, x;
24049
24050 if (area == TEXT_AREA && row->fill_line_p)
24051 /* If row extends face to end of line write the whole line. */
24052 draw_glyphs (w, 0, row, area,
24053 0, row->used[area],
24054 DRAW_NORMAL_TEXT, 0);
24055 else
24056 {
24057 /* Set START_X to the window-relative start position for drawing glyphs of
24058 AREA. The first glyph of the text area can be partially visible.
24059 The first glyphs of other areas cannot. */
24060 start_x = window_box_left_offset (w, area);
24061 x = start_x;
24062 if (area == TEXT_AREA)
24063 x += row->x;
24064
24065 /* Find the first glyph that must be redrawn. */
24066 while (first < end
24067 && x + first->pixel_width < r->x)
24068 {
24069 x += first->pixel_width;
24070 ++first;
24071 }
24072
24073 /* Find the last one. */
24074 last = first;
24075 first_x = x;
24076 while (last < end
24077 && x < r->x + r->width)
24078 {
24079 x += last->pixel_width;
24080 ++last;
24081 }
24082
24083 /* Repaint. */
24084 if (last > first)
24085 draw_glyphs (w, first_x - start_x, row, area,
24086 first - row->glyphs[area], last - row->glyphs[area],
24087 DRAW_NORMAL_TEXT, 0);
24088 }
24089 }
24090
24091
24092 /* Redraw the parts of the glyph row ROW on window W intersecting
24093 rectangle R. R is in window-relative coordinates. Value is
24094 non-zero if mouse-face was overwritten. */
24095
24096 static int
24097 expose_line (w, row, r)
24098 struct window *w;
24099 struct glyph_row *row;
24100 XRectangle *r;
24101 {
24102 xassert (row->enabled_p);
24103
24104 if (row->mode_line_p || w->pseudo_window_p)
24105 draw_glyphs (w, 0, row, TEXT_AREA,
24106 0, row->used[TEXT_AREA],
24107 DRAW_NORMAL_TEXT, 0);
24108 else
24109 {
24110 if (row->used[LEFT_MARGIN_AREA])
24111 expose_area (w, row, r, LEFT_MARGIN_AREA);
24112 if (row->used[TEXT_AREA])
24113 expose_area (w, row, r, TEXT_AREA);
24114 if (row->used[RIGHT_MARGIN_AREA])
24115 expose_area (w, row, r, RIGHT_MARGIN_AREA);
24116 draw_row_fringe_bitmaps (w, row);
24117 }
24118
24119 return row->mouse_face_p;
24120 }
24121
24122
24123 /* Redraw those parts of glyphs rows during expose event handling that
24124 overlap other rows. Redrawing of an exposed line writes over parts
24125 of lines overlapping that exposed line; this function fixes that.
24126
24127 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
24128 row in W's current matrix that is exposed and overlaps other rows.
24129 LAST_OVERLAPPING_ROW is the last such row. */
24130
24131 static void
24132 expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
24133 struct window *w;
24134 struct glyph_row *first_overlapping_row;
24135 struct glyph_row *last_overlapping_row;
24136 XRectangle *r;
24137 {
24138 struct glyph_row *row;
24139
24140 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
24141 if (row->overlapping_p)
24142 {
24143 xassert (row->enabled_p && !row->mode_line_p);
24144
24145 row->clip = r;
24146 if (row->used[LEFT_MARGIN_AREA])
24147 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
24148
24149 if (row->used[TEXT_AREA])
24150 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
24151
24152 if (row->used[RIGHT_MARGIN_AREA])
24153 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
24154 row->clip = NULL;
24155 }
24156 }
24157
24158
24159 /* Return non-zero if W's cursor intersects rectangle R. */
24160
24161 static int
24162 phys_cursor_in_rect_p (w, r)
24163 struct window *w;
24164 XRectangle *r;
24165 {
24166 XRectangle cr, result;
24167 struct glyph *cursor_glyph;
24168 struct glyph_row *row;
24169
24170 if (w->phys_cursor.vpos >= 0
24171 && w->phys_cursor.vpos < w->current_matrix->nrows
24172 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
24173 row->enabled_p)
24174 && row->cursor_in_fringe_p)
24175 {
24176 /* Cursor is in the fringe. */
24177 cr.x = window_box_right_offset (w,
24178 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
24179 ? RIGHT_MARGIN_AREA
24180 : TEXT_AREA));
24181 cr.y = row->y;
24182 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
24183 cr.height = row->height;
24184 return x_intersect_rectangles (&cr, r, &result);
24185 }
24186
24187 cursor_glyph = get_phys_cursor_glyph (w);
24188 if (cursor_glyph)
24189 {
24190 /* r is relative to W's box, but w->phys_cursor.x is relative
24191 to left edge of W's TEXT area. Adjust it. */
24192 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
24193 cr.y = w->phys_cursor.y;
24194 cr.width = cursor_glyph->pixel_width;
24195 cr.height = w->phys_cursor_height;
24196 /* ++KFS: W32 version used W32-specific IntersectRect here, but
24197 I assume the effect is the same -- and this is portable. */
24198 return x_intersect_rectangles (&cr, r, &result);
24199 }
24200 /* If we don't understand the format, pretend we're not in the hot-spot. */
24201 return 0;
24202 }
24203
24204
24205 /* EXPORT:
24206 Draw a vertical window border to the right of window W if W doesn't
24207 have vertical scroll bars. */
24208
24209 void
24210 x_draw_vertical_border (w)
24211 struct window *w;
24212 {
24213 struct frame *f = XFRAME (WINDOW_FRAME (w));
24214
24215 /* We could do better, if we knew what type of scroll-bar the adjacent
24216 windows (on either side) have... But we don't :-(
24217 However, I think this works ok. ++KFS 2003-04-25 */
24218
24219 /* Redraw borders between horizontally adjacent windows. Don't
24220 do it for frames with vertical scroll bars because either the
24221 right scroll bar of a window, or the left scroll bar of its
24222 neighbor will suffice as a border. */
24223 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
24224 return;
24225
24226 if (!WINDOW_RIGHTMOST_P (w)
24227 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
24228 {
24229 int x0, x1, y0, y1;
24230
24231 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
24232 y1 -= 1;
24233
24234 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
24235 x1 -= 1;
24236
24237 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
24238 }
24239 else if (!WINDOW_LEFTMOST_P (w)
24240 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
24241 {
24242 int x0, x1, y0, y1;
24243
24244 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
24245 y1 -= 1;
24246
24247 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
24248 x0 -= 1;
24249
24250 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
24251 }
24252 }
24253
24254
24255 /* Redraw the part of window W intersection rectangle FR. Pixel
24256 coordinates in FR are frame-relative. Call this function with
24257 input blocked. Value is non-zero if the exposure overwrites
24258 mouse-face. */
24259
24260 static int
24261 expose_window (w, fr)
24262 struct window *w;
24263 XRectangle *fr;
24264 {
24265 struct frame *f = XFRAME (w->frame);
24266 XRectangle wr, r;
24267 int mouse_face_overwritten_p = 0;
24268
24269 /* If window is not yet fully initialized, do nothing. This can
24270 happen when toolkit scroll bars are used and a window is split.
24271 Reconfiguring the scroll bar will generate an expose for a newly
24272 created window. */
24273 if (w->current_matrix == NULL)
24274 return 0;
24275
24276 /* When we're currently updating the window, display and current
24277 matrix usually don't agree. Arrange for a thorough display
24278 later. */
24279 if (w == updated_window)
24280 {
24281 SET_FRAME_GARBAGED (f);
24282 return 0;
24283 }
24284
24285 /* Frame-relative pixel rectangle of W. */
24286 wr.x = WINDOW_LEFT_EDGE_X (w);
24287 wr.y = WINDOW_TOP_EDGE_Y (w);
24288 wr.width = WINDOW_TOTAL_WIDTH (w);
24289 wr.height = WINDOW_TOTAL_HEIGHT (w);
24290
24291 if (x_intersect_rectangles (fr, &wr, &r))
24292 {
24293 int yb = window_text_bottom_y (w);
24294 struct glyph_row *row;
24295 int cursor_cleared_p;
24296 struct glyph_row *first_overlapping_row, *last_overlapping_row;
24297
24298 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
24299 r.x, r.y, r.width, r.height));
24300
24301 /* Convert to window coordinates. */
24302 r.x -= WINDOW_LEFT_EDGE_X (w);
24303 r.y -= WINDOW_TOP_EDGE_Y (w);
24304
24305 /* Turn off the cursor. */
24306 if (!w->pseudo_window_p
24307 && phys_cursor_in_rect_p (w, &r))
24308 {
24309 x_clear_cursor (w);
24310 cursor_cleared_p = 1;
24311 }
24312 else
24313 cursor_cleared_p = 0;
24314
24315 /* Update lines intersecting rectangle R. */
24316 first_overlapping_row = last_overlapping_row = NULL;
24317 for (row = w->current_matrix->rows;
24318 row->enabled_p;
24319 ++row)
24320 {
24321 int y0 = row->y;
24322 int y1 = MATRIX_ROW_BOTTOM_Y (row);
24323
24324 if ((y0 >= r.y && y0 < r.y + r.height)
24325 || (y1 > r.y && y1 < r.y + r.height)
24326 || (r.y >= y0 && r.y < y1)
24327 || (r.y + r.height > y0 && r.y + r.height < y1))
24328 {
24329 /* A header line may be overlapping, but there is no need
24330 to fix overlapping areas for them. KFS 2005-02-12 */
24331 if (row->overlapping_p && !row->mode_line_p)
24332 {
24333 if (first_overlapping_row == NULL)
24334 first_overlapping_row = row;
24335 last_overlapping_row = row;
24336 }
24337
24338 row->clip = fr;
24339 if (expose_line (w, row, &r))
24340 mouse_face_overwritten_p = 1;
24341 row->clip = NULL;
24342 }
24343 else if (row->overlapping_p)
24344 {
24345 /* We must redraw a row overlapping the exposed area. */
24346 if (y0 < r.y
24347 ? y0 + row->phys_height > r.y
24348 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
24349 {
24350 if (first_overlapping_row == NULL)
24351 first_overlapping_row = row;
24352 last_overlapping_row = row;
24353 }
24354 }
24355
24356 if (y1 >= yb)
24357 break;
24358 }
24359
24360 /* Display the mode line if there is one. */
24361 if (WINDOW_WANTS_MODELINE_P (w)
24362 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
24363 row->enabled_p)
24364 && row->y < r.y + r.height)
24365 {
24366 if (expose_line (w, row, &r))
24367 mouse_face_overwritten_p = 1;
24368 }
24369
24370 if (!w->pseudo_window_p)
24371 {
24372 /* Fix the display of overlapping rows. */
24373 if (first_overlapping_row)
24374 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
24375 fr);
24376
24377 /* Draw border between windows. */
24378 x_draw_vertical_border (w);
24379
24380 /* Turn the cursor on again. */
24381 if (cursor_cleared_p)
24382 update_window_cursor (w, 1);
24383 }
24384 }
24385
24386 return mouse_face_overwritten_p;
24387 }
24388
24389
24390
24391 /* Redraw (parts) of all windows in the window tree rooted at W that
24392 intersect R. R contains frame pixel coordinates. Value is
24393 non-zero if the exposure overwrites mouse-face. */
24394
24395 static int
24396 expose_window_tree (w, r)
24397 struct window *w;
24398 XRectangle *r;
24399 {
24400 struct frame *f = XFRAME (w->frame);
24401 int mouse_face_overwritten_p = 0;
24402
24403 while (w && !FRAME_GARBAGED_P (f))
24404 {
24405 if (!NILP (w->hchild))
24406 mouse_face_overwritten_p
24407 |= expose_window_tree (XWINDOW (w->hchild), r);
24408 else if (!NILP (w->vchild))
24409 mouse_face_overwritten_p
24410 |= expose_window_tree (XWINDOW (w->vchild), r);
24411 else
24412 mouse_face_overwritten_p |= expose_window (w, r);
24413
24414 w = NILP (w->next) ? NULL : XWINDOW (w->next);
24415 }
24416
24417 return mouse_face_overwritten_p;
24418 }
24419
24420
24421 /* EXPORT:
24422 Redisplay an exposed area of frame F. X and Y are the upper-left
24423 corner of the exposed rectangle. W and H are width and height of
24424 the exposed area. All are pixel values. W or H zero means redraw
24425 the entire frame. */
24426
24427 void
24428 expose_frame (f, x, y, w, h)
24429 struct frame *f;
24430 int x, y, w, h;
24431 {
24432 XRectangle r;
24433 int mouse_face_overwritten_p = 0;
24434
24435 TRACE ((stderr, "expose_frame "));
24436
24437 /* No need to redraw if frame will be redrawn soon. */
24438 if (FRAME_GARBAGED_P (f))
24439 {
24440 TRACE ((stderr, " garbaged\n"));
24441 return;
24442 }
24443
24444 /* If basic faces haven't been realized yet, there is no point in
24445 trying to redraw anything. This can happen when we get an expose
24446 event while Emacs is starting, e.g. by moving another window. */
24447 if (FRAME_FACE_CACHE (f) == NULL
24448 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
24449 {
24450 TRACE ((stderr, " no faces\n"));
24451 return;
24452 }
24453
24454 if (w == 0 || h == 0)
24455 {
24456 r.x = r.y = 0;
24457 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
24458 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
24459 }
24460 else
24461 {
24462 r.x = x;
24463 r.y = y;
24464 r.width = w;
24465 r.height = h;
24466 }
24467
24468 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
24469 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
24470
24471 if (WINDOWP (f->tool_bar_window))
24472 mouse_face_overwritten_p
24473 |= expose_window (XWINDOW (f->tool_bar_window), &r);
24474
24475 #ifdef HAVE_X_WINDOWS
24476 #ifndef MSDOS
24477 #ifndef USE_X_TOOLKIT
24478 if (WINDOWP (f->menu_bar_window))
24479 mouse_face_overwritten_p
24480 |= expose_window (XWINDOW (f->menu_bar_window), &r);
24481 #endif /* not USE_X_TOOLKIT */
24482 #endif
24483 #endif
24484
24485 /* Some window managers support a focus-follows-mouse style with
24486 delayed raising of frames. Imagine a partially obscured frame,
24487 and moving the mouse into partially obscured mouse-face on that
24488 frame. The visible part of the mouse-face will be highlighted,
24489 then the WM raises the obscured frame. With at least one WM, KDE
24490 2.1, Emacs is not getting any event for the raising of the frame
24491 (even tried with SubstructureRedirectMask), only Expose events.
24492 These expose events will draw text normally, i.e. not
24493 highlighted. Which means we must redo the highlight here.
24494 Subsume it under ``we love X''. --gerd 2001-08-15 */
24495 /* Included in Windows version because Windows most likely does not
24496 do the right thing if any third party tool offers
24497 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
24498 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
24499 {
24500 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24501 if (f == dpyinfo->mouse_face_mouse_frame)
24502 {
24503 int x = dpyinfo->mouse_face_mouse_x;
24504 int y = dpyinfo->mouse_face_mouse_y;
24505 clear_mouse_face (dpyinfo);
24506 note_mouse_highlight (f, x, y);
24507 }
24508 }
24509 }
24510
24511
24512 /* EXPORT:
24513 Determine the intersection of two rectangles R1 and R2. Return
24514 the intersection in *RESULT. Value is non-zero if RESULT is not
24515 empty. */
24516
24517 int
24518 x_intersect_rectangles (r1, r2, result)
24519 XRectangle *r1, *r2, *result;
24520 {
24521 XRectangle *left, *right;
24522 XRectangle *upper, *lower;
24523 int intersection_p = 0;
24524
24525 /* Rearrange so that R1 is the left-most rectangle. */
24526 if (r1->x < r2->x)
24527 left = r1, right = r2;
24528 else
24529 left = r2, right = r1;
24530
24531 /* X0 of the intersection is right.x0, if this is inside R1,
24532 otherwise there is no intersection. */
24533 if (right->x <= left->x + left->width)
24534 {
24535 result->x = right->x;
24536
24537 /* The right end of the intersection is the minimum of the
24538 the right ends of left and right. */
24539 result->width = (min (left->x + left->width, right->x + right->width)
24540 - result->x);
24541
24542 /* Same game for Y. */
24543 if (r1->y < r2->y)
24544 upper = r1, lower = r2;
24545 else
24546 upper = r2, lower = r1;
24547
24548 /* The upper end of the intersection is lower.y0, if this is inside
24549 of upper. Otherwise, there is no intersection. */
24550 if (lower->y <= upper->y + upper->height)
24551 {
24552 result->y = lower->y;
24553
24554 /* The lower end of the intersection is the minimum of the lower
24555 ends of upper and lower. */
24556 result->height = (min (lower->y + lower->height,
24557 upper->y + upper->height)
24558 - result->y);
24559 intersection_p = 1;
24560 }
24561 }
24562
24563 return intersection_p;
24564 }
24565
24566 #endif /* HAVE_WINDOW_SYSTEM */
24567
24568 \f
24569 /***********************************************************************
24570 Initialization
24571 ***********************************************************************/
24572
24573 void
24574 syms_of_xdisp ()
24575 {
24576 Vwith_echo_area_save_vector = Qnil;
24577 staticpro (&Vwith_echo_area_save_vector);
24578
24579 Vmessage_stack = Qnil;
24580 staticpro (&Vmessage_stack);
24581
24582 Qinhibit_redisplay = intern ("inhibit-redisplay");
24583 staticpro (&Qinhibit_redisplay);
24584
24585 message_dolog_marker1 = Fmake_marker ();
24586 staticpro (&message_dolog_marker1);
24587 message_dolog_marker2 = Fmake_marker ();
24588 staticpro (&message_dolog_marker2);
24589 message_dolog_marker3 = Fmake_marker ();
24590 staticpro (&message_dolog_marker3);
24591
24592 #if GLYPH_DEBUG
24593 defsubr (&Sdump_frame_glyph_matrix);
24594 defsubr (&Sdump_glyph_matrix);
24595 defsubr (&Sdump_glyph_row);
24596 defsubr (&Sdump_tool_bar_row);
24597 defsubr (&Strace_redisplay);
24598 defsubr (&Strace_to_stderr);
24599 #endif
24600 #ifdef HAVE_WINDOW_SYSTEM
24601 defsubr (&Stool_bar_lines_needed);
24602 defsubr (&Slookup_image_map);
24603 #endif
24604 defsubr (&Sformat_mode_line);
24605 defsubr (&Sinvisible_p);
24606
24607 staticpro (&Qmenu_bar_update_hook);
24608 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
24609
24610 staticpro (&Qoverriding_terminal_local_map);
24611 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
24612
24613 staticpro (&Qoverriding_local_map);
24614 Qoverriding_local_map = intern ("overriding-local-map");
24615
24616 staticpro (&Qwindow_scroll_functions);
24617 Qwindow_scroll_functions = intern ("window-scroll-functions");
24618
24619 staticpro (&Qwindow_text_change_functions);
24620 Qwindow_text_change_functions = intern ("window-text-change-functions");
24621
24622 staticpro (&Qredisplay_end_trigger_functions);
24623 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
24624
24625 staticpro (&Qinhibit_point_motion_hooks);
24626 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24627
24628 Qeval = intern ("eval");
24629 staticpro (&Qeval);
24630
24631 QCdata = intern (":data");
24632 staticpro (&QCdata);
24633 Qdisplay = intern ("display");
24634 staticpro (&Qdisplay);
24635 Qspace_width = intern ("space-width");
24636 staticpro (&Qspace_width);
24637 Qraise = intern ("raise");
24638 staticpro (&Qraise);
24639 Qslice = intern ("slice");
24640 staticpro (&Qslice);
24641 Qspace = intern ("space");
24642 staticpro (&Qspace);
24643 Qmargin = intern ("margin");
24644 staticpro (&Qmargin);
24645 Qpointer = intern ("pointer");
24646 staticpro (&Qpointer);
24647 Qleft_margin = intern ("left-margin");
24648 staticpro (&Qleft_margin);
24649 Qright_margin = intern ("right-margin");
24650 staticpro (&Qright_margin);
24651 Qcenter = intern ("center");
24652 staticpro (&Qcenter);
24653 Qline_height = intern ("line-height");
24654 staticpro (&Qline_height);
24655 QCalign_to = intern (":align-to");
24656 staticpro (&QCalign_to);
24657 QCrelative_width = intern (":relative-width");
24658 staticpro (&QCrelative_width);
24659 QCrelative_height = intern (":relative-height");
24660 staticpro (&QCrelative_height);
24661 QCeval = intern (":eval");
24662 staticpro (&QCeval);
24663 QCpropertize = intern (":propertize");
24664 staticpro (&QCpropertize);
24665 QCfile = intern (":file");
24666 staticpro (&QCfile);
24667 Qfontified = intern ("fontified");
24668 staticpro (&Qfontified);
24669 Qfontification_functions = intern ("fontification-functions");
24670 staticpro (&Qfontification_functions);
24671 Qtrailing_whitespace = intern ("trailing-whitespace");
24672 staticpro (&Qtrailing_whitespace);
24673 Qescape_glyph = intern ("escape-glyph");
24674 staticpro (&Qescape_glyph);
24675 Qnobreak_space = intern ("nobreak-space");
24676 staticpro (&Qnobreak_space);
24677 Qimage = intern ("image");
24678 staticpro (&Qimage);
24679 QCmap = intern (":map");
24680 staticpro (&QCmap);
24681 QCpointer = intern (":pointer");
24682 staticpro (&QCpointer);
24683 Qrect = intern ("rect");
24684 staticpro (&Qrect);
24685 Qcircle = intern ("circle");
24686 staticpro (&Qcircle);
24687 Qpoly = intern ("poly");
24688 staticpro (&Qpoly);
24689 Qmessage_truncate_lines = intern ("message-truncate-lines");
24690 staticpro (&Qmessage_truncate_lines);
24691 Qgrow_only = intern ("grow-only");
24692 staticpro (&Qgrow_only);
24693 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
24694 staticpro (&Qinhibit_menubar_update);
24695 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
24696 staticpro (&Qinhibit_eval_during_redisplay);
24697 Qposition = intern ("position");
24698 staticpro (&Qposition);
24699 Qbuffer_position = intern ("buffer-position");
24700 staticpro (&Qbuffer_position);
24701 Qobject = intern ("object");
24702 staticpro (&Qobject);
24703 Qbar = intern ("bar");
24704 staticpro (&Qbar);
24705 Qhbar = intern ("hbar");
24706 staticpro (&Qhbar);
24707 Qbox = intern ("box");
24708 staticpro (&Qbox);
24709 Qhollow = intern ("hollow");
24710 staticpro (&Qhollow);
24711 Qhand = intern ("hand");
24712 staticpro (&Qhand);
24713 Qarrow = intern ("arrow");
24714 staticpro (&Qarrow);
24715 Qtext = intern ("text");
24716 staticpro (&Qtext);
24717 Qrisky_local_variable = intern ("risky-local-variable");
24718 staticpro (&Qrisky_local_variable);
24719 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
24720 staticpro (&Qinhibit_free_realized_faces);
24721
24722 list_of_error = Fcons (Fcons (intern ("error"),
24723 Fcons (intern ("void-variable"), Qnil)),
24724 Qnil);
24725 staticpro (&list_of_error);
24726
24727 Qlast_arrow_position = intern ("last-arrow-position");
24728 staticpro (&Qlast_arrow_position);
24729 Qlast_arrow_string = intern ("last-arrow-string");
24730 staticpro (&Qlast_arrow_string);
24731
24732 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24733 staticpro (&Qoverlay_arrow_string);
24734 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24735 staticpro (&Qoverlay_arrow_bitmap);
24736
24737 echo_buffer[0] = echo_buffer[1] = Qnil;
24738 staticpro (&echo_buffer[0]);
24739 staticpro (&echo_buffer[1]);
24740
24741 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24742 staticpro (&echo_area_buffer[0]);
24743 staticpro (&echo_area_buffer[1]);
24744
24745 Vmessages_buffer_name = build_string ("*Messages*");
24746 staticpro (&Vmessages_buffer_name);
24747
24748 mode_line_proptrans_alist = Qnil;
24749 staticpro (&mode_line_proptrans_alist);
24750 mode_line_string_list = Qnil;
24751 staticpro (&mode_line_string_list);
24752 mode_line_string_face = Qnil;
24753 staticpro (&mode_line_string_face);
24754 mode_line_string_face_prop = Qnil;
24755 staticpro (&mode_line_string_face_prop);
24756 Vmode_line_unwind_vector = Qnil;
24757 staticpro (&Vmode_line_unwind_vector);
24758
24759 help_echo_string = Qnil;
24760 staticpro (&help_echo_string);
24761 help_echo_object = Qnil;
24762 staticpro (&help_echo_object);
24763 help_echo_window = Qnil;
24764 staticpro (&help_echo_window);
24765 previous_help_echo_string = Qnil;
24766 staticpro (&previous_help_echo_string);
24767 help_echo_pos = -1;
24768
24769 #ifdef HAVE_WINDOW_SYSTEM
24770 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24771 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24772 For example, if a block cursor is over a tab, it will be drawn as
24773 wide as that tab on the display. */);
24774 x_stretch_cursor_p = 0;
24775 #endif
24776
24777 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24778 doc: /* *Non-nil means highlight trailing whitespace.
24779 The face used for trailing whitespace is `trailing-whitespace'. */);
24780 Vshow_trailing_whitespace = Qnil;
24781
24782 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24783 doc: /* *Control highlighting of nobreak space and soft hyphen.
24784 A value of t means highlight the character itself (for nobreak space,
24785 use face `nobreak-space').
24786 A value of nil means no highlighting.
24787 Other values mean display the escape glyph followed by an ordinary
24788 space or ordinary hyphen. */);
24789 Vnobreak_char_display = Qt;
24790
24791 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24792 doc: /* *The pointer shape to show in void text areas.
24793 A value of nil means to show the text pointer. Other options are `arrow',
24794 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24795 Vvoid_text_area_pointer = Qarrow;
24796
24797 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24798 doc: /* Non-nil means don't actually do any redisplay.
24799 This is used for internal purposes. */);
24800 Vinhibit_redisplay = Qnil;
24801
24802 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24803 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24804 Vglobal_mode_string = Qnil;
24805
24806 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24807 doc: /* Marker for where to display an arrow on top of the buffer text.
24808 This must be the beginning of a line in order to work.
24809 See also `overlay-arrow-string'. */);
24810 Voverlay_arrow_position = Qnil;
24811
24812 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24813 doc: /* String to display as an arrow in non-window frames.
24814 See also `overlay-arrow-position'. */);
24815 Voverlay_arrow_string = build_string ("=>");
24816
24817 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24818 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24819 The symbols on this list are examined during redisplay to determine
24820 where to display overlay arrows. */);
24821 Voverlay_arrow_variable_list
24822 = Fcons (intern ("overlay-arrow-position"), Qnil);
24823
24824 DEFVAR_INT ("scroll-step", &scroll_step,
24825 doc: /* *The number of lines to try scrolling a window by when point moves out.
24826 If that fails to bring point back on frame, point is centered instead.
24827 If this is zero, point is always centered after it moves off frame.
24828 If you want scrolling to always be a line at a time, you should set
24829 `scroll-conservatively' to a large value rather than set this to 1. */);
24830
24831 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24832 doc: /* *Scroll up to this many lines, to bring point back on screen.
24833 If point moves off-screen, redisplay will scroll by up to
24834 `scroll-conservatively' lines in order to bring point just barely
24835 onto the screen again. If that cannot be done, then redisplay
24836 recenters point as usual.
24837
24838 A value of zero means always recenter point if it moves off screen. */);
24839 scroll_conservatively = 0;
24840
24841 DEFVAR_INT ("scroll-margin", &scroll_margin,
24842 doc: /* *Number of lines of margin at the top and bottom of a window.
24843 Recenter the window whenever point gets within this many lines
24844 of the top or bottom of the window. */);
24845 scroll_margin = 0;
24846
24847 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24848 doc: /* Pixels per inch value for non-window system displays.
24849 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24850 Vdisplay_pixels_per_inch = make_float (72.0);
24851
24852 #if GLYPH_DEBUG
24853 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24854 #endif
24855
24856 DEFVAR_LISP ("truncate-partial-width-windows",
24857 &Vtruncate_partial_width_windows,
24858 doc: /* Non-nil means truncate lines in windows with less than the frame width.
24859 For an integer value, truncate lines in each window with less than the
24860 full frame width, provided the window width is less than that integer;
24861 otherwise, respect the value of `truncate-lines'.
24862
24863 For any other non-nil value, truncate lines in all windows with
24864 less than the full frame width.
24865
24866 A value of nil means to respect the value of `truncate-lines'.
24867
24868 If `word-wrap' is enabled, you might want to reduce this. */);
24869 Vtruncate_partial_width_windows = make_number (50);
24870
24871 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24872 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24873 Any other value means to use the appropriate face, `mode-line',
24874 `header-line', or `menu' respectively. */);
24875 mode_line_inverse_video = 1;
24876
24877 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24878 doc: /* *Maximum buffer size for which line number should be displayed.
24879 If the buffer is bigger than this, the line number does not appear
24880 in the mode line. A value of nil means no limit. */);
24881 Vline_number_display_limit = Qnil;
24882
24883 DEFVAR_INT ("line-number-display-limit-width",
24884 &line_number_display_limit_width,
24885 doc: /* *Maximum line width (in characters) for line number display.
24886 If the average length of the lines near point is bigger than this, then the
24887 line number may be omitted from the mode line. */);
24888 line_number_display_limit_width = 200;
24889
24890 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24891 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24892 highlight_nonselected_windows = 0;
24893
24894 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24895 doc: /* Non-nil if more than one frame is visible on this display.
24896 Minibuffer-only frames don't count, but iconified frames do.
24897 This variable is not guaranteed to be accurate except while processing
24898 `frame-title-format' and `icon-title-format'. */);
24899
24900 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24901 doc: /* Template for displaying the title bar of visible frames.
24902 \(Assuming the window manager supports this feature.)
24903
24904 This variable has the same structure as `mode-line-format', except that
24905 the %c and %l constructs are ignored. It is used only on frames for
24906 which no explicit name has been set \(see `modify-frame-parameters'). */);
24907
24908 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24909 doc: /* Template for displaying the title bar of an iconified frame.
24910 \(Assuming the window manager supports this feature.)
24911 This variable has the same structure as `mode-line-format' (which see),
24912 and is used only on frames for which no explicit name has been set
24913 \(see `modify-frame-parameters'). */);
24914 Vicon_title_format
24915 = Vframe_title_format
24916 = Fcons (intern ("multiple-frames"),
24917 Fcons (build_string ("%b"),
24918 Fcons (Fcons (empty_unibyte_string,
24919 Fcons (intern ("invocation-name"),
24920 Fcons (build_string ("@"),
24921 Fcons (intern ("system-name"),
24922 Qnil)))),
24923 Qnil)));
24924
24925 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24926 doc: /* Maximum number of lines to keep in the message log buffer.
24927 If nil, disable message logging. If t, log messages but don't truncate
24928 the buffer when it becomes large. */);
24929 Vmessage_log_max = make_number (100);
24930
24931 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24932 doc: /* Functions called before redisplay, if window sizes have changed.
24933 The value should be a list of functions that take one argument.
24934 Just before redisplay, for each frame, if any of its windows have changed
24935 size since the last redisplay, or have been split or deleted,
24936 all the functions in the list are called, with the frame as argument. */);
24937 Vwindow_size_change_functions = Qnil;
24938
24939 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24940 doc: /* List of functions to call before redisplaying a window with scrolling.
24941 Each function is called with two arguments, the window and its new
24942 display-start position. Note that these functions are also called by
24943 `set-window-buffer'. Also note that the value of `window-end' is not
24944 valid when these functions are called. */);
24945 Vwindow_scroll_functions = Qnil;
24946
24947 DEFVAR_LISP ("window-text-change-functions",
24948 &Vwindow_text_change_functions,
24949 doc: /* Functions to call in redisplay when text in the window might change. */);
24950 Vwindow_text_change_functions = Qnil;
24951
24952 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24953 doc: /* Functions called when redisplay of a window reaches the end trigger.
24954 Each function is called with two arguments, the window and the end trigger value.
24955 See `set-window-redisplay-end-trigger'. */);
24956 Vredisplay_end_trigger_functions = Qnil;
24957
24958 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24959 doc: /* *Non-nil means autoselect window with mouse pointer.
24960 If nil, do not autoselect windows.
24961 A positive number means delay autoselection by that many seconds: a
24962 window is autoselected only after the mouse has remained in that
24963 window for the duration of the delay.
24964 A negative number has a similar effect, but causes windows to be
24965 autoselected only after the mouse has stopped moving. \(Because of
24966 the way Emacs compares mouse events, you will occasionally wait twice
24967 that time before the window gets selected.\)
24968 Any other value means to autoselect window instantaneously when the
24969 mouse pointer enters it.
24970
24971 Autoselection selects the minibuffer only if it is active, and never
24972 unselects the minibuffer if it is active.
24973
24974 When customizing this variable make sure that the actual value of
24975 `focus-follows-mouse' matches the behavior of your window manager. */);
24976 Vmouse_autoselect_window = Qnil;
24977
24978 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24979 doc: /* *Non-nil means automatically resize tool-bars.
24980 This dynamically changes the tool-bar's height to the minimum height
24981 that is needed to make all tool-bar items visible.
24982 If value is `grow-only', the tool-bar's height is only increased
24983 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24984 Vauto_resize_tool_bars = Qt;
24985
24986 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24987 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24988 auto_raise_tool_bar_buttons_p = 1;
24989
24990 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24991 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24992 make_cursor_line_fully_visible_p = 1;
24993
24994 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24995 doc: /* *Border below tool-bar in pixels.
24996 If an integer, use it as the height of the border.
24997 If it is one of `internal-border-width' or `border-width', use the
24998 value of the corresponding frame parameter.
24999 Otherwise, no border is added below the tool-bar. */);
25000 Vtool_bar_border = Qinternal_border_width;
25001
25002 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
25003 doc: /* *Margin around tool-bar buttons in pixels.
25004 If an integer, use that for both horizontal and vertical margins.
25005 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
25006 HORZ specifying the horizontal margin, and VERT specifying the
25007 vertical margin. */);
25008 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
25009
25010 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
25011 doc: /* *Relief thickness of tool-bar buttons. */);
25012 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
25013
25014 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
25015 doc: /* List of functions to call to fontify regions of text.
25016 Each function is called with one argument POS. Functions must
25017 fontify a region starting at POS in the current buffer, and give
25018 fontified regions the property `fontified'. */);
25019 Vfontification_functions = Qnil;
25020 Fmake_variable_buffer_local (Qfontification_functions);
25021
25022 DEFVAR_BOOL ("unibyte-display-via-language-environment",
25023 &unibyte_display_via_language_environment,
25024 doc: /* *Non-nil means display unibyte text according to language environment.
25025 Specifically this means that unibyte non-ASCII characters
25026 are displayed by converting them to the equivalent multibyte characters
25027 according to the current language environment. As a result, they are
25028 displayed according to the current fontset. */);
25029 unibyte_display_via_language_environment = 0;
25030
25031 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
25032 doc: /* *Maximum height for resizing mini-windows.
25033 If a float, it specifies a fraction of the mini-window frame's height.
25034 If an integer, it specifies a number of lines. */);
25035 Vmax_mini_window_height = make_float (0.25);
25036
25037 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
25038 doc: /* *How to resize mini-windows.
25039 A value of nil means don't automatically resize mini-windows.
25040 A value of t means resize them to fit the text displayed in them.
25041 A value of `grow-only', the default, means let mini-windows grow
25042 only, until their display becomes empty, at which point the windows
25043 go back to their normal size. */);
25044 Vresize_mini_windows = Qgrow_only;
25045
25046 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
25047 doc: /* Alist specifying how to blink the cursor off.
25048 Each element has the form (ON-STATE . OFF-STATE). Whenever the
25049 `cursor-type' frame-parameter or variable equals ON-STATE,
25050 comparing using `equal', Emacs uses OFF-STATE to specify
25051 how to blink it off. ON-STATE and OFF-STATE are values for
25052 the `cursor-type' frame parameter.
25053
25054 If a frame's ON-STATE has no entry in this list,
25055 the frame's other specifications determine how to blink the cursor off. */);
25056 Vblink_cursor_alist = Qnil;
25057
25058 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
25059 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
25060 automatic_hscrolling_p = 1;
25061 Qauto_hscroll_mode = intern ("auto-hscroll-mode");
25062 staticpro (&Qauto_hscroll_mode);
25063
25064 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
25065 doc: /* *How many columns away from the window edge point is allowed to get
25066 before automatic hscrolling will horizontally scroll the window. */);
25067 hscroll_margin = 5;
25068
25069 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
25070 doc: /* *How many columns to scroll the window when point gets too close to the edge.
25071 When point is less than `hscroll-margin' columns from the window
25072 edge, automatic hscrolling will scroll the window by the amount of columns
25073 determined by this variable. If its value is a positive integer, scroll that
25074 many columns. If it's a positive floating-point number, it specifies the
25075 fraction of the window's width to scroll. If it's nil or zero, point will be
25076 centered horizontally after the scroll. Any other value, including negative
25077 numbers, are treated as if the value were zero.
25078
25079 Automatic hscrolling always moves point outside the scroll margin, so if
25080 point was more than scroll step columns inside the margin, the window will
25081 scroll more than the value given by the scroll step.
25082
25083 Note that the lower bound for automatic hscrolling specified by `scroll-left'
25084 and `scroll-right' overrides this variable's effect. */);
25085 Vhscroll_step = make_number (0);
25086
25087 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
25088 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
25089 Bind this around calls to `message' to let it take effect. */);
25090 message_truncate_lines = 0;
25091
25092 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
25093 doc: /* Normal hook run to update the menu bar definitions.
25094 Redisplay runs this hook before it redisplays the menu bar.
25095 This is used to update submenus such as Buffers,
25096 whose contents depend on various data. */);
25097 Vmenu_bar_update_hook = Qnil;
25098
25099 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
25100 doc: /* Frame for which we are updating a menu.
25101 The enable predicate for a menu binding should check this variable. */);
25102 Vmenu_updating_frame = Qnil;
25103
25104 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
25105 doc: /* Non-nil means don't update menu bars. Internal use only. */);
25106 inhibit_menubar_update = 0;
25107
25108 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
25109 doc: /* Prefix prepended to all continuation lines at display time.
25110 The value may be a string, an image, or a stretch-glyph; it is
25111 interpreted in the same way as the value of a `display' text property.
25112
25113 This variable is overridden by any `wrap-prefix' text or overlay
25114 property.
25115
25116 To add a prefix to non-continuation lines, use `line-prefix'. */);
25117 Vwrap_prefix = Qnil;
25118 staticpro (&Qwrap_prefix);
25119 Qwrap_prefix = intern ("wrap-prefix");
25120 Fmake_variable_buffer_local (Qwrap_prefix);
25121
25122 DEFVAR_LISP ("line-prefix", &Vline_prefix,
25123 doc: /* Prefix prepended to all non-continuation lines at display time.
25124 The value may be a string, an image, or a stretch-glyph; it is
25125 interpreted in the same way as the value of a `display' text property.
25126
25127 This variable is overridden by any `line-prefix' text or overlay
25128 property.
25129
25130 To add a prefix to continuation lines, use `wrap-prefix'. */);
25131 Vline_prefix = Qnil;
25132 staticpro (&Qline_prefix);
25133 Qline_prefix = intern ("line-prefix");
25134 Fmake_variable_buffer_local (Qline_prefix);
25135
25136 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
25137 doc: /* Non-nil means don't eval Lisp during redisplay. */);
25138 inhibit_eval_during_redisplay = 0;
25139
25140 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
25141 doc: /* Non-nil means don't free realized faces. Internal use only. */);
25142 inhibit_free_realized_faces = 0;
25143
25144 #if GLYPH_DEBUG
25145 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
25146 doc: /* Inhibit try_window_id display optimization. */);
25147 inhibit_try_window_id = 0;
25148
25149 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
25150 doc: /* Inhibit try_window_reusing display optimization. */);
25151 inhibit_try_window_reusing = 0;
25152
25153 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
25154 doc: /* Inhibit try_cursor_movement display optimization. */);
25155 inhibit_try_cursor_movement = 0;
25156 #endif /* GLYPH_DEBUG */
25157
25158 DEFVAR_INT ("overline-margin", &overline_margin,
25159 doc: /* *Space between overline and text, in pixels.
25160 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
25161 margin to the caracter height. */);
25162 overline_margin = 2;
25163
25164 DEFVAR_INT ("underline-minimum-offset",
25165 &underline_minimum_offset,
25166 doc: /* Minimum distance between baseline and underline.
25167 This can improve legibility of underlined text at small font sizes,
25168 particularly when using variable `x-use-underline-position-properties'
25169 with fonts that specify an UNDERLINE_POSITION relatively close to the
25170 baseline. The default value is 1. */);
25171 underline_minimum_offset = 1;
25172
25173 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
25174 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
25175 display_hourglass_p = 1;
25176
25177 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
25178 doc: /* *Seconds to wait before displaying an hourglass pointer.
25179 Value must be an integer or float. */);
25180 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
25181
25182 hourglass_atimer = NULL;
25183 hourglass_shown_p = 0;
25184 }
25185
25186
25187 /* Initialize this module when Emacs starts. */
25188
25189 void
25190 init_xdisp ()
25191 {
25192 Lisp_Object root_window;
25193 struct window *mini_w;
25194
25195 current_header_line_height = current_mode_line_height = -1;
25196
25197 CHARPOS (this_line_start_pos) = 0;
25198
25199 mini_w = XWINDOW (minibuf_window);
25200 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
25201
25202 if (!noninteractive)
25203 {
25204 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
25205 int i;
25206
25207 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
25208 set_window_height (root_window,
25209 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
25210 0);
25211 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
25212 set_window_height (minibuf_window, 1, 0);
25213
25214 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
25215 mini_w->total_cols = make_number (FRAME_COLS (f));
25216
25217 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
25218 scratch_glyph_row.glyphs[TEXT_AREA + 1]
25219 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
25220
25221 /* The default ellipsis glyphs `...'. */
25222 for (i = 0; i < 3; ++i)
25223 default_invis_vector[i] = make_number ('.');
25224 }
25225
25226 {
25227 /* Allocate the buffer for frame titles.
25228 Also used for `format-mode-line'. */
25229 int size = 100;
25230 mode_line_noprop_buf = (char *) xmalloc (size);
25231 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
25232 mode_line_noprop_ptr = mode_line_noprop_buf;
25233 mode_line_target = MODE_LINE_DISPLAY;
25234 }
25235
25236 help_echo_showing_p = 0;
25237 }
25238
25239 /* Since w32 does not support atimers, it defines its own implementation of
25240 the following three functions in w32fns.c. */
25241 #ifndef WINDOWSNT
25242
25243 /* Platform-independent portion of hourglass implementation. */
25244
25245 /* Return non-zero if houglass timer has been started or hourglass is shown. */
25246 int
25247 hourglass_started ()
25248 {
25249 return hourglass_shown_p || hourglass_atimer != NULL;
25250 }
25251
25252 /* Cancel a currently active hourglass timer, and start a new one. */
25253 void
25254 start_hourglass ()
25255 {
25256 #if defined (HAVE_WINDOW_SYSTEM)
25257 EMACS_TIME delay;
25258 int secs, usecs = 0;
25259
25260 cancel_hourglass ();
25261
25262 if (INTEGERP (Vhourglass_delay)
25263 && XINT (Vhourglass_delay) > 0)
25264 secs = XFASTINT (Vhourglass_delay);
25265 else if (FLOATP (Vhourglass_delay)
25266 && XFLOAT_DATA (Vhourglass_delay) > 0)
25267 {
25268 Lisp_Object tem;
25269 tem = Ftruncate (Vhourglass_delay, Qnil);
25270 secs = XFASTINT (tem);
25271 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
25272 }
25273 else
25274 secs = DEFAULT_HOURGLASS_DELAY;
25275
25276 EMACS_SET_SECS_USECS (delay, secs, usecs);
25277 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
25278 show_hourglass, NULL);
25279 #endif
25280 }
25281
25282
25283 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
25284 shown. */
25285 void
25286 cancel_hourglass ()
25287 {
25288 #if defined (HAVE_WINDOW_SYSTEM)
25289 if (hourglass_atimer)
25290 {
25291 cancel_atimer (hourglass_atimer);
25292 hourglass_atimer = NULL;
25293 }
25294
25295 if (hourglass_shown_p)
25296 hide_hourglass ();
25297 #endif
25298 }
25299 #endif /* ! WINDOWSNT */
25300
25301 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
25302 (do not change this comment) */