Fix menu bar activation with click for Motif/Lesstif.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
6
7 This file is part of GNU Emacs.
8
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code.
36
37 The following diagram shows how redisplay code is invoked. As you
38 can see, Lisp calls redisplay and vice versa. Under window systems
39 like X, some portions of the redisplay code are also called
40 asynchronously during mouse movement or expose events. It is very
41 important that these code parts do NOT use the C library (malloc,
42 free) because many C libraries under Unix are not reentrant. They
43 may also NOT call functions of the Lisp interpreter which could
44 change the interpreter's state. If you don't follow these rules,
45 you will encounter bugs which are very hard to explain.
46
47 +--------------+ redisplay +----------------+
48 | Lisp machine |---------------->| Redisplay code |<--+
49 +--------------+ (xdisp.c) +----------------+ |
50 ^ | |
51 +----------------------------------+ |
52 Don't use this path when called |
53 asynchronously! |
54 |
55 expose_window (asynchronous) |
56 |
57 X expose events -----+
58
59 What does redisplay do? Obviously, it has to figure out somehow what
60 has been changed since the last time the display has been updated,
61 and to make these changes visible. Preferably it would do that in
62 a moderately intelligent way, i.e. fast.
63
64 Changes in buffer text can be deduced from window and buffer
65 structures, and from some global variables like `beg_unchanged' and
66 `end_unchanged'. The contents of the display are additionally
67 recorded in a `glyph matrix', a two-dimensional matrix of glyph
68 structures. Each row in such a matrix corresponds to a line on the
69 display, and each glyph in a row corresponds to a column displaying
70 a character, an image, or what else. This matrix is called the
71 `current glyph matrix' or `current matrix' in redisplay
72 terminology.
73
74 For buffer parts that have been changed since the last update, a
75 second glyph matrix is constructed, the so called `desired glyph
76 matrix' or short `desired matrix'. Current and desired matrix are
77 then compared to find a cheap way to update the display, e.g. by
78 reusing part of the display by scrolling lines.
79
80 You will find a lot of redisplay optimizations when you start
81 looking at the innards of redisplay. The overall goal of all these
82 optimizations is to make redisplay fast because it is done
83 frequently. Some of these optimizations are implemented by the
84 following functions:
85
86 . try_cursor_movement
87
88 This function tries to update the display if the text in the
89 window did not change and did not scroll, only point moved, and
90 it did not move off the displayed portion of the text.
91
92 . try_window_reusing_current_matrix
93
94 This function reuses the current matrix of a window when text
95 has not changed, but the window start changed (e.g., due to
96 scrolling).
97
98 . try_window_id
99
100 This function attempts to redisplay a window by reusing parts of
101 its existing display. It finds and reuses the part that was not
102 changed, and redraws the rest.
103
104 . try_window
105
106 This function performs the full redisplay of a single window
107 assuming that its fonts were not changed and that the cursor
108 will not end up in the scroll margins. (Loading fonts requires
109 re-adjustment of dimensions of glyph matrices, which makes this
110 method impossible to use.)
111
112 These optimizations are tried in sequence (some can be skipped if
113 it is known that they are not applicable). If none of the
114 optimizations were successful, redisplay calls redisplay_windows,
115 which performs a full redisplay of all windows.
116
117 Desired matrices.
118
119 Desired matrices are always built per Emacs window. The function
120 `display_line' is the central function to look at if you are
121 interested. It constructs one row in a desired matrix given an
122 iterator structure containing both a buffer position and a
123 description of the environment in which the text is to be
124 displayed. But this is too early, read on.
125
126 Characters and pixmaps displayed for a range of buffer text depend
127 on various settings of buffers and windows, on overlays and text
128 properties, on display tables, on selective display. The good news
129 is that all this hairy stuff is hidden behind a small set of
130 interface functions taking an iterator structure (struct it)
131 argument.
132
133 Iteration over things to be displayed is then simple. It is
134 started by initializing an iterator with a call to init_iterator.
135 Calls to get_next_display_element fill the iterator structure with
136 relevant information about the next thing to display. Calls to
137 set_iterator_to_next move the iterator to the next thing.
138
139 Besides this, an iterator also contains information about the
140 display environment in which glyphs for display elements are to be
141 produced. It has fields for the width and height of the display,
142 the information whether long lines are truncated or continued, a
143 current X and Y position, and lots of other stuff you can better
144 see in dispextern.h.
145
146 Glyphs in a desired matrix are normally constructed in a loop
147 calling get_next_display_element and then PRODUCE_GLYPHS. The call
148 to PRODUCE_GLYPHS will fill the iterator structure with pixel
149 information about the element being displayed and at the same time
150 produce glyphs for it. If the display element fits on the line
151 being displayed, set_iterator_to_next is called next, otherwise the
152 glyphs produced are discarded. The function display_line is the
153 workhorse of filling glyph rows in the desired matrix with glyphs.
154 In addition to producing glyphs, it also handles line truncation
155 and continuation, word wrap, and cursor positioning (for the
156 latter, see also set_cursor_from_row).
157
158 Frame matrices.
159
160 That just couldn't be all, could it? What about terminal types not
161 supporting operations on sub-windows of the screen? To update the
162 display on such a terminal, window-based glyph matrices are not
163 well suited. To be able to reuse part of the display (scrolling
164 lines up and down), we must instead have a view of the whole
165 screen. This is what `frame matrices' are for. They are a trick.
166
167 Frames on terminals like above have a glyph pool. Windows on such
168 a frame sub-allocate their glyph memory from their frame's glyph
169 pool. The frame itself is given its own glyph matrices. By
170 coincidence---or maybe something else---rows in window glyph
171 matrices are slices of corresponding rows in frame matrices. Thus
172 writing to window matrices implicitly updates a frame matrix which
173 provides us with the view of the whole screen that we originally
174 wanted to have without having to move many bytes around. To be
175 honest, there is a little bit more done, but not much more. If you
176 plan to extend that code, take a look at dispnew.c. The function
177 build_frame_matrix is a good starting point.
178
179 Bidirectional display.
180
181 Bidirectional display adds quite some hair to this already complex
182 design. The good news are that a large portion of that hairy stuff
183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
184 reordering engine which is called by set_iterator_to_next and
185 returns the next character to display in the visual order. See
186 commentary on bidi.c for more details. As far as redisplay is
187 concerned, the effect of calling bidi_move_to_visually_next, the
188 main interface of the reordering engine, is that the iterator gets
189 magically placed on the buffer or string position that is to be
190 displayed next. In other words, a linear iteration through the
191 buffer/string is replaced with a non-linear one. All the rest of
192 the redisplay is oblivious to the bidi reordering.
193
194 Well, almost oblivious---there are still complications, most of
195 them due to the fact that buffer and string positions no longer
196 change monotonously with glyph indices in a glyph row. Moreover,
197 for continued lines, the buffer positions may not even be
198 monotonously changing with vertical positions. Also, accounting
199 for face changes, overlays, etc. becomes more complex because
200 non-linear iteration could potentially skip many positions with
201 changes, and then cross them again on the way back...
202
203 One other prominent effect of bidirectional display is that some
204 paragraphs of text need to be displayed starting at the right
205 margin of the window---the so-called right-to-left, or R2L
206 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
207 which have their reversed_p flag set. The bidi reordering engine
208 produces characters in such rows starting from the character which
209 should be the rightmost on display. PRODUCE_GLYPHS then reverses
210 the order, when it fills up the glyph row whose reversed_p flag is
211 set, by prepending each new glyph to what is already there, instead
212 of appending it. When the glyph row is complete, the function
213 extend_face_to_end_of_line fills the empty space to the left of the
214 leftmost character with special glyphs, which will display as,
215 well, empty. On text terminals, these special glyphs are simply
216 blank characters. On graphics terminals, there's a single stretch
217 glyph with suitably computed width. Both the blanks and the
218 stretch glyph are given the face of the background of the line.
219 This way, the terminal-specific back-end can still draw the glyphs
220 left to right, even for R2L lines. */
221
222 #include <config.h>
223 #include <stdio.h>
224 #include <limits.h>
225 #include <setjmp.h>
226
227 #include "lisp.h"
228 #include "keyboard.h"
229 #include "frame.h"
230 #include "window.h"
231 #include "termchar.h"
232 #include "dispextern.h"
233 #include "buffer.h"
234 #include "character.h"
235 #include "charset.h"
236 #include "indent.h"
237 #include "commands.h"
238 #include "keymap.h"
239 #include "macros.h"
240 #include "disptab.h"
241 #include "termhooks.h"
242 #include "intervals.h"
243 #include "coding.h"
244 #include "process.h"
245 #include "region-cache.h"
246 #include "font.h"
247 #include "fontset.h"
248 #include "blockinput.h"
249
250 #ifdef HAVE_X_WINDOWS
251 #include "xterm.h"
252 #endif
253 #ifdef WINDOWSNT
254 #include "w32term.h"
255 #endif
256 #ifdef HAVE_NS
257 #include "nsterm.h"
258 #endif
259 #ifdef USE_GTK
260 #include "gtkutil.h"
261 #endif
262
263 #include "font.h"
264
265 #ifndef FRAME_X_OUTPUT
266 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
267 #endif
268
269 #define INFINITY 10000000
270
271 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
272 || defined(HAVE_NS) || defined (USE_GTK)
273 extern void set_frame_menubar (struct frame *f, int, int);
274 #endif
275
276 extern int interrupt_input;
277 extern int command_loop_level;
278
279 extern Lisp_Object do_mouse_tracking;
280
281 extern int minibuffer_auto_raise;
282 extern Lisp_Object Vminibuffer_list;
283
284 extern Lisp_Object Qface;
285 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
286
287 extern Lisp_Object Voverriding_local_map;
288 extern Lisp_Object Voverriding_local_map_menu_flag;
289 extern Lisp_Object Qmenu_item;
290 extern Lisp_Object Qwhen;
291 extern Lisp_Object Qhelp_echo;
292 extern Lisp_Object Qbefore_string, Qafter_string;
293
294 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
295 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
296 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
297 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
298 Lisp_Object Qinhibit_point_motion_hooks;
299 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
300 Lisp_Object Qfontified;
301 Lisp_Object Qgrow_only;
302 Lisp_Object Qinhibit_eval_during_redisplay;
303 Lisp_Object Qbuffer_position, Qposition, Qobject;
304 Lisp_Object Qright_to_left, Qleft_to_right;
305
306 /* Cursor shapes */
307 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
308
309 /* Pointer shapes */
310 Lisp_Object Qarrow, Qhand, Qtext;
311
312 Lisp_Object Qrisky_local_variable;
313
314 /* Holds the list (error). */
315 Lisp_Object list_of_error;
316
317 /* Functions called to fontify regions of text. */
318
319 Lisp_Object Vfontification_functions;
320 Lisp_Object Qfontification_functions;
321
322 /* Non-nil means automatically select any window when the mouse
323 cursor moves into it. */
324 Lisp_Object Vmouse_autoselect_window;
325
326 Lisp_Object Vwrap_prefix, Qwrap_prefix;
327 Lisp_Object Vline_prefix, Qline_prefix;
328
329 /* Non-zero means draw tool bar buttons raised when the mouse moves
330 over them. */
331
332 int auto_raise_tool_bar_buttons_p;
333
334 /* Non-zero means to reposition window if cursor line is only partially visible. */
335
336 int make_cursor_line_fully_visible_p;
337
338 /* Margin below tool bar in pixels. 0 or nil means no margin.
339 If value is `internal-border-width' or `border-width',
340 the corresponding frame parameter is used. */
341
342 Lisp_Object Vtool_bar_border;
343
344 /* Margin around tool bar buttons in pixels. */
345
346 Lisp_Object Vtool_bar_button_margin;
347
348 /* Thickness of shadow to draw around tool bar buttons. */
349
350 EMACS_INT tool_bar_button_relief;
351
352 /* Non-nil means automatically resize tool-bars so that all tool-bar
353 items are visible, and no blank lines remain.
354
355 If value is `grow-only', only make tool-bar bigger. */
356
357 Lisp_Object Vauto_resize_tool_bars;
358
359 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
360
361 Lisp_Object Vtool_bar_style;
362
363 /* Maximum number of characters a label can have to be shown. */
364
365 EMACS_INT tool_bar_max_label_size;
366
367 /* Non-zero means draw block and hollow cursor as wide as the glyph
368 under it. For example, if a block cursor is over a tab, it will be
369 drawn as wide as that tab on the display. */
370
371 int x_stretch_cursor_p;
372
373 /* Non-nil means don't actually do any redisplay. */
374
375 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
376
377 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
378
379 int inhibit_eval_during_redisplay;
380
381 /* Names of text properties relevant for redisplay. */
382
383 Lisp_Object Qdisplay;
384 extern Lisp_Object Qface, Qinvisible, Qwidth;
385
386 /* Symbols used in text property values. */
387
388 Lisp_Object Vdisplay_pixels_per_inch;
389 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
390 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
391 Lisp_Object Qslice;
392 Lisp_Object Qcenter;
393 Lisp_Object Qmargin, Qpointer;
394 Lisp_Object Qline_height;
395 extern Lisp_Object Qheight;
396 extern Lisp_Object QCwidth, QCheight, QCascent;
397 extern Lisp_Object Qscroll_bar;
398 extern Lisp_Object Qcursor;
399
400 /* Non-nil means highlight trailing whitespace. */
401
402 Lisp_Object Vshow_trailing_whitespace;
403
404 /* Non-nil means escape non-break space and hyphens. */
405
406 Lisp_Object Vnobreak_char_display;
407
408 #ifdef HAVE_WINDOW_SYSTEM
409 extern Lisp_Object Voverflow_newline_into_fringe;
410
411 /* Test if overflow newline into fringe. Called with iterator IT
412 at or past right window margin, and with IT->current_x set. */
413
414 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
415 (!NILP (Voverflow_newline_into_fringe) \
416 && FRAME_WINDOW_P ((IT)->f) \
417 && ((IT)->bidi_it.paragraph_dir == R2L \
418 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
419 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
420 && (IT)->current_x == (IT)->last_visible_x \
421 && (IT)->line_wrap != WORD_WRAP)
422
423 #else /* !HAVE_WINDOW_SYSTEM */
424 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
425 #endif /* HAVE_WINDOW_SYSTEM */
426
427 /* Test if the display element loaded in IT is a space or tab
428 character. This is used to determine word wrapping. */
429
430 #define IT_DISPLAYING_WHITESPACE(it) \
431 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
432
433 /* Non-nil means show the text cursor in void text areas
434 i.e. in blank areas after eol and eob. This used to be
435 the default in 21.3. */
436
437 Lisp_Object Vvoid_text_area_pointer;
438
439 /* Name of the face used to highlight trailing whitespace. */
440
441 Lisp_Object Qtrailing_whitespace;
442
443 /* Name and number of the face used to highlight escape glyphs. */
444
445 Lisp_Object Qescape_glyph;
446
447 /* Name and number of the face used to highlight non-breaking spaces. */
448
449 Lisp_Object Qnobreak_space;
450
451 /* The symbol `image' which is the car of the lists used to represent
452 images in Lisp. Also a tool bar style. */
453
454 Lisp_Object Qimage;
455
456 /* The image map types. */
457 Lisp_Object QCmap, QCpointer;
458 Lisp_Object Qrect, Qcircle, Qpoly;
459
460 /* Tool bar styles */
461 Lisp_Object Qtext, Qboth, Qboth_horiz;
462
463 /* Non-zero means print newline to stdout before next mini-buffer
464 message. */
465
466 int noninteractive_need_newline;
467
468 /* Non-zero means print newline to message log before next message. */
469
470 static int message_log_need_newline;
471
472 /* Three markers that message_dolog uses.
473 It could allocate them itself, but that causes trouble
474 in handling memory-full errors. */
475 static Lisp_Object message_dolog_marker1;
476 static Lisp_Object message_dolog_marker2;
477 static Lisp_Object message_dolog_marker3;
478 \f
479 /* The buffer position of the first character appearing entirely or
480 partially on the line of the selected window which contains the
481 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
482 redisplay optimization in redisplay_internal. */
483
484 static struct text_pos this_line_start_pos;
485
486 /* Number of characters past the end of the line above, including the
487 terminating newline. */
488
489 static struct text_pos this_line_end_pos;
490
491 /* The vertical positions and the height of this line. */
492
493 static int this_line_vpos;
494 static int this_line_y;
495 static int this_line_pixel_height;
496
497 /* X position at which this display line starts. Usually zero;
498 negative if first character is partially visible. */
499
500 static int this_line_start_x;
501
502 /* Buffer that this_line_.* variables are referring to. */
503
504 static struct buffer *this_line_buffer;
505
506 /* Nonzero means truncate lines in all windows less wide than the
507 frame. */
508
509 Lisp_Object Vtruncate_partial_width_windows;
510
511 /* A flag to control how to display unibyte 8-bit character. */
512
513 int unibyte_display_via_language_environment;
514
515 /* Nonzero means we have more than one non-mini-buffer-only frame.
516 Not guaranteed to be accurate except while parsing
517 frame-title-format. */
518
519 int multiple_frames;
520
521 Lisp_Object Vglobal_mode_string;
522
523
524 /* List of variables (symbols) which hold markers for overlay arrows.
525 The symbols on this list are examined during redisplay to determine
526 where to display overlay arrows. */
527
528 Lisp_Object Voverlay_arrow_variable_list;
529
530 /* Marker for where to display an arrow on top of the buffer text. */
531
532 Lisp_Object Voverlay_arrow_position;
533
534 /* String to display for the arrow. Only used on terminal frames. */
535
536 Lisp_Object Voverlay_arrow_string;
537
538 /* Values of those variables at last redisplay are stored as
539 properties on `overlay-arrow-position' symbol. However, if
540 Voverlay_arrow_position is a marker, last-arrow-position is its
541 numerical position. */
542
543 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
544
545 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
546 properties on a symbol in overlay-arrow-variable-list. */
547
548 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
549
550 /* Like mode-line-format, but for the title bar on a visible frame. */
551
552 Lisp_Object Vframe_title_format;
553
554 /* Like mode-line-format, but for the title bar on an iconified frame. */
555
556 Lisp_Object Vicon_title_format;
557
558 /* List of functions to call when a window's size changes. These
559 functions get one arg, a frame on which one or more windows' sizes
560 have changed. */
561
562 static Lisp_Object Vwindow_size_change_functions;
563
564 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
565
566 /* Nonzero if an overlay arrow has been displayed in this window. */
567
568 static int overlay_arrow_seen;
569
570 /* Nonzero means highlight the region even in nonselected windows. */
571
572 int highlight_nonselected_windows;
573
574 /* If cursor motion alone moves point off frame, try scrolling this
575 many lines up or down if that will bring it back. */
576
577 static EMACS_INT scroll_step;
578
579 /* Nonzero means scroll just far enough to bring point back on the
580 screen, when appropriate. */
581
582 static EMACS_INT scroll_conservatively;
583
584 /* Recenter the window whenever point gets within this many lines of
585 the top or bottom of the window. This value is translated into a
586 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
587 that there is really a fixed pixel height scroll margin. */
588
589 EMACS_INT scroll_margin;
590
591 /* Number of windows showing the buffer of the selected window (or
592 another buffer with the same base buffer). keyboard.c refers to
593 this. */
594
595 int buffer_shared;
596
597 /* Vector containing glyphs for an ellipsis `...'. */
598
599 static Lisp_Object default_invis_vector[3];
600
601 /* Zero means display the mode-line/header-line/menu-bar in the default face
602 (this slightly odd definition is for compatibility with previous versions
603 of emacs), non-zero means display them using their respective faces.
604
605 This variable is deprecated. */
606
607 int mode_line_inverse_video;
608
609 /* Prompt to display in front of the mini-buffer contents. */
610
611 Lisp_Object minibuf_prompt;
612
613 /* Width of current mini-buffer prompt. Only set after display_line
614 of the line that contains the prompt. */
615
616 int minibuf_prompt_width;
617
618 /* This is the window where the echo area message was displayed. It
619 is always a mini-buffer window, but it may not be the same window
620 currently active as a mini-buffer. */
621
622 Lisp_Object echo_area_window;
623
624 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
625 pushes the current message and the value of
626 message_enable_multibyte on the stack, the function restore_message
627 pops the stack and displays MESSAGE again. */
628
629 Lisp_Object Vmessage_stack;
630
631 /* Nonzero means multibyte characters were enabled when the echo area
632 message was specified. */
633
634 int message_enable_multibyte;
635
636 /* Nonzero if we should redraw the mode lines on the next redisplay. */
637
638 int update_mode_lines;
639
640 /* Nonzero if window sizes or contents have changed since last
641 redisplay that finished. */
642
643 int windows_or_buffers_changed;
644
645 /* Nonzero means a frame's cursor type has been changed. */
646
647 int cursor_type_changed;
648
649 /* Nonzero after display_mode_line if %l was used and it displayed a
650 line number. */
651
652 int line_number_displayed;
653
654 /* Maximum buffer size for which to display line numbers. */
655
656 Lisp_Object Vline_number_display_limit;
657
658 /* Line width to consider when repositioning for line number display. */
659
660 static EMACS_INT line_number_display_limit_width;
661
662 /* Number of lines to keep in the message log buffer. t means
663 infinite. nil means don't log at all. */
664
665 Lisp_Object Vmessage_log_max;
666
667 /* The name of the *Messages* buffer, a string. */
668
669 static Lisp_Object Vmessages_buffer_name;
670
671 /* Current, index 0, and last displayed echo area message. Either
672 buffers from echo_buffers, or nil to indicate no message. */
673
674 Lisp_Object echo_area_buffer[2];
675
676 /* The buffers referenced from echo_area_buffer. */
677
678 static Lisp_Object echo_buffer[2];
679
680 /* A vector saved used in with_area_buffer to reduce consing. */
681
682 static Lisp_Object Vwith_echo_area_save_vector;
683
684 /* Non-zero means display_echo_area should display the last echo area
685 message again. Set by redisplay_preserve_echo_area. */
686
687 static int display_last_displayed_message_p;
688
689 /* Nonzero if echo area is being used by print; zero if being used by
690 message. */
691
692 int message_buf_print;
693
694 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
695
696 Lisp_Object Qinhibit_menubar_update;
697 int inhibit_menubar_update;
698
699 /* When evaluating expressions from menu bar items (enable conditions,
700 for instance), this is the frame they are being processed for. */
701
702 Lisp_Object Vmenu_updating_frame;
703
704 /* Maximum height for resizing mini-windows. Either a float
705 specifying a fraction of the available height, or an integer
706 specifying a number of lines. */
707
708 Lisp_Object Vmax_mini_window_height;
709
710 /* Non-zero means messages should be displayed with truncated
711 lines instead of being continued. */
712
713 int message_truncate_lines;
714 Lisp_Object Qmessage_truncate_lines;
715
716 /* Set to 1 in clear_message to make redisplay_internal aware
717 of an emptied echo area. */
718
719 static int message_cleared_p;
720
721 /* How to blink the default frame cursor off. */
722 Lisp_Object Vblink_cursor_alist;
723
724 /* A scratch glyph row with contents used for generating truncation
725 glyphs. Also used in direct_output_for_insert. */
726
727 #define MAX_SCRATCH_GLYPHS 100
728 struct glyph_row scratch_glyph_row;
729 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
730
731 /* Ascent and height of the last line processed by move_it_to. */
732
733 static int last_max_ascent, last_height;
734
735 /* Non-zero if there's a help-echo in the echo area. */
736
737 int help_echo_showing_p;
738
739 /* If >= 0, computed, exact values of mode-line and header-line height
740 to use in the macros CURRENT_MODE_LINE_HEIGHT and
741 CURRENT_HEADER_LINE_HEIGHT. */
742
743 int current_mode_line_height, current_header_line_height;
744
745 /* The maximum distance to look ahead for text properties. Values
746 that are too small let us call compute_char_face and similar
747 functions too often which is expensive. Values that are too large
748 let us call compute_char_face and alike too often because we
749 might not be interested in text properties that far away. */
750
751 #define TEXT_PROP_DISTANCE_LIMIT 100
752
753 #if GLYPH_DEBUG
754
755 /* Variables to turn off display optimizations from Lisp. */
756
757 int inhibit_try_window_id, inhibit_try_window_reusing;
758 int inhibit_try_cursor_movement;
759
760 /* Non-zero means print traces of redisplay if compiled with
761 GLYPH_DEBUG != 0. */
762
763 int trace_redisplay_p;
764
765 #endif /* GLYPH_DEBUG */
766
767 #ifdef DEBUG_TRACE_MOVE
768 /* Non-zero means trace with TRACE_MOVE to stderr. */
769 int trace_move;
770
771 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
772 #else
773 #define TRACE_MOVE(x) (void) 0
774 #endif
775
776 /* Non-zero means automatically scroll windows horizontally to make
777 point visible. */
778
779 int automatic_hscrolling_p;
780 Lisp_Object Qauto_hscroll_mode;
781
782 /* How close to the margin can point get before the window is scrolled
783 horizontally. */
784 EMACS_INT hscroll_margin;
785
786 /* How much to scroll horizontally when point is inside the above margin. */
787 Lisp_Object Vhscroll_step;
788
789 /* The variable `resize-mini-windows'. If nil, don't resize
790 mini-windows. If t, always resize them to fit the text they
791 display. If `grow-only', let mini-windows grow only until they
792 become empty. */
793
794 Lisp_Object Vresize_mini_windows;
795
796 /* Buffer being redisplayed -- for redisplay_window_error. */
797
798 struct buffer *displayed_buffer;
799
800 /* Space between overline and text. */
801
802 EMACS_INT overline_margin;
803
804 /* Require underline to be at least this many screen pixels below baseline
805 This to avoid underline "merging" with the base of letters at small
806 font sizes, particularly when x_use_underline_position_properties is on. */
807
808 EMACS_INT underline_minimum_offset;
809
810 /* Value returned from text property handlers (see below). */
811
812 enum prop_handled
813 {
814 HANDLED_NORMALLY,
815 HANDLED_RECOMPUTE_PROPS,
816 HANDLED_OVERLAY_STRING_CONSUMED,
817 HANDLED_RETURN
818 };
819
820 /* A description of text properties that redisplay is interested
821 in. */
822
823 struct props
824 {
825 /* The name of the property. */
826 Lisp_Object *name;
827
828 /* A unique index for the property. */
829 enum prop_idx idx;
830
831 /* A handler function called to set up iterator IT from the property
832 at IT's current position. Value is used to steer handle_stop. */
833 enum prop_handled (*handler) (struct it *it);
834 };
835
836 static enum prop_handled handle_face_prop (struct it *);
837 static enum prop_handled handle_invisible_prop (struct it *);
838 static enum prop_handled handle_display_prop (struct it *);
839 static enum prop_handled handle_composition_prop (struct it *);
840 static enum prop_handled handle_overlay_change (struct it *);
841 static enum prop_handled handle_fontified_prop (struct it *);
842
843 /* Properties handled by iterators. */
844
845 static struct props it_props[] =
846 {
847 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
848 /* Handle `face' before `display' because some sub-properties of
849 `display' need to know the face. */
850 {&Qface, FACE_PROP_IDX, handle_face_prop},
851 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
852 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
853 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
854 {NULL, 0, NULL}
855 };
856
857 /* Value is the position described by X. If X is a marker, value is
858 the marker_position of X. Otherwise, value is X. */
859
860 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
861
862 /* Enumeration returned by some move_it_.* functions internally. */
863
864 enum move_it_result
865 {
866 /* Not used. Undefined value. */
867 MOVE_UNDEFINED,
868
869 /* Move ended at the requested buffer position or ZV. */
870 MOVE_POS_MATCH_OR_ZV,
871
872 /* Move ended at the requested X pixel position. */
873 MOVE_X_REACHED,
874
875 /* Move within a line ended at the end of a line that must be
876 continued. */
877 MOVE_LINE_CONTINUED,
878
879 /* Move within a line ended at the end of a line that would
880 be displayed truncated. */
881 MOVE_LINE_TRUNCATED,
882
883 /* Move within a line ended at a line end. */
884 MOVE_NEWLINE_OR_CR
885 };
886
887 /* This counter is used to clear the face cache every once in a while
888 in redisplay_internal. It is incremented for each redisplay.
889 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
890 cleared. */
891
892 #define CLEAR_FACE_CACHE_COUNT 500
893 static int clear_face_cache_count;
894
895 /* Similarly for the image cache. */
896
897 #ifdef HAVE_WINDOW_SYSTEM
898 #define CLEAR_IMAGE_CACHE_COUNT 101
899 static int clear_image_cache_count;
900 #endif
901
902 /* Non-zero while redisplay_internal is in progress. */
903
904 int redisplaying_p;
905
906 /* Non-zero means don't free realized faces. Bound while freeing
907 realized faces is dangerous because glyph matrices might still
908 reference them. */
909
910 int inhibit_free_realized_faces;
911 Lisp_Object Qinhibit_free_realized_faces;
912
913 /* If a string, XTread_socket generates an event to display that string.
914 (The display is done in read_char.) */
915
916 Lisp_Object help_echo_string;
917 Lisp_Object help_echo_window;
918 Lisp_Object help_echo_object;
919 int help_echo_pos;
920
921 /* Temporary variable for XTread_socket. */
922
923 Lisp_Object previous_help_echo_string;
924
925 /* Null glyph slice */
926
927 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
928
929 /* Platform-independent portion of hourglass implementation. */
930
931 /* Non-zero means we're allowed to display a hourglass pointer. */
932 int display_hourglass_p;
933
934 /* Non-zero means an hourglass cursor is currently shown. */
935 int hourglass_shown_p;
936
937 /* If non-null, an asynchronous timer that, when it expires, displays
938 an hourglass cursor on all frames. */
939 struct atimer *hourglass_atimer;
940
941 /* Number of seconds to wait before displaying an hourglass cursor. */
942 Lisp_Object Vhourglass_delay;
943
944 /* Default number of seconds to wait before displaying an hourglass
945 cursor. */
946 #define DEFAULT_HOURGLASS_DELAY 1
947
948 \f
949 /* Function prototypes. */
950
951 static void setup_for_ellipsis (struct it *, int);
952 static void mark_window_display_accurate_1 (struct window *, int);
953 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
954 static int display_prop_string_p (Lisp_Object, Lisp_Object);
955 static int cursor_row_p (struct window *, struct glyph_row *);
956 static int redisplay_mode_lines (Lisp_Object, int);
957 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
958
959 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
960
961 static void handle_line_prefix (struct it *);
962
963 static void pint2str (char *, int, int);
964 static void pint2hrstr (char *, int, int);
965 static struct text_pos run_window_scroll_functions (Lisp_Object,
966 struct text_pos);
967 static void reconsider_clip_changes (struct window *, struct buffer *);
968 static int text_outside_line_unchanged_p (struct window *, int, int);
969 static void store_mode_line_noprop_char (char);
970 static int store_mode_line_noprop (const unsigned char *, int, int);
971 static void x_consider_frame_title (Lisp_Object);
972 static void handle_stop (struct it *);
973 static void handle_stop_backwards (struct it *, EMACS_INT);
974 static int tool_bar_lines_needed (struct frame *, int *);
975 static int single_display_spec_intangible_p (Lisp_Object);
976 static void ensure_echo_area_buffers (void);
977 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
978 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
979 static int with_echo_area_buffer (struct window *, int,
980 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
981 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
982 static void clear_garbaged_frames (void);
983 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
984 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
985 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
986 static int display_echo_area (struct window *);
987 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
988 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
989 static Lisp_Object unwind_redisplay (Lisp_Object);
990 static int string_char_and_length (const unsigned char *, int *);
991 static struct text_pos display_prop_end (struct it *, Lisp_Object,
992 struct text_pos);
993 static int compute_window_start_on_continuation_line (struct window *);
994 static Lisp_Object safe_eval_handler (Lisp_Object);
995 static void insert_left_trunc_glyphs (struct it *);
996 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
997 Lisp_Object);
998 static void extend_face_to_end_of_line (struct it *);
999 static int append_space_for_newline (struct it *, int);
1000 static int cursor_row_fully_visible_p (struct window *, int, int);
1001 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
1002 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
1003 static int trailing_whitespace_p (int);
1004 static int message_log_check_duplicate (int, int, int, int);
1005 static void push_it (struct it *);
1006 static void pop_it (struct it *);
1007 static void sync_frame_with_window_matrix_rows (struct window *);
1008 static void select_frame_for_redisplay (Lisp_Object);
1009 static void redisplay_internal (int);
1010 static int echo_area_display (int);
1011 static void redisplay_windows (Lisp_Object);
1012 static void redisplay_window (Lisp_Object, int);
1013 static Lisp_Object redisplay_window_error (Lisp_Object);
1014 static Lisp_Object redisplay_window_0 (Lisp_Object);
1015 static Lisp_Object redisplay_window_1 (Lisp_Object);
1016 static int update_menu_bar (struct frame *, int, int);
1017 static int try_window_reusing_current_matrix (struct window *);
1018 static int try_window_id (struct window *);
1019 static int display_line (struct it *);
1020 static int display_mode_lines (struct window *);
1021 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
1022 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
1023 static int store_mode_line_string (char *, Lisp_Object, int, int, int, Lisp_Object);
1024 static char *decode_mode_spec (struct window *, int, int, int,
1025 Lisp_Object *);
1026 static void display_menu_bar (struct window *);
1027 static int display_count_lines (int, int, int, int, int *);
1028 static int display_string (unsigned char *, Lisp_Object, Lisp_Object,
1029 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
1030 static void compute_line_metrics (struct it *);
1031 static void run_redisplay_end_trigger_hook (struct it *);
1032 static int get_overlay_strings (struct it *, int);
1033 static int get_overlay_strings_1 (struct it *, int, int);
1034 static void next_overlay_string (struct it *);
1035 static void reseat (struct it *, struct text_pos, int);
1036 static void reseat_1 (struct it *, struct text_pos, int);
1037 static void back_to_previous_visible_line_start (struct it *);
1038 void reseat_at_previous_visible_line_start (struct it *);
1039 static void reseat_at_next_visible_line_start (struct it *, int);
1040 static int next_element_from_ellipsis (struct it *);
1041 static int next_element_from_display_vector (struct it *);
1042 static int next_element_from_string (struct it *);
1043 static int next_element_from_c_string (struct it *);
1044 static int next_element_from_buffer (struct it *);
1045 static int next_element_from_composition (struct it *);
1046 static int next_element_from_image (struct it *);
1047 static int next_element_from_stretch (struct it *);
1048 static void load_overlay_strings (struct it *, int);
1049 static int init_from_display_pos (struct it *, struct window *,
1050 struct display_pos *);
1051 static void reseat_to_string (struct it *, unsigned char *,
1052 Lisp_Object, int, int, int, int);
1053 static enum move_it_result
1054 move_it_in_display_line_to (struct it *, EMACS_INT, int,
1055 enum move_operation_enum);
1056 void move_it_vertically_backward (struct it *, int);
1057 static void init_to_row_start (struct it *, struct window *,
1058 struct glyph_row *);
1059 static int init_to_row_end (struct it *, struct window *,
1060 struct glyph_row *);
1061 static void back_to_previous_line_start (struct it *);
1062 static int forward_to_next_line_start (struct it *, int *);
1063 static struct text_pos string_pos_nchars_ahead (struct text_pos,
1064 Lisp_Object, int);
1065 static struct text_pos string_pos (int, Lisp_Object);
1066 static struct text_pos c_string_pos (int, unsigned char *, int);
1067 static int number_of_chars (unsigned char *, int);
1068 static void compute_stop_pos (struct it *);
1069 static void compute_string_pos (struct text_pos *, struct text_pos,
1070 Lisp_Object);
1071 static int face_before_or_after_it_pos (struct it *, int);
1072 static EMACS_INT next_overlay_change (EMACS_INT);
1073 static int handle_single_display_spec (struct it *, Lisp_Object,
1074 Lisp_Object, Lisp_Object,
1075 struct text_pos *, int);
1076 static int underlying_face_id (struct it *);
1077 static int in_ellipses_for_invisible_text_p (struct display_pos *,
1078 struct window *);
1079
1080 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1081 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1082
1083 #ifdef HAVE_WINDOW_SYSTEM
1084
1085 static void update_tool_bar (struct frame *, int);
1086 static void build_desired_tool_bar_string (struct frame *f);
1087 static int redisplay_tool_bar (struct frame *);
1088 static void display_tool_bar_line (struct it *, int);
1089 static void notice_overwritten_cursor (struct window *,
1090 enum glyph_row_area,
1091 int, int, int, int);
1092 static void append_stretch_glyph (struct it *, Lisp_Object,
1093 int, int, int);
1094
1095
1096
1097 #endif /* HAVE_WINDOW_SYSTEM */
1098
1099 \f
1100 /***********************************************************************
1101 Window display dimensions
1102 ***********************************************************************/
1103
1104 /* Return the bottom boundary y-position for text lines in window W.
1105 This is the first y position at which a line cannot start.
1106 It is relative to the top of the window.
1107
1108 This is the height of W minus the height of a mode line, if any. */
1109
1110 INLINE int
1111 window_text_bottom_y (struct window *w)
1112 {
1113 int height = WINDOW_TOTAL_HEIGHT (w);
1114
1115 if (WINDOW_WANTS_MODELINE_P (w))
1116 height -= CURRENT_MODE_LINE_HEIGHT (w);
1117 return height;
1118 }
1119
1120 /* Return the pixel width of display area AREA of window W. AREA < 0
1121 means return the total width of W, not including fringes to
1122 the left and right of the window. */
1123
1124 INLINE int
1125 window_box_width (struct window *w, int area)
1126 {
1127 int cols = XFASTINT (w->total_cols);
1128 int pixels = 0;
1129
1130 if (!w->pseudo_window_p)
1131 {
1132 cols -= WINDOW_SCROLL_BAR_COLS (w);
1133
1134 if (area == TEXT_AREA)
1135 {
1136 if (INTEGERP (w->left_margin_cols))
1137 cols -= XFASTINT (w->left_margin_cols);
1138 if (INTEGERP (w->right_margin_cols))
1139 cols -= XFASTINT (w->right_margin_cols);
1140 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1141 }
1142 else if (area == LEFT_MARGIN_AREA)
1143 {
1144 cols = (INTEGERP (w->left_margin_cols)
1145 ? XFASTINT (w->left_margin_cols) : 0);
1146 pixels = 0;
1147 }
1148 else if (area == RIGHT_MARGIN_AREA)
1149 {
1150 cols = (INTEGERP (w->right_margin_cols)
1151 ? XFASTINT (w->right_margin_cols) : 0);
1152 pixels = 0;
1153 }
1154 }
1155
1156 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1157 }
1158
1159
1160 /* Return the pixel height of the display area of window W, not
1161 including mode lines of W, if any. */
1162
1163 INLINE int
1164 window_box_height (struct window *w)
1165 {
1166 struct frame *f = XFRAME (w->frame);
1167 int height = WINDOW_TOTAL_HEIGHT (w);
1168
1169 xassert (height >= 0);
1170
1171 /* Note: the code below that determines the mode-line/header-line
1172 height is essentially the same as that contained in the macro
1173 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1174 the appropriate glyph row has its `mode_line_p' flag set,
1175 and if it doesn't, uses estimate_mode_line_height instead. */
1176
1177 if (WINDOW_WANTS_MODELINE_P (w))
1178 {
1179 struct glyph_row *ml_row
1180 = (w->current_matrix && w->current_matrix->rows
1181 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1182 : 0);
1183 if (ml_row && ml_row->mode_line_p)
1184 height -= ml_row->height;
1185 else
1186 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1187 }
1188
1189 if (WINDOW_WANTS_HEADER_LINE_P (w))
1190 {
1191 struct glyph_row *hl_row
1192 = (w->current_matrix && w->current_matrix->rows
1193 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1194 : 0);
1195 if (hl_row && hl_row->mode_line_p)
1196 height -= hl_row->height;
1197 else
1198 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1199 }
1200
1201 /* With a very small font and a mode-line that's taller than
1202 default, we might end up with a negative height. */
1203 return max (0, height);
1204 }
1205
1206 /* Return the window-relative coordinate of the left edge of display
1207 area AREA of window W. AREA < 0 means return the left edge of the
1208 whole window, to the right of the left fringe of W. */
1209
1210 INLINE int
1211 window_box_left_offset (struct window *w, int area)
1212 {
1213 int x;
1214
1215 if (w->pseudo_window_p)
1216 return 0;
1217
1218 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1219
1220 if (area == TEXT_AREA)
1221 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1222 + window_box_width (w, LEFT_MARGIN_AREA));
1223 else if (area == RIGHT_MARGIN_AREA)
1224 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1225 + window_box_width (w, LEFT_MARGIN_AREA)
1226 + window_box_width (w, TEXT_AREA)
1227 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1228 ? 0
1229 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1230 else if (area == LEFT_MARGIN_AREA
1231 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1232 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1233
1234 return x;
1235 }
1236
1237
1238 /* Return the window-relative coordinate of the right edge of display
1239 area AREA of window W. AREA < 0 means return the left edge of the
1240 whole window, to the left of the right fringe of W. */
1241
1242 INLINE int
1243 window_box_right_offset (struct window *w, int area)
1244 {
1245 return window_box_left_offset (w, area) + window_box_width (w, area);
1246 }
1247
1248 /* Return the frame-relative coordinate of the left edge of display
1249 area AREA of window W. AREA < 0 means return the left edge of the
1250 whole window, to the right of the left fringe of W. */
1251
1252 INLINE int
1253 window_box_left (struct window *w, int area)
1254 {
1255 struct frame *f = XFRAME (w->frame);
1256 int x;
1257
1258 if (w->pseudo_window_p)
1259 return FRAME_INTERNAL_BORDER_WIDTH (f);
1260
1261 x = (WINDOW_LEFT_EDGE_X (w)
1262 + window_box_left_offset (w, area));
1263
1264 return x;
1265 }
1266
1267
1268 /* Return the frame-relative coordinate of the right edge of display
1269 area AREA of window W. AREA < 0 means return the left edge of the
1270 whole window, to the left of the right fringe of W. */
1271
1272 INLINE int
1273 window_box_right (struct window *w, int area)
1274 {
1275 return window_box_left (w, area) + window_box_width (w, area);
1276 }
1277
1278 /* Get the bounding box of the display area AREA of window W, without
1279 mode lines, in frame-relative coordinates. AREA < 0 means the
1280 whole window, not including the left and right fringes of
1281 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1282 coordinates of the upper-left corner of the box. Return in
1283 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1284
1285 INLINE void
1286 window_box (struct window *w, int area, int *box_x, int *box_y,
1287 int *box_width, int *box_height)
1288 {
1289 if (box_width)
1290 *box_width = window_box_width (w, area);
1291 if (box_height)
1292 *box_height = window_box_height (w);
1293 if (box_x)
1294 *box_x = window_box_left (w, area);
1295 if (box_y)
1296 {
1297 *box_y = WINDOW_TOP_EDGE_Y (w);
1298 if (WINDOW_WANTS_HEADER_LINE_P (w))
1299 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1300 }
1301 }
1302
1303
1304 /* Get the bounding box of the display area AREA of window W, without
1305 mode lines. AREA < 0 means the whole window, not including the
1306 left and right fringe of the window. Return in *TOP_LEFT_X
1307 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1308 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1309 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1310 box. */
1311
1312 INLINE void
1313 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1314 int *bottom_right_x, int *bottom_right_y)
1315 {
1316 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1317 bottom_right_y);
1318 *bottom_right_x += *top_left_x;
1319 *bottom_right_y += *top_left_y;
1320 }
1321
1322
1323 \f
1324 /***********************************************************************
1325 Utilities
1326 ***********************************************************************/
1327
1328 /* Return the bottom y-position of the line the iterator IT is in.
1329 This can modify IT's settings. */
1330
1331 int
1332 line_bottom_y (struct it *it)
1333 {
1334 int line_height = it->max_ascent + it->max_descent;
1335 int line_top_y = it->current_y;
1336
1337 if (line_height == 0)
1338 {
1339 if (last_height)
1340 line_height = last_height;
1341 else if (IT_CHARPOS (*it) < ZV)
1342 {
1343 move_it_by_lines (it, 1, 1);
1344 line_height = (it->max_ascent || it->max_descent
1345 ? it->max_ascent + it->max_descent
1346 : last_height);
1347 }
1348 else
1349 {
1350 struct glyph_row *row = it->glyph_row;
1351
1352 /* Use the default character height. */
1353 it->glyph_row = NULL;
1354 it->what = IT_CHARACTER;
1355 it->c = ' ';
1356 it->len = 1;
1357 PRODUCE_GLYPHS (it);
1358 line_height = it->ascent + it->descent;
1359 it->glyph_row = row;
1360 }
1361 }
1362
1363 return line_top_y + line_height;
1364 }
1365
1366
1367 /* Return 1 if position CHARPOS is visible in window W.
1368 CHARPOS < 0 means return info about WINDOW_END position.
1369 If visible, set *X and *Y to pixel coordinates of top left corner.
1370 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1371 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1372
1373 int
1374 pos_visible_p (struct window *w, int charpos, int *x, int *y,
1375 int *rtop, int *rbot, int *rowh, int *vpos)
1376 {
1377 struct it it;
1378 struct text_pos top;
1379 int visible_p = 0;
1380 struct buffer *old_buffer = NULL;
1381
1382 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1383 return visible_p;
1384
1385 if (XBUFFER (w->buffer) != current_buffer)
1386 {
1387 old_buffer = current_buffer;
1388 set_buffer_internal_1 (XBUFFER (w->buffer));
1389 }
1390
1391 SET_TEXT_POS_FROM_MARKER (top, w->start);
1392
1393 /* Compute exact mode line heights. */
1394 if (WINDOW_WANTS_MODELINE_P (w))
1395 current_mode_line_height
1396 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1397 current_buffer->mode_line_format);
1398
1399 if (WINDOW_WANTS_HEADER_LINE_P (w))
1400 current_header_line_height
1401 = display_mode_line (w, HEADER_LINE_FACE_ID,
1402 current_buffer->header_line_format);
1403
1404 start_display (&it, w, top);
1405 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1406 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1407
1408 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1409 {
1410 /* We have reached CHARPOS, or passed it. How the call to
1411 move_it_to can overshoot: (i) If CHARPOS is on invisible
1412 text, move_it_to stops at the end of the invisible text,
1413 after CHARPOS. (ii) If CHARPOS is in a display vector,
1414 move_it_to stops on its last glyph. */
1415 int top_x = it.current_x;
1416 int top_y = it.current_y;
1417 enum it_method it_method = it.method;
1418 /* Calling line_bottom_y may change it.method, it.position, etc. */
1419 int bottom_y = (last_height = 0, line_bottom_y (&it));
1420 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1421
1422 if (top_y < window_top_y)
1423 visible_p = bottom_y > window_top_y;
1424 else if (top_y < it.last_visible_y)
1425 visible_p = 1;
1426 if (visible_p)
1427 {
1428 if (it_method == GET_FROM_DISPLAY_VECTOR)
1429 {
1430 /* We stopped on the last glyph of a display vector.
1431 Try and recompute. Hack alert! */
1432 if (charpos < 2 || top.charpos >= charpos)
1433 top_x = it.glyph_row->x;
1434 else
1435 {
1436 struct it it2;
1437 start_display (&it2, w, top);
1438 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1439 get_next_display_element (&it2);
1440 PRODUCE_GLYPHS (&it2);
1441 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1442 || it2.current_x > it2.last_visible_x)
1443 top_x = it.glyph_row->x;
1444 else
1445 {
1446 top_x = it2.current_x;
1447 top_y = it2.current_y;
1448 }
1449 }
1450 }
1451
1452 *x = top_x;
1453 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1454 *rtop = max (0, window_top_y - top_y);
1455 *rbot = max (0, bottom_y - it.last_visible_y);
1456 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1457 - max (top_y, window_top_y)));
1458 *vpos = it.vpos;
1459 }
1460 }
1461 else
1462 {
1463 struct it it2;
1464
1465 it2 = it;
1466 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1467 move_it_by_lines (&it, 1, 0);
1468 if (charpos < IT_CHARPOS (it)
1469 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1470 {
1471 visible_p = 1;
1472 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1473 *x = it2.current_x;
1474 *y = it2.current_y + it2.max_ascent - it2.ascent;
1475 *rtop = max (0, -it2.current_y);
1476 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1477 - it.last_visible_y));
1478 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1479 it.last_visible_y)
1480 - max (it2.current_y,
1481 WINDOW_HEADER_LINE_HEIGHT (w))));
1482 *vpos = it2.vpos;
1483 }
1484 }
1485
1486 if (old_buffer)
1487 set_buffer_internal_1 (old_buffer);
1488
1489 current_header_line_height = current_mode_line_height = -1;
1490
1491 if (visible_p && XFASTINT (w->hscroll) > 0)
1492 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1493
1494 #if 0
1495 /* Debugging code. */
1496 if (visible_p)
1497 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1498 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1499 else
1500 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1501 #endif
1502
1503 return visible_p;
1504 }
1505
1506
1507 /* Return the next character from STR which is MAXLEN bytes long.
1508 Return in *LEN the length of the character. This is like
1509 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1510 we find one, we return a `?', but with the length of the invalid
1511 character. */
1512
1513 static INLINE int
1514 string_char_and_length (const unsigned char *str, int *len)
1515 {
1516 int c;
1517
1518 c = STRING_CHAR_AND_LENGTH (str, *len);
1519 if (!CHAR_VALID_P (c, 1))
1520 /* We may not change the length here because other places in Emacs
1521 don't use this function, i.e. they silently accept invalid
1522 characters. */
1523 c = '?';
1524
1525 return c;
1526 }
1527
1528
1529
1530 /* Given a position POS containing a valid character and byte position
1531 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1532
1533 static struct text_pos
1534 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
1535 {
1536 xassert (STRINGP (string) && nchars >= 0);
1537
1538 if (STRING_MULTIBYTE (string))
1539 {
1540 int rest = SBYTES (string) - BYTEPOS (pos);
1541 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1542 int len;
1543
1544 while (nchars--)
1545 {
1546 string_char_and_length (p, &len);
1547 p += len, rest -= len;
1548 xassert (rest >= 0);
1549 CHARPOS (pos) += 1;
1550 BYTEPOS (pos) += len;
1551 }
1552 }
1553 else
1554 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1555
1556 return pos;
1557 }
1558
1559
1560 /* Value is the text position, i.e. character and byte position,
1561 for character position CHARPOS in STRING. */
1562
1563 static INLINE struct text_pos
1564 string_pos (int charpos, Lisp_Object string)
1565 {
1566 struct text_pos pos;
1567 xassert (STRINGP (string));
1568 xassert (charpos >= 0);
1569 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1570 return pos;
1571 }
1572
1573
1574 /* Value is a text position, i.e. character and byte position, for
1575 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1576 means recognize multibyte characters. */
1577
1578 static struct text_pos
1579 c_string_pos (int charpos, unsigned char *s, int multibyte_p)
1580 {
1581 struct text_pos pos;
1582
1583 xassert (s != NULL);
1584 xassert (charpos >= 0);
1585
1586 if (multibyte_p)
1587 {
1588 int rest = strlen (s), len;
1589
1590 SET_TEXT_POS (pos, 0, 0);
1591 while (charpos--)
1592 {
1593 string_char_and_length (s, &len);
1594 s += len, rest -= len;
1595 xassert (rest >= 0);
1596 CHARPOS (pos) += 1;
1597 BYTEPOS (pos) += len;
1598 }
1599 }
1600 else
1601 SET_TEXT_POS (pos, charpos, charpos);
1602
1603 return pos;
1604 }
1605
1606
1607 /* Value is the number of characters in C string S. MULTIBYTE_P
1608 non-zero means recognize multibyte characters. */
1609
1610 static int
1611 number_of_chars (unsigned char *s, int multibyte_p)
1612 {
1613 int nchars;
1614
1615 if (multibyte_p)
1616 {
1617 int rest = strlen (s), len;
1618 unsigned char *p = (unsigned char *) s;
1619
1620 for (nchars = 0; rest > 0; ++nchars)
1621 {
1622 string_char_and_length (p, &len);
1623 rest -= len, p += len;
1624 }
1625 }
1626 else
1627 nchars = strlen (s);
1628
1629 return nchars;
1630 }
1631
1632
1633 /* Compute byte position NEWPOS->bytepos corresponding to
1634 NEWPOS->charpos. POS is a known position in string STRING.
1635 NEWPOS->charpos must be >= POS.charpos. */
1636
1637 static void
1638 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1639 {
1640 xassert (STRINGP (string));
1641 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1642
1643 if (STRING_MULTIBYTE (string))
1644 *newpos = string_pos_nchars_ahead (pos, string,
1645 CHARPOS (*newpos) - CHARPOS (pos));
1646 else
1647 BYTEPOS (*newpos) = CHARPOS (*newpos);
1648 }
1649
1650 /* EXPORT:
1651 Return an estimation of the pixel height of mode or header lines on
1652 frame F. FACE_ID specifies what line's height to estimate. */
1653
1654 int
1655 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1656 {
1657 #ifdef HAVE_WINDOW_SYSTEM
1658 if (FRAME_WINDOW_P (f))
1659 {
1660 int height = FONT_HEIGHT (FRAME_FONT (f));
1661
1662 /* This function is called so early when Emacs starts that the face
1663 cache and mode line face are not yet initialized. */
1664 if (FRAME_FACE_CACHE (f))
1665 {
1666 struct face *face = FACE_FROM_ID (f, face_id);
1667 if (face)
1668 {
1669 if (face->font)
1670 height = FONT_HEIGHT (face->font);
1671 if (face->box_line_width > 0)
1672 height += 2 * face->box_line_width;
1673 }
1674 }
1675
1676 return height;
1677 }
1678 #endif
1679
1680 return 1;
1681 }
1682
1683 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1684 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1685 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1686 not force the value into range. */
1687
1688 void
1689 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1690 int *x, int *y, NativeRectangle *bounds, int noclip)
1691 {
1692
1693 #ifdef HAVE_WINDOW_SYSTEM
1694 if (FRAME_WINDOW_P (f))
1695 {
1696 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1697 even for negative values. */
1698 if (pix_x < 0)
1699 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1700 if (pix_y < 0)
1701 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1702
1703 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1704 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1705
1706 if (bounds)
1707 STORE_NATIVE_RECT (*bounds,
1708 FRAME_COL_TO_PIXEL_X (f, pix_x),
1709 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1710 FRAME_COLUMN_WIDTH (f) - 1,
1711 FRAME_LINE_HEIGHT (f) - 1);
1712
1713 if (!noclip)
1714 {
1715 if (pix_x < 0)
1716 pix_x = 0;
1717 else if (pix_x > FRAME_TOTAL_COLS (f))
1718 pix_x = FRAME_TOTAL_COLS (f);
1719
1720 if (pix_y < 0)
1721 pix_y = 0;
1722 else if (pix_y > FRAME_LINES (f))
1723 pix_y = FRAME_LINES (f);
1724 }
1725 }
1726 #endif
1727
1728 *x = pix_x;
1729 *y = pix_y;
1730 }
1731
1732
1733 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1734 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1735 can't tell the positions because W's display is not up to date,
1736 return 0. */
1737
1738 int
1739 glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1740 int *frame_x, int *frame_y)
1741 {
1742 #ifdef HAVE_WINDOW_SYSTEM
1743 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1744 {
1745 int success_p;
1746
1747 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1748 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1749
1750 if (display_completed)
1751 {
1752 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1753 struct glyph *glyph = row->glyphs[TEXT_AREA];
1754 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1755
1756 hpos = row->x;
1757 vpos = row->y;
1758 while (glyph < end)
1759 {
1760 hpos += glyph->pixel_width;
1761 ++glyph;
1762 }
1763
1764 /* If first glyph is partially visible, its first visible position is still 0. */
1765 if (hpos < 0)
1766 hpos = 0;
1767
1768 success_p = 1;
1769 }
1770 else
1771 {
1772 hpos = vpos = 0;
1773 success_p = 0;
1774 }
1775
1776 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1777 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1778 return success_p;
1779 }
1780 #endif
1781
1782 *frame_x = hpos;
1783 *frame_y = vpos;
1784 return 1;
1785 }
1786
1787
1788 #ifdef HAVE_WINDOW_SYSTEM
1789
1790 /* Find the glyph under window-relative coordinates X/Y in window W.
1791 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1792 strings. Return in *HPOS and *VPOS the row and column number of
1793 the glyph found. Return in *AREA the glyph area containing X.
1794 Value is a pointer to the glyph found or null if X/Y is not on
1795 text, or we can't tell because W's current matrix is not up to
1796 date. */
1797
1798 static
1799 struct glyph *
1800 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1801 int *dx, int *dy, int *area)
1802 {
1803 struct glyph *glyph, *end;
1804 struct glyph_row *row = NULL;
1805 int x0, i;
1806
1807 /* Find row containing Y. Give up if some row is not enabled. */
1808 for (i = 0; i < w->current_matrix->nrows; ++i)
1809 {
1810 row = MATRIX_ROW (w->current_matrix, i);
1811 if (!row->enabled_p)
1812 return NULL;
1813 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1814 break;
1815 }
1816
1817 *vpos = i;
1818 *hpos = 0;
1819
1820 /* Give up if Y is not in the window. */
1821 if (i == w->current_matrix->nrows)
1822 return NULL;
1823
1824 /* Get the glyph area containing X. */
1825 if (w->pseudo_window_p)
1826 {
1827 *area = TEXT_AREA;
1828 x0 = 0;
1829 }
1830 else
1831 {
1832 if (x < window_box_left_offset (w, TEXT_AREA))
1833 {
1834 *area = LEFT_MARGIN_AREA;
1835 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1836 }
1837 else if (x < window_box_right_offset (w, TEXT_AREA))
1838 {
1839 *area = TEXT_AREA;
1840 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1841 }
1842 else
1843 {
1844 *area = RIGHT_MARGIN_AREA;
1845 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1846 }
1847 }
1848
1849 /* Find glyph containing X. */
1850 glyph = row->glyphs[*area];
1851 end = glyph + row->used[*area];
1852 x -= x0;
1853 while (glyph < end && x >= glyph->pixel_width)
1854 {
1855 x -= glyph->pixel_width;
1856 ++glyph;
1857 }
1858
1859 if (glyph == end)
1860 return NULL;
1861
1862 if (dx)
1863 {
1864 *dx = x;
1865 *dy = y - (row->y + row->ascent - glyph->ascent);
1866 }
1867
1868 *hpos = glyph - row->glyphs[*area];
1869 return glyph;
1870 }
1871
1872
1873 /* EXPORT:
1874 Convert frame-relative x/y to coordinates relative to window W.
1875 Takes pseudo-windows into account. */
1876
1877 void
1878 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1879 {
1880 if (w->pseudo_window_p)
1881 {
1882 /* A pseudo-window is always full-width, and starts at the
1883 left edge of the frame, plus a frame border. */
1884 struct frame *f = XFRAME (w->frame);
1885 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1886 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1887 }
1888 else
1889 {
1890 *x -= WINDOW_LEFT_EDGE_X (w);
1891 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1892 }
1893 }
1894
1895 /* EXPORT:
1896 Return in RECTS[] at most N clipping rectangles for glyph string S.
1897 Return the number of stored rectangles. */
1898
1899 int
1900 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1901 {
1902 XRectangle r;
1903
1904 if (n <= 0)
1905 return 0;
1906
1907 if (s->row->full_width_p)
1908 {
1909 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1910 r.x = WINDOW_LEFT_EDGE_X (s->w);
1911 r.width = WINDOW_TOTAL_WIDTH (s->w);
1912
1913 /* Unless displaying a mode or menu bar line, which are always
1914 fully visible, clip to the visible part of the row. */
1915 if (s->w->pseudo_window_p)
1916 r.height = s->row->visible_height;
1917 else
1918 r.height = s->height;
1919 }
1920 else
1921 {
1922 /* This is a text line that may be partially visible. */
1923 r.x = window_box_left (s->w, s->area);
1924 r.width = window_box_width (s->w, s->area);
1925 r.height = s->row->visible_height;
1926 }
1927
1928 if (s->clip_head)
1929 if (r.x < s->clip_head->x)
1930 {
1931 if (r.width >= s->clip_head->x - r.x)
1932 r.width -= s->clip_head->x - r.x;
1933 else
1934 r.width = 0;
1935 r.x = s->clip_head->x;
1936 }
1937 if (s->clip_tail)
1938 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1939 {
1940 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1941 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1942 else
1943 r.width = 0;
1944 }
1945
1946 /* If S draws overlapping rows, it's sufficient to use the top and
1947 bottom of the window for clipping because this glyph string
1948 intentionally draws over other lines. */
1949 if (s->for_overlaps)
1950 {
1951 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1952 r.height = window_text_bottom_y (s->w) - r.y;
1953
1954 /* Alas, the above simple strategy does not work for the
1955 environments with anti-aliased text: if the same text is
1956 drawn onto the same place multiple times, it gets thicker.
1957 If the overlap we are processing is for the erased cursor, we
1958 take the intersection with the rectagle of the cursor. */
1959 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1960 {
1961 XRectangle rc, r_save = r;
1962
1963 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1964 rc.y = s->w->phys_cursor.y;
1965 rc.width = s->w->phys_cursor_width;
1966 rc.height = s->w->phys_cursor_height;
1967
1968 x_intersect_rectangles (&r_save, &rc, &r);
1969 }
1970 }
1971 else
1972 {
1973 /* Don't use S->y for clipping because it doesn't take partially
1974 visible lines into account. For example, it can be negative for
1975 partially visible lines at the top of a window. */
1976 if (!s->row->full_width_p
1977 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1978 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1979 else
1980 r.y = max (0, s->row->y);
1981 }
1982
1983 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1984
1985 /* If drawing the cursor, don't let glyph draw outside its
1986 advertised boundaries. Cleartype does this under some circumstances. */
1987 if (s->hl == DRAW_CURSOR)
1988 {
1989 struct glyph *glyph = s->first_glyph;
1990 int height, max_y;
1991
1992 if (s->x > r.x)
1993 {
1994 r.width -= s->x - r.x;
1995 r.x = s->x;
1996 }
1997 r.width = min (r.width, glyph->pixel_width);
1998
1999 /* If r.y is below window bottom, ensure that we still see a cursor. */
2000 height = min (glyph->ascent + glyph->descent,
2001 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2002 max_y = window_text_bottom_y (s->w) - height;
2003 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2004 if (s->ybase - glyph->ascent > max_y)
2005 {
2006 r.y = max_y;
2007 r.height = height;
2008 }
2009 else
2010 {
2011 /* Don't draw cursor glyph taller than our actual glyph. */
2012 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2013 if (height < r.height)
2014 {
2015 max_y = r.y + r.height;
2016 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2017 r.height = min (max_y - r.y, height);
2018 }
2019 }
2020 }
2021
2022 if (s->row->clip)
2023 {
2024 XRectangle r_save = r;
2025
2026 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2027 r.width = 0;
2028 }
2029
2030 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2031 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2032 {
2033 #ifdef CONVERT_FROM_XRECT
2034 CONVERT_FROM_XRECT (r, *rects);
2035 #else
2036 *rects = r;
2037 #endif
2038 return 1;
2039 }
2040 else
2041 {
2042 /* If we are processing overlapping and allowed to return
2043 multiple clipping rectangles, we exclude the row of the glyph
2044 string from the clipping rectangle. This is to avoid drawing
2045 the same text on the environment with anti-aliasing. */
2046 #ifdef CONVERT_FROM_XRECT
2047 XRectangle rs[2];
2048 #else
2049 XRectangle *rs = rects;
2050 #endif
2051 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2052
2053 if (s->for_overlaps & OVERLAPS_PRED)
2054 {
2055 rs[i] = r;
2056 if (r.y + r.height > row_y)
2057 {
2058 if (r.y < row_y)
2059 rs[i].height = row_y - r.y;
2060 else
2061 rs[i].height = 0;
2062 }
2063 i++;
2064 }
2065 if (s->for_overlaps & OVERLAPS_SUCC)
2066 {
2067 rs[i] = r;
2068 if (r.y < row_y + s->row->visible_height)
2069 {
2070 if (r.y + r.height > row_y + s->row->visible_height)
2071 {
2072 rs[i].y = row_y + s->row->visible_height;
2073 rs[i].height = r.y + r.height - rs[i].y;
2074 }
2075 else
2076 rs[i].height = 0;
2077 }
2078 i++;
2079 }
2080
2081 n = i;
2082 #ifdef CONVERT_FROM_XRECT
2083 for (i = 0; i < n; i++)
2084 CONVERT_FROM_XRECT (rs[i], rects[i]);
2085 #endif
2086 return n;
2087 }
2088 }
2089
2090 /* EXPORT:
2091 Return in *NR the clipping rectangle for glyph string S. */
2092
2093 void
2094 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2095 {
2096 get_glyph_string_clip_rects (s, nr, 1);
2097 }
2098
2099
2100 /* EXPORT:
2101 Return the position and height of the phys cursor in window W.
2102 Set w->phys_cursor_width to width of phys cursor.
2103 */
2104
2105 void
2106 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2107 struct glyph *glyph, int *xp, int *yp, int *heightp)
2108 {
2109 struct frame *f = XFRAME (WINDOW_FRAME (w));
2110 int x, y, wd, h, h0, y0;
2111
2112 /* Compute the width of the rectangle to draw. If on a stretch
2113 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2114 rectangle as wide as the glyph, but use a canonical character
2115 width instead. */
2116 wd = glyph->pixel_width - 1;
2117 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2118 wd++; /* Why? */
2119 #endif
2120
2121 x = w->phys_cursor.x;
2122 if (x < 0)
2123 {
2124 wd += x;
2125 x = 0;
2126 }
2127
2128 if (glyph->type == STRETCH_GLYPH
2129 && !x_stretch_cursor_p)
2130 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2131 w->phys_cursor_width = wd;
2132
2133 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2134
2135 /* If y is below window bottom, ensure that we still see a cursor. */
2136 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2137
2138 h = max (h0, glyph->ascent + glyph->descent);
2139 h0 = min (h0, glyph->ascent + glyph->descent);
2140
2141 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2142 if (y < y0)
2143 {
2144 h = max (h - (y0 - y) + 1, h0);
2145 y = y0 - 1;
2146 }
2147 else
2148 {
2149 y0 = window_text_bottom_y (w) - h0;
2150 if (y > y0)
2151 {
2152 h += y - y0;
2153 y = y0;
2154 }
2155 }
2156
2157 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2158 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2159 *heightp = h;
2160 }
2161
2162 /*
2163 * Remember which glyph the mouse is over.
2164 */
2165
2166 void
2167 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2168 {
2169 Lisp_Object window;
2170 struct window *w;
2171 struct glyph_row *r, *gr, *end_row;
2172 enum window_part part;
2173 enum glyph_row_area area;
2174 int x, y, width, height;
2175
2176 /* Try to determine frame pixel position and size of the glyph under
2177 frame pixel coordinates X/Y on frame F. */
2178
2179 if (!f->glyphs_initialized_p
2180 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2181 NILP (window)))
2182 {
2183 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2184 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2185 goto virtual_glyph;
2186 }
2187
2188 w = XWINDOW (window);
2189 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2190 height = WINDOW_FRAME_LINE_HEIGHT (w);
2191
2192 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2193 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2194
2195 if (w->pseudo_window_p)
2196 {
2197 area = TEXT_AREA;
2198 part = ON_MODE_LINE; /* Don't adjust margin. */
2199 goto text_glyph;
2200 }
2201
2202 switch (part)
2203 {
2204 case ON_LEFT_MARGIN:
2205 area = LEFT_MARGIN_AREA;
2206 goto text_glyph;
2207
2208 case ON_RIGHT_MARGIN:
2209 area = RIGHT_MARGIN_AREA;
2210 goto text_glyph;
2211
2212 case ON_HEADER_LINE:
2213 case ON_MODE_LINE:
2214 gr = (part == ON_HEADER_LINE
2215 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2216 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2217 gy = gr->y;
2218 area = TEXT_AREA;
2219 goto text_glyph_row_found;
2220
2221 case ON_TEXT:
2222 area = TEXT_AREA;
2223
2224 text_glyph:
2225 gr = 0; gy = 0;
2226 for (; r <= end_row && r->enabled_p; ++r)
2227 if (r->y + r->height > y)
2228 {
2229 gr = r; gy = r->y;
2230 break;
2231 }
2232
2233 text_glyph_row_found:
2234 if (gr && gy <= y)
2235 {
2236 struct glyph *g = gr->glyphs[area];
2237 struct glyph *end = g + gr->used[area];
2238
2239 height = gr->height;
2240 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2241 if (gx + g->pixel_width > x)
2242 break;
2243
2244 if (g < end)
2245 {
2246 if (g->type == IMAGE_GLYPH)
2247 {
2248 /* Don't remember when mouse is over image, as
2249 image may have hot-spots. */
2250 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2251 return;
2252 }
2253 width = g->pixel_width;
2254 }
2255 else
2256 {
2257 /* Use nominal char spacing at end of line. */
2258 x -= gx;
2259 gx += (x / width) * width;
2260 }
2261
2262 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2263 gx += window_box_left_offset (w, area);
2264 }
2265 else
2266 {
2267 /* Use nominal line height at end of window. */
2268 gx = (x / width) * width;
2269 y -= gy;
2270 gy += (y / height) * height;
2271 }
2272 break;
2273
2274 case ON_LEFT_FRINGE:
2275 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2276 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2277 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2278 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2279 goto row_glyph;
2280
2281 case ON_RIGHT_FRINGE:
2282 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2283 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2284 : window_box_right_offset (w, TEXT_AREA));
2285 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2286 goto row_glyph;
2287
2288 case ON_SCROLL_BAR:
2289 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2290 ? 0
2291 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2292 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2293 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2294 : 0)));
2295 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2296
2297 row_glyph:
2298 gr = 0, gy = 0;
2299 for (; r <= end_row && r->enabled_p; ++r)
2300 if (r->y + r->height > y)
2301 {
2302 gr = r; gy = r->y;
2303 break;
2304 }
2305
2306 if (gr && gy <= y)
2307 height = gr->height;
2308 else
2309 {
2310 /* Use nominal line height at end of window. */
2311 y -= gy;
2312 gy += (y / height) * height;
2313 }
2314 break;
2315
2316 default:
2317 ;
2318 virtual_glyph:
2319 /* If there is no glyph under the mouse, then we divide the screen
2320 into a grid of the smallest glyph in the frame, and use that
2321 as our "glyph". */
2322
2323 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2324 round down even for negative values. */
2325 if (gx < 0)
2326 gx -= width - 1;
2327 if (gy < 0)
2328 gy -= height - 1;
2329
2330 gx = (gx / width) * width;
2331 gy = (gy / height) * height;
2332
2333 goto store_rect;
2334 }
2335
2336 gx += WINDOW_LEFT_EDGE_X (w);
2337 gy += WINDOW_TOP_EDGE_Y (w);
2338
2339 store_rect:
2340 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2341
2342 /* Visible feedback for debugging. */
2343 #if 0
2344 #if HAVE_X_WINDOWS
2345 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2346 f->output_data.x->normal_gc,
2347 gx, gy, width, height);
2348 #endif
2349 #endif
2350 }
2351
2352
2353 #endif /* HAVE_WINDOW_SYSTEM */
2354
2355 \f
2356 /***********************************************************************
2357 Lisp form evaluation
2358 ***********************************************************************/
2359
2360 /* Error handler for safe_eval and safe_call. */
2361
2362 static Lisp_Object
2363 safe_eval_handler (Lisp_Object arg)
2364 {
2365 add_to_log ("Error during redisplay: %s", arg, Qnil);
2366 return Qnil;
2367 }
2368
2369
2370 /* Evaluate SEXPR and return the result, or nil if something went
2371 wrong. Prevent redisplay during the evaluation. */
2372
2373 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2374 Return the result, or nil if something went wrong. Prevent
2375 redisplay during the evaluation. */
2376
2377 Lisp_Object
2378 safe_call (int nargs, Lisp_Object *args)
2379 {
2380 Lisp_Object val;
2381
2382 if (inhibit_eval_during_redisplay)
2383 val = Qnil;
2384 else
2385 {
2386 int count = SPECPDL_INDEX ();
2387 struct gcpro gcpro1;
2388
2389 GCPRO1 (args[0]);
2390 gcpro1.nvars = nargs;
2391 specbind (Qinhibit_redisplay, Qt);
2392 /* Use Qt to ensure debugger does not run,
2393 so there is no possibility of wanting to redisplay. */
2394 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2395 safe_eval_handler);
2396 UNGCPRO;
2397 val = unbind_to (count, val);
2398 }
2399
2400 return val;
2401 }
2402
2403
2404 /* Call function FN with one argument ARG.
2405 Return the result, or nil if something went wrong. */
2406
2407 Lisp_Object
2408 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2409 {
2410 Lisp_Object args[2];
2411 args[0] = fn;
2412 args[1] = arg;
2413 return safe_call (2, args);
2414 }
2415
2416 static Lisp_Object Qeval;
2417
2418 Lisp_Object
2419 safe_eval (Lisp_Object sexpr)
2420 {
2421 return safe_call1 (Qeval, sexpr);
2422 }
2423
2424 /* Call function FN with one argument ARG.
2425 Return the result, or nil if something went wrong. */
2426
2427 Lisp_Object
2428 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2429 {
2430 Lisp_Object args[3];
2431 args[0] = fn;
2432 args[1] = arg1;
2433 args[2] = arg2;
2434 return safe_call (3, args);
2435 }
2436
2437
2438 \f
2439 /***********************************************************************
2440 Debugging
2441 ***********************************************************************/
2442
2443 #if 0
2444
2445 /* Define CHECK_IT to perform sanity checks on iterators.
2446 This is for debugging. It is too slow to do unconditionally. */
2447
2448 static void
2449 check_it (it)
2450 struct it *it;
2451 {
2452 if (it->method == GET_FROM_STRING)
2453 {
2454 xassert (STRINGP (it->string));
2455 xassert (IT_STRING_CHARPOS (*it) >= 0);
2456 }
2457 else
2458 {
2459 xassert (IT_STRING_CHARPOS (*it) < 0);
2460 if (it->method == GET_FROM_BUFFER)
2461 {
2462 /* Check that character and byte positions agree. */
2463 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2464 }
2465 }
2466
2467 if (it->dpvec)
2468 xassert (it->current.dpvec_index >= 0);
2469 else
2470 xassert (it->current.dpvec_index < 0);
2471 }
2472
2473 #define CHECK_IT(IT) check_it ((IT))
2474
2475 #else /* not 0 */
2476
2477 #define CHECK_IT(IT) (void) 0
2478
2479 #endif /* not 0 */
2480
2481
2482 #if GLYPH_DEBUG
2483
2484 /* Check that the window end of window W is what we expect it
2485 to be---the last row in the current matrix displaying text. */
2486
2487 static void
2488 check_window_end (w)
2489 struct window *w;
2490 {
2491 if (!MINI_WINDOW_P (w)
2492 && !NILP (w->window_end_valid))
2493 {
2494 struct glyph_row *row;
2495 xassert ((row = MATRIX_ROW (w->current_matrix,
2496 XFASTINT (w->window_end_vpos)),
2497 !row->enabled_p
2498 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2499 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2500 }
2501 }
2502
2503 #define CHECK_WINDOW_END(W) check_window_end ((W))
2504
2505 #else /* not GLYPH_DEBUG */
2506
2507 #define CHECK_WINDOW_END(W) (void) 0
2508
2509 #endif /* not GLYPH_DEBUG */
2510
2511
2512 \f
2513 /***********************************************************************
2514 Iterator initialization
2515 ***********************************************************************/
2516
2517 /* Initialize IT for displaying current_buffer in window W, starting
2518 at character position CHARPOS. CHARPOS < 0 means that no buffer
2519 position is specified which is useful when the iterator is assigned
2520 a position later. BYTEPOS is the byte position corresponding to
2521 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2522
2523 If ROW is not null, calls to produce_glyphs with IT as parameter
2524 will produce glyphs in that row.
2525
2526 BASE_FACE_ID is the id of a base face to use. It must be one of
2527 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2528 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2529 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2530
2531 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2532 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2533 will be initialized to use the corresponding mode line glyph row of
2534 the desired matrix of W. */
2535
2536 void
2537 init_iterator (struct it *it, struct window *w,
2538 EMACS_INT charpos, EMACS_INT bytepos,
2539 struct glyph_row *row, enum face_id base_face_id)
2540 {
2541 int highlight_region_p;
2542 enum face_id remapped_base_face_id = base_face_id;
2543
2544 /* Some precondition checks. */
2545 xassert (w != NULL && it != NULL);
2546 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2547 && charpos <= ZV));
2548
2549 /* If face attributes have been changed since the last redisplay,
2550 free realized faces now because they depend on face definitions
2551 that might have changed. Don't free faces while there might be
2552 desired matrices pending which reference these faces. */
2553 if (face_change_count && !inhibit_free_realized_faces)
2554 {
2555 face_change_count = 0;
2556 free_all_realized_faces (Qnil);
2557 }
2558
2559 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2560 if (! NILP (Vface_remapping_alist))
2561 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2562
2563 /* Use one of the mode line rows of W's desired matrix if
2564 appropriate. */
2565 if (row == NULL)
2566 {
2567 if (base_face_id == MODE_LINE_FACE_ID
2568 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2569 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2570 else if (base_face_id == HEADER_LINE_FACE_ID)
2571 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2572 }
2573
2574 /* Clear IT. */
2575 memset (it, 0, sizeof *it);
2576 it->current.overlay_string_index = -1;
2577 it->current.dpvec_index = -1;
2578 it->base_face_id = remapped_base_face_id;
2579 it->string = Qnil;
2580 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2581
2582 /* The window in which we iterate over current_buffer: */
2583 XSETWINDOW (it->window, w);
2584 it->w = w;
2585 it->f = XFRAME (w->frame);
2586
2587 it->cmp_it.id = -1;
2588
2589 /* Extra space between lines (on window systems only). */
2590 if (base_face_id == DEFAULT_FACE_ID
2591 && FRAME_WINDOW_P (it->f))
2592 {
2593 if (NATNUMP (current_buffer->extra_line_spacing))
2594 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2595 else if (FLOATP (current_buffer->extra_line_spacing))
2596 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2597 * FRAME_LINE_HEIGHT (it->f));
2598 else if (it->f->extra_line_spacing > 0)
2599 it->extra_line_spacing = it->f->extra_line_spacing;
2600 it->max_extra_line_spacing = 0;
2601 }
2602
2603 /* If realized faces have been removed, e.g. because of face
2604 attribute changes of named faces, recompute them. When running
2605 in batch mode, the face cache of the initial frame is null. If
2606 we happen to get called, make a dummy face cache. */
2607 if (FRAME_FACE_CACHE (it->f) == NULL)
2608 init_frame_faces (it->f);
2609 if (FRAME_FACE_CACHE (it->f)->used == 0)
2610 recompute_basic_faces (it->f);
2611
2612 /* Current value of the `slice', `space-width', and 'height' properties. */
2613 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2614 it->space_width = Qnil;
2615 it->font_height = Qnil;
2616 it->override_ascent = -1;
2617
2618 /* Are control characters displayed as `^C'? */
2619 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2620
2621 /* -1 means everything between a CR and the following line end
2622 is invisible. >0 means lines indented more than this value are
2623 invisible. */
2624 it->selective = (INTEGERP (current_buffer->selective_display)
2625 ? XFASTINT (current_buffer->selective_display)
2626 : (!NILP (current_buffer->selective_display)
2627 ? -1 : 0));
2628 it->selective_display_ellipsis_p
2629 = !NILP (current_buffer->selective_display_ellipses);
2630
2631 /* Display table to use. */
2632 it->dp = window_display_table (w);
2633
2634 /* Are multibyte characters enabled in current_buffer? */
2635 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2636
2637 /* Do we need to reorder bidirectional text? Not if this is a
2638 unibyte buffer: by definition, none of the single-byte characters
2639 are strong R2L, so no reordering is needed. And bidi.c doesn't
2640 support unibyte buffers anyway. */
2641 it->bidi_p
2642 = !NILP (current_buffer->bidi_display_reordering) && it->multibyte_p;
2643
2644 /* Non-zero if we should highlight the region. */
2645 highlight_region_p
2646 = (!NILP (Vtransient_mark_mode)
2647 && !NILP (current_buffer->mark_active)
2648 && XMARKER (current_buffer->mark)->buffer != 0);
2649
2650 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2651 start and end of a visible region in window IT->w. Set both to
2652 -1 to indicate no region. */
2653 if (highlight_region_p
2654 /* Maybe highlight only in selected window. */
2655 && (/* Either show region everywhere. */
2656 highlight_nonselected_windows
2657 /* Or show region in the selected window. */
2658 || w == XWINDOW (selected_window)
2659 /* Or show the region if we are in the mini-buffer and W is
2660 the window the mini-buffer refers to. */
2661 || (MINI_WINDOW_P (XWINDOW (selected_window))
2662 && WINDOWP (minibuf_selected_window)
2663 && w == XWINDOW (minibuf_selected_window))))
2664 {
2665 int charpos = marker_position (current_buffer->mark);
2666 it->region_beg_charpos = min (PT, charpos);
2667 it->region_end_charpos = max (PT, charpos);
2668 }
2669 else
2670 it->region_beg_charpos = it->region_end_charpos = -1;
2671
2672 /* Get the position at which the redisplay_end_trigger hook should
2673 be run, if it is to be run at all. */
2674 if (MARKERP (w->redisplay_end_trigger)
2675 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2676 it->redisplay_end_trigger_charpos
2677 = marker_position (w->redisplay_end_trigger);
2678 else if (INTEGERP (w->redisplay_end_trigger))
2679 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2680
2681 /* Correct bogus values of tab_width. */
2682 it->tab_width = XINT (current_buffer->tab_width);
2683 if (it->tab_width <= 0 || it->tab_width > 1000)
2684 it->tab_width = 8;
2685
2686 /* Are lines in the display truncated? */
2687 if (base_face_id != DEFAULT_FACE_ID
2688 || XINT (it->w->hscroll)
2689 || (! WINDOW_FULL_WIDTH_P (it->w)
2690 && ((!NILP (Vtruncate_partial_width_windows)
2691 && !INTEGERP (Vtruncate_partial_width_windows))
2692 || (INTEGERP (Vtruncate_partial_width_windows)
2693 && (WINDOW_TOTAL_COLS (it->w)
2694 < XINT (Vtruncate_partial_width_windows))))))
2695 it->line_wrap = TRUNCATE;
2696 else if (NILP (current_buffer->truncate_lines))
2697 it->line_wrap = NILP (current_buffer->word_wrap)
2698 ? WINDOW_WRAP : WORD_WRAP;
2699 else
2700 it->line_wrap = TRUNCATE;
2701
2702 /* Get dimensions of truncation and continuation glyphs. These are
2703 displayed as fringe bitmaps under X, so we don't need them for such
2704 frames. */
2705 if (!FRAME_WINDOW_P (it->f))
2706 {
2707 if (it->line_wrap == TRUNCATE)
2708 {
2709 /* We will need the truncation glyph. */
2710 xassert (it->glyph_row == NULL);
2711 produce_special_glyphs (it, IT_TRUNCATION);
2712 it->truncation_pixel_width = it->pixel_width;
2713 }
2714 else
2715 {
2716 /* We will need the continuation glyph. */
2717 xassert (it->glyph_row == NULL);
2718 produce_special_glyphs (it, IT_CONTINUATION);
2719 it->continuation_pixel_width = it->pixel_width;
2720 }
2721
2722 /* Reset these values to zero because the produce_special_glyphs
2723 above has changed them. */
2724 it->pixel_width = it->ascent = it->descent = 0;
2725 it->phys_ascent = it->phys_descent = 0;
2726 }
2727
2728 /* Set this after getting the dimensions of truncation and
2729 continuation glyphs, so that we don't produce glyphs when calling
2730 produce_special_glyphs, above. */
2731 it->glyph_row = row;
2732 it->area = TEXT_AREA;
2733
2734 /* Forget any previous info about this row being reversed. */
2735 if (it->glyph_row)
2736 it->glyph_row->reversed_p = 0;
2737
2738 /* Get the dimensions of the display area. The display area
2739 consists of the visible window area plus a horizontally scrolled
2740 part to the left of the window. All x-values are relative to the
2741 start of this total display area. */
2742 if (base_face_id != DEFAULT_FACE_ID)
2743 {
2744 /* Mode lines, menu bar in terminal frames. */
2745 it->first_visible_x = 0;
2746 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2747 }
2748 else
2749 {
2750 it->first_visible_x
2751 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2752 it->last_visible_x = (it->first_visible_x
2753 + window_box_width (w, TEXT_AREA));
2754
2755 /* If we truncate lines, leave room for the truncator glyph(s) at
2756 the right margin. Otherwise, leave room for the continuation
2757 glyph(s). Truncation and continuation glyphs are not inserted
2758 for window-based redisplay. */
2759 if (!FRAME_WINDOW_P (it->f))
2760 {
2761 if (it->line_wrap == TRUNCATE)
2762 it->last_visible_x -= it->truncation_pixel_width;
2763 else
2764 it->last_visible_x -= it->continuation_pixel_width;
2765 }
2766
2767 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2768 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2769 }
2770
2771 /* Leave room for a border glyph. */
2772 if (!FRAME_WINDOW_P (it->f)
2773 && !WINDOW_RIGHTMOST_P (it->w))
2774 it->last_visible_x -= 1;
2775
2776 it->last_visible_y = window_text_bottom_y (w);
2777
2778 /* For mode lines and alike, arrange for the first glyph having a
2779 left box line if the face specifies a box. */
2780 if (base_face_id != DEFAULT_FACE_ID)
2781 {
2782 struct face *face;
2783
2784 it->face_id = remapped_base_face_id;
2785
2786 /* If we have a boxed mode line, make the first character appear
2787 with a left box line. */
2788 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2789 if (face->box != FACE_NO_BOX)
2790 it->start_of_box_run_p = 1;
2791 }
2792
2793 /* If we are to reorder bidirectional text, init the bidi
2794 iterator. */
2795 if (it->bidi_p)
2796 {
2797 /* Note the paragraph direction that this buffer wants to
2798 use. */
2799 if (EQ (current_buffer->bidi_paragraph_direction, Qleft_to_right))
2800 it->paragraph_embedding = L2R;
2801 else if (EQ (current_buffer->bidi_paragraph_direction, Qright_to_left))
2802 it->paragraph_embedding = R2L;
2803 else
2804 it->paragraph_embedding = NEUTRAL_DIR;
2805 bidi_init_it (charpos, bytepos, &it->bidi_it);
2806 }
2807
2808 /* If a buffer position was specified, set the iterator there,
2809 getting overlays and face properties from that position. */
2810 if (charpos >= BUF_BEG (current_buffer))
2811 {
2812 it->end_charpos = ZV;
2813 it->face_id = -1;
2814 IT_CHARPOS (*it) = charpos;
2815
2816 /* Compute byte position if not specified. */
2817 if (bytepos < charpos)
2818 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2819 else
2820 IT_BYTEPOS (*it) = bytepos;
2821
2822 it->start = it->current;
2823
2824 /* Compute faces etc. */
2825 reseat (it, it->current.pos, 1);
2826 }
2827
2828 CHECK_IT (it);
2829 }
2830
2831
2832 /* Initialize IT for the display of window W with window start POS. */
2833
2834 void
2835 start_display (struct it *it, struct window *w, 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 (struct display_pos *pos, struct window *w)
2908 {
2909 Lisp_Object prop, window;
2910 int ellipses_p = 0;
2911 int charpos = CHARPOS (pos->pos);
2912
2913 /* If POS specifies a position in a display vector, this might
2914 be for an ellipsis displayed for invisible text. We won't
2915 get the iterator set up for delivering that ellipsis unless
2916 we make sure that it gets aware of the invisible text. */
2917 if (pos->dpvec_index >= 0
2918 && pos->overlay_string_index < 0
2919 && CHARPOS (pos->string_pos) < 0
2920 && charpos > BEGV
2921 && (XSETWINDOW (window, w),
2922 prop = Fget_char_property (make_number (charpos),
2923 Qinvisible, window),
2924 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2925 {
2926 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2927 window);
2928 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2929 }
2930
2931 return ellipses_p;
2932 }
2933
2934
2935 /* Initialize IT for stepping through current_buffer in window W,
2936 starting at position POS that includes overlay string and display
2937 vector/ control character translation position information. Value
2938 is zero if there are overlay strings with newlines at POS. */
2939
2940 static int
2941 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2942 {
2943 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2944 int i, overlay_strings_with_newlines = 0;
2945
2946 /* If POS specifies a position in a display vector, this might
2947 be for an ellipsis displayed for invisible text. We won't
2948 get the iterator set up for delivering that ellipsis unless
2949 we make sure that it gets aware of the invisible text. */
2950 if (in_ellipses_for_invisible_text_p (pos, w))
2951 {
2952 --charpos;
2953 bytepos = 0;
2954 }
2955
2956 /* Keep in mind: the call to reseat in init_iterator skips invisible
2957 text, so we might end up at a position different from POS. This
2958 is only a problem when POS is a row start after a newline and an
2959 overlay starts there with an after-string, and the overlay has an
2960 invisible property. Since we don't skip invisible text in
2961 display_line and elsewhere immediately after consuming the
2962 newline before the row start, such a POS will not be in a string,
2963 but the call to init_iterator below will move us to the
2964 after-string. */
2965 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2966
2967 /* This only scans the current chunk -- it should scan all chunks.
2968 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2969 to 16 in 22.1 to make this a lesser problem. */
2970 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2971 {
2972 const char *s = SDATA (it->overlay_strings[i]);
2973 const char *e = s + SBYTES (it->overlay_strings[i]);
2974
2975 while (s < e && *s != '\n')
2976 ++s;
2977
2978 if (s < e)
2979 {
2980 overlay_strings_with_newlines = 1;
2981 break;
2982 }
2983 }
2984
2985 /* If position is within an overlay string, set up IT to the right
2986 overlay string. */
2987 if (pos->overlay_string_index >= 0)
2988 {
2989 int relative_index;
2990
2991 /* If the first overlay string happens to have a `display'
2992 property for an image, the iterator will be set up for that
2993 image, and we have to undo that setup first before we can
2994 correct the overlay string index. */
2995 if (it->method == GET_FROM_IMAGE)
2996 pop_it (it);
2997
2998 /* We already have the first chunk of overlay strings in
2999 IT->overlay_strings. Load more until the one for
3000 pos->overlay_string_index is in IT->overlay_strings. */
3001 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3002 {
3003 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3004 it->current.overlay_string_index = 0;
3005 while (n--)
3006 {
3007 load_overlay_strings (it, 0);
3008 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3009 }
3010 }
3011
3012 it->current.overlay_string_index = pos->overlay_string_index;
3013 relative_index = (it->current.overlay_string_index
3014 % OVERLAY_STRING_CHUNK_SIZE);
3015 it->string = it->overlay_strings[relative_index];
3016 xassert (STRINGP (it->string));
3017 it->current.string_pos = pos->string_pos;
3018 it->method = GET_FROM_STRING;
3019 }
3020
3021 if (CHARPOS (pos->string_pos) >= 0)
3022 {
3023 /* Recorded position is not in an overlay string, but in another
3024 string. This can only be a string from a `display' property.
3025 IT should already be filled with that string. */
3026 it->current.string_pos = pos->string_pos;
3027 xassert (STRINGP (it->string));
3028 }
3029
3030 /* Restore position in display vector translations, control
3031 character translations or ellipses. */
3032 if (pos->dpvec_index >= 0)
3033 {
3034 if (it->dpvec == NULL)
3035 get_next_display_element (it);
3036 xassert (it->dpvec && it->current.dpvec_index == 0);
3037 it->current.dpvec_index = pos->dpvec_index;
3038 }
3039
3040 CHECK_IT (it);
3041 return !overlay_strings_with_newlines;
3042 }
3043
3044
3045 /* Initialize IT for stepping through current_buffer in window W
3046 starting at ROW->start. */
3047
3048 static void
3049 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3050 {
3051 init_from_display_pos (it, w, &row->start);
3052 it->start = row->start;
3053 it->continuation_lines_width = row->continuation_lines_width;
3054 CHECK_IT (it);
3055 }
3056
3057
3058 /* Initialize IT for stepping through current_buffer in window W
3059 starting in the line following ROW, i.e. starting at ROW->end.
3060 Value is zero if there are overlay strings with newlines at ROW's
3061 end position. */
3062
3063 static int
3064 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3065 {
3066 int success = 0;
3067
3068 if (init_from_display_pos (it, w, &row->end))
3069 {
3070 if (row->continued_p)
3071 it->continuation_lines_width
3072 = row->continuation_lines_width + row->pixel_width;
3073 CHECK_IT (it);
3074 success = 1;
3075 }
3076
3077 return success;
3078 }
3079
3080
3081
3082 \f
3083 /***********************************************************************
3084 Text properties
3085 ***********************************************************************/
3086
3087 /* Called when IT reaches IT->stop_charpos. Handle text property and
3088 overlay changes. Set IT->stop_charpos to the next position where
3089 to stop. */
3090
3091 static void
3092 handle_stop (struct it *it)
3093 {
3094 enum prop_handled handled;
3095 int handle_overlay_change_p;
3096 struct props *p;
3097
3098 it->dpvec = NULL;
3099 it->current.dpvec_index = -1;
3100 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3101 it->ignore_overlay_strings_at_pos_p = 0;
3102 it->ellipsis_p = 0;
3103
3104 /* Use face of preceding text for ellipsis (if invisible) */
3105 if (it->selective_display_ellipsis_p)
3106 it->saved_face_id = it->face_id;
3107
3108 do
3109 {
3110 handled = HANDLED_NORMALLY;
3111
3112 /* Call text property handlers. */
3113 for (p = it_props; p->handler; ++p)
3114 {
3115 handled = p->handler (it);
3116
3117 if (handled == HANDLED_RECOMPUTE_PROPS)
3118 break;
3119 else if (handled == HANDLED_RETURN)
3120 {
3121 /* We still want to show before and after strings from
3122 overlays even if the actual buffer text is replaced. */
3123 if (!handle_overlay_change_p
3124 || it->sp > 1
3125 || !get_overlay_strings_1 (it, 0, 0))
3126 {
3127 if (it->ellipsis_p)
3128 setup_for_ellipsis (it, 0);
3129 /* When handling a display spec, we might load an
3130 empty string. In that case, discard it here. We
3131 used to discard it in handle_single_display_spec,
3132 but that causes get_overlay_strings_1, above, to
3133 ignore overlay strings that we must check. */
3134 if (STRINGP (it->string) && !SCHARS (it->string))
3135 pop_it (it);
3136 return;
3137 }
3138 else if (STRINGP (it->string) && !SCHARS (it->string))
3139 pop_it (it);
3140 else
3141 {
3142 it->ignore_overlay_strings_at_pos_p = 1;
3143 it->string_from_display_prop_p = 0;
3144 handle_overlay_change_p = 0;
3145 }
3146 handled = HANDLED_RECOMPUTE_PROPS;
3147 break;
3148 }
3149 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3150 handle_overlay_change_p = 0;
3151 }
3152
3153 if (handled != HANDLED_RECOMPUTE_PROPS)
3154 {
3155 /* Don't check for overlay strings below when set to deliver
3156 characters from a display vector. */
3157 if (it->method == GET_FROM_DISPLAY_VECTOR)
3158 handle_overlay_change_p = 0;
3159
3160 /* Handle overlay changes.
3161 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3162 if it finds overlays. */
3163 if (handle_overlay_change_p)
3164 handled = handle_overlay_change (it);
3165 }
3166
3167 if (it->ellipsis_p)
3168 {
3169 setup_for_ellipsis (it, 0);
3170 break;
3171 }
3172 }
3173 while (handled == HANDLED_RECOMPUTE_PROPS);
3174
3175 /* Determine where to stop next. */
3176 if (handled == HANDLED_NORMALLY)
3177 compute_stop_pos (it);
3178 }
3179
3180
3181 /* Compute IT->stop_charpos from text property and overlay change
3182 information for IT's current position. */
3183
3184 static void
3185 compute_stop_pos (struct it *it)
3186 {
3187 register INTERVAL iv, next_iv;
3188 Lisp_Object object, limit, position;
3189 EMACS_INT charpos, bytepos;
3190
3191 /* If nowhere else, stop at the end. */
3192 it->stop_charpos = it->end_charpos;
3193
3194 if (STRINGP (it->string))
3195 {
3196 /* Strings are usually short, so don't limit the search for
3197 properties. */
3198 object = it->string;
3199 limit = Qnil;
3200 charpos = IT_STRING_CHARPOS (*it);
3201 bytepos = IT_STRING_BYTEPOS (*it);
3202 }
3203 else
3204 {
3205 EMACS_INT pos;
3206
3207 /* If next overlay change is in front of the current stop pos
3208 (which is IT->end_charpos), stop there. Note: value of
3209 next_overlay_change is point-max if no overlay change
3210 follows. */
3211 charpos = IT_CHARPOS (*it);
3212 bytepos = IT_BYTEPOS (*it);
3213 pos = next_overlay_change (charpos);
3214 if (pos < it->stop_charpos)
3215 it->stop_charpos = pos;
3216
3217 /* If showing the region, we have to stop at the region
3218 start or end because the face might change there. */
3219 if (it->region_beg_charpos > 0)
3220 {
3221 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3222 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3223 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3224 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3225 }
3226
3227 /* Set up variables for computing the stop position from text
3228 property changes. */
3229 XSETBUFFER (object, current_buffer);
3230 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3231 }
3232
3233 /* Get the interval containing IT's position. Value is a null
3234 interval if there isn't such an interval. */
3235 position = make_number (charpos);
3236 iv = validate_interval_range (object, &position, &position, 0);
3237 if (!NULL_INTERVAL_P (iv))
3238 {
3239 Lisp_Object values_here[LAST_PROP_IDX];
3240 struct props *p;
3241
3242 /* Get properties here. */
3243 for (p = it_props; p->handler; ++p)
3244 values_here[p->idx] = textget (iv->plist, *p->name);
3245
3246 /* Look for an interval following iv that has different
3247 properties. */
3248 for (next_iv = next_interval (iv);
3249 (!NULL_INTERVAL_P (next_iv)
3250 && (NILP (limit)
3251 || XFASTINT (limit) > next_iv->position));
3252 next_iv = next_interval (next_iv))
3253 {
3254 for (p = it_props; p->handler; ++p)
3255 {
3256 Lisp_Object new_value;
3257
3258 new_value = textget (next_iv->plist, *p->name);
3259 if (!EQ (values_here[p->idx], new_value))
3260 break;
3261 }
3262
3263 if (p->handler)
3264 break;
3265 }
3266
3267 if (!NULL_INTERVAL_P (next_iv))
3268 {
3269 if (INTEGERP (limit)
3270 && next_iv->position >= XFASTINT (limit))
3271 /* No text property change up to limit. */
3272 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3273 else
3274 /* Text properties change in next_iv. */
3275 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3276 }
3277 }
3278
3279 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3280 it->stop_charpos, it->string);
3281
3282 xassert (STRINGP (it->string)
3283 || (it->stop_charpos >= BEGV
3284 && it->stop_charpos >= IT_CHARPOS (*it)));
3285 }
3286
3287
3288 /* Return the position of the next overlay change after POS in
3289 current_buffer. Value is point-max if no overlay change
3290 follows. This is like `next-overlay-change' but doesn't use
3291 xmalloc. */
3292
3293 static EMACS_INT
3294 next_overlay_change (EMACS_INT pos)
3295 {
3296 int noverlays;
3297 EMACS_INT endpos;
3298 Lisp_Object *overlays;
3299 int i;
3300
3301 /* Get all overlays at the given position. */
3302 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3303
3304 /* If any of these overlays ends before endpos,
3305 use its ending point instead. */
3306 for (i = 0; i < noverlays; ++i)
3307 {
3308 Lisp_Object oend;
3309 EMACS_INT oendpos;
3310
3311 oend = OVERLAY_END (overlays[i]);
3312 oendpos = OVERLAY_POSITION (oend);
3313 endpos = min (endpos, oendpos);
3314 }
3315
3316 return endpos;
3317 }
3318
3319
3320 \f
3321 /***********************************************************************
3322 Fontification
3323 ***********************************************************************/
3324
3325 /* Handle changes in the `fontified' property of the current buffer by
3326 calling hook functions from Qfontification_functions to fontify
3327 regions of text. */
3328
3329 static enum prop_handled
3330 handle_fontified_prop (struct it *it)
3331 {
3332 Lisp_Object prop, pos;
3333 enum prop_handled handled = HANDLED_NORMALLY;
3334
3335 if (!NILP (Vmemory_full))
3336 return handled;
3337
3338 /* Get the value of the `fontified' property at IT's current buffer
3339 position. (The `fontified' property doesn't have a special
3340 meaning in strings.) If the value is nil, call functions from
3341 Qfontification_functions. */
3342 if (!STRINGP (it->string)
3343 && it->s == NULL
3344 && !NILP (Vfontification_functions)
3345 && !NILP (Vrun_hooks)
3346 && (pos = make_number (IT_CHARPOS (*it)),
3347 prop = Fget_char_property (pos, Qfontified, Qnil),
3348 /* Ignore the special cased nil value always present at EOB since
3349 no amount of fontifying will be able to change it. */
3350 NILP (prop) && IT_CHARPOS (*it) < Z))
3351 {
3352 int count = SPECPDL_INDEX ();
3353 Lisp_Object val;
3354
3355 val = Vfontification_functions;
3356 specbind (Qfontification_functions, Qnil);
3357
3358 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3359 safe_call1 (val, pos);
3360 else
3361 {
3362 Lisp_Object globals, fn;
3363 struct gcpro gcpro1, gcpro2;
3364
3365 globals = Qnil;
3366 GCPRO2 (val, globals);
3367
3368 for (; CONSP (val); val = XCDR (val))
3369 {
3370 fn = XCAR (val);
3371
3372 if (EQ (fn, Qt))
3373 {
3374 /* A value of t indicates this hook has a local
3375 binding; it means to run the global binding too.
3376 In a global value, t should not occur. If it
3377 does, we must ignore it to avoid an endless
3378 loop. */
3379 for (globals = Fdefault_value (Qfontification_functions);
3380 CONSP (globals);
3381 globals = XCDR (globals))
3382 {
3383 fn = XCAR (globals);
3384 if (!EQ (fn, Qt))
3385 safe_call1 (fn, pos);
3386 }
3387 }
3388 else
3389 safe_call1 (fn, pos);
3390 }
3391
3392 UNGCPRO;
3393 }
3394
3395 unbind_to (count, Qnil);
3396
3397 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3398 something. This avoids an endless loop if they failed to
3399 fontify the text for which reason ever. */
3400 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3401 handled = HANDLED_RECOMPUTE_PROPS;
3402 }
3403
3404 return handled;
3405 }
3406
3407
3408 \f
3409 /***********************************************************************
3410 Faces
3411 ***********************************************************************/
3412
3413 /* Set up iterator IT from face properties at its current position.
3414 Called from handle_stop. */
3415
3416 static enum prop_handled
3417 handle_face_prop (struct it *it)
3418 {
3419 int new_face_id;
3420 EMACS_INT next_stop;
3421
3422 if (!STRINGP (it->string))
3423 {
3424 new_face_id
3425 = face_at_buffer_position (it->w,
3426 IT_CHARPOS (*it),
3427 it->region_beg_charpos,
3428 it->region_end_charpos,
3429 &next_stop,
3430 (IT_CHARPOS (*it)
3431 + TEXT_PROP_DISTANCE_LIMIT),
3432 0, it->base_face_id);
3433
3434 /* Is this a start of a run of characters with box face?
3435 Caveat: this can be called for a freshly initialized
3436 iterator; face_id is -1 in this case. We know that the new
3437 face will not change until limit, i.e. if the new face has a
3438 box, all characters up to limit will have one. But, as
3439 usual, we don't know whether limit is really the end. */
3440 if (new_face_id != it->face_id)
3441 {
3442 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3443
3444 /* If new face has a box but old face has not, this is
3445 the start of a run of characters with box, i.e. it has
3446 a shadow on the left side. The value of face_id of the
3447 iterator will be -1 if this is the initial call that gets
3448 the face. In this case, we have to look in front of IT's
3449 position and see whether there is a face != new_face_id. */
3450 it->start_of_box_run_p
3451 = (new_face->box != FACE_NO_BOX
3452 && (it->face_id >= 0
3453 || IT_CHARPOS (*it) == BEG
3454 || new_face_id != face_before_it_pos (it)));
3455 it->face_box_p = new_face->box != FACE_NO_BOX;
3456 }
3457 }
3458 else
3459 {
3460 int base_face_id, bufpos;
3461 int i;
3462 Lisp_Object from_overlay
3463 = (it->current.overlay_string_index >= 0
3464 ? it->string_overlays[it->current.overlay_string_index]
3465 : Qnil);
3466
3467 /* See if we got to this string directly or indirectly from
3468 an overlay property. That includes the before-string or
3469 after-string of an overlay, strings in display properties
3470 provided by an overlay, their text properties, etc.
3471
3472 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3473 if (! NILP (from_overlay))
3474 for (i = it->sp - 1; i >= 0; i--)
3475 {
3476 if (it->stack[i].current.overlay_string_index >= 0)
3477 from_overlay
3478 = it->string_overlays[it->stack[i].current.overlay_string_index];
3479 else if (! NILP (it->stack[i].from_overlay))
3480 from_overlay = it->stack[i].from_overlay;
3481
3482 if (!NILP (from_overlay))
3483 break;
3484 }
3485
3486 if (! NILP (from_overlay))
3487 {
3488 bufpos = IT_CHARPOS (*it);
3489 /* For a string from an overlay, the base face depends
3490 only on text properties and ignores overlays. */
3491 base_face_id
3492 = face_for_overlay_string (it->w,
3493 IT_CHARPOS (*it),
3494 it->region_beg_charpos,
3495 it->region_end_charpos,
3496 &next_stop,
3497 (IT_CHARPOS (*it)
3498 + TEXT_PROP_DISTANCE_LIMIT),
3499 0,
3500 from_overlay);
3501 }
3502 else
3503 {
3504 bufpos = 0;
3505
3506 /* For strings from a `display' property, use the face at
3507 IT's current buffer position as the base face to merge
3508 with, so that overlay strings appear in the same face as
3509 surrounding text, unless they specify their own
3510 faces. */
3511 base_face_id = underlying_face_id (it);
3512 }
3513
3514 new_face_id = face_at_string_position (it->w,
3515 it->string,
3516 IT_STRING_CHARPOS (*it),
3517 bufpos,
3518 it->region_beg_charpos,
3519 it->region_end_charpos,
3520 &next_stop,
3521 base_face_id, 0);
3522
3523 /* Is this a start of a run of characters with box? Caveat:
3524 this can be called for a freshly allocated iterator; face_id
3525 is -1 is this case. We know that the new face will not
3526 change until the next check pos, i.e. if the new face has a
3527 box, all characters up to that position will have a
3528 box. But, as usual, we don't know whether that position
3529 is really the end. */
3530 if (new_face_id != it->face_id)
3531 {
3532 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3533 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3534
3535 /* If new face has a box but old face hasn't, this is the
3536 start of a run of characters with box, i.e. it has a
3537 shadow on the left side. */
3538 it->start_of_box_run_p
3539 = new_face->box && (old_face == NULL || !old_face->box);
3540 it->face_box_p = new_face->box != FACE_NO_BOX;
3541 }
3542 }
3543
3544 it->face_id = new_face_id;
3545 return HANDLED_NORMALLY;
3546 }
3547
3548
3549 /* Return the ID of the face ``underlying'' IT's current position,
3550 which is in a string. If the iterator is associated with a
3551 buffer, return the face at IT's current buffer position.
3552 Otherwise, use the iterator's base_face_id. */
3553
3554 static int
3555 underlying_face_id (struct it *it)
3556 {
3557 int face_id = it->base_face_id, i;
3558
3559 xassert (STRINGP (it->string));
3560
3561 for (i = it->sp - 1; i >= 0; --i)
3562 if (NILP (it->stack[i].string))
3563 face_id = it->stack[i].face_id;
3564
3565 return face_id;
3566 }
3567
3568
3569 /* Compute the face one character before or after the current position
3570 of IT. BEFORE_P non-zero means get the face in front of IT's
3571 position. Value is the id of the face. */
3572
3573 static int
3574 face_before_or_after_it_pos (struct it *it, int before_p)
3575 {
3576 int face_id, limit;
3577 EMACS_INT next_check_charpos;
3578 struct text_pos pos;
3579
3580 xassert (it->s == NULL);
3581
3582 if (STRINGP (it->string))
3583 {
3584 int bufpos, base_face_id;
3585
3586 /* No face change past the end of the string (for the case
3587 we are padding with spaces). No face change before the
3588 string start. */
3589 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3590 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3591 return it->face_id;
3592
3593 /* Set pos to the position before or after IT's current position. */
3594 if (before_p)
3595 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3596 else
3597 /* For composition, we must check the character after the
3598 composition. */
3599 pos = (it->what == IT_COMPOSITION
3600 ? string_pos (IT_STRING_CHARPOS (*it)
3601 + it->cmp_it.nchars, it->string)
3602 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3603
3604 if (it->current.overlay_string_index >= 0)
3605 bufpos = IT_CHARPOS (*it);
3606 else
3607 bufpos = 0;
3608
3609 base_face_id = underlying_face_id (it);
3610
3611 /* Get the face for ASCII, or unibyte. */
3612 face_id = face_at_string_position (it->w,
3613 it->string,
3614 CHARPOS (pos),
3615 bufpos,
3616 it->region_beg_charpos,
3617 it->region_end_charpos,
3618 &next_check_charpos,
3619 base_face_id, 0);
3620
3621 /* Correct the face for charsets different from ASCII. Do it
3622 for the multibyte case only. The face returned above is
3623 suitable for unibyte text if IT->string is unibyte. */
3624 if (STRING_MULTIBYTE (it->string))
3625 {
3626 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3627 int rest = SBYTES (it->string) - BYTEPOS (pos);
3628 int c, len;
3629 struct face *face = FACE_FROM_ID (it->f, face_id);
3630
3631 c = string_char_and_length (p, &len);
3632 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3633 }
3634 }
3635 else
3636 {
3637 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3638 || (IT_CHARPOS (*it) <= BEGV && before_p))
3639 return it->face_id;
3640
3641 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3642 pos = it->current.pos;
3643
3644 if (before_p)
3645 DEC_TEXT_POS (pos, it->multibyte_p);
3646 else
3647 {
3648 if (it->what == IT_COMPOSITION)
3649 /* For composition, we must check the position after the
3650 composition. */
3651 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3652 else
3653 INC_TEXT_POS (pos, it->multibyte_p);
3654 }
3655
3656 /* Determine face for CHARSET_ASCII, or unibyte. */
3657 face_id = face_at_buffer_position (it->w,
3658 CHARPOS (pos),
3659 it->region_beg_charpos,
3660 it->region_end_charpos,
3661 &next_check_charpos,
3662 limit, 0, -1);
3663
3664 /* Correct the face for charsets different from ASCII. Do it
3665 for the multibyte case only. The face returned above is
3666 suitable for unibyte text if current_buffer is unibyte. */
3667 if (it->multibyte_p)
3668 {
3669 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3670 struct face *face = FACE_FROM_ID (it->f, face_id);
3671 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3672 }
3673 }
3674
3675 return face_id;
3676 }
3677
3678
3679 \f
3680 /***********************************************************************
3681 Invisible text
3682 ***********************************************************************/
3683
3684 /* Set up iterator IT from invisible properties at its current
3685 position. Called from handle_stop. */
3686
3687 static enum prop_handled
3688 handle_invisible_prop (struct it *it)
3689 {
3690 enum prop_handled handled = HANDLED_NORMALLY;
3691
3692 if (STRINGP (it->string))
3693 {
3694 extern Lisp_Object Qinvisible;
3695 Lisp_Object prop, end_charpos, limit, charpos;
3696
3697 /* Get the value of the invisible text property at the
3698 current position. Value will be nil if there is no such
3699 property. */
3700 charpos = make_number (IT_STRING_CHARPOS (*it));
3701 prop = Fget_text_property (charpos, Qinvisible, it->string);
3702
3703 if (!NILP (prop)
3704 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3705 {
3706 handled = HANDLED_RECOMPUTE_PROPS;
3707
3708 /* Get the position at which the next change of the
3709 invisible text property can be found in IT->string.
3710 Value will be nil if the property value is the same for
3711 all the rest of IT->string. */
3712 XSETINT (limit, SCHARS (it->string));
3713 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3714 it->string, limit);
3715
3716 /* Text at current position is invisible. The next
3717 change in the property is at position end_charpos.
3718 Move IT's current position to that position. */
3719 if (INTEGERP (end_charpos)
3720 && XFASTINT (end_charpos) < XFASTINT (limit))
3721 {
3722 struct text_pos old;
3723 old = it->current.string_pos;
3724 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3725 compute_string_pos (&it->current.string_pos, old, it->string);
3726 }
3727 else
3728 {
3729 /* The rest of the string is invisible. If this is an
3730 overlay string, proceed with the next overlay string
3731 or whatever comes and return a character from there. */
3732 if (it->current.overlay_string_index >= 0)
3733 {
3734 next_overlay_string (it);
3735 /* Don't check for overlay strings when we just
3736 finished processing them. */
3737 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3738 }
3739 else
3740 {
3741 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3742 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3743 }
3744 }
3745 }
3746 }
3747 else
3748 {
3749 int invis_p;
3750 EMACS_INT newpos, next_stop, start_charpos, tem;
3751 Lisp_Object pos, prop, overlay;
3752
3753 /* First of all, is there invisible text at this position? */
3754 tem = start_charpos = IT_CHARPOS (*it);
3755 pos = make_number (tem);
3756 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3757 &overlay);
3758 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3759
3760 /* If we are on invisible text, skip over it. */
3761 if (invis_p && start_charpos < it->end_charpos)
3762 {
3763 /* Record whether we have to display an ellipsis for the
3764 invisible text. */
3765 int display_ellipsis_p = invis_p == 2;
3766
3767 handled = HANDLED_RECOMPUTE_PROPS;
3768
3769 /* Loop skipping over invisible text. The loop is left at
3770 ZV or with IT on the first char being visible again. */
3771 do
3772 {
3773 /* Try to skip some invisible text. Return value is the
3774 position reached which can be equal to where we start
3775 if there is nothing invisible there. This skips both
3776 over invisible text properties and overlays with
3777 invisible property. */
3778 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3779
3780 /* If we skipped nothing at all we weren't at invisible
3781 text in the first place. If everything to the end of
3782 the buffer was skipped, end the loop. */
3783 if (newpos == tem || newpos >= ZV)
3784 invis_p = 0;
3785 else
3786 {
3787 /* We skipped some characters but not necessarily
3788 all there are. Check if we ended up on visible
3789 text. Fget_char_property returns the property of
3790 the char before the given position, i.e. if we
3791 get invis_p = 0, this means that the char at
3792 newpos is visible. */
3793 pos = make_number (newpos);
3794 prop = Fget_char_property (pos, Qinvisible, it->window);
3795 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3796 }
3797
3798 /* If we ended up on invisible text, proceed to
3799 skip starting with next_stop. */
3800 if (invis_p)
3801 tem = next_stop;
3802
3803 /* If there are adjacent invisible texts, don't lose the
3804 second one's ellipsis. */
3805 if (invis_p == 2)
3806 display_ellipsis_p = 1;
3807 }
3808 while (invis_p);
3809
3810 /* The position newpos is now either ZV or on visible text. */
3811 if (it->bidi_p && newpos < ZV)
3812 {
3813 /* With bidi iteration, the region of invisible text
3814 could start and/or end in the middle of a non-base
3815 embedding level. Therefore, we need to skip
3816 invisible text using the bidi iterator, starting at
3817 IT's current position, until we find ourselves
3818 outside the invisible text. Skipping invisible text
3819 _after_ bidi iteration avoids affecting the visual
3820 order of the displayed text when invisible properties
3821 are added or removed. */
3822 if (it->bidi_it.first_elt)
3823 {
3824 /* If we were `reseat'ed to a new paragraph,
3825 determine the paragraph base direction. We need
3826 to do it now because next_element_from_buffer may
3827 not have a chance to do it, if we are going to
3828 skip any text at the beginning, which resets the
3829 FIRST_ELT flag. */
3830 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
3831 }
3832 do
3833 {
3834 bidi_move_to_visually_next (&it->bidi_it);
3835 }
3836 while (it->stop_charpos <= it->bidi_it.charpos
3837 && it->bidi_it.charpos < newpos);
3838 IT_CHARPOS (*it) = it->bidi_it.charpos;
3839 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3840 /* If we overstepped NEWPOS, record its position in the
3841 iterator, so that we skip invisible text if later the
3842 bidi iteration lands us in the invisible region
3843 again. */
3844 if (IT_CHARPOS (*it) >= newpos)
3845 it->prev_stop = newpos;
3846 }
3847 else
3848 {
3849 IT_CHARPOS (*it) = newpos;
3850 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3851 }
3852
3853 /* If there are before-strings at the start of invisible
3854 text, and the text is invisible because of a text
3855 property, arrange to show before-strings because 20.x did
3856 it that way. (If the text is invisible because of an
3857 overlay property instead of a text property, this is
3858 already handled in the overlay code.) */
3859 if (NILP (overlay)
3860 && get_overlay_strings (it, it->stop_charpos))
3861 {
3862 handled = HANDLED_RECOMPUTE_PROPS;
3863 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3864 }
3865 else if (display_ellipsis_p)
3866 {
3867 /* Make sure that the glyphs of the ellipsis will get
3868 correct `charpos' values. If we would not update
3869 it->position here, the glyphs would belong to the
3870 last visible character _before_ the invisible
3871 text, which confuses `set_cursor_from_row'.
3872
3873 We use the last invisible position instead of the
3874 first because this way the cursor is always drawn on
3875 the first "." of the ellipsis, whenever PT is inside
3876 the invisible text. Otherwise the cursor would be
3877 placed _after_ the ellipsis when the point is after the
3878 first invisible character. */
3879 if (!STRINGP (it->object))
3880 {
3881 it->position.charpos = newpos - 1;
3882 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3883 }
3884 it->ellipsis_p = 1;
3885 /* Let the ellipsis display before
3886 considering any properties of the following char.
3887 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3888 handled = HANDLED_RETURN;
3889 }
3890 }
3891 }
3892
3893 return handled;
3894 }
3895
3896
3897 /* Make iterator IT return `...' next.
3898 Replaces LEN characters from buffer. */
3899
3900 static void
3901 setup_for_ellipsis (struct it *it, int len)
3902 {
3903 /* Use the display table definition for `...'. Invalid glyphs
3904 will be handled by the method returning elements from dpvec. */
3905 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3906 {
3907 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3908 it->dpvec = v->contents;
3909 it->dpend = v->contents + v->size;
3910 }
3911 else
3912 {
3913 /* Default `...'. */
3914 it->dpvec = default_invis_vector;
3915 it->dpend = default_invis_vector + 3;
3916 }
3917
3918 it->dpvec_char_len = len;
3919 it->current.dpvec_index = 0;
3920 it->dpvec_face_id = -1;
3921
3922 /* Remember the current face id in case glyphs specify faces.
3923 IT's face is restored in set_iterator_to_next.
3924 saved_face_id was set to preceding char's face in handle_stop. */
3925 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3926 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3927
3928 it->method = GET_FROM_DISPLAY_VECTOR;
3929 it->ellipsis_p = 1;
3930 }
3931
3932
3933 \f
3934 /***********************************************************************
3935 'display' property
3936 ***********************************************************************/
3937
3938 /* Set up iterator IT from `display' property at its current position.
3939 Called from handle_stop.
3940 We return HANDLED_RETURN if some part of the display property
3941 overrides the display of the buffer text itself.
3942 Otherwise we return HANDLED_NORMALLY. */
3943
3944 static enum prop_handled
3945 handle_display_prop (struct it *it)
3946 {
3947 Lisp_Object prop, object, overlay;
3948 struct text_pos *position;
3949 /* Nonzero if some property replaces the display of the text itself. */
3950 int display_replaced_p = 0;
3951
3952 if (STRINGP (it->string))
3953 {
3954 object = it->string;
3955 position = &it->current.string_pos;
3956 }
3957 else
3958 {
3959 XSETWINDOW (object, it->w);
3960 position = &it->current.pos;
3961 }
3962
3963 /* Reset those iterator values set from display property values. */
3964 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3965 it->space_width = Qnil;
3966 it->font_height = Qnil;
3967 it->voffset = 0;
3968
3969 /* We don't support recursive `display' properties, i.e. string
3970 values that have a string `display' property, that have a string
3971 `display' property etc. */
3972 if (!it->string_from_display_prop_p)
3973 it->area = TEXT_AREA;
3974
3975 prop = get_char_property_and_overlay (make_number (position->charpos),
3976 Qdisplay, object, &overlay);
3977 if (NILP (prop))
3978 return HANDLED_NORMALLY;
3979 /* Now OVERLAY is the overlay that gave us this property, or nil
3980 if it was a text property. */
3981
3982 if (!STRINGP (it->string))
3983 object = it->w->buffer;
3984
3985 if (CONSP (prop)
3986 /* Simple properties. */
3987 && !EQ (XCAR (prop), Qimage)
3988 && !EQ (XCAR (prop), Qspace)
3989 && !EQ (XCAR (prop), Qwhen)
3990 && !EQ (XCAR (prop), Qslice)
3991 && !EQ (XCAR (prop), Qspace_width)
3992 && !EQ (XCAR (prop), Qheight)
3993 && !EQ (XCAR (prop), Qraise)
3994 /* Marginal area specifications. */
3995 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3996 && !EQ (XCAR (prop), Qleft_fringe)
3997 && !EQ (XCAR (prop), Qright_fringe)
3998 && !NILP (XCAR (prop)))
3999 {
4000 for (; CONSP (prop); prop = XCDR (prop))
4001 {
4002 if (handle_single_display_spec (it, XCAR (prop), 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 }
4013 else if (VECTORP (prop))
4014 {
4015 int i;
4016 for (i = 0; i < ASIZE (prop); ++i)
4017 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4018 position, display_replaced_p))
4019 {
4020 display_replaced_p = 1;
4021 /* If some text in a string is replaced, `position' no
4022 longer points to the position of `object'. */
4023 if (STRINGP (object))
4024 break;
4025 }
4026 }
4027 else
4028 {
4029 if (handle_single_display_spec (it, prop, object, overlay,
4030 position, 0))
4031 display_replaced_p = 1;
4032 }
4033
4034 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4035 }
4036
4037
4038 /* Value is the position of the end of the `display' property starting
4039 at START_POS in OBJECT. */
4040
4041 static struct text_pos
4042 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4043 {
4044 Lisp_Object end;
4045 struct text_pos end_pos;
4046
4047 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4048 Qdisplay, object, Qnil);
4049 CHARPOS (end_pos) = XFASTINT (end);
4050 if (STRINGP (object))
4051 compute_string_pos (&end_pos, start_pos, it->string);
4052 else
4053 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4054
4055 return end_pos;
4056 }
4057
4058
4059 /* Set up IT from a single `display' specification PROP. OBJECT
4060 is the object in which the `display' property was found. *POSITION
4061 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4062 means that we previously saw a display specification which already
4063 replaced text display with something else, for example an image;
4064 we ignore such properties after the first one has been processed.
4065
4066 OVERLAY is the overlay this `display' property came from,
4067 or nil if it was a text property.
4068
4069 If PROP is a `space' or `image' specification, and in some other
4070 cases too, set *POSITION to the position where the `display'
4071 property ends.
4072
4073 Value is non-zero if something was found which replaces the display
4074 of buffer or string text. */
4075
4076 static int
4077 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4078 Lisp_Object overlay, struct text_pos *position,
4079 int display_replaced_before_p)
4080 {
4081 Lisp_Object form;
4082 Lisp_Object location, value;
4083 struct text_pos start_pos, save_pos;
4084 int valid_p;
4085
4086 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4087 If the result is non-nil, use VALUE instead of SPEC. */
4088 form = Qt;
4089 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4090 {
4091 spec = XCDR (spec);
4092 if (!CONSP (spec))
4093 return 0;
4094 form = XCAR (spec);
4095 spec = XCDR (spec);
4096 }
4097
4098 if (!NILP (form) && !EQ (form, Qt))
4099 {
4100 int count = SPECPDL_INDEX ();
4101 struct gcpro gcpro1;
4102
4103 /* Bind `object' to the object having the `display' property, a
4104 buffer or string. Bind `position' to the position in the
4105 object where the property was found, and `buffer-position'
4106 to the current position in the buffer. */
4107 specbind (Qobject, object);
4108 specbind (Qposition, make_number (CHARPOS (*position)));
4109 specbind (Qbuffer_position,
4110 make_number (STRINGP (object)
4111 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4112 GCPRO1 (form);
4113 form = safe_eval (form);
4114 UNGCPRO;
4115 unbind_to (count, Qnil);
4116 }
4117
4118 if (NILP (form))
4119 return 0;
4120
4121 /* Handle `(height HEIGHT)' specifications. */
4122 if (CONSP (spec)
4123 && EQ (XCAR (spec), Qheight)
4124 && CONSP (XCDR (spec)))
4125 {
4126 if (!FRAME_WINDOW_P (it->f))
4127 return 0;
4128
4129 it->font_height = XCAR (XCDR (spec));
4130 if (!NILP (it->font_height))
4131 {
4132 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4133 int new_height = -1;
4134
4135 if (CONSP (it->font_height)
4136 && (EQ (XCAR (it->font_height), Qplus)
4137 || EQ (XCAR (it->font_height), Qminus))
4138 && CONSP (XCDR (it->font_height))
4139 && INTEGERP (XCAR (XCDR (it->font_height))))
4140 {
4141 /* `(+ N)' or `(- N)' where N is an integer. */
4142 int steps = XINT (XCAR (XCDR (it->font_height)));
4143 if (EQ (XCAR (it->font_height), Qplus))
4144 steps = - steps;
4145 it->face_id = smaller_face (it->f, it->face_id, steps);
4146 }
4147 else if (FUNCTIONP (it->font_height))
4148 {
4149 /* Call function with current height as argument.
4150 Value is the new height. */
4151 Lisp_Object height;
4152 height = safe_call1 (it->font_height,
4153 face->lface[LFACE_HEIGHT_INDEX]);
4154 if (NUMBERP (height))
4155 new_height = XFLOATINT (height);
4156 }
4157 else if (NUMBERP (it->font_height))
4158 {
4159 /* Value is a multiple of the canonical char height. */
4160 struct face *face;
4161
4162 face = FACE_FROM_ID (it->f,
4163 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4164 new_height = (XFLOATINT (it->font_height)
4165 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4166 }
4167 else
4168 {
4169 /* Evaluate IT->font_height with `height' bound to the
4170 current specified height to get the new height. */
4171 int count = SPECPDL_INDEX ();
4172
4173 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4174 value = safe_eval (it->font_height);
4175 unbind_to (count, Qnil);
4176
4177 if (NUMBERP (value))
4178 new_height = XFLOATINT (value);
4179 }
4180
4181 if (new_height > 0)
4182 it->face_id = face_with_height (it->f, it->face_id, new_height);
4183 }
4184
4185 return 0;
4186 }
4187
4188 /* Handle `(space-width WIDTH)'. */
4189 if (CONSP (spec)
4190 && EQ (XCAR (spec), Qspace_width)
4191 && CONSP (XCDR (spec)))
4192 {
4193 if (!FRAME_WINDOW_P (it->f))
4194 return 0;
4195
4196 value = XCAR (XCDR (spec));
4197 if (NUMBERP (value) && XFLOATINT (value) > 0)
4198 it->space_width = value;
4199
4200 return 0;
4201 }
4202
4203 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4204 if (CONSP (spec)
4205 && EQ (XCAR (spec), Qslice))
4206 {
4207 Lisp_Object tem;
4208
4209 if (!FRAME_WINDOW_P (it->f))
4210 return 0;
4211
4212 if (tem = XCDR (spec), CONSP (tem))
4213 {
4214 it->slice.x = XCAR (tem);
4215 if (tem = XCDR (tem), CONSP (tem))
4216 {
4217 it->slice.y = XCAR (tem);
4218 if (tem = XCDR (tem), CONSP (tem))
4219 {
4220 it->slice.width = XCAR (tem);
4221 if (tem = XCDR (tem), CONSP (tem))
4222 it->slice.height = XCAR (tem);
4223 }
4224 }
4225 }
4226
4227 return 0;
4228 }
4229
4230 /* Handle `(raise FACTOR)'. */
4231 if (CONSP (spec)
4232 && EQ (XCAR (spec), Qraise)
4233 && CONSP (XCDR (spec)))
4234 {
4235 if (!FRAME_WINDOW_P (it->f))
4236 return 0;
4237
4238 #ifdef HAVE_WINDOW_SYSTEM
4239 value = XCAR (XCDR (spec));
4240 if (NUMBERP (value))
4241 {
4242 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4243 it->voffset = - (XFLOATINT (value)
4244 * (FONT_HEIGHT (face->font)));
4245 }
4246 #endif /* HAVE_WINDOW_SYSTEM */
4247
4248 return 0;
4249 }
4250
4251 /* Don't handle the other kinds of display specifications
4252 inside a string that we got from a `display' property. */
4253 if (it->string_from_display_prop_p)
4254 return 0;
4255
4256 /* Characters having this form of property are not displayed, so
4257 we have to find the end of the property. */
4258 start_pos = *position;
4259 *position = display_prop_end (it, object, start_pos);
4260 value = Qnil;
4261
4262 /* Stop the scan at that end position--we assume that all
4263 text properties change there. */
4264 it->stop_charpos = position->charpos;
4265
4266 /* Handle `(left-fringe BITMAP [FACE])'
4267 and `(right-fringe BITMAP [FACE])'. */
4268 if (CONSP (spec)
4269 && (EQ (XCAR (spec), Qleft_fringe)
4270 || EQ (XCAR (spec), Qright_fringe))
4271 && CONSP (XCDR (spec)))
4272 {
4273 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4274 int fringe_bitmap;
4275
4276 if (!FRAME_WINDOW_P (it->f))
4277 /* If we return here, POSITION has been advanced
4278 across the text with this property. */
4279 return 0;
4280
4281 #ifdef HAVE_WINDOW_SYSTEM
4282 value = XCAR (XCDR (spec));
4283 if (!SYMBOLP (value)
4284 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4285 /* If we return here, POSITION has been advanced
4286 across the text with this property. */
4287 return 0;
4288
4289 if (CONSP (XCDR (XCDR (spec))))
4290 {
4291 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4292 int face_id2 = lookup_derived_face (it->f, face_name,
4293 FRINGE_FACE_ID, 0);
4294 if (face_id2 >= 0)
4295 face_id = face_id2;
4296 }
4297
4298 /* Save current settings of IT so that we can restore them
4299 when we are finished with the glyph property value. */
4300
4301 save_pos = it->position;
4302 it->position = *position;
4303 push_it (it);
4304 it->position = save_pos;
4305
4306 it->area = TEXT_AREA;
4307 it->what = IT_IMAGE;
4308 it->image_id = -1; /* no image */
4309 it->position = start_pos;
4310 it->object = NILP (object) ? it->w->buffer : object;
4311 it->method = GET_FROM_IMAGE;
4312 it->from_overlay = Qnil;
4313 it->face_id = face_id;
4314
4315 /* Say that we haven't consumed the characters with
4316 `display' property yet. The call to pop_it in
4317 set_iterator_to_next will clean this up. */
4318 *position = start_pos;
4319
4320 if (EQ (XCAR (spec), Qleft_fringe))
4321 {
4322 it->left_user_fringe_bitmap = fringe_bitmap;
4323 it->left_user_fringe_face_id = face_id;
4324 }
4325 else
4326 {
4327 it->right_user_fringe_bitmap = fringe_bitmap;
4328 it->right_user_fringe_face_id = face_id;
4329 }
4330 #endif /* HAVE_WINDOW_SYSTEM */
4331 return 1;
4332 }
4333
4334 /* Prepare to handle `((margin left-margin) ...)',
4335 `((margin right-margin) ...)' and `((margin nil) ...)'
4336 prefixes for display specifications. */
4337 location = Qunbound;
4338 if (CONSP (spec) && CONSP (XCAR (spec)))
4339 {
4340 Lisp_Object tem;
4341
4342 value = XCDR (spec);
4343 if (CONSP (value))
4344 value = XCAR (value);
4345
4346 tem = XCAR (spec);
4347 if (EQ (XCAR (tem), Qmargin)
4348 && (tem = XCDR (tem),
4349 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4350 (NILP (tem)
4351 || EQ (tem, Qleft_margin)
4352 || EQ (tem, Qright_margin))))
4353 location = tem;
4354 }
4355
4356 if (EQ (location, Qunbound))
4357 {
4358 location = Qnil;
4359 value = spec;
4360 }
4361
4362 /* After this point, VALUE is the property after any
4363 margin prefix has been stripped. It must be a string,
4364 an image specification, or `(space ...)'.
4365
4366 LOCATION specifies where to display: `left-margin',
4367 `right-margin' or nil. */
4368
4369 valid_p = (STRINGP (value)
4370 #ifdef HAVE_WINDOW_SYSTEM
4371 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4372 #endif /* not HAVE_WINDOW_SYSTEM */
4373 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4374
4375 if (valid_p && !display_replaced_before_p)
4376 {
4377 /* Save current settings of IT so that we can restore them
4378 when we are finished with the glyph property value. */
4379 save_pos = it->position;
4380 it->position = *position;
4381 push_it (it);
4382 it->position = save_pos;
4383 it->from_overlay = overlay;
4384
4385 if (NILP (location))
4386 it->area = TEXT_AREA;
4387 else if (EQ (location, Qleft_margin))
4388 it->area = LEFT_MARGIN_AREA;
4389 else
4390 it->area = RIGHT_MARGIN_AREA;
4391
4392 if (STRINGP (value))
4393 {
4394 it->string = value;
4395 it->multibyte_p = STRING_MULTIBYTE (it->string);
4396 it->current.overlay_string_index = -1;
4397 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4398 it->end_charpos = it->string_nchars = SCHARS (it->string);
4399 it->method = GET_FROM_STRING;
4400 it->stop_charpos = 0;
4401 it->string_from_display_prop_p = 1;
4402 /* Say that we haven't consumed the characters with
4403 `display' property yet. The call to pop_it in
4404 set_iterator_to_next will clean this up. */
4405 if (BUFFERP (object))
4406 *position = start_pos;
4407 }
4408 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4409 {
4410 it->method = GET_FROM_STRETCH;
4411 it->object = value;
4412 *position = it->position = start_pos;
4413 }
4414 #ifdef HAVE_WINDOW_SYSTEM
4415 else
4416 {
4417 it->what = IT_IMAGE;
4418 it->image_id = lookup_image (it->f, value);
4419 it->position = start_pos;
4420 it->object = NILP (object) ? it->w->buffer : object;
4421 it->method = GET_FROM_IMAGE;
4422
4423 /* Say that we haven't consumed the characters with
4424 `display' property yet. The call to pop_it in
4425 set_iterator_to_next will clean this up. */
4426 *position = start_pos;
4427 }
4428 #endif /* HAVE_WINDOW_SYSTEM */
4429
4430 return 1;
4431 }
4432
4433 /* Invalid property or property not supported. Restore
4434 POSITION to what it was before. */
4435 *position = start_pos;
4436 return 0;
4437 }
4438
4439
4440 /* Check if SPEC is a display sub-property value whose text should be
4441 treated as intangible. */
4442
4443 static int
4444 single_display_spec_intangible_p (Lisp_Object prop)
4445 {
4446 /* Skip over `when FORM'. */
4447 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4448 {
4449 prop = XCDR (prop);
4450 if (!CONSP (prop))
4451 return 0;
4452 prop = XCDR (prop);
4453 }
4454
4455 if (STRINGP (prop))
4456 return 1;
4457
4458 if (!CONSP (prop))
4459 return 0;
4460
4461 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4462 we don't need to treat text as intangible. */
4463 if (EQ (XCAR (prop), Qmargin))
4464 {
4465 prop = XCDR (prop);
4466 if (!CONSP (prop))
4467 return 0;
4468
4469 prop = XCDR (prop);
4470 if (!CONSP (prop)
4471 || EQ (XCAR (prop), Qleft_margin)
4472 || EQ (XCAR (prop), Qright_margin))
4473 return 0;
4474 }
4475
4476 return (CONSP (prop)
4477 && (EQ (XCAR (prop), Qimage)
4478 || EQ (XCAR (prop), Qspace)));
4479 }
4480
4481
4482 /* Check if PROP is a display property value whose text should be
4483 treated as intangible. */
4484
4485 int
4486 display_prop_intangible_p (Lisp_Object prop)
4487 {
4488 if (CONSP (prop)
4489 && CONSP (XCAR (prop))
4490 && !EQ (Qmargin, XCAR (XCAR (prop))))
4491 {
4492 /* A list of sub-properties. */
4493 while (CONSP (prop))
4494 {
4495 if (single_display_spec_intangible_p (XCAR (prop)))
4496 return 1;
4497 prop = XCDR (prop);
4498 }
4499 }
4500 else if (VECTORP (prop))
4501 {
4502 /* A vector of sub-properties. */
4503 int i;
4504 for (i = 0; i < ASIZE (prop); ++i)
4505 if (single_display_spec_intangible_p (AREF (prop, i)))
4506 return 1;
4507 }
4508 else
4509 return single_display_spec_intangible_p (prop);
4510
4511 return 0;
4512 }
4513
4514
4515 /* Return 1 if PROP is a display sub-property value containing STRING. */
4516
4517 static int
4518 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4519 {
4520 if (EQ (string, prop))
4521 return 1;
4522
4523 /* Skip over `when FORM'. */
4524 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4525 {
4526 prop = XCDR (prop);
4527 if (!CONSP (prop))
4528 return 0;
4529 prop = XCDR (prop);
4530 }
4531
4532 if (CONSP (prop))
4533 /* Skip over `margin LOCATION'. */
4534 if (EQ (XCAR (prop), Qmargin))
4535 {
4536 prop = XCDR (prop);
4537 if (!CONSP (prop))
4538 return 0;
4539
4540 prop = XCDR (prop);
4541 if (!CONSP (prop))
4542 return 0;
4543 }
4544
4545 return CONSP (prop) && EQ (XCAR (prop), string);
4546 }
4547
4548
4549 /* Return 1 if STRING appears in the `display' property PROP. */
4550
4551 static int
4552 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4553 {
4554 if (CONSP (prop)
4555 && CONSP (XCAR (prop))
4556 && !EQ (Qmargin, XCAR (XCAR (prop))))
4557 {
4558 /* A list of sub-properties. */
4559 while (CONSP (prop))
4560 {
4561 if (single_display_spec_string_p (XCAR (prop), string))
4562 return 1;
4563 prop = XCDR (prop);
4564 }
4565 }
4566 else if (VECTORP (prop))
4567 {
4568 /* A vector of sub-properties. */
4569 int i;
4570 for (i = 0; i < ASIZE (prop); ++i)
4571 if (single_display_spec_string_p (AREF (prop, i), string))
4572 return 1;
4573 }
4574 else
4575 return single_display_spec_string_p (prop, string);
4576
4577 return 0;
4578 }
4579
4580 /* Look for STRING in overlays and text properties in W's buffer,
4581 between character positions FROM and TO (excluding TO).
4582 BACK_P non-zero means look back (in this case, TO is supposed to be
4583 less than FROM).
4584 Value is the first character position where STRING was found, or
4585 zero if it wasn't found before hitting TO.
4586
4587 W's buffer must be current.
4588
4589 This function may only use code that doesn't eval because it is
4590 called asynchronously from note_mouse_highlight. */
4591
4592 static EMACS_INT
4593 string_buffer_position_lim (struct window *w, Lisp_Object string,
4594 EMACS_INT from, EMACS_INT to, int back_p)
4595 {
4596 Lisp_Object limit, prop, pos;
4597 int found = 0;
4598
4599 pos = make_number (from);
4600
4601 if (!back_p) /* looking forward */
4602 {
4603 limit = make_number (min (to, ZV));
4604 while (!found && !EQ (pos, limit))
4605 {
4606 prop = Fget_char_property (pos, Qdisplay, Qnil);
4607 if (!NILP (prop) && display_prop_string_p (prop, string))
4608 found = 1;
4609 else
4610 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4611 limit);
4612 }
4613 }
4614 else /* looking back */
4615 {
4616 limit = make_number (max (to, BEGV));
4617 while (!found && !EQ (pos, limit))
4618 {
4619 prop = Fget_char_property (pos, Qdisplay, Qnil);
4620 if (!NILP (prop) && display_prop_string_p (prop, string))
4621 found = 1;
4622 else
4623 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4624 limit);
4625 }
4626 }
4627
4628 return found ? XINT (pos) : 0;
4629 }
4630
4631 /* Determine which buffer position in W's buffer STRING comes from.
4632 AROUND_CHARPOS is an approximate position where it could come from.
4633 Value is the buffer position or 0 if it couldn't be determined.
4634
4635 W's buffer must be current.
4636
4637 This function is necessary because we don't record buffer positions
4638 in glyphs generated from strings (to keep struct glyph small).
4639 This function may only use code that doesn't eval because it is
4640 called asynchronously from note_mouse_highlight. */
4641
4642 EMACS_INT
4643 string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
4644 {
4645 Lisp_Object limit, prop, pos;
4646 const int MAX_DISTANCE = 1000;
4647 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4648 around_charpos + MAX_DISTANCE,
4649 0);
4650
4651 if (!found)
4652 found = string_buffer_position_lim (w, string, around_charpos,
4653 around_charpos - MAX_DISTANCE, 1);
4654 return found;
4655 }
4656
4657
4658 \f
4659 /***********************************************************************
4660 `composition' property
4661 ***********************************************************************/
4662
4663 /* Set up iterator IT from `composition' property at its current
4664 position. Called from handle_stop. */
4665
4666 static enum prop_handled
4667 handle_composition_prop (struct it *it)
4668 {
4669 Lisp_Object prop, string;
4670 EMACS_INT pos, pos_byte, start, end;
4671
4672 if (STRINGP (it->string))
4673 {
4674 unsigned char *s;
4675
4676 pos = IT_STRING_CHARPOS (*it);
4677 pos_byte = IT_STRING_BYTEPOS (*it);
4678 string = it->string;
4679 s = SDATA (string) + pos_byte;
4680 it->c = STRING_CHAR (s);
4681 }
4682 else
4683 {
4684 pos = IT_CHARPOS (*it);
4685 pos_byte = IT_BYTEPOS (*it);
4686 string = Qnil;
4687 it->c = FETCH_CHAR (pos_byte);
4688 }
4689
4690 /* If there's a valid composition and point is not inside of the
4691 composition (in the case that the composition is from the current
4692 buffer), draw a glyph composed from the composition components. */
4693 if (find_composition (pos, -1, &start, &end, &prop, string)
4694 && COMPOSITION_VALID_P (start, end, prop)
4695 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4696 {
4697 if (start != pos)
4698 {
4699 if (STRINGP (it->string))
4700 pos_byte = string_char_to_byte (it->string, start);
4701 else
4702 pos_byte = CHAR_TO_BYTE (start);
4703 }
4704 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4705 prop, string);
4706
4707 if (it->cmp_it.id >= 0)
4708 {
4709 it->cmp_it.ch = -1;
4710 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4711 it->cmp_it.nglyphs = -1;
4712 }
4713 }
4714
4715 return HANDLED_NORMALLY;
4716 }
4717
4718
4719 \f
4720 /***********************************************************************
4721 Overlay strings
4722 ***********************************************************************/
4723
4724 /* The following structure is used to record overlay strings for
4725 later sorting in load_overlay_strings. */
4726
4727 struct overlay_entry
4728 {
4729 Lisp_Object overlay;
4730 Lisp_Object string;
4731 int priority;
4732 int after_string_p;
4733 };
4734
4735
4736 /* Set up iterator IT from overlay strings at its current position.
4737 Called from handle_stop. */
4738
4739 static enum prop_handled
4740 handle_overlay_change (struct it *it)
4741 {
4742 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4743 return HANDLED_RECOMPUTE_PROPS;
4744 else
4745 return HANDLED_NORMALLY;
4746 }
4747
4748
4749 /* Set up the next overlay string for delivery by IT, if there is an
4750 overlay string to deliver. Called by set_iterator_to_next when the
4751 end of the current overlay string is reached. If there are more
4752 overlay strings to display, IT->string and
4753 IT->current.overlay_string_index are set appropriately here.
4754 Otherwise IT->string is set to nil. */
4755
4756 static void
4757 next_overlay_string (struct it *it)
4758 {
4759 ++it->current.overlay_string_index;
4760 if (it->current.overlay_string_index == it->n_overlay_strings)
4761 {
4762 /* No more overlay strings. Restore IT's settings to what
4763 they were before overlay strings were processed, and
4764 continue to deliver from current_buffer. */
4765
4766 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4767 pop_it (it);
4768 xassert (it->sp > 0
4769 || (NILP (it->string)
4770 && it->method == GET_FROM_BUFFER
4771 && it->stop_charpos >= BEGV
4772 && it->stop_charpos <= it->end_charpos));
4773 it->current.overlay_string_index = -1;
4774 it->n_overlay_strings = 0;
4775
4776 /* If we're at the end of the buffer, record that we have
4777 processed the overlay strings there already, so that
4778 next_element_from_buffer doesn't try it again. */
4779 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4780 it->overlay_strings_at_end_processed_p = 1;
4781 }
4782 else
4783 {
4784 /* There are more overlay strings to process. If
4785 IT->current.overlay_string_index has advanced to a position
4786 where we must load IT->overlay_strings with more strings, do
4787 it. */
4788 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4789
4790 if (it->current.overlay_string_index && i == 0)
4791 load_overlay_strings (it, 0);
4792
4793 /* Initialize IT to deliver display elements from the overlay
4794 string. */
4795 it->string = it->overlay_strings[i];
4796 it->multibyte_p = STRING_MULTIBYTE (it->string);
4797 SET_TEXT_POS (it->current.string_pos, 0, 0);
4798 it->method = GET_FROM_STRING;
4799 it->stop_charpos = 0;
4800 if (it->cmp_it.stop_pos >= 0)
4801 it->cmp_it.stop_pos = 0;
4802 }
4803
4804 CHECK_IT (it);
4805 }
4806
4807
4808 /* Compare two overlay_entry structures E1 and E2. Used as a
4809 comparison function for qsort in load_overlay_strings. Overlay
4810 strings for the same position are sorted so that
4811
4812 1. All after-strings come in front of before-strings, except
4813 when they come from the same overlay.
4814
4815 2. Within after-strings, strings are sorted so that overlay strings
4816 from overlays with higher priorities come first.
4817
4818 2. Within before-strings, strings are sorted so that overlay
4819 strings from overlays with higher priorities come last.
4820
4821 Value is analogous to strcmp. */
4822
4823
4824 static int
4825 compare_overlay_entries (const void *e1, const void *e2)
4826 {
4827 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4828 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4829 int result;
4830
4831 if (entry1->after_string_p != entry2->after_string_p)
4832 {
4833 /* Let after-strings appear in front of before-strings if
4834 they come from different overlays. */
4835 if (EQ (entry1->overlay, entry2->overlay))
4836 result = entry1->after_string_p ? 1 : -1;
4837 else
4838 result = entry1->after_string_p ? -1 : 1;
4839 }
4840 else if (entry1->after_string_p)
4841 /* After-strings sorted in order of decreasing priority. */
4842 result = entry2->priority - entry1->priority;
4843 else
4844 /* Before-strings sorted in order of increasing priority. */
4845 result = entry1->priority - entry2->priority;
4846
4847 return result;
4848 }
4849
4850
4851 /* Load the vector IT->overlay_strings with overlay strings from IT's
4852 current buffer position, or from CHARPOS if that is > 0. Set
4853 IT->n_overlays to the total number of overlay strings found.
4854
4855 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4856 a time. On entry into load_overlay_strings,
4857 IT->current.overlay_string_index gives the number of overlay
4858 strings that have already been loaded by previous calls to this
4859 function.
4860
4861 IT->add_overlay_start contains an additional overlay start
4862 position to consider for taking overlay strings from, if non-zero.
4863 This position comes into play when the overlay has an `invisible'
4864 property, and both before and after-strings. When we've skipped to
4865 the end of the overlay, because of its `invisible' property, we
4866 nevertheless want its before-string to appear.
4867 IT->add_overlay_start will contain the overlay start position
4868 in this case.
4869
4870 Overlay strings are sorted so that after-string strings come in
4871 front of before-string strings. Within before and after-strings,
4872 strings are sorted by overlay priority. See also function
4873 compare_overlay_entries. */
4874
4875 static void
4876 load_overlay_strings (struct it *it, int charpos)
4877 {
4878 extern Lisp_Object Qwindow, Qpriority;
4879 Lisp_Object overlay, window, str, invisible;
4880 struct Lisp_Overlay *ov;
4881 int start, end;
4882 int size = 20;
4883 int n = 0, i, j, invis_p;
4884 struct overlay_entry *entries
4885 = (struct overlay_entry *) alloca (size * sizeof *entries);
4886
4887 if (charpos <= 0)
4888 charpos = IT_CHARPOS (*it);
4889
4890 /* Append the overlay string STRING of overlay OVERLAY to vector
4891 `entries' which has size `size' and currently contains `n'
4892 elements. AFTER_P non-zero means STRING is an after-string of
4893 OVERLAY. */
4894 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4895 do \
4896 { \
4897 Lisp_Object priority; \
4898 \
4899 if (n == size) \
4900 { \
4901 int new_size = 2 * size; \
4902 struct overlay_entry *old = entries; \
4903 entries = \
4904 (struct overlay_entry *) alloca (new_size \
4905 * sizeof *entries); \
4906 memcpy (entries, old, size * sizeof *entries); \
4907 size = new_size; \
4908 } \
4909 \
4910 entries[n].string = (STRING); \
4911 entries[n].overlay = (OVERLAY); \
4912 priority = Foverlay_get ((OVERLAY), Qpriority); \
4913 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4914 entries[n].after_string_p = (AFTER_P); \
4915 ++n; \
4916 } \
4917 while (0)
4918
4919 /* Process overlay before the overlay center. */
4920 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4921 {
4922 XSETMISC (overlay, ov);
4923 xassert (OVERLAYP (overlay));
4924 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4925 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4926
4927 if (end < charpos)
4928 break;
4929
4930 /* Skip this overlay if it doesn't start or end at IT's current
4931 position. */
4932 if (end != charpos && start != charpos)
4933 continue;
4934
4935 /* Skip this overlay if it doesn't apply to IT->w. */
4936 window = Foverlay_get (overlay, Qwindow);
4937 if (WINDOWP (window) && XWINDOW (window) != it->w)
4938 continue;
4939
4940 /* If the text ``under'' the overlay is invisible, both before-
4941 and after-strings from this overlay are visible; start and
4942 end position are indistinguishable. */
4943 invisible = Foverlay_get (overlay, Qinvisible);
4944 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4945
4946 /* If overlay has a non-empty before-string, record it. */
4947 if ((start == charpos || (end == charpos && invis_p))
4948 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4949 && SCHARS (str))
4950 RECORD_OVERLAY_STRING (overlay, str, 0);
4951
4952 /* If overlay has a non-empty after-string, record it. */
4953 if ((end == charpos || (start == charpos && invis_p))
4954 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4955 && SCHARS (str))
4956 RECORD_OVERLAY_STRING (overlay, str, 1);
4957 }
4958
4959 /* Process overlays after the overlay center. */
4960 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4961 {
4962 XSETMISC (overlay, ov);
4963 xassert (OVERLAYP (overlay));
4964 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4965 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4966
4967 if (start > charpos)
4968 break;
4969
4970 /* Skip this overlay if it doesn't start or end at IT's current
4971 position. */
4972 if (end != charpos && start != charpos)
4973 continue;
4974
4975 /* Skip this overlay if it doesn't apply to IT->w. */
4976 window = Foverlay_get (overlay, Qwindow);
4977 if (WINDOWP (window) && XWINDOW (window) != it->w)
4978 continue;
4979
4980 /* If the text ``under'' the overlay is invisible, it has a zero
4981 dimension, and both before- and after-strings apply. */
4982 invisible = Foverlay_get (overlay, Qinvisible);
4983 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4984
4985 /* If overlay has a non-empty before-string, record it. */
4986 if ((start == charpos || (end == charpos && invis_p))
4987 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4988 && SCHARS (str))
4989 RECORD_OVERLAY_STRING (overlay, str, 0);
4990
4991 /* If overlay has a non-empty after-string, record it. */
4992 if ((end == charpos || (start == charpos && invis_p))
4993 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4994 && SCHARS (str))
4995 RECORD_OVERLAY_STRING (overlay, str, 1);
4996 }
4997
4998 #undef RECORD_OVERLAY_STRING
4999
5000 /* Sort entries. */
5001 if (n > 1)
5002 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5003
5004 /* Record the total number of strings to process. */
5005 it->n_overlay_strings = n;
5006
5007 /* IT->current.overlay_string_index is the number of overlay strings
5008 that have already been consumed by IT. Copy some of the
5009 remaining overlay strings to IT->overlay_strings. */
5010 i = 0;
5011 j = it->current.overlay_string_index;
5012 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5013 {
5014 it->overlay_strings[i] = entries[j].string;
5015 it->string_overlays[i++] = entries[j++].overlay;
5016 }
5017
5018 CHECK_IT (it);
5019 }
5020
5021
5022 /* Get the first chunk of overlay strings at IT's current buffer
5023 position, or at CHARPOS if that is > 0. Value is non-zero if at
5024 least one overlay string was found. */
5025
5026 static int
5027 get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
5028 {
5029 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5030 process. This fills IT->overlay_strings with strings, and sets
5031 IT->n_overlay_strings to the total number of strings to process.
5032 IT->pos.overlay_string_index has to be set temporarily to zero
5033 because load_overlay_strings needs this; it must be set to -1
5034 when no overlay strings are found because a zero value would
5035 indicate a position in the first overlay string. */
5036 it->current.overlay_string_index = 0;
5037 load_overlay_strings (it, charpos);
5038
5039 /* If we found overlay strings, set up IT to deliver display
5040 elements from the first one. Otherwise set up IT to deliver
5041 from current_buffer. */
5042 if (it->n_overlay_strings)
5043 {
5044 /* Make sure we know settings in current_buffer, so that we can
5045 restore meaningful values when we're done with the overlay
5046 strings. */
5047 if (compute_stop_p)
5048 compute_stop_pos (it);
5049 xassert (it->face_id >= 0);
5050
5051 /* Save IT's settings. They are restored after all overlay
5052 strings have been processed. */
5053 xassert (!compute_stop_p || it->sp == 0);
5054
5055 /* When called from handle_stop, there might be an empty display
5056 string loaded. In that case, don't bother saving it. */
5057 if (!STRINGP (it->string) || SCHARS (it->string))
5058 push_it (it);
5059
5060 /* Set up IT to deliver display elements from the first overlay
5061 string. */
5062 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5063 it->string = it->overlay_strings[0];
5064 it->from_overlay = Qnil;
5065 it->stop_charpos = 0;
5066 xassert (STRINGP (it->string));
5067 it->end_charpos = SCHARS (it->string);
5068 it->multibyte_p = STRING_MULTIBYTE (it->string);
5069 it->method = GET_FROM_STRING;
5070 return 1;
5071 }
5072
5073 it->current.overlay_string_index = -1;
5074 return 0;
5075 }
5076
5077 static int
5078 get_overlay_strings (struct it *it, int charpos)
5079 {
5080 it->string = Qnil;
5081 it->method = GET_FROM_BUFFER;
5082
5083 (void) get_overlay_strings_1 (it, charpos, 1);
5084
5085 CHECK_IT (it);
5086
5087 /* Value is non-zero if we found at least one overlay string. */
5088 return STRINGP (it->string);
5089 }
5090
5091
5092 \f
5093 /***********************************************************************
5094 Saving and restoring state
5095 ***********************************************************************/
5096
5097 /* Save current settings of IT on IT->stack. Called, for example,
5098 before setting up IT for an overlay string, to be able to restore
5099 IT's settings to what they were after the overlay string has been
5100 processed. */
5101
5102 static void
5103 push_it (struct it *it)
5104 {
5105 struct iterator_stack_entry *p;
5106
5107 xassert (it->sp < IT_STACK_SIZE);
5108 p = it->stack + it->sp;
5109
5110 p->stop_charpos = it->stop_charpos;
5111 p->prev_stop = it->prev_stop;
5112 p->base_level_stop = it->base_level_stop;
5113 p->cmp_it = it->cmp_it;
5114 xassert (it->face_id >= 0);
5115 p->face_id = it->face_id;
5116 p->string = it->string;
5117 p->method = it->method;
5118 p->from_overlay = it->from_overlay;
5119 switch (p->method)
5120 {
5121 case GET_FROM_IMAGE:
5122 p->u.image.object = it->object;
5123 p->u.image.image_id = it->image_id;
5124 p->u.image.slice = it->slice;
5125 break;
5126 case GET_FROM_STRETCH:
5127 p->u.stretch.object = it->object;
5128 break;
5129 }
5130 p->position = it->position;
5131 p->current = it->current;
5132 p->end_charpos = it->end_charpos;
5133 p->string_nchars = it->string_nchars;
5134 p->area = it->area;
5135 p->multibyte_p = it->multibyte_p;
5136 p->avoid_cursor_p = it->avoid_cursor_p;
5137 p->space_width = it->space_width;
5138 p->font_height = it->font_height;
5139 p->voffset = it->voffset;
5140 p->string_from_display_prop_p = it->string_from_display_prop_p;
5141 p->display_ellipsis_p = 0;
5142 p->line_wrap = it->line_wrap;
5143 ++it->sp;
5144 }
5145
5146 static void
5147 iterate_out_of_display_property (struct it *it)
5148 {
5149 /* Maybe initialize paragraph direction. If we are at the beginning
5150 of a new paragraph, next_element_from_buffer may not have a
5151 chance to do that. */
5152 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5153 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
5154 /* prev_stop can be zero, so check against BEGV as well. */
5155 while (it->bidi_it.charpos >= BEGV
5156 && it->prev_stop <= it->bidi_it.charpos
5157 && it->bidi_it.charpos < CHARPOS (it->position))
5158 bidi_move_to_visually_next (&it->bidi_it);
5159 /* Record the stop_pos we just crossed, for when we cross it
5160 back, maybe. */
5161 if (it->bidi_it.charpos > CHARPOS (it->position))
5162 it->prev_stop = CHARPOS (it->position);
5163 /* If we ended up not where pop_it put us, resync IT's
5164 positional members with the bidi iterator. */
5165 if (it->bidi_it.charpos != CHARPOS (it->position))
5166 {
5167 SET_TEXT_POS (it->position,
5168 it->bidi_it.charpos, it->bidi_it.bytepos);
5169 it->current.pos = it->position;
5170 }
5171 }
5172
5173 /* Restore IT's settings from IT->stack. Called, for example, when no
5174 more overlay strings must be processed, and we return to delivering
5175 display elements from a buffer, or when the end of a string from a
5176 `display' property is reached and we return to delivering display
5177 elements from an overlay string, or from a buffer. */
5178
5179 static void
5180 pop_it (struct it *it)
5181 {
5182 struct iterator_stack_entry *p;
5183
5184 xassert (it->sp > 0);
5185 --it->sp;
5186 p = it->stack + it->sp;
5187 it->stop_charpos = p->stop_charpos;
5188 it->prev_stop = p->prev_stop;
5189 it->base_level_stop = p->base_level_stop;
5190 it->cmp_it = p->cmp_it;
5191 it->face_id = p->face_id;
5192 it->current = p->current;
5193 it->position = p->position;
5194 it->string = p->string;
5195 it->from_overlay = p->from_overlay;
5196 if (NILP (it->string))
5197 SET_TEXT_POS (it->current.string_pos, -1, -1);
5198 it->method = p->method;
5199 switch (it->method)
5200 {
5201 case GET_FROM_IMAGE:
5202 it->image_id = p->u.image.image_id;
5203 it->object = p->u.image.object;
5204 it->slice = p->u.image.slice;
5205 break;
5206 case GET_FROM_STRETCH:
5207 it->object = p->u.comp.object;
5208 break;
5209 case GET_FROM_BUFFER:
5210 it->object = it->w->buffer;
5211 if (it->bidi_p)
5212 {
5213 /* Bidi-iterate until we get out of the portion of text, if
5214 any, covered by a `display' text property or an overlay
5215 with `display' property. (We cannot just jump there,
5216 because the internal coherency of the bidi iterator state
5217 can not be preserved across such jumps.) We also must
5218 determine the paragraph base direction if the overlay we
5219 just processed is at the beginning of a new
5220 paragraph. */
5221 iterate_out_of_display_property (it);
5222 }
5223 break;
5224 case GET_FROM_STRING:
5225 it->object = it->string;
5226 break;
5227 case GET_FROM_DISPLAY_VECTOR:
5228 if (it->s)
5229 it->method = GET_FROM_C_STRING;
5230 else if (STRINGP (it->string))
5231 it->method = GET_FROM_STRING;
5232 else
5233 {
5234 it->method = GET_FROM_BUFFER;
5235 it->object = it->w->buffer;
5236 }
5237 }
5238 it->end_charpos = p->end_charpos;
5239 it->string_nchars = p->string_nchars;
5240 it->area = p->area;
5241 it->multibyte_p = p->multibyte_p;
5242 it->avoid_cursor_p = p->avoid_cursor_p;
5243 it->space_width = p->space_width;
5244 it->font_height = p->font_height;
5245 it->voffset = p->voffset;
5246 it->string_from_display_prop_p = p->string_from_display_prop_p;
5247 it->line_wrap = p->line_wrap;
5248 }
5249
5250
5251 \f
5252 /***********************************************************************
5253 Moving over lines
5254 ***********************************************************************/
5255
5256 /* Set IT's current position to the previous line start. */
5257
5258 static void
5259 back_to_previous_line_start (struct it *it)
5260 {
5261 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5262 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5263 }
5264
5265
5266 /* Move IT to the next line start.
5267
5268 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5269 we skipped over part of the text (as opposed to moving the iterator
5270 continuously over the text). Otherwise, don't change the value
5271 of *SKIPPED_P.
5272
5273 Newlines may come from buffer text, overlay strings, or strings
5274 displayed via the `display' property. That's the reason we can't
5275 simply use find_next_newline_no_quit.
5276
5277 Note that this function may not skip over invisible text that is so
5278 because of text properties and immediately follows a newline. If
5279 it would, function reseat_at_next_visible_line_start, when called
5280 from set_iterator_to_next, would effectively make invisible
5281 characters following a newline part of the wrong glyph row, which
5282 leads to wrong cursor motion. */
5283
5284 static int
5285 forward_to_next_line_start (struct it *it, int *skipped_p)
5286 {
5287 int old_selective, newline_found_p, n;
5288 const int MAX_NEWLINE_DISTANCE = 500;
5289
5290 /* If already on a newline, just consume it to avoid unintended
5291 skipping over invisible text below. */
5292 if (it->what == IT_CHARACTER
5293 && it->c == '\n'
5294 && CHARPOS (it->position) == IT_CHARPOS (*it))
5295 {
5296 set_iterator_to_next (it, 0);
5297 it->c = 0;
5298 return 1;
5299 }
5300
5301 /* Don't handle selective display in the following. It's (a)
5302 unnecessary because it's done by the caller, and (b) leads to an
5303 infinite recursion because next_element_from_ellipsis indirectly
5304 calls this function. */
5305 old_selective = it->selective;
5306 it->selective = 0;
5307
5308 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5309 from buffer text. */
5310 for (n = newline_found_p = 0;
5311 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5312 n += STRINGP (it->string) ? 0 : 1)
5313 {
5314 if (!get_next_display_element (it))
5315 return 0;
5316 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5317 set_iterator_to_next (it, 0);
5318 }
5319
5320 /* If we didn't find a newline near enough, see if we can use a
5321 short-cut. */
5322 if (!newline_found_p)
5323 {
5324 int start = IT_CHARPOS (*it);
5325 int limit = find_next_newline_no_quit (start, 1);
5326 Lisp_Object pos;
5327
5328 xassert (!STRINGP (it->string));
5329
5330 /* If there isn't any `display' property in sight, and no
5331 overlays, we can just use the position of the newline in
5332 buffer text. */
5333 if (it->stop_charpos >= limit
5334 || ((pos = Fnext_single_property_change (make_number (start),
5335 Qdisplay,
5336 Qnil, make_number (limit)),
5337 NILP (pos))
5338 && next_overlay_change (start) == ZV))
5339 {
5340 IT_CHARPOS (*it) = limit;
5341 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5342 *skipped_p = newline_found_p = 1;
5343 }
5344 else
5345 {
5346 while (get_next_display_element (it)
5347 && !newline_found_p)
5348 {
5349 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5350 set_iterator_to_next (it, 0);
5351 }
5352 }
5353 }
5354
5355 it->selective = old_selective;
5356 return newline_found_p;
5357 }
5358
5359
5360 /* Set IT's current position to the previous visible line start. Skip
5361 invisible text that is so either due to text properties or due to
5362 selective display. Caution: this does not change IT->current_x and
5363 IT->hpos. */
5364
5365 static void
5366 back_to_previous_visible_line_start (struct it *it)
5367 {
5368 while (IT_CHARPOS (*it) > BEGV)
5369 {
5370 back_to_previous_line_start (it);
5371
5372 if (IT_CHARPOS (*it) <= BEGV)
5373 break;
5374
5375 /* If selective > 0, then lines indented more than its value are
5376 invisible. */
5377 if (it->selective > 0
5378 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5379 (double) it->selective)) /* iftc */
5380 continue;
5381
5382 /* Check the newline before point for invisibility. */
5383 {
5384 Lisp_Object prop;
5385 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5386 Qinvisible, it->window);
5387 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5388 continue;
5389 }
5390
5391 if (IT_CHARPOS (*it) <= BEGV)
5392 break;
5393
5394 {
5395 struct it it2;
5396 int pos;
5397 EMACS_INT beg, end;
5398 Lisp_Object val, overlay;
5399
5400 /* If newline is part of a composition, continue from start of composition */
5401 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5402 && beg < IT_CHARPOS (*it))
5403 goto replaced;
5404
5405 /* If newline is replaced by a display property, find start of overlay
5406 or interval and continue search from that point. */
5407 it2 = *it;
5408 pos = --IT_CHARPOS (it2);
5409 --IT_BYTEPOS (it2);
5410 it2.sp = 0;
5411 it2.string_from_display_prop_p = 0;
5412 if (handle_display_prop (&it2) == HANDLED_RETURN
5413 && !NILP (val = get_char_property_and_overlay
5414 (make_number (pos), Qdisplay, Qnil, &overlay))
5415 && (OVERLAYP (overlay)
5416 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5417 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5418 goto replaced;
5419
5420 /* Newline is not replaced by anything -- so we are done. */
5421 break;
5422
5423 replaced:
5424 if (beg < BEGV)
5425 beg = BEGV;
5426 IT_CHARPOS (*it) = beg;
5427 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5428 }
5429 }
5430
5431 it->continuation_lines_width = 0;
5432
5433 xassert (IT_CHARPOS (*it) >= BEGV);
5434 xassert (IT_CHARPOS (*it) == BEGV
5435 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5436 CHECK_IT (it);
5437 }
5438
5439
5440 /* Reseat iterator IT at the previous visible line start. Skip
5441 invisible text that is so either due to text properties or due to
5442 selective display. At the end, update IT's overlay information,
5443 face information etc. */
5444
5445 void
5446 reseat_at_previous_visible_line_start (struct it *it)
5447 {
5448 back_to_previous_visible_line_start (it);
5449 reseat (it, it->current.pos, 1);
5450 CHECK_IT (it);
5451 }
5452
5453
5454 /* Reseat iterator IT on the next visible line start in the current
5455 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5456 preceding the line start. Skip over invisible text that is so
5457 because of selective display. Compute faces, overlays etc at the
5458 new position. Note that this function does not skip over text that
5459 is invisible because of text properties. */
5460
5461 static void
5462 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5463 {
5464 int newline_found_p, skipped_p = 0;
5465
5466 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5467
5468 /* Skip over lines that are invisible because they are indented
5469 more than the value of IT->selective. */
5470 if (it->selective > 0)
5471 while (IT_CHARPOS (*it) < ZV
5472 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5473 (double) it->selective)) /* iftc */
5474 {
5475 xassert (IT_BYTEPOS (*it) == BEGV
5476 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5477 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5478 }
5479
5480 /* Position on the newline if that's what's requested. */
5481 if (on_newline_p && newline_found_p)
5482 {
5483 if (STRINGP (it->string))
5484 {
5485 if (IT_STRING_CHARPOS (*it) > 0)
5486 {
5487 --IT_STRING_CHARPOS (*it);
5488 --IT_STRING_BYTEPOS (*it);
5489 }
5490 }
5491 else if (IT_CHARPOS (*it) > BEGV)
5492 {
5493 --IT_CHARPOS (*it);
5494 --IT_BYTEPOS (*it);
5495 reseat (it, it->current.pos, 0);
5496 }
5497 }
5498 else if (skipped_p)
5499 reseat (it, it->current.pos, 0);
5500
5501 CHECK_IT (it);
5502 }
5503
5504
5505 \f
5506 /***********************************************************************
5507 Changing an iterator's position
5508 ***********************************************************************/
5509
5510 /* Change IT's current position to POS in current_buffer. If FORCE_P
5511 is non-zero, always check for text properties at the new position.
5512 Otherwise, text properties are only looked up if POS >=
5513 IT->check_charpos of a property. */
5514
5515 static void
5516 reseat (struct it *it, struct text_pos pos, int force_p)
5517 {
5518 int original_pos = IT_CHARPOS (*it);
5519
5520 reseat_1 (it, pos, 0);
5521
5522 /* Determine where to check text properties. Avoid doing it
5523 where possible because text property lookup is very expensive. */
5524 if (force_p
5525 || CHARPOS (pos) > it->stop_charpos
5526 || CHARPOS (pos) < original_pos)
5527 {
5528 if (it->bidi_p)
5529 {
5530 /* For bidi iteration, we need to prime prev_stop and
5531 base_level_stop with our best estimations. */
5532 if (CHARPOS (pos) < it->prev_stop)
5533 {
5534 handle_stop_backwards (it, BEGV);
5535 if (CHARPOS (pos) < it->base_level_stop)
5536 it->base_level_stop = 0;
5537 }
5538 else if (CHARPOS (pos) > it->stop_charpos
5539 && it->stop_charpos >= BEGV)
5540 handle_stop_backwards (it, it->stop_charpos);
5541 else /* force_p */
5542 handle_stop (it);
5543 }
5544 else
5545 {
5546 handle_stop (it);
5547 it->prev_stop = it->base_level_stop = 0;
5548 }
5549
5550 }
5551
5552 CHECK_IT (it);
5553 }
5554
5555
5556 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5557 IT->stop_pos to POS, also. */
5558
5559 static void
5560 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5561 {
5562 /* Don't call this function when scanning a C string. */
5563 xassert (it->s == NULL);
5564
5565 /* POS must be a reasonable value. */
5566 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5567
5568 it->current.pos = it->position = pos;
5569 it->end_charpos = ZV;
5570 it->dpvec = NULL;
5571 it->current.dpvec_index = -1;
5572 it->current.overlay_string_index = -1;
5573 IT_STRING_CHARPOS (*it) = -1;
5574 IT_STRING_BYTEPOS (*it) = -1;
5575 it->string = Qnil;
5576 it->string_from_display_prop_p = 0;
5577 it->method = GET_FROM_BUFFER;
5578 it->object = it->w->buffer;
5579 it->area = TEXT_AREA;
5580 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5581 it->sp = 0;
5582 it->string_from_display_prop_p = 0;
5583 it->face_before_selective_p = 0;
5584 if (it->bidi_p)
5585 it->bidi_it.first_elt = 1;
5586
5587 if (set_stop_p)
5588 {
5589 it->stop_charpos = CHARPOS (pos);
5590 it->base_level_stop = CHARPOS (pos);
5591 }
5592 }
5593
5594
5595 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5596 If S is non-null, it is a C string to iterate over. Otherwise,
5597 STRING gives a Lisp string to iterate over.
5598
5599 If PRECISION > 0, don't return more then PRECISION number of
5600 characters from the string.
5601
5602 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5603 characters have been returned. FIELD_WIDTH < 0 means an infinite
5604 field width.
5605
5606 MULTIBYTE = 0 means disable processing of multibyte characters,
5607 MULTIBYTE > 0 means enable it,
5608 MULTIBYTE < 0 means use IT->multibyte_p.
5609
5610 IT must be initialized via a prior call to init_iterator before
5611 calling this function. */
5612
5613 static void
5614 reseat_to_string (struct it *it, unsigned char *s, Lisp_Object string,
5615 int charpos, int precision, int field_width, int multibyte)
5616 {
5617 /* No region in strings. */
5618 it->region_beg_charpos = it->region_end_charpos = -1;
5619
5620 /* No text property checks performed by default, but see below. */
5621 it->stop_charpos = -1;
5622
5623 /* Set iterator position and end position. */
5624 memset (&it->current, 0, sizeof it->current);
5625 it->current.overlay_string_index = -1;
5626 it->current.dpvec_index = -1;
5627 xassert (charpos >= 0);
5628
5629 /* If STRING is specified, use its multibyteness, otherwise use the
5630 setting of MULTIBYTE, if specified. */
5631 if (multibyte >= 0)
5632 it->multibyte_p = multibyte > 0;
5633
5634 if (s == NULL)
5635 {
5636 xassert (STRINGP (string));
5637 it->string = string;
5638 it->s = NULL;
5639 it->end_charpos = it->string_nchars = SCHARS (string);
5640 it->method = GET_FROM_STRING;
5641 it->current.string_pos = string_pos (charpos, string);
5642 }
5643 else
5644 {
5645 it->s = s;
5646 it->string = Qnil;
5647
5648 /* Note that we use IT->current.pos, not it->current.string_pos,
5649 for displaying C strings. */
5650 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5651 if (it->multibyte_p)
5652 {
5653 it->current.pos = c_string_pos (charpos, s, 1);
5654 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5655 }
5656 else
5657 {
5658 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5659 it->end_charpos = it->string_nchars = strlen (s);
5660 }
5661
5662 it->method = GET_FROM_C_STRING;
5663 }
5664
5665 /* PRECISION > 0 means don't return more than PRECISION characters
5666 from the string. */
5667 if (precision > 0 && it->end_charpos - charpos > precision)
5668 it->end_charpos = it->string_nchars = charpos + precision;
5669
5670 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5671 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5672 FIELD_WIDTH < 0 means infinite field width. This is useful for
5673 padding with `-' at the end of a mode line. */
5674 if (field_width < 0)
5675 field_width = INFINITY;
5676 if (field_width > it->end_charpos - charpos)
5677 it->end_charpos = charpos + field_width;
5678
5679 /* Use the standard display table for displaying strings. */
5680 if (DISP_TABLE_P (Vstandard_display_table))
5681 it->dp = XCHAR_TABLE (Vstandard_display_table);
5682
5683 it->stop_charpos = charpos;
5684 if (s == NULL && it->multibyte_p)
5685 {
5686 EMACS_INT endpos = SCHARS (it->string);
5687 if (endpos > it->end_charpos)
5688 endpos = it->end_charpos;
5689 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5690 it->string);
5691 }
5692 CHECK_IT (it);
5693 }
5694
5695
5696 \f
5697 /***********************************************************************
5698 Iteration
5699 ***********************************************************************/
5700
5701 /* Map enum it_method value to corresponding next_element_from_* function. */
5702
5703 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5704 {
5705 next_element_from_buffer,
5706 next_element_from_display_vector,
5707 next_element_from_string,
5708 next_element_from_c_string,
5709 next_element_from_image,
5710 next_element_from_stretch
5711 };
5712
5713 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5714
5715
5716 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5717 (possibly with the following characters). */
5718
5719 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5720 ((IT)->cmp_it.id >= 0 \
5721 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5722 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5723 END_CHARPOS, (IT)->w, \
5724 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5725 (IT)->string)))
5726
5727
5728 /* Load IT's display element fields with information about the next
5729 display element from the current position of IT. Value is zero if
5730 end of buffer (or C string) is reached. */
5731
5732 static struct frame *last_escape_glyph_frame = NULL;
5733 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5734 static int last_escape_glyph_merged_face_id = 0;
5735
5736 int
5737 get_next_display_element (struct it *it)
5738 {
5739 /* Non-zero means that we found a display element. Zero means that
5740 we hit the end of what we iterate over. Performance note: the
5741 function pointer `method' used here turns out to be faster than
5742 using a sequence of if-statements. */
5743 int success_p;
5744
5745 get_next:
5746 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5747
5748 if (it->what == IT_CHARACTER)
5749 {
5750 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5751 and only if (a) the resolved directionality of that character
5752 is R..." */
5753 /* FIXME: Do we need an exception for characters from display
5754 tables? */
5755 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5756 it->c = bidi_mirror_char (it->c);
5757 /* Map via display table or translate control characters.
5758 IT->c, IT->len etc. have been set to the next character by
5759 the function call above. If we have a display table, and it
5760 contains an entry for IT->c, translate it. Don't do this if
5761 IT->c itself comes from a display table, otherwise we could
5762 end up in an infinite recursion. (An alternative could be to
5763 count the recursion depth of this function and signal an
5764 error when a certain maximum depth is reached.) Is it worth
5765 it? */
5766 if (success_p && it->dpvec == NULL)
5767 {
5768 Lisp_Object dv;
5769 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5770 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5771 nbsp_or_shy = char_is_other;
5772 int decoded = it->c;
5773
5774 if (it->dp
5775 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5776 VECTORP (dv)))
5777 {
5778 struct Lisp_Vector *v = XVECTOR (dv);
5779
5780 /* Return the first character from the display table
5781 entry, if not empty. If empty, don't display the
5782 current character. */
5783 if (v->size)
5784 {
5785 it->dpvec_char_len = it->len;
5786 it->dpvec = v->contents;
5787 it->dpend = v->contents + v->size;
5788 it->current.dpvec_index = 0;
5789 it->dpvec_face_id = -1;
5790 it->saved_face_id = it->face_id;
5791 it->method = GET_FROM_DISPLAY_VECTOR;
5792 it->ellipsis_p = 0;
5793 }
5794 else
5795 {
5796 set_iterator_to_next (it, 0);
5797 }
5798 goto get_next;
5799 }
5800
5801 if (unibyte_display_via_language_environment
5802 && !ASCII_CHAR_P (it->c))
5803 decoded = DECODE_CHAR (unibyte, it->c);
5804
5805 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5806 {
5807 if (it->multibyte_p)
5808 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5809 : it->c == 0xAD ? char_is_soft_hyphen
5810 : char_is_other);
5811 else if (unibyte_display_via_language_environment)
5812 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5813 : decoded == 0xAD ? char_is_soft_hyphen
5814 : char_is_other);
5815 }
5816
5817 /* Translate control characters into `\003' or `^C' form.
5818 Control characters coming from a display table entry are
5819 currently not translated because we use IT->dpvec to hold
5820 the translation. This could easily be changed but I
5821 don't believe that it is worth doing.
5822
5823 If it->multibyte_p is nonzero, non-printable non-ASCII
5824 characters are also translated to octal form.
5825
5826 If it->multibyte_p is zero, eight-bit characters that
5827 don't have corresponding multibyte char code are also
5828 translated to octal form. */
5829 if ((it->c < ' '
5830 ? (it->area != TEXT_AREA
5831 /* In mode line, treat \n, \t like other crl chars. */
5832 || (it->c != '\t'
5833 && it->glyph_row
5834 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5835 || (it->c != '\n' && it->c != '\t'))
5836 : (nbsp_or_shy
5837 || (it->multibyte_p
5838 ? ! CHAR_PRINTABLE_P (it->c)
5839 : (! unibyte_display_via_language_environment
5840 ? it->c >= 0x80
5841 : (decoded >= 0x80 && decoded < 0xA0))))))
5842 {
5843 /* IT->c is a control character which must be displayed
5844 either as '\003' or as `^C' where the '\\' and '^'
5845 can be defined in the display table. Fill
5846 IT->ctl_chars with glyphs for what we have to
5847 display. Then, set IT->dpvec to these glyphs. */
5848 Lisp_Object gc;
5849 int ctl_len;
5850 int face_id, lface_id = 0 ;
5851 int escape_glyph;
5852
5853 /* Handle control characters with ^. */
5854
5855 if (it->c < 128 && it->ctl_arrow_p)
5856 {
5857 int g;
5858
5859 g = '^'; /* default glyph for Control */
5860 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5861 if (it->dp
5862 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5863 && GLYPH_CODE_CHAR_VALID_P (gc))
5864 {
5865 g = GLYPH_CODE_CHAR (gc);
5866 lface_id = GLYPH_CODE_FACE (gc);
5867 }
5868 if (lface_id)
5869 {
5870 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5871 }
5872 else if (it->f == last_escape_glyph_frame
5873 && it->face_id == last_escape_glyph_face_id)
5874 {
5875 face_id = last_escape_glyph_merged_face_id;
5876 }
5877 else
5878 {
5879 /* Merge the escape-glyph face into the current face. */
5880 face_id = merge_faces (it->f, Qescape_glyph, 0,
5881 it->face_id);
5882 last_escape_glyph_frame = it->f;
5883 last_escape_glyph_face_id = it->face_id;
5884 last_escape_glyph_merged_face_id = face_id;
5885 }
5886
5887 XSETINT (it->ctl_chars[0], g);
5888 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5889 ctl_len = 2;
5890 goto display_control;
5891 }
5892
5893 /* Handle non-break space in the mode where it only gets
5894 highlighting. */
5895
5896 if (EQ (Vnobreak_char_display, Qt)
5897 && nbsp_or_shy == char_is_nbsp)
5898 {
5899 /* Merge the no-break-space face into the current face. */
5900 face_id = merge_faces (it->f, Qnobreak_space, 0,
5901 it->face_id);
5902
5903 it->c = ' ';
5904 XSETINT (it->ctl_chars[0], ' ');
5905 ctl_len = 1;
5906 goto display_control;
5907 }
5908
5909 /* Handle sequences that start with the "escape glyph". */
5910
5911 /* the default escape glyph is \. */
5912 escape_glyph = '\\';
5913
5914 if (it->dp
5915 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5916 && GLYPH_CODE_CHAR_VALID_P (gc))
5917 {
5918 escape_glyph = GLYPH_CODE_CHAR (gc);
5919 lface_id = GLYPH_CODE_FACE (gc);
5920 }
5921 if (lface_id)
5922 {
5923 /* The display table specified a face.
5924 Merge it into face_id and also into escape_glyph. */
5925 face_id = merge_faces (it->f, Qt, lface_id,
5926 it->face_id);
5927 }
5928 else if (it->f == last_escape_glyph_frame
5929 && it->face_id == last_escape_glyph_face_id)
5930 {
5931 face_id = last_escape_glyph_merged_face_id;
5932 }
5933 else
5934 {
5935 /* Merge the escape-glyph face into the current face. */
5936 face_id = merge_faces (it->f, Qescape_glyph, 0,
5937 it->face_id);
5938 last_escape_glyph_frame = it->f;
5939 last_escape_glyph_face_id = it->face_id;
5940 last_escape_glyph_merged_face_id = face_id;
5941 }
5942
5943 /* Handle soft hyphens in the mode where they only get
5944 highlighting. */
5945
5946 if (EQ (Vnobreak_char_display, Qt)
5947 && nbsp_or_shy == char_is_soft_hyphen)
5948 {
5949 it->c = '-';
5950 XSETINT (it->ctl_chars[0], '-');
5951 ctl_len = 1;
5952 goto display_control;
5953 }
5954
5955 /* Handle non-break space and soft hyphen
5956 with the escape glyph. */
5957
5958 if (nbsp_or_shy)
5959 {
5960 XSETINT (it->ctl_chars[0], escape_glyph);
5961 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5962 XSETINT (it->ctl_chars[1], it->c);
5963 ctl_len = 2;
5964 goto display_control;
5965 }
5966
5967 {
5968 unsigned char str[MAX_MULTIBYTE_LENGTH];
5969 int len;
5970 int i;
5971
5972 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5973 if (CHAR_BYTE8_P (it->c))
5974 {
5975 str[0] = CHAR_TO_BYTE8 (it->c);
5976 len = 1;
5977 }
5978 else if (it->c < 256)
5979 {
5980 str[0] = it->c;
5981 len = 1;
5982 }
5983 else
5984 {
5985 /* It's an invalid character, which shouldn't
5986 happen actually, but due to bugs it may
5987 happen. Let's print the char as is, there's
5988 not much meaningful we can do with it. */
5989 str[0] = it->c;
5990 str[1] = it->c >> 8;
5991 str[2] = it->c >> 16;
5992 str[3] = it->c >> 24;
5993 len = 4;
5994 }
5995
5996 for (i = 0; i < len; i++)
5997 {
5998 int g;
5999 XSETINT (it->ctl_chars[i * 4], escape_glyph);
6000 /* Insert three more glyphs into IT->ctl_chars for
6001 the octal display of the character. */
6002 g = ((str[i] >> 6) & 7) + '0';
6003 XSETINT (it->ctl_chars[i * 4 + 1], g);
6004 g = ((str[i] >> 3) & 7) + '0';
6005 XSETINT (it->ctl_chars[i * 4 + 2], g);
6006 g = (str[i] & 7) + '0';
6007 XSETINT (it->ctl_chars[i * 4 + 3], g);
6008 }
6009 ctl_len = len * 4;
6010 }
6011
6012 display_control:
6013 /* Set up IT->dpvec and return first character from it. */
6014 it->dpvec_char_len = it->len;
6015 it->dpvec = it->ctl_chars;
6016 it->dpend = it->dpvec + ctl_len;
6017 it->current.dpvec_index = 0;
6018 it->dpvec_face_id = face_id;
6019 it->saved_face_id = it->face_id;
6020 it->method = GET_FROM_DISPLAY_VECTOR;
6021 it->ellipsis_p = 0;
6022 goto get_next;
6023 }
6024 }
6025 }
6026
6027 #ifdef HAVE_WINDOW_SYSTEM
6028 /* Adjust face id for a multibyte character. There are no multibyte
6029 character in unibyte text. */
6030 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6031 && it->multibyte_p
6032 && success_p
6033 && FRAME_WINDOW_P (it->f))
6034 {
6035 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6036
6037 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6038 {
6039 /* Automatic composition with glyph-string. */
6040 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6041
6042 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6043 }
6044 else
6045 {
6046 int pos = (it->s ? -1
6047 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6048 : IT_CHARPOS (*it));
6049
6050 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
6051 }
6052 }
6053 #endif
6054
6055 /* Is this character the last one of a run of characters with
6056 box? If yes, set IT->end_of_box_run_p to 1. */
6057 if (it->face_box_p
6058 && it->s == NULL)
6059 {
6060 if (it->method == GET_FROM_STRING && it->sp)
6061 {
6062 int face_id = underlying_face_id (it);
6063 struct face *face = FACE_FROM_ID (it->f, face_id);
6064
6065 if (face)
6066 {
6067 if (face->box == FACE_NO_BOX)
6068 {
6069 /* If the box comes from face properties in a
6070 display string, check faces in that string. */
6071 int string_face_id = face_after_it_pos (it);
6072 it->end_of_box_run_p
6073 = (FACE_FROM_ID (it->f, string_face_id)->box
6074 == FACE_NO_BOX);
6075 }
6076 /* Otherwise, the box comes from the underlying face.
6077 If this is the last string character displayed, check
6078 the next buffer location. */
6079 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6080 && (it->current.overlay_string_index
6081 == it->n_overlay_strings - 1))
6082 {
6083 EMACS_INT ignore;
6084 int next_face_id;
6085 struct text_pos pos = it->current.pos;
6086 INC_TEXT_POS (pos, it->multibyte_p);
6087
6088 next_face_id = face_at_buffer_position
6089 (it->w, CHARPOS (pos), it->region_beg_charpos,
6090 it->region_end_charpos, &ignore,
6091 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6092 -1);
6093 it->end_of_box_run_p
6094 = (FACE_FROM_ID (it->f, next_face_id)->box
6095 == FACE_NO_BOX);
6096 }
6097 }
6098 }
6099 else
6100 {
6101 int face_id = face_after_it_pos (it);
6102 it->end_of_box_run_p
6103 = (face_id != it->face_id
6104 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6105 }
6106 }
6107
6108 /* Value is 0 if end of buffer or string reached. */
6109 return success_p;
6110 }
6111
6112
6113 /* Move IT to the next display element.
6114
6115 RESEAT_P non-zero means if called on a newline in buffer text,
6116 skip to the next visible line start.
6117
6118 Functions get_next_display_element and set_iterator_to_next are
6119 separate because I find this arrangement easier to handle than a
6120 get_next_display_element function that also increments IT's
6121 position. The way it is we can first look at an iterator's current
6122 display element, decide whether it fits on a line, and if it does,
6123 increment the iterator position. The other way around we probably
6124 would either need a flag indicating whether the iterator has to be
6125 incremented the next time, or we would have to implement a
6126 decrement position function which would not be easy to write. */
6127
6128 void
6129 set_iterator_to_next (struct it *it, int reseat_p)
6130 {
6131 /* Reset flags indicating start and end of a sequence of characters
6132 with box. Reset them at the start of this function because
6133 moving the iterator to a new position might set them. */
6134 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6135
6136 switch (it->method)
6137 {
6138 case GET_FROM_BUFFER:
6139 /* The current display element of IT is a character from
6140 current_buffer. Advance in the buffer, and maybe skip over
6141 invisible lines that are so because of selective display. */
6142 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6143 reseat_at_next_visible_line_start (it, 0);
6144 else if (it->cmp_it.id >= 0)
6145 {
6146 /* We are currently getting glyphs from a composition. */
6147 int i;
6148
6149 if (! it->bidi_p)
6150 {
6151 IT_CHARPOS (*it) += it->cmp_it.nchars;
6152 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6153 if (it->cmp_it.to < it->cmp_it.nglyphs)
6154 {
6155 it->cmp_it.from = it->cmp_it.to;
6156 }
6157 else
6158 {
6159 it->cmp_it.id = -1;
6160 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6161 IT_BYTEPOS (*it),
6162 it->stop_charpos, Qnil);
6163 }
6164 }
6165 else if (! it->cmp_it.reversed_p)
6166 {
6167 /* Composition created while scanning forward. */
6168 /* Update IT's char/byte positions to point to the first
6169 character of the next grapheme cluster, or to the
6170 character visually after the current composition. */
6171 for (i = 0; i < it->cmp_it.nchars; i++)
6172 bidi_move_to_visually_next (&it->bidi_it);
6173 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6174 IT_CHARPOS (*it) = it->bidi_it.charpos;
6175
6176 if (it->cmp_it.to < it->cmp_it.nglyphs)
6177 {
6178 /* Proceed to the next grapheme cluster. */
6179 it->cmp_it.from = it->cmp_it.to;
6180 }
6181 else
6182 {
6183 /* No more grapheme clusters in this composition.
6184 Find the next stop position. */
6185 EMACS_INT stop = it->stop_charpos;
6186 if (it->bidi_it.scan_dir < 0)
6187 /* Now we are scanning backward and don't know
6188 where to stop. */
6189 stop = -1;
6190 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6191 IT_BYTEPOS (*it), stop, Qnil);
6192 }
6193 }
6194 else
6195 {
6196 /* Composition created while scanning backward. */
6197 /* Update IT's char/byte positions to point to the last
6198 character of the previous grapheme cluster, or the
6199 character visually after the current composition. */
6200 for (i = 0; i < it->cmp_it.nchars; i++)
6201 bidi_move_to_visually_next (&it->bidi_it);
6202 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6203 IT_CHARPOS (*it) = it->bidi_it.charpos;
6204 if (it->cmp_it.from > 0)
6205 {
6206 /* Proceed to the previous grapheme cluster. */
6207 it->cmp_it.to = it->cmp_it.from;
6208 }
6209 else
6210 {
6211 /* No more grapheme clusters in this composition.
6212 Find the next stop position. */
6213 EMACS_INT stop = it->stop_charpos;
6214 if (it->bidi_it.scan_dir < 0)
6215 /* Now we are scanning backward and don't know
6216 where to stop. */
6217 stop = -1;
6218 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6219 IT_BYTEPOS (*it), stop, Qnil);
6220 }
6221 }
6222 }
6223 else
6224 {
6225 xassert (it->len != 0);
6226
6227 if (!it->bidi_p)
6228 {
6229 IT_BYTEPOS (*it) += it->len;
6230 IT_CHARPOS (*it) += 1;
6231 }
6232 else
6233 {
6234 int prev_scan_dir = it->bidi_it.scan_dir;
6235 /* If this is a new paragraph, determine its base
6236 direction (a.k.a. its base embedding level). */
6237 if (it->bidi_it.new_paragraph)
6238 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6239 bidi_move_to_visually_next (&it->bidi_it);
6240 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6241 IT_CHARPOS (*it) = it->bidi_it.charpos;
6242 if (prev_scan_dir != it->bidi_it.scan_dir)
6243 {
6244 /* As the scan direction was changed, we must
6245 re-compute the stop position for composition. */
6246 EMACS_INT stop = it->stop_charpos;
6247 if (it->bidi_it.scan_dir < 0)
6248 stop = -1;
6249 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6250 IT_BYTEPOS (*it), stop, Qnil);
6251 }
6252 }
6253 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6254 }
6255 break;
6256
6257 case GET_FROM_C_STRING:
6258 /* Current display element of IT is from a C string. */
6259 IT_BYTEPOS (*it) += it->len;
6260 IT_CHARPOS (*it) += 1;
6261 break;
6262
6263 case GET_FROM_DISPLAY_VECTOR:
6264 /* Current display element of IT is from a display table entry.
6265 Advance in the display table definition. Reset it to null if
6266 end reached, and continue with characters from buffers/
6267 strings. */
6268 ++it->current.dpvec_index;
6269
6270 /* Restore face of the iterator to what they were before the
6271 display vector entry (these entries may contain faces). */
6272 it->face_id = it->saved_face_id;
6273
6274 if (it->dpvec + it->current.dpvec_index == it->dpend)
6275 {
6276 int recheck_faces = it->ellipsis_p;
6277
6278 if (it->s)
6279 it->method = GET_FROM_C_STRING;
6280 else if (STRINGP (it->string))
6281 it->method = GET_FROM_STRING;
6282 else
6283 {
6284 it->method = GET_FROM_BUFFER;
6285 it->object = it->w->buffer;
6286 }
6287
6288 it->dpvec = NULL;
6289 it->current.dpvec_index = -1;
6290
6291 /* Skip over characters which were displayed via IT->dpvec. */
6292 if (it->dpvec_char_len < 0)
6293 reseat_at_next_visible_line_start (it, 1);
6294 else if (it->dpvec_char_len > 0)
6295 {
6296 if (it->method == GET_FROM_STRING
6297 && it->n_overlay_strings > 0)
6298 it->ignore_overlay_strings_at_pos_p = 1;
6299 it->len = it->dpvec_char_len;
6300 set_iterator_to_next (it, reseat_p);
6301 }
6302
6303 /* Maybe recheck faces after display vector */
6304 if (recheck_faces)
6305 it->stop_charpos = IT_CHARPOS (*it);
6306 }
6307 break;
6308
6309 case GET_FROM_STRING:
6310 /* Current display element is a character from a Lisp string. */
6311 xassert (it->s == NULL && STRINGP (it->string));
6312 if (it->cmp_it.id >= 0)
6313 {
6314 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6315 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6316 if (it->cmp_it.to < it->cmp_it.nglyphs)
6317 it->cmp_it.from = it->cmp_it.to;
6318 else
6319 {
6320 it->cmp_it.id = -1;
6321 composition_compute_stop_pos (&it->cmp_it,
6322 IT_STRING_CHARPOS (*it),
6323 IT_STRING_BYTEPOS (*it),
6324 it->stop_charpos, it->string);
6325 }
6326 }
6327 else
6328 {
6329 IT_STRING_BYTEPOS (*it) += it->len;
6330 IT_STRING_CHARPOS (*it) += 1;
6331 }
6332
6333 consider_string_end:
6334
6335 if (it->current.overlay_string_index >= 0)
6336 {
6337 /* IT->string is an overlay string. Advance to the
6338 next, if there is one. */
6339 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6340 {
6341 it->ellipsis_p = 0;
6342 next_overlay_string (it);
6343 if (it->ellipsis_p)
6344 setup_for_ellipsis (it, 0);
6345 }
6346 }
6347 else
6348 {
6349 /* IT->string is not an overlay string. If we reached
6350 its end, and there is something on IT->stack, proceed
6351 with what is on the stack. This can be either another
6352 string, this time an overlay string, or a buffer. */
6353 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6354 && it->sp > 0)
6355 {
6356 pop_it (it);
6357 if (it->method == GET_FROM_STRING)
6358 goto consider_string_end;
6359 }
6360 }
6361 break;
6362
6363 case GET_FROM_IMAGE:
6364 case GET_FROM_STRETCH:
6365 /* The position etc with which we have to proceed are on
6366 the stack. The position may be at the end of a string,
6367 if the `display' property takes up the whole string. */
6368 xassert (it->sp > 0);
6369 pop_it (it);
6370 if (it->method == GET_FROM_STRING)
6371 goto consider_string_end;
6372 break;
6373
6374 default:
6375 /* There are no other methods defined, so this should be a bug. */
6376 abort ();
6377 }
6378
6379 xassert (it->method != GET_FROM_STRING
6380 || (STRINGP (it->string)
6381 && IT_STRING_CHARPOS (*it) >= 0));
6382 }
6383
6384 /* Load IT's display element fields with information about the next
6385 display element which comes from a display table entry or from the
6386 result of translating a control character to one of the forms `^C'
6387 or `\003'.
6388
6389 IT->dpvec holds the glyphs to return as characters.
6390 IT->saved_face_id holds the face id before the display vector--it
6391 is restored into IT->face_id in set_iterator_to_next. */
6392
6393 static int
6394 next_element_from_display_vector (struct it *it)
6395 {
6396 Lisp_Object gc;
6397
6398 /* Precondition. */
6399 xassert (it->dpvec && it->current.dpvec_index >= 0);
6400
6401 it->face_id = it->saved_face_id;
6402
6403 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6404 That seemed totally bogus - so I changed it... */
6405 gc = it->dpvec[it->current.dpvec_index];
6406
6407 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6408 {
6409 it->c = GLYPH_CODE_CHAR (gc);
6410 it->len = CHAR_BYTES (it->c);
6411
6412 /* The entry may contain a face id to use. Such a face id is
6413 the id of a Lisp face, not a realized face. A face id of
6414 zero means no face is specified. */
6415 if (it->dpvec_face_id >= 0)
6416 it->face_id = it->dpvec_face_id;
6417 else
6418 {
6419 int lface_id = GLYPH_CODE_FACE (gc);
6420 if (lface_id > 0)
6421 it->face_id = merge_faces (it->f, Qt, lface_id,
6422 it->saved_face_id);
6423 }
6424 }
6425 else
6426 /* Display table entry is invalid. Return a space. */
6427 it->c = ' ', it->len = 1;
6428
6429 /* Don't change position and object of the iterator here. They are
6430 still the values of the character that had this display table
6431 entry or was translated, and that's what we want. */
6432 it->what = IT_CHARACTER;
6433 return 1;
6434 }
6435
6436
6437 /* Load IT with the next display element from Lisp string IT->string.
6438 IT->current.string_pos is the current position within the string.
6439 If IT->current.overlay_string_index >= 0, the Lisp string is an
6440 overlay string. */
6441
6442 static int
6443 next_element_from_string (struct it *it)
6444 {
6445 struct text_pos position;
6446
6447 xassert (STRINGP (it->string));
6448 xassert (IT_STRING_CHARPOS (*it) >= 0);
6449 position = it->current.string_pos;
6450
6451 /* Time to check for invisible text? */
6452 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6453 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6454 {
6455 handle_stop (it);
6456
6457 /* Since a handler may have changed IT->method, we must
6458 recurse here. */
6459 return GET_NEXT_DISPLAY_ELEMENT (it);
6460 }
6461
6462 if (it->current.overlay_string_index >= 0)
6463 {
6464 /* Get the next character from an overlay string. In overlay
6465 strings, There is no field width or padding with spaces to
6466 do. */
6467 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6468 {
6469 it->what = IT_EOB;
6470 return 0;
6471 }
6472 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6473 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6474 && next_element_from_composition (it))
6475 {
6476 return 1;
6477 }
6478 else if (STRING_MULTIBYTE (it->string))
6479 {
6480 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6481 const unsigned char *s = (SDATA (it->string)
6482 + IT_STRING_BYTEPOS (*it));
6483 it->c = string_char_and_length (s, &it->len);
6484 }
6485 else
6486 {
6487 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6488 it->len = 1;
6489 }
6490 }
6491 else
6492 {
6493 /* Get the next character from a Lisp string that is not an
6494 overlay string. Such strings come from the mode line, for
6495 example. We may have to pad with spaces, or truncate the
6496 string. See also next_element_from_c_string. */
6497 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6498 {
6499 it->what = IT_EOB;
6500 return 0;
6501 }
6502 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6503 {
6504 /* Pad with spaces. */
6505 it->c = ' ', it->len = 1;
6506 CHARPOS (position) = BYTEPOS (position) = -1;
6507 }
6508 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6509 IT_STRING_BYTEPOS (*it), it->string_nchars)
6510 && next_element_from_composition (it))
6511 {
6512 return 1;
6513 }
6514 else if (STRING_MULTIBYTE (it->string))
6515 {
6516 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6517 const unsigned char *s = (SDATA (it->string)
6518 + IT_STRING_BYTEPOS (*it));
6519 it->c = string_char_and_length (s, &it->len);
6520 }
6521 else
6522 {
6523 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6524 it->len = 1;
6525 }
6526 }
6527
6528 /* Record what we have and where it came from. */
6529 it->what = IT_CHARACTER;
6530 it->object = it->string;
6531 it->position = position;
6532 return 1;
6533 }
6534
6535
6536 /* Load IT with next display element from C string IT->s.
6537 IT->string_nchars is the maximum number of characters to return
6538 from the string. IT->end_charpos may be greater than
6539 IT->string_nchars when this function is called, in which case we
6540 may have to return padding spaces. Value is zero if end of string
6541 reached, including padding spaces. */
6542
6543 static int
6544 next_element_from_c_string (struct it *it)
6545 {
6546 int success_p = 1;
6547
6548 xassert (it->s);
6549 it->what = IT_CHARACTER;
6550 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6551 it->object = Qnil;
6552
6553 /* IT's position can be greater IT->string_nchars in case a field
6554 width or precision has been specified when the iterator was
6555 initialized. */
6556 if (IT_CHARPOS (*it) >= it->end_charpos)
6557 {
6558 /* End of the game. */
6559 it->what = IT_EOB;
6560 success_p = 0;
6561 }
6562 else if (IT_CHARPOS (*it) >= it->string_nchars)
6563 {
6564 /* Pad with spaces. */
6565 it->c = ' ', it->len = 1;
6566 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6567 }
6568 else if (it->multibyte_p)
6569 {
6570 /* Implementation note: The calls to strlen apparently aren't a
6571 performance problem because there is no noticeable performance
6572 difference between Emacs running in unibyte or multibyte mode. */
6573 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6574 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6575 }
6576 else
6577 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6578
6579 return success_p;
6580 }
6581
6582
6583 /* Set up IT to return characters from an ellipsis, if appropriate.
6584 The definition of the ellipsis glyphs may come from a display table
6585 entry. This function fills IT with the first glyph from the
6586 ellipsis if an ellipsis is to be displayed. */
6587
6588 static int
6589 next_element_from_ellipsis (struct it *it)
6590 {
6591 if (it->selective_display_ellipsis_p)
6592 setup_for_ellipsis (it, it->len);
6593 else
6594 {
6595 /* The face at the current position may be different from the
6596 face we find after the invisible text. Remember what it
6597 was in IT->saved_face_id, and signal that it's there by
6598 setting face_before_selective_p. */
6599 it->saved_face_id = it->face_id;
6600 it->method = GET_FROM_BUFFER;
6601 it->object = it->w->buffer;
6602 reseat_at_next_visible_line_start (it, 1);
6603 it->face_before_selective_p = 1;
6604 }
6605
6606 return GET_NEXT_DISPLAY_ELEMENT (it);
6607 }
6608
6609
6610 /* Deliver an image display element. The iterator IT is already
6611 filled with image information (done in handle_display_prop). Value
6612 is always 1. */
6613
6614
6615 static int
6616 next_element_from_image (struct it *it)
6617 {
6618 it->what = IT_IMAGE;
6619 it->ignore_overlay_strings_at_pos_p = 0;
6620 return 1;
6621 }
6622
6623
6624 /* Fill iterator IT with next display element from a stretch glyph
6625 property. IT->object is the value of the text property. Value is
6626 always 1. */
6627
6628 static int
6629 next_element_from_stretch (struct it *it)
6630 {
6631 it->what = IT_STRETCH;
6632 return 1;
6633 }
6634
6635 /* Scan forward from CHARPOS in the current buffer, until we find a
6636 stop position > current IT's position. Then handle the stop
6637 position before that. This is called when we bump into a stop
6638 position while reordering bidirectional text. CHARPOS should be
6639 the last previously processed stop_pos (or BEGV, if none were
6640 processed yet) whose position is less that IT's current
6641 position. */
6642
6643 static void
6644 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6645 {
6646 EMACS_INT where_we_are = IT_CHARPOS (*it);
6647 struct display_pos save_current = it->current;
6648 struct text_pos save_position = it->position;
6649 struct text_pos pos1;
6650 EMACS_INT next_stop;
6651
6652 /* Scan in strict logical order. */
6653 it->bidi_p = 0;
6654 do
6655 {
6656 it->prev_stop = charpos;
6657 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6658 reseat_1 (it, pos1, 0);
6659 compute_stop_pos (it);
6660 /* We must advance forward, right? */
6661 if (it->stop_charpos <= it->prev_stop)
6662 abort ();
6663 charpos = it->stop_charpos;
6664 }
6665 while (charpos <= where_we_are);
6666
6667 next_stop = it->stop_charpos;
6668 it->stop_charpos = it->prev_stop;
6669 it->bidi_p = 1;
6670 it->current = save_current;
6671 it->position = save_position;
6672 handle_stop (it);
6673 it->stop_charpos = next_stop;
6674 }
6675
6676 /* Load IT with the next display element from current_buffer. Value
6677 is zero if end of buffer reached. IT->stop_charpos is the next
6678 position at which to stop and check for text properties or buffer
6679 end. */
6680
6681 static int
6682 next_element_from_buffer (struct it *it)
6683 {
6684 int success_p = 1;
6685
6686 xassert (IT_CHARPOS (*it) >= BEGV);
6687
6688 /* With bidi reordering, the character to display might not be the
6689 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6690 we were reseat()ed to a new buffer position, which is potentially
6691 a different paragraph. */
6692 if (it->bidi_p && it->bidi_it.first_elt)
6693 {
6694 it->bidi_it.charpos = IT_CHARPOS (*it);
6695 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6696 if (it->bidi_it.bytepos == ZV_BYTE)
6697 {
6698 /* Nothing to do, but reset the FIRST_ELT flag, like
6699 bidi_paragraph_init does, because we are not going to
6700 call it. */
6701 it->bidi_it.first_elt = 0;
6702 }
6703 else if (it->bidi_it.bytepos == BEGV_BYTE
6704 /* FIXME: Should support all Unicode line separators. */
6705 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6706 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6707 {
6708 /* If we are at the beginning of a line, we can produce the
6709 next element right away. */
6710 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6711 bidi_move_to_visually_next (&it->bidi_it);
6712 }
6713 else
6714 {
6715 int orig_bytepos = IT_BYTEPOS (*it);
6716
6717 /* We need to prime the bidi iterator starting at the line's
6718 beginning, before we will be able to produce the next
6719 element. */
6720 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6721 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6722 it->bidi_it.charpos = IT_CHARPOS (*it);
6723 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6724 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6725 do
6726 {
6727 /* Now return to buffer position where we were asked to
6728 get the next display element, and produce that. */
6729 bidi_move_to_visually_next (&it->bidi_it);
6730 }
6731 while (it->bidi_it.bytepos != orig_bytepos
6732 && it->bidi_it.bytepos < ZV_BYTE);
6733 }
6734
6735 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6736 /* Adjust IT's position information to where we ended up. */
6737 IT_CHARPOS (*it) = it->bidi_it.charpos;
6738 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6739 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6740 {
6741 EMACS_INT stop = it->stop_charpos;
6742 if (it->bidi_it.scan_dir < 0)
6743 stop = -1;
6744 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6745 IT_BYTEPOS (*it), stop, Qnil);
6746 }
6747 }
6748
6749 if (IT_CHARPOS (*it) >= it->stop_charpos)
6750 {
6751 if (IT_CHARPOS (*it) >= it->end_charpos)
6752 {
6753 int overlay_strings_follow_p;
6754
6755 /* End of the game, except when overlay strings follow that
6756 haven't been returned yet. */
6757 if (it->overlay_strings_at_end_processed_p)
6758 overlay_strings_follow_p = 0;
6759 else
6760 {
6761 it->overlay_strings_at_end_processed_p = 1;
6762 overlay_strings_follow_p = get_overlay_strings (it, 0);
6763 }
6764
6765 if (overlay_strings_follow_p)
6766 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6767 else
6768 {
6769 it->what = IT_EOB;
6770 it->position = it->current.pos;
6771 success_p = 0;
6772 }
6773 }
6774 else if (!(!it->bidi_p
6775 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6776 || IT_CHARPOS (*it) == it->stop_charpos))
6777 {
6778 /* With bidi non-linear iteration, we could find ourselves
6779 far beyond the last computed stop_charpos, with several
6780 other stop positions in between that we missed. Scan
6781 them all now, in buffer's logical order, until we find
6782 and handle the last stop_charpos that precedes our
6783 current position. */
6784 handle_stop_backwards (it, it->stop_charpos);
6785 return GET_NEXT_DISPLAY_ELEMENT (it);
6786 }
6787 else
6788 {
6789 if (it->bidi_p)
6790 {
6791 /* Take note of the stop position we just moved across,
6792 for when we will move back across it. */
6793 it->prev_stop = it->stop_charpos;
6794 /* If we are at base paragraph embedding level, take
6795 note of the last stop position seen at this
6796 level. */
6797 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6798 it->base_level_stop = it->stop_charpos;
6799 }
6800 handle_stop (it);
6801 return GET_NEXT_DISPLAY_ELEMENT (it);
6802 }
6803 }
6804 else if (it->bidi_p
6805 /* We can sometimes back up for reasons that have nothing
6806 to do with bidi reordering. E.g., compositions. The
6807 code below is only needed when we are above the base
6808 embedding level, so test for that explicitly. */
6809 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6810 && IT_CHARPOS (*it) < it->prev_stop)
6811 {
6812 if (it->base_level_stop <= 0)
6813 it->base_level_stop = BEGV;
6814 if (IT_CHARPOS (*it) < it->base_level_stop)
6815 abort ();
6816 handle_stop_backwards (it, it->base_level_stop);
6817 return GET_NEXT_DISPLAY_ELEMENT (it);
6818 }
6819 else
6820 {
6821 /* No face changes, overlays etc. in sight, so just return a
6822 character from current_buffer. */
6823 unsigned char *p;
6824 EMACS_INT stop;
6825
6826 /* Maybe run the redisplay end trigger hook. Performance note:
6827 This doesn't seem to cost measurable time. */
6828 if (it->redisplay_end_trigger_charpos
6829 && it->glyph_row
6830 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6831 run_redisplay_end_trigger_hook (it);
6832
6833 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6834 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6835 stop)
6836 && next_element_from_composition (it))
6837 {
6838 return 1;
6839 }
6840
6841 /* Get the next character, maybe multibyte. */
6842 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6843 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6844 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6845 else
6846 it->c = *p, it->len = 1;
6847
6848 /* Record what we have and where it came from. */
6849 it->what = IT_CHARACTER;
6850 it->object = it->w->buffer;
6851 it->position = it->current.pos;
6852
6853 /* Normally we return the character found above, except when we
6854 really want to return an ellipsis for selective display. */
6855 if (it->selective)
6856 {
6857 if (it->c == '\n')
6858 {
6859 /* A value of selective > 0 means hide lines indented more
6860 than that number of columns. */
6861 if (it->selective > 0
6862 && IT_CHARPOS (*it) + 1 < ZV
6863 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6864 IT_BYTEPOS (*it) + 1,
6865 (double) it->selective)) /* iftc */
6866 {
6867 success_p = next_element_from_ellipsis (it);
6868 it->dpvec_char_len = -1;
6869 }
6870 }
6871 else if (it->c == '\r' && it->selective == -1)
6872 {
6873 /* A value of selective == -1 means that everything from the
6874 CR to the end of the line is invisible, with maybe an
6875 ellipsis displayed for it. */
6876 success_p = next_element_from_ellipsis (it);
6877 it->dpvec_char_len = -1;
6878 }
6879 }
6880 }
6881
6882 /* Value is zero if end of buffer reached. */
6883 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6884 return success_p;
6885 }
6886
6887
6888 /* Run the redisplay end trigger hook for IT. */
6889
6890 static void
6891 run_redisplay_end_trigger_hook (struct it *it)
6892 {
6893 Lisp_Object args[3];
6894
6895 /* IT->glyph_row should be non-null, i.e. we should be actually
6896 displaying something, or otherwise we should not run the hook. */
6897 xassert (it->glyph_row);
6898
6899 /* Set up hook arguments. */
6900 args[0] = Qredisplay_end_trigger_functions;
6901 args[1] = it->window;
6902 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6903 it->redisplay_end_trigger_charpos = 0;
6904
6905 /* Since we are *trying* to run these functions, don't try to run
6906 them again, even if they get an error. */
6907 it->w->redisplay_end_trigger = Qnil;
6908 Frun_hook_with_args (3, args);
6909
6910 /* Notice if it changed the face of the character we are on. */
6911 handle_face_prop (it);
6912 }
6913
6914
6915 /* Deliver a composition display element. Unlike the other
6916 next_element_from_XXX, this function is not registered in the array
6917 get_next_element[]. It is called from next_element_from_buffer and
6918 next_element_from_string when necessary. */
6919
6920 static int
6921 next_element_from_composition (struct it *it)
6922 {
6923 it->what = IT_COMPOSITION;
6924 it->len = it->cmp_it.nbytes;
6925 if (STRINGP (it->string))
6926 {
6927 if (it->c < 0)
6928 {
6929 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6930 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6931 return 0;
6932 }
6933 it->position = it->current.string_pos;
6934 it->object = it->string;
6935 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6936 IT_STRING_BYTEPOS (*it), it->string);
6937 }
6938 else
6939 {
6940 if (it->c < 0)
6941 {
6942 IT_CHARPOS (*it) += it->cmp_it.nchars;
6943 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6944 if (it->bidi_p)
6945 {
6946 if (it->bidi_it.new_paragraph)
6947 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6948 /* Resync the bidi iterator with IT's new position.
6949 FIXME: this doesn't support bidirectional text. */
6950 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6951 bidi_move_to_visually_next (&it->bidi_it);
6952 }
6953 return 0;
6954 }
6955 it->position = it->current.pos;
6956 it->object = it->w->buffer;
6957 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6958 IT_BYTEPOS (*it), Qnil);
6959 }
6960 return 1;
6961 }
6962
6963
6964 \f
6965 /***********************************************************************
6966 Moving an iterator without producing glyphs
6967 ***********************************************************************/
6968
6969 /* Check if iterator is at a position corresponding to a valid buffer
6970 position after some move_it_ call. */
6971
6972 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6973 ((it)->method == GET_FROM_STRING \
6974 ? IT_STRING_CHARPOS (*it) == 0 \
6975 : 1)
6976
6977
6978 /* Move iterator IT to a specified buffer or X position within one
6979 line on the display without producing glyphs.
6980
6981 OP should be a bit mask including some or all of these bits:
6982 MOVE_TO_X: Stop upon reaching x-position TO_X.
6983 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6984 Regardless of OP's value, stop upon reaching the end of the display line.
6985
6986 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6987 This means, in particular, that TO_X includes window's horizontal
6988 scroll amount.
6989
6990 The return value has several possible values that
6991 say what condition caused the scan to stop:
6992
6993 MOVE_POS_MATCH_OR_ZV
6994 - when TO_POS or ZV was reached.
6995
6996 MOVE_X_REACHED
6997 -when TO_X was reached before TO_POS or ZV were reached.
6998
6999 MOVE_LINE_CONTINUED
7000 - when we reached the end of the display area and the line must
7001 be continued.
7002
7003 MOVE_LINE_TRUNCATED
7004 - when we reached the end of the display area and the line is
7005 truncated.
7006
7007 MOVE_NEWLINE_OR_CR
7008 - when we stopped at a line end, i.e. a newline or a CR and selective
7009 display is on. */
7010
7011 static enum move_it_result
7012 move_it_in_display_line_to (struct it *it,
7013 EMACS_INT to_charpos, int to_x,
7014 enum move_operation_enum op)
7015 {
7016 enum move_it_result result = MOVE_UNDEFINED;
7017 struct glyph_row *saved_glyph_row;
7018 struct it wrap_it, atpos_it, atx_it;
7019 int may_wrap = 0;
7020 enum it_method prev_method = it->method;
7021 EMACS_INT prev_pos = IT_CHARPOS (*it);
7022
7023 /* Don't produce glyphs in produce_glyphs. */
7024 saved_glyph_row = it->glyph_row;
7025 it->glyph_row = NULL;
7026
7027 /* Use wrap_it to save a copy of IT wherever a word wrap could
7028 occur. Use atpos_it to save a copy of IT at the desired buffer
7029 position, if found, so that we can scan ahead and check if the
7030 word later overshoots the window edge. Use atx_it similarly, for
7031 pixel positions. */
7032 wrap_it.sp = -1;
7033 atpos_it.sp = -1;
7034 atx_it.sp = -1;
7035
7036 #define BUFFER_POS_REACHED_P() \
7037 ((op & MOVE_TO_POS) != 0 \
7038 && BUFFERP (it->object) \
7039 && (IT_CHARPOS (*it) == to_charpos \
7040 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7041 && (it->method == GET_FROM_BUFFER \
7042 || (it->method == GET_FROM_DISPLAY_VECTOR \
7043 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7044
7045 /* If there's a line-/wrap-prefix, handle it. */
7046 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7047 && it->current_y < it->last_visible_y)
7048 handle_line_prefix (it);
7049
7050 while (1)
7051 {
7052 int x, i, ascent = 0, descent = 0;
7053
7054 /* Utility macro to reset an iterator with x, ascent, and descent. */
7055 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7056 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7057 (IT)->max_descent = descent)
7058
7059 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7060 glyph). */
7061 if ((op & MOVE_TO_POS) != 0
7062 && BUFFERP (it->object)
7063 && it->method == GET_FROM_BUFFER
7064 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7065 || (it->bidi_p
7066 && (prev_method == GET_FROM_IMAGE
7067 || prev_method == GET_FROM_STRETCH)
7068 /* Passed TO_CHARPOS from left to right. */
7069 && ((prev_pos < to_charpos
7070 && IT_CHARPOS (*it) > to_charpos)
7071 /* Passed TO_CHARPOS from right to left. */
7072 || (prev_pos > to_charpos
7073 && IT_CHARPOS (*it) < to_charpos)))))
7074 {
7075 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7076 {
7077 result = MOVE_POS_MATCH_OR_ZV;
7078 break;
7079 }
7080 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7081 /* If wrap_it is valid, the current position might be in a
7082 word that is wrapped. So, save the iterator in
7083 atpos_it and continue to see if wrapping happens. */
7084 atpos_it = *it;
7085 }
7086
7087 prev_method = it->method;
7088 if (it->method == GET_FROM_BUFFER)
7089 prev_pos = IT_CHARPOS (*it);
7090 /* Stop when ZV reached.
7091 We used to stop here when TO_CHARPOS reached as well, but that is
7092 too soon if this glyph does not fit on this line. So we handle it
7093 explicitly below. */
7094 if (!get_next_display_element (it))
7095 {
7096 result = MOVE_POS_MATCH_OR_ZV;
7097 break;
7098 }
7099
7100 if (it->line_wrap == TRUNCATE)
7101 {
7102 if (BUFFER_POS_REACHED_P ())
7103 {
7104 result = MOVE_POS_MATCH_OR_ZV;
7105 break;
7106 }
7107 }
7108 else
7109 {
7110 if (it->line_wrap == WORD_WRAP)
7111 {
7112 if (IT_DISPLAYING_WHITESPACE (it))
7113 may_wrap = 1;
7114 else if (may_wrap)
7115 {
7116 /* We have reached a glyph that follows one or more
7117 whitespace characters. If the position is
7118 already found, we are done. */
7119 if (atpos_it.sp >= 0)
7120 {
7121 *it = atpos_it;
7122 result = MOVE_POS_MATCH_OR_ZV;
7123 goto done;
7124 }
7125 if (atx_it.sp >= 0)
7126 {
7127 *it = atx_it;
7128 result = MOVE_X_REACHED;
7129 goto done;
7130 }
7131 /* Otherwise, we can wrap here. */
7132 wrap_it = *it;
7133 may_wrap = 0;
7134 }
7135 }
7136 }
7137
7138 /* Remember the line height for the current line, in case
7139 the next element doesn't fit on the line. */
7140 ascent = it->max_ascent;
7141 descent = it->max_descent;
7142
7143 /* The call to produce_glyphs will get the metrics of the
7144 display element IT is loaded with. Record the x-position
7145 before this display element, in case it doesn't fit on the
7146 line. */
7147 x = it->current_x;
7148
7149 PRODUCE_GLYPHS (it);
7150
7151 if (it->area != TEXT_AREA)
7152 {
7153 set_iterator_to_next (it, 1);
7154 continue;
7155 }
7156
7157 /* The number of glyphs we get back in IT->nglyphs will normally
7158 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7159 character on a terminal frame, or (iii) a line end. For the
7160 second case, IT->nglyphs - 1 padding glyphs will be present.
7161 (On X frames, there is only one glyph produced for a
7162 composite character.)
7163
7164 The behavior implemented below means, for continuation lines,
7165 that as many spaces of a TAB as fit on the current line are
7166 displayed there. For terminal frames, as many glyphs of a
7167 multi-glyph character are displayed in the current line, too.
7168 This is what the old redisplay code did, and we keep it that
7169 way. Under X, the whole shape of a complex character must
7170 fit on the line or it will be completely displayed in the
7171 next line.
7172
7173 Note that both for tabs and padding glyphs, all glyphs have
7174 the same width. */
7175 if (it->nglyphs)
7176 {
7177 /* More than one glyph or glyph doesn't fit on line. All
7178 glyphs have the same width. */
7179 int single_glyph_width = it->pixel_width / it->nglyphs;
7180 int new_x;
7181 int x_before_this_char = x;
7182 int hpos_before_this_char = it->hpos;
7183
7184 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7185 {
7186 new_x = x + single_glyph_width;
7187
7188 /* We want to leave anything reaching TO_X to the caller. */
7189 if ((op & MOVE_TO_X) && new_x > to_x)
7190 {
7191 if (BUFFER_POS_REACHED_P ())
7192 {
7193 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7194 goto buffer_pos_reached;
7195 if (atpos_it.sp < 0)
7196 {
7197 atpos_it = *it;
7198 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7199 }
7200 }
7201 else
7202 {
7203 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7204 {
7205 it->current_x = x;
7206 result = MOVE_X_REACHED;
7207 break;
7208 }
7209 if (atx_it.sp < 0)
7210 {
7211 atx_it = *it;
7212 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7213 }
7214 }
7215 }
7216
7217 if (/* Lines are continued. */
7218 it->line_wrap != TRUNCATE
7219 && (/* And glyph doesn't fit on the line. */
7220 new_x > it->last_visible_x
7221 /* Or it fits exactly and we're on a window
7222 system frame. */
7223 || (new_x == it->last_visible_x
7224 && FRAME_WINDOW_P (it->f))))
7225 {
7226 if (/* IT->hpos == 0 means the very first glyph
7227 doesn't fit on the line, e.g. a wide image. */
7228 it->hpos == 0
7229 || (new_x == it->last_visible_x
7230 && FRAME_WINDOW_P (it->f)))
7231 {
7232 ++it->hpos;
7233 it->current_x = new_x;
7234
7235 /* The character's last glyph just barely fits
7236 in this row. */
7237 if (i == it->nglyphs - 1)
7238 {
7239 /* If this is the destination position,
7240 return a position *before* it in this row,
7241 now that we know it fits in this row. */
7242 if (BUFFER_POS_REACHED_P ())
7243 {
7244 if (it->line_wrap != WORD_WRAP
7245 || wrap_it.sp < 0)
7246 {
7247 it->hpos = hpos_before_this_char;
7248 it->current_x = x_before_this_char;
7249 result = MOVE_POS_MATCH_OR_ZV;
7250 break;
7251 }
7252 if (it->line_wrap == WORD_WRAP
7253 && atpos_it.sp < 0)
7254 {
7255 atpos_it = *it;
7256 atpos_it.current_x = x_before_this_char;
7257 atpos_it.hpos = hpos_before_this_char;
7258 }
7259 }
7260
7261 set_iterator_to_next (it, 1);
7262 /* On graphical terminals, newlines may
7263 "overflow" into the fringe if
7264 overflow-newline-into-fringe is non-nil.
7265 On text-only terminals, newlines may
7266 overflow into the last glyph on the
7267 display line.*/
7268 if (!FRAME_WINDOW_P (it->f)
7269 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7270 {
7271 if (!get_next_display_element (it))
7272 {
7273 result = MOVE_POS_MATCH_OR_ZV;
7274 break;
7275 }
7276 if (BUFFER_POS_REACHED_P ())
7277 {
7278 if (ITERATOR_AT_END_OF_LINE_P (it))
7279 result = MOVE_POS_MATCH_OR_ZV;
7280 else
7281 result = MOVE_LINE_CONTINUED;
7282 break;
7283 }
7284 if (ITERATOR_AT_END_OF_LINE_P (it))
7285 {
7286 result = MOVE_NEWLINE_OR_CR;
7287 break;
7288 }
7289 }
7290 }
7291 }
7292 else
7293 IT_RESET_X_ASCENT_DESCENT (it);
7294
7295 if (wrap_it.sp >= 0)
7296 {
7297 *it = wrap_it;
7298 atpos_it.sp = -1;
7299 atx_it.sp = -1;
7300 }
7301
7302 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7303 IT_CHARPOS (*it)));
7304 result = MOVE_LINE_CONTINUED;
7305 break;
7306 }
7307
7308 if (BUFFER_POS_REACHED_P ())
7309 {
7310 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7311 goto buffer_pos_reached;
7312 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7313 {
7314 atpos_it = *it;
7315 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7316 }
7317 }
7318
7319 if (new_x > it->first_visible_x)
7320 {
7321 /* Glyph is visible. Increment number of glyphs that
7322 would be displayed. */
7323 ++it->hpos;
7324 }
7325 }
7326
7327 if (result != MOVE_UNDEFINED)
7328 break;
7329 }
7330 else if (BUFFER_POS_REACHED_P ())
7331 {
7332 buffer_pos_reached:
7333 IT_RESET_X_ASCENT_DESCENT (it);
7334 result = MOVE_POS_MATCH_OR_ZV;
7335 break;
7336 }
7337 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7338 {
7339 /* Stop when TO_X specified and reached. This check is
7340 necessary here because of lines consisting of a line end,
7341 only. The line end will not produce any glyphs and we
7342 would never get MOVE_X_REACHED. */
7343 xassert (it->nglyphs == 0);
7344 result = MOVE_X_REACHED;
7345 break;
7346 }
7347
7348 /* Is this a line end? If yes, we're done. */
7349 if (ITERATOR_AT_END_OF_LINE_P (it))
7350 {
7351 result = MOVE_NEWLINE_OR_CR;
7352 break;
7353 }
7354
7355 if (it->method == GET_FROM_BUFFER)
7356 prev_pos = IT_CHARPOS (*it);
7357 /* The current display element has been consumed. Advance
7358 to the next. */
7359 set_iterator_to_next (it, 1);
7360
7361 /* Stop if lines are truncated and IT's current x-position is
7362 past the right edge of the window now. */
7363 if (it->line_wrap == TRUNCATE
7364 && it->current_x >= it->last_visible_x)
7365 {
7366 if (!FRAME_WINDOW_P (it->f)
7367 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7368 {
7369 if (!get_next_display_element (it)
7370 || BUFFER_POS_REACHED_P ())
7371 {
7372 result = MOVE_POS_MATCH_OR_ZV;
7373 break;
7374 }
7375 if (ITERATOR_AT_END_OF_LINE_P (it))
7376 {
7377 result = MOVE_NEWLINE_OR_CR;
7378 break;
7379 }
7380 }
7381 result = MOVE_LINE_TRUNCATED;
7382 break;
7383 }
7384 #undef IT_RESET_X_ASCENT_DESCENT
7385 }
7386
7387 #undef BUFFER_POS_REACHED_P
7388
7389 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7390 restore the saved iterator. */
7391 if (atpos_it.sp >= 0)
7392 *it = atpos_it;
7393 else if (atx_it.sp >= 0)
7394 *it = atx_it;
7395
7396 done:
7397
7398 /* Restore the iterator settings altered at the beginning of this
7399 function. */
7400 it->glyph_row = saved_glyph_row;
7401 return result;
7402 }
7403
7404 /* For external use. */
7405 void
7406 move_it_in_display_line (struct it *it,
7407 EMACS_INT to_charpos, int to_x,
7408 enum move_operation_enum op)
7409 {
7410 if (it->line_wrap == WORD_WRAP
7411 && (op & MOVE_TO_X))
7412 {
7413 struct it save_it = *it;
7414 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7415 /* When word-wrap is on, TO_X may lie past the end
7416 of a wrapped line. Then it->current is the
7417 character on the next line, so backtrack to the
7418 space before the wrap point. */
7419 if (skip == MOVE_LINE_CONTINUED)
7420 {
7421 int prev_x = max (it->current_x - 1, 0);
7422 *it = save_it;
7423 move_it_in_display_line_to
7424 (it, -1, prev_x, MOVE_TO_X);
7425 }
7426 }
7427 else
7428 move_it_in_display_line_to (it, to_charpos, to_x, op);
7429 }
7430
7431
7432 /* Move IT forward until it satisfies one or more of the criteria in
7433 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7434
7435 OP is a bit-mask that specifies where to stop, and in particular,
7436 which of those four position arguments makes a difference. See the
7437 description of enum move_operation_enum.
7438
7439 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7440 screen line, this function will set IT to the next position >
7441 TO_CHARPOS. */
7442
7443 void
7444 move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
7445 {
7446 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7447 int line_height, line_start_x = 0, reached = 0;
7448
7449 for (;;)
7450 {
7451 if (op & MOVE_TO_VPOS)
7452 {
7453 /* If no TO_CHARPOS and no TO_X specified, stop at the
7454 start of the line TO_VPOS. */
7455 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7456 {
7457 if (it->vpos == to_vpos)
7458 {
7459 reached = 1;
7460 break;
7461 }
7462 else
7463 skip = move_it_in_display_line_to (it, -1, -1, 0);
7464 }
7465 else
7466 {
7467 /* TO_VPOS >= 0 means stop at TO_X in the line at
7468 TO_VPOS, or at TO_POS, whichever comes first. */
7469 if (it->vpos == to_vpos)
7470 {
7471 reached = 2;
7472 break;
7473 }
7474
7475 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7476
7477 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7478 {
7479 reached = 3;
7480 break;
7481 }
7482 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7483 {
7484 /* We have reached TO_X but not in the line we want. */
7485 skip = move_it_in_display_line_to (it, to_charpos,
7486 -1, MOVE_TO_POS);
7487 if (skip == MOVE_POS_MATCH_OR_ZV)
7488 {
7489 reached = 4;
7490 break;
7491 }
7492 }
7493 }
7494 }
7495 else if (op & MOVE_TO_Y)
7496 {
7497 struct it it_backup;
7498
7499 if (it->line_wrap == WORD_WRAP)
7500 it_backup = *it;
7501
7502 /* TO_Y specified means stop at TO_X in the line containing
7503 TO_Y---or at TO_CHARPOS if this is reached first. The
7504 problem is that we can't really tell whether the line
7505 contains TO_Y before we have completely scanned it, and
7506 this may skip past TO_X. What we do is to first scan to
7507 TO_X.
7508
7509 If TO_X is not specified, use a TO_X of zero. The reason
7510 is to make the outcome of this function more predictable.
7511 If we didn't use TO_X == 0, we would stop at the end of
7512 the line which is probably not what a caller would expect
7513 to happen. */
7514 skip = move_it_in_display_line_to
7515 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7516 (MOVE_TO_X | (op & MOVE_TO_POS)));
7517
7518 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7519 if (skip == MOVE_POS_MATCH_OR_ZV)
7520 reached = 5;
7521 else if (skip == MOVE_X_REACHED)
7522 {
7523 /* If TO_X was reached, we want to know whether TO_Y is
7524 in the line. We know this is the case if the already
7525 scanned glyphs make the line tall enough. Otherwise,
7526 we must check by scanning the rest of the line. */
7527 line_height = it->max_ascent + it->max_descent;
7528 if (to_y >= it->current_y
7529 && to_y < it->current_y + line_height)
7530 {
7531 reached = 6;
7532 break;
7533 }
7534 it_backup = *it;
7535 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7536 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7537 op & MOVE_TO_POS);
7538 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7539 line_height = it->max_ascent + it->max_descent;
7540 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7541
7542 if (to_y >= it->current_y
7543 && to_y < it->current_y + line_height)
7544 {
7545 /* If TO_Y is in this line and TO_X was reached
7546 above, we scanned too far. We have to restore
7547 IT's settings to the ones before skipping. */
7548 *it = it_backup;
7549 reached = 6;
7550 }
7551 else
7552 {
7553 skip = skip2;
7554 if (skip == MOVE_POS_MATCH_OR_ZV)
7555 reached = 7;
7556 }
7557 }
7558 else
7559 {
7560 /* Check whether TO_Y is in this line. */
7561 line_height = it->max_ascent + it->max_descent;
7562 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7563
7564 if (to_y >= it->current_y
7565 && to_y < it->current_y + line_height)
7566 {
7567 /* When word-wrap is on, TO_X may lie past the end
7568 of a wrapped line. Then it->current is the
7569 character on the next line, so backtrack to the
7570 space before the wrap point. */
7571 if (skip == MOVE_LINE_CONTINUED
7572 && it->line_wrap == WORD_WRAP)
7573 {
7574 int prev_x = max (it->current_x - 1, 0);
7575 *it = it_backup;
7576 skip = move_it_in_display_line_to
7577 (it, -1, prev_x, MOVE_TO_X);
7578 }
7579 reached = 6;
7580 }
7581 }
7582
7583 if (reached)
7584 break;
7585 }
7586 else if (BUFFERP (it->object)
7587 && (it->method == GET_FROM_BUFFER
7588 || it->method == GET_FROM_STRETCH)
7589 && IT_CHARPOS (*it) >= to_charpos)
7590 skip = MOVE_POS_MATCH_OR_ZV;
7591 else
7592 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7593
7594 switch (skip)
7595 {
7596 case MOVE_POS_MATCH_OR_ZV:
7597 reached = 8;
7598 goto out;
7599
7600 case MOVE_NEWLINE_OR_CR:
7601 set_iterator_to_next (it, 1);
7602 it->continuation_lines_width = 0;
7603 break;
7604
7605 case MOVE_LINE_TRUNCATED:
7606 it->continuation_lines_width = 0;
7607 reseat_at_next_visible_line_start (it, 0);
7608 if ((op & MOVE_TO_POS) != 0
7609 && IT_CHARPOS (*it) > to_charpos)
7610 {
7611 reached = 9;
7612 goto out;
7613 }
7614 break;
7615
7616 case MOVE_LINE_CONTINUED:
7617 /* For continued lines ending in a tab, some of the glyphs
7618 associated with the tab are displayed on the current
7619 line. Since it->current_x does not include these glyphs,
7620 we use it->last_visible_x instead. */
7621 if (it->c == '\t')
7622 {
7623 it->continuation_lines_width += it->last_visible_x;
7624 /* When moving by vpos, ensure that the iterator really
7625 advances to the next line (bug#847, bug#969). Fixme:
7626 do we need to do this in other circumstances? */
7627 if (it->current_x != it->last_visible_x
7628 && (op & MOVE_TO_VPOS)
7629 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7630 {
7631 line_start_x = it->current_x + it->pixel_width
7632 - it->last_visible_x;
7633 set_iterator_to_next (it, 0);
7634 }
7635 }
7636 else
7637 it->continuation_lines_width += it->current_x;
7638 break;
7639
7640 default:
7641 abort ();
7642 }
7643
7644 /* Reset/increment for the next run. */
7645 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7646 it->current_x = line_start_x;
7647 line_start_x = 0;
7648 it->hpos = 0;
7649 it->current_y += it->max_ascent + it->max_descent;
7650 ++it->vpos;
7651 last_height = it->max_ascent + it->max_descent;
7652 last_max_ascent = it->max_ascent;
7653 it->max_ascent = it->max_descent = 0;
7654 }
7655
7656 out:
7657
7658 /* On text terminals, we may stop at the end of a line in the middle
7659 of a multi-character glyph. If the glyph itself is continued,
7660 i.e. it is actually displayed on the next line, don't treat this
7661 stopping point as valid; move to the next line instead (unless
7662 that brings us offscreen). */
7663 if (!FRAME_WINDOW_P (it->f)
7664 && op & MOVE_TO_POS
7665 && IT_CHARPOS (*it) == to_charpos
7666 && it->what == IT_CHARACTER
7667 && it->nglyphs > 1
7668 && it->line_wrap == WINDOW_WRAP
7669 && it->current_x == it->last_visible_x - 1
7670 && it->c != '\n'
7671 && it->c != '\t'
7672 && it->vpos < XFASTINT (it->w->window_end_vpos))
7673 {
7674 it->continuation_lines_width += it->current_x;
7675 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7676 it->current_y += it->max_ascent + it->max_descent;
7677 ++it->vpos;
7678 last_height = it->max_ascent + it->max_descent;
7679 last_max_ascent = it->max_ascent;
7680 }
7681
7682 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7683 }
7684
7685
7686 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7687
7688 If DY > 0, move IT backward at least that many pixels. DY = 0
7689 means move IT backward to the preceding line start or BEGV. This
7690 function may move over more than DY pixels if IT->current_y - DY
7691 ends up in the middle of a line; in this case IT->current_y will be
7692 set to the top of the line moved to. */
7693
7694 void
7695 move_it_vertically_backward (struct it *it, int dy)
7696 {
7697 int nlines, h;
7698 struct it it2, it3;
7699 int start_pos;
7700
7701 move_further_back:
7702 xassert (dy >= 0);
7703
7704 start_pos = IT_CHARPOS (*it);
7705
7706 /* Estimate how many newlines we must move back. */
7707 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7708
7709 /* Set the iterator's position that many lines back. */
7710 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7711 back_to_previous_visible_line_start (it);
7712
7713 /* Reseat the iterator here. When moving backward, we don't want
7714 reseat to skip forward over invisible text, set up the iterator
7715 to deliver from overlay strings at the new position etc. So,
7716 use reseat_1 here. */
7717 reseat_1 (it, it->current.pos, 1);
7718
7719 /* We are now surely at a line start. */
7720 it->current_x = it->hpos = 0;
7721 it->continuation_lines_width = 0;
7722
7723 /* Move forward and see what y-distance we moved. First move to the
7724 start of the next line so that we get its height. We need this
7725 height to be able to tell whether we reached the specified
7726 y-distance. */
7727 it2 = *it;
7728 it2.max_ascent = it2.max_descent = 0;
7729 do
7730 {
7731 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7732 MOVE_TO_POS | MOVE_TO_VPOS);
7733 }
7734 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7735 xassert (IT_CHARPOS (*it) >= BEGV);
7736 it3 = it2;
7737
7738 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7739 xassert (IT_CHARPOS (*it) >= BEGV);
7740 /* H is the actual vertical distance from the position in *IT
7741 and the starting position. */
7742 h = it2.current_y - it->current_y;
7743 /* NLINES is the distance in number of lines. */
7744 nlines = it2.vpos - it->vpos;
7745
7746 /* Correct IT's y and vpos position
7747 so that they are relative to the starting point. */
7748 it->vpos -= nlines;
7749 it->current_y -= h;
7750
7751 if (dy == 0)
7752 {
7753 /* DY == 0 means move to the start of the screen line. The
7754 value of nlines is > 0 if continuation lines were involved. */
7755 if (nlines > 0)
7756 move_it_by_lines (it, nlines, 1);
7757 }
7758 else
7759 {
7760 /* The y-position we try to reach, relative to *IT.
7761 Note that H has been subtracted in front of the if-statement. */
7762 int target_y = it->current_y + h - dy;
7763 int y0 = it3.current_y;
7764 int y1 = line_bottom_y (&it3);
7765 int line_height = y1 - y0;
7766
7767 /* If we did not reach target_y, try to move further backward if
7768 we can. If we moved too far backward, try to move forward. */
7769 if (target_y < it->current_y
7770 /* This is heuristic. In a window that's 3 lines high, with
7771 a line height of 13 pixels each, recentering with point
7772 on the bottom line will try to move -39/2 = 19 pixels
7773 backward. Try to avoid moving into the first line. */
7774 && (it->current_y - target_y
7775 > min (window_box_height (it->w), line_height * 2 / 3))
7776 && IT_CHARPOS (*it) > BEGV)
7777 {
7778 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7779 target_y - it->current_y));
7780 dy = it->current_y - target_y;
7781 goto move_further_back;
7782 }
7783 else if (target_y >= it->current_y + line_height
7784 && IT_CHARPOS (*it) < ZV)
7785 {
7786 /* Should move forward by at least one line, maybe more.
7787
7788 Note: Calling move_it_by_lines can be expensive on
7789 terminal frames, where compute_motion is used (via
7790 vmotion) to do the job, when there are very long lines
7791 and truncate-lines is nil. That's the reason for
7792 treating terminal frames specially here. */
7793
7794 if (!FRAME_WINDOW_P (it->f))
7795 move_it_vertically (it, target_y - (it->current_y + line_height));
7796 else
7797 {
7798 do
7799 {
7800 move_it_by_lines (it, 1, 1);
7801 }
7802 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7803 }
7804 }
7805 }
7806 }
7807
7808
7809 /* Move IT by a specified amount of pixel lines DY. DY negative means
7810 move backwards. DY = 0 means move to start of screen line. At the
7811 end, IT will be on the start of a screen line. */
7812
7813 void
7814 move_it_vertically (struct it *it, int dy)
7815 {
7816 if (dy <= 0)
7817 move_it_vertically_backward (it, -dy);
7818 else
7819 {
7820 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7821 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7822 MOVE_TO_POS | MOVE_TO_Y);
7823 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7824
7825 /* If buffer ends in ZV without a newline, move to the start of
7826 the line to satisfy the post-condition. */
7827 if (IT_CHARPOS (*it) == ZV
7828 && ZV > BEGV
7829 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7830 move_it_by_lines (it, 0, 0);
7831 }
7832 }
7833
7834
7835 /* Move iterator IT past the end of the text line it is in. */
7836
7837 void
7838 move_it_past_eol (struct it *it)
7839 {
7840 enum move_it_result rc;
7841
7842 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7843 if (rc == MOVE_NEWLINE_OR_CR)
7844 set_iterator_to_next (it, 0);
7845 }
7846
7847
7848 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7849 negative means move up. DVPOS == 0 means move to the start of the
7850 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7851 NEED_Y_P is zero, IT->current_y will be left unchanged.
7852
7853 Further optimization ideas: If we would know that IT->f doesn't use
7854 a face with proportional font, we could be faster for
7855 truncate-lines nil. */
7856
7857 void
7858 move_it_by_lines (struct it *it, int dvpos, int need_y_p)
7859 {
7860 struct position pos;
7861
7862 /* The commented-out optimization uses vmotion on terminals. This
7863 gives bad results, because elements like it->what, on which
7864 callers such as pos_visible_p rely, aren't updated. */
7865 /* if (!FRAME_WINDOW_P (it->f))
7866 {
7867 struct text_pos textpos;
7868
7869 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7870 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7871 reseat (it, textpos, 1);
7872 it->vpos += pos.vpos;
7873 it->current_y += pos.vpos;
7874 }
7875 else */
7876
7877 if (dvpos == 0)
7878 {
7879 /* DVPOS == 0 means move to the start of the screen line. */
7880 move_it_vertically_backward (it, 0);
7881 xassert (it->current_x == 0 && it->hpos == 0);
7882 /* Let next call to line_bottom_y calculate real line height */
7883 last_height = 0;
7884 }
7885 else if (dvpos > 0)
7886 {
7887 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7888 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7889 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7890 }
7891 else
7892 {
7893 struct it it2;
7894 int start_charpos, i;
7895
7896 /* Start at the beginning of the screen line containing IT's
7897 position. This may actually move vertically backwards,
7898 in case of overlays, so adjust dvpos accordingly. */
7899 dvpos += it->vpos;
7900 move_it_vertically_backward (it, 0);
7901 dvpos -= it->vpos;
7902
7903 /* Go back -DVPOS visible lines and reseat the iterator there. */
7904 start_charpos = IT_CHARPOS (*it);
7905 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7906 back_to_previous_visible_line_start (it);
7907 reseat (it, it->current.pos, 1);
7908
7909 /* Move further back if we end up in a string or an image. */
7910 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7911 {
7912 /* First try to move to start of display line. */
7913 dvpos += it->vpos;
7914 move_it_vertically_backward (it, 0);
7915 dvpos -= it->vpos;
7916 if (IT_POS_VALID_AFTER_MOVE_P (it))
7917 break;
7918 /* If start of line is still in string or image,
7919 move further back. */
7920 back_to_previous_visible_line_start (it);
7921 reseat (it, it->current.pos, 1);
7922 dvpos--;
7923 }
7924
7925 it->current_x = it->hpos = 0;
7926
7927 /* Above call may have moved too far if continuation lines
7928 are involved. Scan forward and see if it did. */
7929 it2 = *it;
7930 it2.vpos = it2.current_y = 0;
7931 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7932 it->vpos -= it2.vpos;
7933 it->current_y -= it2.current_y;
7934 it->current_x = it->hpos = 0;
7935
7936 /* If we moved too far back, move IT some lines forward. */
7937 if (it2.vpos > -dvpos)
7938 {
7939 int delta = it2.vpos + dvpos;
7940 it2 = *it;
7941 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7942 /* Move back again if we got too far ahead. */
7943 if (IT_CHARPOS (*it) >= start_charpos)
7944 *it = it2;
7945 }
7946 }
7947 }
7948
7949 /* Return 1 if IT points into the middle of a display vector. */
7950
7951 int
7952 in_display_vector_p (struct it *it)
7953 {
7954 return (it->method == GET_FROM_DISPLAY_VECTOR
7955 && it->current.dpvec_index > 0
7956 && it->dpvec + it->current.dpvec_index != it->dpend);
7957 }
7958
7959 \f
7960 /***********************************************************************
7961 Messages
7962 ***********************************************************************/
7963
7964
7965 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7966 to *Messages*. */
7967
7968 void
7969 add_to_log (char *format, Lisp_Object arg1, Lisp_Object arg2)
7970 {
7971 Lisp_Object args[3];
7972 Lisp_Object msg, fmt;
7973 char *buffer;
7974 int len;
7975 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7976 USE_SAFE_ALLOCA;
7977
7978 /* Do nothing if called asynchronously. Inserting text into
7979 a buffer may call after-change-functions and alike and
7980 that would means running Lisp asynchronously. */
7981 if (handling_signal)
7982 return;
7983
7984 fmt = msg = Qnil;
7985 GCPRO4 (fmt, msg, arg1, arg2);
7986
7987 args[0] = fmt = build_string (format);
7988 args[1] = arg1;
7989 args[2] = arg2;
7990 msg = Fformat (3, args);
7991
7992 len = SBYTES (msg) + 1;
7993 SAFE_ALLOCA (buffer, char *, len);
7994 memcpy (buffer, SDATA (msg), len);
7995
7996 message_dolog (buffer, len - 1, 1, 0);
7997 SAFE_FREE ();
7998
7999 UNGCPRO;
8000 }
8001
8002
8003 /* Output a newline in the *Messages* buffer if "needs" one. */
8004
8005 void
8006 message_log_maybe_newline (void)
8007 {
8008 if (message_log_need_newline)
8009 message_dolog ("", 0, 1, 0);
8010 }
8011
8012
8013 /* Add a string M of length NBYTES to the message log, optionally
8014 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8015 nonzero, means interpret the contents of M as multibyte. This
8016 function calls low-level routines in order to bypass text property
8017 hooks, etc. which might not be safe to run.
8018
8019 This may GC (insert may run before/after change hooks),
8020 so the buffer M must NOT point to a Lisp string. */
8021
8022 void
8023 message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
8024 {
8025 if (!NILP (Vmemory_full))
8026 return;
8027
8028 if (!NILP (Vmessage_log_max))
8029 {
8030 struct buffer *oldbuf;
8031 Lisp_Object oldpoint, oldbegv, oldzv;
8032 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8033 int point_at_end = 0;
8034 int zv_at_end = 0;
8035 Lisp_Object old_deactivate_mark, tem;
8036 struct gcpro gcpro1;
8037
8038 old_deactivate_mark = Vdeactivate_mark;
8039 oldbuf = current_buffer;
8040 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8041 current_buffer->undo_list = Qt;
8042
8043 oldpoint = message_dolog_marker1;
8044 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8045 oldbegv = message_dolog_marker2;
8046 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8047 oldzv = message_dolog_marker3;
8048 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8049 GCPRO1 (old_deactivate_mark);
8050
8051 if (PT == Z)
8052 point_at_end = 1;
8053 if (ZV == Z)
8054 zv_at_end = 1;
8055
8056 BEGV = BEG;
8057 BEGV_BYTE = BEG_BYTE;
8058 ZV = Z;
8059 ZV_BYTE = Z_BYTE;
8060 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8061
8062 /* Insert the string--maybe converting multibyte to single byte
8063 or vice versa, so that all the text fits the buffer. */
8064 if (multibyte
8065 && NILP (current_buffer->enable_multibyte_characters))
8066 {
8067 int i, c, char_bytes;
8068 unsigned char work[1];
8069
8070 /* Convert a multibyte string to single-byte
8071 for the *Message* buffer. */
8072 for (i = 0; i < nbytes; i += char_bytes)
8073 {
8074 c = string_char_and_length (m + i, &char_bytes);
8075 work[0] = (ASCII_CHAR_P (c)
8076 ? c
8077 : multibyte_char_to_unibyte (c, Qnil));
8078 insert_1_both (work, 1, 1, 1, 0, 0);
8079 }
8080 }
8081 else if (! multibyte
8082 && ! NILP (current_buffer->enable_multibyte_characters))
8083 {
8084 int i, c, char_bytes;
8085 unsigned char *msg = (unsigned char *) m;
8086 unsigned char str[MAX_MULTIBYTE_LENGTH];
8087 /* Convert a single-byte string to multibyte
8088 for the *Message* buffer. */
8089 for (i = 0; i < nbytes; i++)
8090 {
8091 c = msg[i];
8092 MAKE_CHAR_MULTIBYTE (c);
8093 char_bytes = CHAR_STRING (c, str);
8094 insert_1_both (str, 1, char_bytes, 1, 0, 0);
8095 }
8096 }
8097 else if (nbytes)
8098 insert_1 (m, nbytes, 1, 0, 0);
8099
8100 if (nlflag)
8101 {
8102 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
8103 insert_1 ("\n", 1, 1, 0, 0);
8104
8105 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8106 this_bol = PT;
8107 this_bol_byte = PT_BYTE;
8108
8109 /* See if this line duplicates the previous one.
8110 If so, combine duplicates. */
8111 if (this_bol > BEG)
8112 {
8113 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8114 prev_bol = PT;
8115 prev_bol_byte = PT_BYTE;
8116
8117 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
8118 this_bol, this_bol_byte);
8119 if (dup)
8120 {
8121 del_range_both (prev_bol, prev_bol_byte,
8122 this_bol, this_bol_byte, 0);
8123 if (dup > 1)
8124 {
8125 char dupstr[40];
8126 int duplen;
8127
8128 /* If you change this format, don't forget to also
8129 change message_log_check_duplicate. */
8130 sprintf (dupstr, " [%d times]", dup);
8131 duplen = strlen (dupstr);
8132 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8133 insert_1 (dupstr, duplen, 1, 0, 1);
8134 }
8135 }
8136 }
8137
8138 /* If we have more than the desired maximum number of lines
8139 in the *Messages* buffer now, delete the oldest ones.
8140 This is safe because we don't have undo in this buffer. */
8141
8142 if (NATNUMP (Vmessage_log_max))
8143 {
8144 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8145 -XFASTINT (Vmessage_log_max) - 1, 0);
8146 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8147 }
8148 }
8149 BEGV = XMARKER (oldbegv)->charpos;
8150 BEGV_BYTE = marker_byte_position (oldbegv);
8151
8152 if (zv_at_end)
8153 {
8154 ZV = Z;
8155 ZV_BYTE = Z_BYTE;
8156 }
8157 else
8158 {
8159 ZV = XMARKER (oldzv)->charpos;
8160 ZV_BYTE = marker_byte_position (oldzv);
8161 }
8162
8163 if (point_at_end)
8164 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8165 else
8166 /* We can't do Fgoto_char (oldpoint) because it will run some
8167 Lisp code. */
8168 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8169 XMARKER (oldpoint)->bytepos);
8170
8171 UNGCPRO;
8172 unchain_marker (XMARKER (oldpoint));
8173 unchain_marker (XMARKER (oldbegv));
8174 unchain_marker (XMARKER (oldzv));
8175
8176 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8177 set_buffer_internal (oldbuf);
8178 if (NILP (tem))
8179 windows_or_buffers_changed = old_windows_or_buffers_changed;
8180 message_log_need_newline = !nlflag;
8181 Vdeactivate_mark = old_deactivate_mark;
8182 }
8183 }
8184
8185
8186 /* We are at the end of the buffer after just having inserted a newline.
8187 (Note: We depend on the fact we won't be crossing the gap.)
8188 Check to see if the most recent message looks a lot like the previous one.
8189 Return 0 if different, 1 if the new one should just replace it, or a
8190 value N > 1 if we should also append " [N times]". */
8191
8192 static int
8193 message_log_check_duplicate (int prev_bol, int prev_bol_byte,
8194 int this_bol, int this_bol_byte)
8195 {
8196 int i;
8197 int len = Z_BYTE - 1 - this_bol_byte;
8198 int seen_dots = 0;
8199 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8200 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8201
8202 for (i = 0; i < len; i++)
8203 {
8204 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8205 seen_dots = 1;
8206 if (p1[i] != p2[i])
8207 return seen_dots;
8208 }
8209 p1 += len;
8210 if (*p1 == '\n')
8211 return 2;
8212 if (*p1++ == ' ' && *p1++ == '[')
8213 {
8214 int n = 0;
8215 while (*p1 >= '0' && *p1 <= '9')
8216 n = n * 10 + *p1++ - '0';
8217 if (strncmp (p1, " times]\n", 8) == 0)
8218 return n+1;
8219 }
8220 return 0;
8221 }
8222 \f
8223
8224 /* Display an echo area message M with a specified length of NBYTES
8225 bytes. The string may include null characters. If M is 0, clear
8226 out any existing message, and let the mini-buffer text show
8227 through.
8228
8229 This may GC, so the buffer M must NOT point to a Lisp string. */
8230
8231 void
8232 message2 (const char *m, int nbytes, int multibyte)
8233 {
8234 /* First flush out any partial line written with print. */
8235 message_log_maybe_newline ();
8236 if (m)
8237 message_dolog (m, nbytes, 1, multibyte);
8238 message2_nolog (m, nbytes, multibyte);
8239 }
8240
8241
8242 /* The non-logging counterpart of message2. */
8243
8244 void
8245 message2_nolog (const char *m, int nbytes, int multibyte)
8246 {
8247 struct frame *sf = SELECTED_FRAME ();
8248 message_enable_multibyte = multibyte;
8249
8250 if (FRAME_INITIAL_P (sf))
8251 {
8252 if (noninteractive_need_newline)
8253 putc ('\n', stderr);
8254 noninteractive_need_newline = 0;
8255 if (m)
8256 fwrite (m, nbytes, 1, stderr);
8257 if (cursor_in_echo_area == 0)
8258 fprintf (stderr, "\n");
8259 fflush (stderr);
8260 }
8261 /* A null message buffer means that the frame hasn't really been
8262 initialized yet. Error messages get reported properly by
8263 cmd_error, so this must be just an informative message; toss it. */
8264 else if (INTERACTIVE
8265 && sf->glyphs_initialized_p
8266 && FRAME_MESSAGE_BUF (sf))
8267 {
8268 Lisp_Object mini_window;
8269 struct frame *f;
8270
8271 /* Get the frame containing the mini-buffer
8272 that the selected frame is using. */
8273 mini_window = FRAME_MINIBUF_WINDOW (sf);
8274 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8275
8276 FRAME_SAMPLE_VISIBILITY (f);
8277 if (FRAME_VISIBLE_P (sf)
8278 && ! FRAME_VISIBLE_P (f))
8279 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8280
8281 if (m)
8282 {
8283 set_message (m, Qnil, nbytes, multibyte);
8284 if (minibuffer_auto_raise)
8285 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8286 }
8287 else
8288 clear_message (1, 1);
8289
8290 do_pending_window_change (0);
8291 echo_area_display (1);
8292 do_pending_window_change (0);
8293 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8294 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8295 }
8296 }
8297
8298
8299 /* Display an echo area message M with a specified length of NBYTES
8300 bytes. The string may include null characters. If M is not a
8301 string, clear out any existing message, and let the mini-buffer
8302 text show through.
8303
8304 This function cancels echoing. */
8305
8306 void
8307 message3 (Lisp_Object m, int nbytes, int multibyte)
8308 {
8309 struct gcpro gcpro1;
8310
8311 GCPRO1 (m);
8312 clear_message (1,1);
8313 cancel_echoing ();
8314
8315 /* First flush out any partial line written with print. */
8316 message_log_maybe_newline ();
8317 if (STRINGP (m))
8318 {
8319 char *buffer;
8320 USE_SAFE_ALLOCA;
8321
8322 SAFE_ALLOCA (buffer, char *, nbytes);
8323 memcpy (buffer, SDATA (m), nbytes);
8324 message_dolog (buffer, nbytes, 1, multibyte);
8325 SAFE_FREE ();
8326 }
8327 message3_nolog (m, nbytes, multibyte);
8328
8329 UNGCPRO;
8330 }
8331
8332
8333 /* The non-logging version of message3.
8334 This does not cancel echoing, because it is used for echoing.
8335 Perhaps we need to make a separate function for echoing
8336 and make this cancel echoing. */
8337
8338 void
8339 message3_nolog (Lisp_Object m, int nbytes, int multibyte)
8340 {
8341 struct frame *sf = SELECTED_FRAME ();
8342 message_enable_multibyte = multibyte;
8343
8344 if (FRAME_INITIAL_P (sf))
8345 {
8346 if (noninteractive_need_newline)
8347 putc ('\n', stderr);
8348 noninteractive_need_newline = 0;
8349 if (STRINGP (m))
8350 fwrite (SDATA (m), nbytes, 1, stderr);
8351 if (cursor_in_echo_area == 0)
8352 fprintf (stderr, "\n");
8353 fflush (stderr);
8354 }
8355 /* A null message buffer means that the frame hasn't really been
8356 initialized yet. Error messages get reported properly by
8357 cmd_error, so this must be just an informative message; toss it. */
8358 else if (INTERACTIVE
8359 && sf->glyphs_initialized_p
8360 && FRAME_MESSAGE_BUF (sf))
8361 {
8362 Lisp_Object mini_window;
8363 Lisp_Object frame;
8364 struct frame *f;
8365
8366 /* Get the frame containing the mini-buffer
8367 that the selected frame is using. */
8368 mini_window = FRAME_MINIBUF_WINDOW (sf);
8369 frame = XWINDOW (mini_window)->frame;
8370 f = XFRAME (frame);
8371
8372 FRAME_SAMPLE_VISIBILITY (f);
8373 if (FRAME_VISIBLE_P (sf)
8374 && !FRAME_VISIBLE_P (f))
8375 Fmake_frame_visible (frame);
8376
8377 if (STRINGP (m) && SCHARS (m) > 0)
8378 {
8379 set_message (NULL, m, nbytes, multibyte);
8380 if (minibuffer_auto_raise)
8381 Fraise_frame (frame);
8382 /* Assume we are not echoing.
8383 (If we are, echo_now will override this.) */
8384 echo_message_buffer = Qnil;
8385 }
8386 else
8387 clear_message (1, 1);
8388
8389 do_pending_window_change (0);
8390 echo_area_display (1);
8391 do_pending_window_change (0);
8392 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8393 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8394 }
8395 }
8396
8397
8398 /* Display a null-terminated echo area message M. If M is 0, clear
8399 out any existing message, and let the mini-buffer text show through.
8400
8401 The buffer M must continue to exist until after the echo area gets
8402 cleared or some other message gets displayed there. Do not pass
8403 text that is stored in a Lisp string. Do not pass text in a buffer
8404 that was alloca'd. */
8405
8406 void
8407 message1 (const char *m)
8408 {
8409 message2 (m, (m ? strlen (m) : 0), 0);
8410 }
8411
8412
8413 /* The non-logging counterpart of message1. */
8414
8415 void
8416 message1_nolog (const char *m)
8417 {
8418 message2_nolog (m, (m ? strlen (m) : 0), 0);
8419 }
8420
8421 /* Display a message M which contains a single %s
8422 which gets replaced with STRING. */
8423
8424 void
8425 message_with_string (const char *m, Lisp_Object string, int log)
8426 {
8427 CHECK_STRING (string);
8428
8429 if (noninteractive)
8430 {
8431 if (m)
8432 {
8433 if (noninteractive_need_newline)
8434 putc ('\n', stderr);
8435 noninteractive_need_newline = 0;
8436 fprintf (stderr, m, SDATA (string));
8437 if (!cursor_in_echo_area)
8438 fprintf (stderr, "\n");
8439 fflush (stderr);
8440 }
8441 }
8442 else if (INTERACTIVE)
8443 {
8444 /* The frame whose minibuffer we're going to display the message on.
8445 It may be larger than the selected frame, so we need
8446 to use its buffer, not the selected frame's buffer. */
8447 Lisp_Object mini_window;
8448 struct frame *f, *sf = SELECTED_FRAME ();
8449
8450 /* Get the frame containing the minibuffer
8451 that the selected frame is using. */
8452 mini_window = FRAME_MINIBUF_WINDOW (sf);
8453 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8454
8455 /* A null message buffer means that the frame hasn't really been
8456 initialized yet. Error messages get reported properly by
8457 cmd_error, so this must be just an informative message; toss it. */
8458 if (FRAME_MESSAGE_BUF (f))
8459 {
8460 Lisp_Object args[2], message;
8461 struct gcpro gcpro1, gcpro2;
8462
8463 args[0] = build_string (m);
8464 args[1] = message = string;
8465 GCPRO2 (args[0], message);
8466 gcpro1.nvars = 2;
8467
8468 message = Fformat (2, args);
8469
8470 if (log)
8471 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8472 else
8473 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8474
8475 UNGCPRO;
8476
8477 /* Print should start at the beginning of the message
8478 buffer next time. */
8479 message_buf_print = 0;
8480 }
8481 }
8482 }
8483
8484
8485 /* Dump an informative message to the minibuf. If M is 0, clear out
8486 any existing message, and let the mini-buffer text show through. */
8487
8488 static void
8489 vmessage (const char *m, va_list ap)
8490 {
8491 if (noninteractive)
8492 {
8493 if (m)
8494 {
8495 if (noninteractive_need_newline)
8496 putc ('\n', stderr);
8497 noninteractive_need_newline = 0;
8498 vfprintf (stderr, m, ap);
8499 if (cursor_in_echo_area == 0)
8500 fprintf (stderr, "\n");
8501 fflush (stderr);
8502 }
8503 }
8504 else if (INTERACTIVE)
8505 {
8506 /* The frame whose mini-buffer we're going to display the message
8507 on. It may be larger than the selected frame, so we need to
8508 use its buffer, not the selected frame's buffer. */
8509 Lisp_Object mini_window;
8510 struct frame *f, *sf = SELECTED_FRAME ();
8511
8512 /* Get the frame containing the mini-buffer
8513 that the selected frame is using. */
8514 mini_window = FRAME_MINIBUF_WINDOW (sf);
8515 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8516
8517 /* A null message buffer means that the frame hasn't really been
8518 initialized yet. Error messages get reported properly by
8519 cmd_error, so this must be just an informative message; toss
8520 it. */
8521 if (FRAME_MESSAGE_BUF (f))
8522 {
8523 if (m)
8524 {
8525 int len;
8526
8527 len = doprnt (FRAME_MESSAGE_BUF (f),
8528 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8529
8530 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8531 }
8532 else
8533 message1 (0);
8534
8535 /* Print should start at the beginning of the message
8536 buffer next time. */
8537 message_buf_print = 0;
8538 }
8539 }
8540 }
8541
8542 void
8543 message (const char *m, ...)
8544 {
8545 va_list ap;
8546 va_start (ap, m);
8547 vmessage (m, ap);
8548 va_end (ap);
8549 }
8550
8551
8552 /* The non-logging version of message. */
8553
8554 void
8555 message_nolog (const char *m, ...)
8556 {
8557 Lisp_Object old_log_max;
8558 va_list ap;
8559 va_start (ap, m);
8560 old_log_max = Vmessage_log_max;
8561 Vmessage_log_max = Qnil;
8562 vmessage (m, ap);
8563 Vmessage_log_max = old_log_max;
8564 va_end (ap);
8565 }
8566
8567
8568 /* Display the current message in the current mini-buffer. This is
8569 only called from error handlers in process.c, and is not time
8570 critical. */
8571
8572 void
8573 update_echo_area (void)
8574 {
8575 if (!NILP (echo_area_buffer[0]))
8576 {
8577 Lisp_Object string;
8578 string = Fcurrent_message ();
8579 message3 (string, SBYTES (string),
8580 !NILP (current_buffer->enable_multibyte_characters));
8581 }
8582 }
8583
8584
8585 /* Make sure echo area buffers in `echo_buffers' are live.
8586 If they aren't, make new ones. */
8587
8588 static void
8589 ensure_echo_area_buffers (void)
8590 {
8591 int i;
8592
8593 for (i = 0; i < 2; ++i)
8594 if (!BUFFERP (echo_buffer[i])
8595 || NILP (XBUFFER (echo_buffer[i])->name))
8596 {
8597 char name[30];
8598 Lisp_Object old_buffer;
8599 int j;
8600
8601 old_buffer = echo_buffer[i];
8602 sprintf (name, " *Echo Area %d*", i);
8603 echo_buffer[i] = Fget_buffer_create (build_string (name));
8604 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8605 /* to force word wrap in echo area -
8606 it was decided to postpone this*/
8607 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8608
8609 for (j = 0; j < 2; ++j)
8610 if (EQ (old_buffer, echo_area_buffer[j]))
8611 echo_area_buffer[j] = echo_buffer[i];
8612 }
8613 }
8614
8615
8616 /* Call FN with args A1..A4 with either the current or last displayed
8617 echo_area_buffer as current buffer.
8618
8619 WHICH zero means use the current message buffer
8620 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8621 from echo_buffer[] and clear it.
8622
8623 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8624 suitable buffer from echo_buffer[] and clear it.
8625
8626 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8627 that the current message becomes the last displayed one, make
8628 choose a suitable buffer for echo_area_buffer[0], and clear it.
8629
8630 Value is what FN returns. */
8631
8632 static int
8633 with_echo_area_buffer (struct window *w, int which,
8634 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8635 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8636 {
8637 Lisp_Object buffer;
8638 int this_one, the_other, clear_buffer_p, rc;
8639 int count = SPECPDL_INDEX ();
8640
8641 /* If buffers aren't live, make new ones. */
8642 ensure_echo_area_buffers ();
8643
8644 clear_buffer_p = 0;
8645
8646 if (which == 0)
8647 this_one = 0, the_other = 1;
8648 else if (which > 0)
8649 this_one = 1, the_other = 0;
8650 else
8651 {
8652 this_one = 0, the_other = 1;
8653 clear_buffer_p = 1;
8654
8655 /* We need a fresh one in case the current echo buffer equals
8656 the one containing the last displayed echo area message. */
8657 if (!NILP (echo_area_buffer[this_one])
8658 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8659 echo_area_buffer[this_one] = Qnil;
8660 }
8661
8662 /* Choose a suitable buffer from echo_buffer[] is we don't
8663 have one. */
8664 if (NILP (echo_area_buffer[this_one]))
8665 {
8666 echo_area_buffer[this_one]
8667 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8668 ? echo_buffer[the_other]
8669 : echo_buffer[this_one]);
8670 clear_buffer_p = 1;
8671 }
8672
8673 buffer = echo_area_buffer[this_one];
8674
8675 /* Don't get confused by reusing the buffer used for echoing
8676 for a different purpose. */
8677 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8678 cancel_echoing ();
8679
8680 record_unwind_protect (unwind_with_echo_area_buffer,
8681 with_echo_area_buffer_unwind_data (w));
8682
8683 /* Make the echo area buffer current. Note that for display
8684 purposes, it is not necessary that the displayed window's buffer
8685 == current_buffer, except for text property lookup. So, let's
8686 only set that buffer temporarily here without doing a full
8687 Fset_window_buffer. We must also change w->pointm, though,
8688 because otherwise an assertions in unshow_buffer fails, and Emacs
8689 aborts. */
8690 set_buffer_internal_1 (XBUFFER (buffer));
8691 if (w)
8692 {
8693 w->buffer = buffer;
8694 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8695 }
8696
8697 current_buffer->undo_list = Qt;
8698 current_buffer->read_only = Qnil;
8699 specbind (Qinhibit_read_only, Qt);
8700 specbind (Qinhibit_modification_hooks, Qt);
8701
8702 if (clear_buffer_p && Z > BEG)
8703 del_range (BEG, Z);
8704
8705 xassert (BEGV >= BEG);
8706 xassert (ZV <= Z && ZV >= BEGV);
8707
8708 rc = fn (a1, a2, a3, a4);
8709
8710 xassert (BEGV >= BEG);
8711 xassert (ZV <= Z && ZV >= BEGV);
8712
8713 unbind_to (count, Qnil);
8714 return rc;
8715 }
8716
8717
8718 /* Save state that should be preserved around the call to the function
8719 FN called in with_echo_area_buffer. */
8720
8721 static Lisp_Object
8722 with_echo_area_buffer_unwind_data (struct window *w)
8723 {
8724 int i = 0;
8725 Lisp_Object vector, tmp;
8726
8727 /* Reduce consing by keeping one vector in
8728 Vwith_echo_area_save_vector. */
8729 vector = Vwith_echo_area_save_vector;
8730 Vwith_echo_area_save_vector = Qnil;
8731
8732 if (NILP (vector))
8733 vector = Fmake_vector (make_number (7), Qnil);
8734
8735 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8736 ASET (vector, i, Vdeactivate_mark); ++i;
8737 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8738
8739 if (w)
8740 {
8741 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8742 ASET (vector, i, w->buffer); ++i;
8743 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8744 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8745 }
8746 else
8747 {
8748 int end = i + 4;
8749 for (; i < end; ++i)
8750 ASET (vector, i, Qnil);
8751 }
8752
8753 xassert (i == ASIZE (vector));
8754 return vector;
8755 }
8756
8757
8758 /* Restore global state from VECTOR which was created by
8759 with_echo_area_buffer_unwind_data. */
8760
8761 static Lisp_Object
8762 unwind_with_echo_area_buffer (Lisp_Object vector)
8763 {
8764 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8765 Vdeactivate_mark = AREF (vector, 1);
8766 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8767
8768 if (WINDOWP (AREF (vector, 3)))
8769 {
8770 struct window *w;
8771 Lisp_Object buffer, charpos, bytepos;
8772
8773 w = XWINDOW (AREF (vector, 3));
8774 buffer = AREF (vector, 4);
8775 charpos = AREF (vector, 5);
8776 bytepos = AREF (vector, 6);
8777
8778 w->buffer = buffer;
8779 set_marker_both (w->pointm, buffer,
8780 XFASTINT (charpos), XFASTINT (bytepos));
8781 }
8782
8783 Vwith_echo_area_save_vector = vector;
8784 return Qnil;
8785 }
8786
8787
8788 /* Set up the echo area for use by print functions. MULTIBYTE_P
8789 non-zero means we will print multibyte. */
8790
8791 void
8792 setup_echo_area_for_printing (int multibyte_p)
8793 {
8794 /* If we can't find an echo area any more, exit. */
8795 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8796 Fkill_emacs (Qnil);
8797
8798 ensure_echo_area_buffers ();
8799
8800 if (!message_buf_print)
8801 {
8802 /* A message has been output since the last time we printed.
8803 Choose a fresh echo area buffer. */
8804 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8805 echo_area_buffer[0] = echo_buffer[1];
8806 else
8807 echo_area_buffer[0] = echo_buffer[0];
8808
8809 /* Switch to that buffer and clear it. */
8810 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8811 current_buffer->truncate_lines = Qnil;
8812
8813 if (Z > BEG)
8814 {
8815 int count = SPECPDL_INDEX ();
8816 specbind (Qinhibit_read_only, Qt);
8817 /* Note that undo recording is always disabled. */
8818 del_range (BEG, Z);
8819 unbind_to (count, Qnil);
8820 }
8821 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8822
8823 /* Set up the buffer for the multibyteness we need. */
8824 if (multibyte_p
8825 != !NILP (current_buffer->enable_multibyte_characters))
8826 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8827
8828 /* Raise the frame containing the echo area. */
8829 if (minibuffer_auto_raise)
8830 {
8831 struct frame *sf = SELECTED_FRAME ();
8832 Lisp_Object mini_window;
8833 mini_window = FRAME_MINIBUF_WINDOW (sf);
8834 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8835 }
8836
8837 message_log_maybe_newline ();
8838 message_buf_print = 1;
8839 }
8840 else
8841 {
8842 if (NILP (echo_area_buffer[0]))
8843 {
8844 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8845 echo_area_buffer[0] = echo_buffer[1];
8846 else
8847 echo_area_buffer[0] = echo_buffer[0];
8848 }
8849
8850 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8851 {
8852 /* Someone switched buffers between print requests. */
8853 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8854 current_buffer->truncate_lines = Qnil;
8855 }
8856 }
8857 }
8858
8859
8860 /* Display an echo area message in window W. Value is non-zero if W's
8861 height is changed. If display_last_displayed_message_p is
8862 non-zero, display the message that was last displayed, otherwise
8863 display the current message. */
8864
8865 static int
8866 display_echo_area (struct window *w)
8867 {
8868 int i, no_message_p, window_height_changed_p, count;
8869
8870 /* Temporarily disable garbage collections while displaying the echo
8871 area. This is done because a GC can print a message itself.
8872 That message would modify the echo area buffer's contents while a
8873 redisplay of the buffer is going on, and seriously confuse
8874 redisplay. */
8875 count = inhibit_garbage_collection ();
8876
8877 /* If there is no message, we must call display_echo_area_1
8878 nevertheless because it resizes the window. But we will have to
8879 reset the echo_area_buffer in question to nil at the end because
8880 with_echo_area_buffer will sets it to an empty buffer. */
8881 i = display_last_displayed_message_p ? 1 : 0;
8882 no_message_p = NILP (echo_area_buffer[i]);
8883
8884 window_height_changed_p
8885 = with_echo_area_buffer (w, display_last_displayed_message_p,
8886 display_echo_area_1,
8887 (EMACS_INT) w, Qnil, 0, 0);
8888
8889 if (no_message_p)
8890 echo_area_buffer[i] = Qnil;
8891
8892 unbind_to (count, Qnil);
8893 return window_height_changed_p;
8894 }
8895
8896
8897 /* Helper for display_echo_area. Display the current buffer which
8898 contains the current echo area message in window W, a mini-window,
8899 a pointer to which is passed in A1. A2..A4 are currently not used.
8900 Change the height of W so that all of the message is displayed.
8901 Value is non-zero if height of W was changed. */
8902
8903 static int
8904 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8905 {
8906 struct window *w = (struct window *) a1;
8907 Lisp_Object window;
8908 struct text_pos start;
8909 int window_height_changed_p = 0;
8910
8911 /* Do this before displaying, so that we have a large enough glyph
8912 matrix for the display. If we can't get enough space for the
8913 whole text, display the last N lines. That works by setting w->start. */
8914 window_height_changed_p = resize_mini_window (w, 0);
8915
8916 /* Use the starting position chosen by resize_mini_window. */
8917 SET_TEXT_POS_FROM_MARKER (start, w->start);
8918
8919 /* Display. */
8920 clear_glyph_matrix (w->desired_matrix);
8921 XSETWINDOW (window, w);
8922 try_window (window, start, 0);
8923
8924 return window_height_changed_p;
8925 }
8926
8927
8928 /* Resize the echo area window to exactly the size needed for the
8929 currently displayed message, if there is one. If a mini-buffer
8930 is active, don't shrink it. */
8931
8932 void
8933 resize_echo_area_exactly (void)
8934 {
8935 if (BUFFERP (echo_area_buffer[0])
8936 && WINDOWP (echo_area_window))
8937 {
8938 struct window *w = XWINDOW (echo_area_window);
8939 int resized_p;
8940 Lisp_Object resize_exactly;
8941
8942 if (minibuf_level == 0)
8943 resize_exactly = Qt;
8944 else
8945 resize_exactly = Qnil;
8946
8947 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8948 (EMACS_INT) w, resize_exactly, 0, 0);
8949 if (resized_p)
8950 {
8951 ++windows_or_buffers_changed;
8952 ++update_mode_lines;
8953 redisplay_internal (0);
8954 }
8955 }
8956 }
8957
8958
8959 /* Callback function for with_echo_area_buffer, when used from
8960 resize_echo_area_exactly. A1 contains a pointer to the window to
8961 resize, EXACTLY non-nil means resize the mini-window exactly to the
8962 size of the text displayed. A3 and A4 are not used. Value is what
8963 resize_mini_window returns. */
8964
8965 static int
8966 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8967 {
8968 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8969 }
8970
8971
8972 /* Resize mini-window W to fit the size of its contents. EXACT_P
8973 means size the window exactly to the size needed. Otherwise, it's
8974 only enlarged until W's buffer is empty.
8975
8976 Set W->start to the right place to begin display. If the whole
8977 contents fit, start at the beginning. Otherwise, start so as
8978 to make the end of the contents appear. This is particularly
8979 important for y-or-n-p, but seems desirable generally.
8980
8981 Value is non-zero if the window height has been changed. */
8982
8983 int
8984 resize_mini_window (struct window *w, int exact_p)
8985 {
8986 struct frame *f = XFRAME (w->frame);
8987 int window_height_changed_p = 0;
8988
8989 xassert (MINI_WINDOW_P (w));
8990
8991 /* By default, start display at the beginning. */
8992 set_marker_both (w->start, w->buffer,
8993 BUF_BEGV (XBUFFER (w->buffer)),
8994 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8995
8996 /* Don't resize windows while redisplaying a window; it would
8997 confuse redisplay functions when the size of the window they are
8998 displaying changes from under them. Such a resizing can happen,
8999 for instance, when which-func prints a long message while
9000 we are running fontification-functions. We're running these
9001 functions with safe_call which binds inhibit-redisplay to t. */
9002 if (!NILP (Vinhibit_redisplay))
9003 return 0;
9004
9005 /* Nil means don't try to resize. */
9006 if (NILP (Vresize_mini_windows)
9007 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9008 return 0;
9009
9010 if (!FRAME_MINIBUF_ONLY_P (f))
9011 {
9012 struct it it;
9013 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9014 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9015 int height, max_height;
9016 int unit = FRAME_LINE_HEIGHT (f);
9017 struct text_pos start;
9018 struct buffer *old_current_buffer = NULL;
9019
9020 if (current_buffer != XBUFFER (w->buffer))
9021 {
9022 old_current_buffer = current_buffer;
9023 set_buffer_internal (XBUFFER (w->buffer));
9024 }
9025
9026 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9027
9028 /* Compute the max. number of lines specified by the user. */
9029 if (FLOATP (Vmax_mini_window_height))
9030 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9031 else if (INTEGERP (Vmax_mini_window_height))
9032 max_height = XINT (Vmax_mini_window_height);
9033 else
9034 max_height = total_height / 4;
9035
9036 /* Correct that max. height if it's bogus. */
9037 max_height = max (1, max_height);
9038 max_height = min (total_height, max_height);
9039
9040 /* Find out the height of the text in the window. */
9041 if (it.line_wrap == TRUNCATE)
9042 height = 1;
9043 else
9044 {
9045 last_height = 0;
9046 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9047 if (it.max_ascent == 0 && it.max_descent == 0)
9048 height = it.current_y + last_height;
9049 else
9050 height = it.current_y + it.max_ascent + it.max_descent;
9051 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9052 height = (height + unit - 1) / unit;
9053 }
9054
9055 /* Compute a suitable window start. */
9056 if (height > max_height)
9057 {
9058 height = max_height;
9059 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9060 move_it_vertically_backward (&it, (height - 1) * unit);
9061 start = it.current.pos;
9062 }
9063 else
9064 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9065 SET_MARKER_FROM_TEXT_POS (w->start, start);
9066
9067 if (EQ (Vresize_mini_windows, Qgrow_only))
9068 {
9069 /* Let it grow only, until we display an empty message, in which
9070 case the window shrinks again. */
9071 if (height > WINDOW_TOTAL_LINES (w))
9072 {
9073 int old_height = WINDOW_TOTAL_LINES (w);
9074 freeze_window_starts (f, 1);
9075 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9076 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9077 }
9078 else if (height < WINDOW_TOTAL_LINES (w)
9079 && (exact_p || BEGV == ZV))
9080 {
9081 int old_height = WINDOW_TOTAL_LINES (w);
9082 freeze_window_starts (f, 0);
9083 shrink_mini_window (w);
9084 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9085 }
9086 }
9087 else
9088 {
9089 /* Always resize to exact size needed. */
9090 if (height > WINDOW_TOTAL_LINES (w))
9091 {
9092 int old_height = WINDOW_TOTAL_LINES (w);
9093 freeze_window_starts (f, 1);
9094 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9095 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9096 }
9097 else if (height < WINDOW_TOTAL_LINES (w))
9098 {
9099 int old_height = WINDOW_TOTAL_LINES (w);
9100 freeze_window_starts (f, 0);
9101 shrink_mini_window (w);
9102
9103 if (height)
9104 {
9105 freeze_window_starts (f, 1);
9106 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9107 }
9108
9109 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9110 }
9111 }
9112
9113 if (old_current_buffer)
9114 set_buffer_internal (old_current_buffer);
9115 }
9116
9117 return window_height_changed_p;
9118 }
9119
9120
9121 /* Value is the current message, a string, or nil if there is no
9122 current message. */
9123
9124 Lisp_Object
9125 current_message (void)
9126 {
9127 Lisp_Object msg;
9128
9129 if (!BUFFERP (echo_area_buffer[0]))
9130 msg = Qnil;
9131 else
9132 {
9133 with_echo_area_buffer (0, 0, current_message_1,
9134 (EMACS_INT) &msg, Qnil, 0, 0);
9135 if (NILP (msg))
9136 echo_area_buffer[0] = Qnil;
9137 }
9138
9139 return msg;
9140 }
9141
9142
9143 static int
9144 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9145 {
9146 Lisp_Object *msg = (Lisp_Object *) a1;
9147
9148 if (Z > BEG)
9149 *msg = make_buffer_string (BEG, Z, 1);
9150 else
9151 *msg = Qnil;
9152 return 0;
9153 }
9154
9155
9156 /* Push the current message on Vmessage_stack for later restauration
9157 by restore_message. Value is non-zero if the current message isn't
9158 empty. This is a relatively infrequent operation, so it's not
9159 worth optimizing. */
9160
9161 int
9162 push_message (void)
9163 {
9164 Lisp_Object msg;
9165 msg = current_message ();
9166 Vmessage_stack = Fcons (msg, Vmessage_stack);
9167 return STRINGP (msg);
9168 }
9169
9170
9171 /* Restore message display from the top of Vmessage_stack. */
9172
9173 void
9174 restore_message (void)
9175 {
9176 Lisp_Object msg;
9177
9178 xassert (CONSP (Vmessage_stack));
9179 msg = XCAR (Vmessage_stack);
9180 if (STRINGP (msg))
9181 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9182 else
9183 message3_nolog (msg, 0, 0);
9184 }
9185
9186
9187 /* Handler for record_unwind_protect calling pop_message. */
9188
9189 Lisp_Object
9190 pop_message_unwind (Lisp_Object dummy)
9191 {
9192 pop_message ();
9193 return Qnil;
9194 }
9195
9196 /* Pop the top-most entry off Vmessage_stack. */
9197
9198 void
9199 pop_message (void)
9200 {
9201 xassert (CONSP (Vmessage_stack));
9202 Vmessage_stack = XCDR (Vmessage_stack);
9203 }
9204
9205
9206 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9207 exits. If the stack is not empty, we have a missing pop_message
9208 somewhere. */
9209
9210 void
9211 check_message_stack (void)
9212 {
9213 if (!NILP (Vmessage_stack))
9214 abort ();
9215 }
9216
9217
9218 /* Truncate to NCHARS what will be displayed in the echo area the next
9219 time we display it---but don't redisplay it now. */
9220
9221 void
9222 truncate_echo_area (int nchars)
9223 {
9224 if (nchars == 0)
9225 echo_area_buffer[0] = Qnil;
9226 /* A null message buffer means that the frame hasn't really been
9227 initialized yet. Error messages get reported properly by
9228 cmd_error, so this must be just an informative message; toss it. */
9229 else if (!noninteractive
9230 && INTERACTIVE
9231 && !NILP (echo_area_buffer[0]))
9232 {
9233 struct frame *sf = SELECTED_FRAME ();
9234 if (FRAME_MESSAGE_BUF (sf))
9235 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9236 }
9237 }
9238
9239
9240 /* Helper function for truncate_echo_area. Truncate the current
9241 message to at most NCHARS characters. */
9242
9243 static int
9244 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9245 {
9246 if (BEG + nchars < Z)
9247 del_range (BEG + nchars, Z);
9248 if (Z == BEG)
9249 echo_area_buffer[0] = Qnil;
9250 return 0;
9251 }
9252
9253
9254 /* Set the current message to a substring of S or STRING.
9255
9256 If STRING is a Lisp string, set the message to the first NBYTES
9257 bytes from STRING. NBYTES zero means use the whole string. If
9258 STRING is multibyte, the message will be displayed multibyte.
9259
9260 If S is not null, set the message to the first LEN bytes of S. LEN
9261 zero means use the whole string. MULTIBYTE_P non-zero means S is
9262 multibyte. Display the message multibyte in that case.
9263
9264 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9265 to t before calling set_message_1 (which calls insert).
9266 */
9267
9268 void
9269 set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
9270 {
9271 message_enable_multibyte
9272 = ((s && multibyte_p)
9273 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9274
9275 with_echo_area_buffer (0, -1, set_message_1,
9276 (EMACS_INT) s, string, nbytes, multibyte_p);
9277 message_buf_print = 0;
9278 help_echo_showing_p = 0;
9279 }
9280
9281
9282 /* Helper function for set_message. Arguments have the same meaning
9283 as there, with A1 corresponding to S and A2 corresponding to STRING
9284 This function is called with the echo area buffer being
9285 current. */
9286
9287 static int
9288 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9289 {
9290 const char *s = (const char *) a1;
9291 Lisp_Object string = a2;
9292
9293 /* Change multibyteness of the echo buffer appropriately. */
9294 if (message_enable_multibyte
9295 != !NILP (current_buffer->enable_multibyte_characters))
9296 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9297
9298 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9299
9300 /* Insert new message at BEG. */
9301 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9302
9303 if (STRINGP (string))
9304 {
9305 int nchars;
9306
9307 if (nbytes == 0)
9308 nbytes = SBYTES (string);
9309 nchars = string_byte_to_char (string, nbytes);
9310
9311 /* This function takes care of single/multibyte conversion. We
9312 just have to ensure that the echo area buffer has the right
9313 setting of enable_multibyte_characters. */
9314 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9315 }
9316 else if (s)
9317 {
9318 if (nbytes == 0)
9319 nbytes = strlen (s);
9320
9321 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9322 {
9323 /* Convert from multi-byte to single-byte. */
9324 int i, c, n;
9325 unsigned char work[1];
9326
9327 /* Convert a multibyte string to single-byte. */
9328 for (i = 0; i < nbytes; i += n)
9329 {
9330 c = string_char_and_length (s + i, &n);
9331 work[0] = (ASCII_CHAR_P (c)
9332 ? c
9333 : multibyte_char_to_unibyte (c, Qnil));
9334 insert_1_both (work, 1, 1, 1, 0, 0);
9335 }
9336 }
9337 else if (!multibyte_p
9338 && !NILP (current_buffer->enable_multibyte_characters))
9339 {
9340 /* Convert from single-byte to multi-byte. */
9341 int i, c, n;
9342 const unsigned char *msg = (const unsigned char *) s;
9343 unsigned char str[MAX_MULTIBYTE_LENGTH];
9344
9345 /* Convert a single-byte string to multibyte. */
9346 for (i = 0; i < nbytes; i++)
9347 {
9348 c = msg[i];
9349 MAKE_CHAR_MULTIBYTE (c);
9350 n = CHAR_STRING (c, str);
9351 insert_1_both (str, 1, n, 1, 0, 0);
9352 }
9353 }
9354 else
9355 insert_1 (s, nbytes, 1, 0, 0);
9356 }
9357
9358 return 0;
9359 }
9360
9361
9362 /* Clear messages. CURRENT_P non-zero means clear the current
9363 message. LAST_DISPLAYED_P non-zero means clear the message
9364 last displayed. */
9365
9366 void
9367 clear_message (int current_p, int last_displayed_p)
9368 {
9369 if (current_p)
9370 {
9371 echo_area_buffer[0] = Qnil;
9372 message_cleared_p = 1;
9373 }
9374
9375 if (last_displayed_p)
9376 echo_area_buffer[1] = Qnil;
9377
9378 message_buf_print = 0;
9379 }
9380
9381 /* Clear garbaged frames.
9382
9383 This function is used where the old redisplay called
9384 redraw_garbaged_frames which in turn called redraw_frame which in
9385 turn called clear_frame. The call to clear_frame was a source of
9386 flickering. I believe a clear_frame is not necessary. It should
9387 suffice in the new redisplay to invalidate all current matrices,
9388 and ensure a complete redisplay of all windows. */
9389
9390 static void
9391 clear_garbaged_frames (void)
9392 {
9393 if (frame_garbaged)
9394 {
9395 Lisp_Object tail, frame;
9396 int changed_count = 0;
9397
9398 FOR_EACH_FRAME (tail, frame)
9399 {
9400 struct frame *f = XFRAME (frame);
9401
9402 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9403 {
9404 if (f->resized_p)
9405 {
9406 Fredraw_frame (frame);
9407 f->force_flush_display_p = 1;
9408 }
9409 clear_current_matrices (f);
9410 changed_count++;
9411 f->garbaged = 0;
9412 f->resized_p = 0;
9413 }
9414 }
9415
9416 frame_garbaged = 0;
9417 if (changed_count)
9418 ++windows_or_buffers_changed;
9419 }
9420 }
9421
9422
9423 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9424 is non-zero update selected_frame. Value is non-zero if the
9425 mini-windows height has been changed. */
9426
9427 static int
9428 echo_area_display (int update_frame_p)
9429 {
9430 Lisp_Object mini_window;
9431 struct window *w;
9432 struct frame *f;
9433 int window_height_changed_p = 0;
9434 struct frame *sf = SELECTED_FRAME ();
9435
9436 mini_window = FRAME_MINIBUF_WINDOW (sf);
9437 w = XWINDOW (mini_window);
9438 f = XFRAME (WINDOW_FRAME (w));
9439
9440 /* Don't display if frame is invisible or not yet initialized. */
9441 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9442 return 0;
9443
9444 #ifdef HAVE_WINDOW_SYSTEM
9445 /* When Emacs starts, selected_frame may be the initial terminal
9446 frame. If we let this through, a message would be displayed on
9447 the terminal. */
9448 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9449 return 0;
9450 #endif /* HAVE_WINDOW_SYSTEM */
9451
9452 /* Redraw garbaged frames. */
9453 if (frame_garbaged)
9454 clear_garbaged_frames ();
9455
9456 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9457 {
9458 echo_area_window = mini_window;
9459 window_height_changed_p = display_echo_area (w);
9460 w->must_be_updated_p = 1;
9461
9462 /* Update the display, unless called from redisplay_internal.
9463 Also don't update the screen during redisplay itself. The
9464 update will happen at the end of redisplay, and an update
9465 here could cause confusion. */
9466 if (update_frame_p && !redisplaying_p)
9467 {
9468 int n = 0;
9469
9470 /* If the display update has been interrupted by pending
9471 input, update mode lines in the frame. Due to the
9472 pending input, it might have been that redisplay hasn't
9473 been called, so that mode lines above the echo area are
9474 garbaged. This looks odd, so we prevent it here. */
9475 if (!display_completed)
9476 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9477
9478 if (window_height_changed_p
9479 /* Don't do this if Emacs is shutting down. Redisplay
9480 needs to run hooks. */
9481 && !NILP (Vrun_hooks))
9482 {
9483 /* Must update other windows. Likewise as in other
9484 cases, don't let this update be interrupted by
9485 pending input. */
9486 int count = SPECPDL_INDEX ();
9487 specbind (Qredisplay_dont_pause, Qt);
9488 windows_or_buffers_changed = 1;
9489 redisplay_internal (0);
9490 unbind_to (count, Qnil);
9491 }
9492 else if (FRAME_WINDOW_P (f) && n == 0)
9493 {
9494 /* Window configuration is the same as before.
9495 Can do with a display update of the echo area,
9496 unless we displayed some mode lines. */
9497 update_single_window (w, 1);
9498 FRAME_RIF (f)->flush_display (f);
9499 }
9500 else
9501 update_frame (f, 1, 1);
9502
9503 /* If cursor is in the echo area, make sure that the next
9504 redisplay displays the minibuffer, so that the cursor will
9505 be replaced with what the minibuffer wants. */
9506 if (cursor_in_echo_area)
9507 ++windows_or_buffers_changed;
9508 }
9509 }
9510 else if (!EQ (mini_window, selected_window))
9511 windows_or_buffers_changed++;
9512
9513 /* Last displayed message is now the current message. */
9514 echo_area_buffer[1] = echo_area_buffer[0];
9515 /* Inform read_char that we're not echoing. */
9516 echo_message_buffer = Qnil;
9517
9518 /* Prevent redisplay optimization in redisplay_internal by resetting
9519 this_line_start_pos. This is done because the mini-buffer now
9520 displays the message instead of its buffer text. */
9521 if (EQ (mini_window, selected_window))
9522 CHARPOS (this_line_start_pos) = 0;
9523
9524 return window_height_changed_p;
9525 }
9526
9527
9528 \f
9529 /***********************************************************************
9530 Mode Lines and Frame Titles
9531 ***********************************************************************/
9532
9533 /* A buffer for constructing non-propertized mode-line strings and
9534 frame titles in it; allocated from the heap in init_xdisp and
9535 resized as needed in store_mode_line_noprop_char. */
9536
9537 static char *mode_line_noprop_buf;
9538
9539 /* The buffer's end, and a current output position in it. */
9540
9541 static char *mode_line_noprop_buf_end;
9542 static char *mode_line_noprop_ptr;
9543
9544 #define MODE_LINE_NOPROP_LEN(start) \
9545 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9546
9547 static enum {
9548 MODE_LINE_DISPLAY = 0,
9549 MODE_LINE_TITLE,
9550 MODE_LINE_NOPROP,
9551 MODE_LINE_STRING
9552 } mode_line_target;
9553
9554 /* Alist that caches the results of :propertize.
9555 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9556 static Lisp_Object mode_line_proptrans_alist;
9557
9558 /* List of strings making up the mode-line. */
9559 static Lisp_Object mode_line_string_list;
9560
9561 /* Base face property when building propertized mode line string. */
9562 static Lisp_Object mode_line_string_face;
9563 static Lisp_Object mode_line_string_face_prop;
9564
9565
9566 /* Unwind data for mode line strings */
9567
9568 static Lisp_Object Vmode_line_unwind_vector;
9569
9570 static Lisp_Object
9571 format_mode_line_unwind_data (struct buffer *obuf,
9572 Lisp_Object owin,
9573 int save_proptrans)
9574 {
9575 Lisp_Object vector, tmp;
9576
9577 /* Reduce consing by keeping one vector in
9578 Vwith_echo_area_save_vector. */
9579 vector = Vmode_line_unwind_vector;
9580 Vmode_line_unwind_vector = Qnil;
9581
9582 if (NILP (vector))
9583 vector = Fmake_vector (make_number (8), Qnil);
9584
9585 ASET (vector, 0, make_number (mode_line_target));
9586 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9587 ASET (vector, 2, mode_line_string_list);
9588 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9589 ASET (vector, 4, mode_line_string_face);
9590 ASET (vector, 5, mode_line_string_face_prop);
9591
9592 if (obuf)
9593 XSETBUFFER (tmp, obuf);
9594 else
9595 tmp = Qnil;
9596 ASET (vector, 6, tmp);
9597 ASET (vector, 7, owin);
9598
9599 return vector;
9600 }
9601
9602 static Lisp_Object
9603 unwind_format_mode_line (Lisp_Object vector)
9604 {
9605 mode_line_target = XINT (AREF (vector, 0));
9606 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9607 mode_line_string_list = AREF (vector, 2);
9608 if (! EQ (AREF (vector, 3), Qt))
9609 mode_line_proptrans_alist = AREF (vector, 3);
9610 mode_line_string_face = AREF (vector, 4);
9611 mode_line_string_face_prop = AREF (vector, 5);
9612
9613 if (!NILP (AREF (vector, 7)))
9614 /* Select window before buffer, since it may change the buffer. */
9615 Fselect_window (AREF (vector, 7), Qt);
9616
9617 if (!NILP (AREF (vector, 6)))
9618 {
9619 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9620 ASET (vector, 6, Qnil);
9621 }
9622
9623 Vmode_line_unwind_vector = vector;
9624 return Qnil;
9625 }
9626
9627
9628 /* Store a single character C for the frame title in mode_line_noprop_buf.
9629 Re-allocate mode_line_noprop_buf if necessary. */
9630
9631 static void
9632 store_mode_line_noprop_char (char c)
9633 {
9634 /* If output position has reached the end of the allocated buffer,
9635 double the buffer's size. */
9636 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9637 {
9638 int len = MODE_LINE_NOPROP_LEN (0);
9639 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9640 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9641 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9642 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9643 }
9644
9645 *mode_line_noprop_ptr++ = c;
9646 }
9647
9648
9649 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9650 mode_line_noprop_ptr. STR is the string to store. Do not copy
9651 characters that yield more columns than PRECISION; PRECISION <= 0
9652 means copy the whole string. Pad with spaces until FIELD_WIDTH
9653 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9654 pad. Called from display_mode_element when it is used to build a
9655 frame title. */
9656
9657 static int
9658 store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
9659 {
9660 int n = 0;
9661 int dummy, nbytes;
9662
9663 /* Copy at most PRECISION chars from STR. */
9664 nbytes = strlen (str);
9665 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9666 while (nbytes--)
9667 store_mode_line_noprop_char (*str++);
9668
9669 /* Fill up with spaces until FIELD_WIDTH reached. */
9670 while (field_width > 0
9671 && n < field_width)
9672 {
9673 store_mode_line_noprop_char (' ');
9674 ++n;
9675 }
9676
9677 return n;
9678 }
9679
9680 /***********************************************************************
9681 Frame Titles
9682 ***********************************************************************/
9683
9684 #ifdef HAVE_WINDOW_SYSTEM
9685
9686 /* Set the title of FRAME, if it has changed. The title format is
9687 Vicon_title_format if FRAME is iconified, otherwise it is
9688 frame_title_format. */
9689
9690 static void
9691 x_consider_frame_title (Lisp_Object frame)
9692 {
9693 struct frame *f = XFRAME (frame);
9694
9695 if (FRAME_WINDOW_P (f)
9696 || FRAME_MINIBUF_ONLY_P (f)
9697 || f->explicit_name)
9698 {
9699 /* Do we have more than one visible frame on this X display? */
9700 Lisp_Object tail;
9701 Lisp_Object fmt;
9702 int title_start;
9703 char *title;
9704 int len;
9705 struct it it;
9706 int count = SPECPDL_INDEX ();
9707
9708 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9709 {
9710 Lisp_Object other_frame = XCAR (tail);
9711 struct frame *tf = XFRAME (other_frame);
9712
9713 if (tf != f
9714 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9715 && !FRAME_MINIBUF_ONLY_P (tf)
9716 && !EQ (other_frame, tip_frame)
9717 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9718 break;
9719 }
9720
9721 /* Set global variable indicating that multiple frames exist. */
9722 multiple_frames = CONSP (tail);
9723
9724 /* Switch to the buffer of selected window of the frame. Set up
9725 mode_line_target so that display_mode_element will output into
9726 mode_line_noprop_buf; then display the title. */
9727 record_unwind_protect (unwind_format_mode_line,
9728 format_mode_line_unwind_data
9729 (current_buffer, selected_window, 0));
9730
9731 Fselect_window (f->selected_window, Qt);
9732 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9733 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9734
9735 mode_line_target = MODE_LINE_TITLE;
9736 title_start = MODE_LINE_NOPROP_LEN (0);
9737 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9738 NULL, DEFAULT_FACE_ID);
9739 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9740 len = MODE_LINE_NOPROP_LEN (title_start);
9741 title = mode_line_noprop_buf + title_start;
9742 unbind_to (count, Qnil);
9743
9744 /* Set the title only if it's changed. This avoids consing in
9745 the common case where it hasn't. (If it turns out that we've
9746 already wasted too much time by walking through the list with
9747 display_mode_element, then we might need to optimize at a
9748 higher level than this.) */
9749 if (! STRINGP (f->name)
9750 || SBYTES (f->name) != len
9751 || memcmp (title, SDATA (f->name), len) != 0)
9752 x_implicitly_set_name (f, make_string (title, len), Qnil);
9753 }
9754 }
9755
9756 #endif /* not HAVE_WINDOW_SYSTEM */
9757
9758
9759
9760 \f
9761 /***********************************************************************
9762 Menu Bars
9763 ***********************************************************************/
9764
9765
9766 /* Prepare for redisplay by updating menu-bar item lists when
9767 appropriate. This can call eval. */
9768
9769 void
9770 prepare_menu_bars (void)
9771 {
9772 int all_windows;
9773 struct gcpro gcpro1, gcpro2;
9774 struct frame *f;
9775 Lisp_Object tooltip_frame;
9776
9777 #ifdef HAVE_WINDOW_SYSTEM
9778 tooltip_frame = tip_frame;
9779 #else
9780 tooltip_frame = Qnil;
9781 #endif
9782
9783 /* Update all frame titles based on their buffer names, etc. We do
9784 this before the menu bars so that the buffer-menu will show the
9785 up-to-date frame titles. */
9786 #ifdef HAVE_WINDOW_SYSTEM
9787 if (windows_or_buffers_changed || update_mode_lines)
9788 {
9789 Lisp_Object tail, frame;
9790
9791 FOR_EACH_FRAME (tail, frame)
9792 {
9793 f = XFRAME (frame);
9794 if (!EQ (frame, tooltip_frame)
9795 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9796 x_consider_frame_title (frame);
9797 }
9798 }
9799 #endif /* HAVE_WINDOW_SYSTEM */
9800
9801 /* Update the menu bar item lists, if appropriate. This has to be
9802 done before any actual redisplay or generation of display lines. */
9803 all_windows = (update_mode_lines
9804 || buffer_shared > 1
9805 || windows_or_buffers_changed);
9806 if (all_windows)
9807 {
9808 Lisp_Object tail, frame;
9809 int count = SPECPDL_INDEX ();
9810 /* 1 means that update_menu_bar has run its hooks
9811 so any further calls to update_menu_bar shouldn't do so again. */
9812 int menu_bar_hooks_run = 0;
9813
9814 record_unwind_save_match_data ();
9815
9816 FOR_EACH_FRAME (tail, frame)
9817 {
9818 f = XFRAME (frame);
9819
9820 /* Ignore tooltip frame. */
9821 if (EQ (frame, tooltip_frame))
9822 continue;
9823
9824 /* If a window on this frame changed size, report that to
9825 the user and clear the size-change flag. */
9826 if (FRAME_WINDOW_SIZES_CHANGED (f))
9827 {
9828 Lisp_Object functions;
9829
9830 /* Clear flag first in case we get an error below. */
9831 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9832 functions = Vwindow_size_change_functions;
9833 GCPRO2 (tail, functions);
9834
9835 while (CONSP (functions))
9836 {
9837 if (!EQ (XCAR (functions), Qt))
9838 call1 (XCAR (functions), frame);
9839 functions = XCDR (functions);
9840 }
9841 UNGCPRO;
9842 }
9843
9844 GCPRO1 (tail);
9845 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9846 #ifdef HAVE_WINDOW_SYSTEM
9847 update_tool_bar (f, 0);
9848 #endif
9849 #ifdef HAVE_NS
9850 if (windows_or_buffers_changed
9851 && FRAME_NS_P (f))
9852 ns_set_doc_edited (f, Fbuffer_modified_p
9853 (XWINDOW (f->selected_window)->buffer));
9854 #endif
9855 UNGCPRO;
9856 }
9857
9858 unbind_to (count, Qnil);
9859 }
9860 else
9861 {
9862 struct frame *sf = SELECTED_FRAME ();
9863 update_menu_bar (sf, 1, 0);
9864 #ifdef HAVE_WINDOW_SYSTEM
9865 update_tool_bar (sf, 1);
9866 #endif
9867 }
9868 }
9869
9870
9871 /* Update the menu bar item list for frame F. This has to be done
9872 before we start to fill in any display lines, because it can call
9873 eval.
9874
9875 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9876
9877 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9878 already ran the menu bar hooks for this redisplay, so there
9879 is no need to run them again. The return value is the
9880 updated value of this flag, to pass to the next call. */
9881
9882 static int
9883 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9884 {
9885 Lisp_Object window;
9886 register struct window *w;
9887
9888 /* If called recursively during a menu update, do nothing. This can
9889 happen when, for instance, an activate-menubar-hook causes a
9890 redisplay. */
9891 if (inhibit_menubar_update)
9892 return hooks_run;
9893
9894 window = FRAME_SELECTED_WINDOW (f);
9895 w = XWINDOW (window);
9896
9897 if (FRAME_WINDOW_P (f)
9898 ?
9899 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9900 || defined (HAVE_NS) || defined (USE_GTK)
9901 FRAME_EXTERNAL_MENU_BAR (f)
9902 #else
9903 FRAME_MENU_BAR_LINES (f) > 0
9904 #endif
9905 : FRAME_MENU_BAR_LINES (f) > 0)
9906 {
9907 /* If the user has switched buffers or windows, we need to
9908 recompute to reflect the new bindings. But we'll
9909 recompute when update_mode_lines is set too; that means
9910 that people can use force-mode-line-update to request
9911 that the menu bar be recomputed. The adverse effect on
9912 the rest of the redisplay algorithm is about the same as
9913 windows_or_buffers_changed anyway. */
9914 if (windows_or_buffers_changed
9915 /* This used to test w->update_mode_line, but we believe
9916 there is no need to recompute the menu in that case. */
9917 || update_mode_lines
9918 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9919 < BUF_MODIFF (XBUFFER (w->buffer)))
9920 != !NILP (w->last_had_star))
9921 || ((!NILP (Vtransient_mark_mode)
9922 && !NILP (XBUFFER (w->buffer)->mark_active))
9923 != !NILP (w->region_showing)))
9924 {
9925 struct buffer *prev = current_buffer;
9926 int count = SPECPDL_INDEX ();
9927
9928 specbind (Qinhibit_menubar_update, Qt);
9929
9930 set_buffer_internal_1 (XBUFFER (w->buffer));
9931 if (save_match_data)
9932 record_unwind_save_match_data ();
9933 if (NILP (Voverriding_local_map_menu_flag))
9934 {
9935 specbind (Qoverriding_terminal_local_map, Qnil);
9936 specbind (Qoverriding_local_map, Qnil);
9937 }
9938
9939 if (!hooks_run)
9940 {
9941 /* Run the Lucid hook. */
9942 safe_run_hooks (Qactivate_menubar_hook);
9943
9944 /* If it has changed current-menubar from previous value,
9945 really recompute the menu-bar from the value. */
9946 if (! NILP (Vlucid_menu_bar_dirty_flag))
9947 call0 (Qrecompute_lucid_menubar);
9948
9949 safe_run_hooks (Qmenu_bar_update_hook);
9950
9951 hooks_run = 1;
9952 }
9953
9954 XSETFRAME (Vmenu_updating_frame, f);
9955 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9956
9957 /* Redisplay the menu bar in case we changed it. */
9958 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9959 || defined (HAVE_NS) || defined (USE_GTK)
9960 if (FRAME_WINDOW_P (f))
9961 {
9962 #if defined (HAVE_NS)
9963 /* All frames on Mac OS share the same menubar. So only
9964 the selected frame should be allowed to set it. */
9965 if (f == SELECTED_FRAME ())
9966 #endif
9967 set_frame_menubar (f, 0, 0);
9968 }
9969 else
9970 /* On a terminal screen, the menu bar is an ordinary screen
9971 line, and this makes it get updated. */
9972 w->update_mode_line = Qt;
9973 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9974 /* In the non-toolkit version, the menu bar is an ordinary screen
9975 line, and this makes it get updated. */
9976 w->update_mode_line = Qt;
9977 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9978
9979 unbind_to (count, Qnil);
9980 set_buffer_internal_1 (prev);
9981 }
9982 }
9983
9984 return hooks_run;
9985 }
9986
9987
9988 \f
9989 /***********************************************************************
9990 Output Cursor
9991 ***********************************************************************/
9992
9993 #ifdef HAVE_WINDOW_SYSTEM
9994
9995 /* EXPORT:
9996 Nominal cursor position -- where to draw output.
9997 HPOS and VPOS are window relative glyph matrix coordinates.
9998 X and Y are window relative pixel coordinates. */
9999
10000 struct cursor_pos output_cursor;
10001
10002
10003 /* EXPORT:
10004 Set the global variable output_cursor to CURSOR. All cursor
10005 positions are relative to updated_window. */
10006
10007 void
10008 set_output_cursor (struct cursor_pos *cursor)
10009 {
10010 output_cursor.hpos = cursor->hpos;
10011 output_cursor.vpos = cursor->vpos;
10012 output_cursor.x = cursor->x;
10013 output_cursor.y = cursor->y;
10014 }
10015
10016
10017 /* EXPORT for RIF:
10018 Set a nominal cursor position.
10019
10020 HPOS and VPOS are column/row positions in a window glyph matrix. X
10021 and Y are window text area relative pixel positions.
10022
10023 If this is done during an update, updated_window will contain the
10024 window that is being updated and the position is the future output
10025 cursor position for that window. If updated_window is null, use
10026 selected_window and display the cursor at the given position. */
10027
10028 void
10029 x_cursor_to (int vpos, int hpos, int y, int x)
10030 {
10031 struct window *w;
10032
10033 /* If updated_window is not set, work on selected_window. */
10034 if (updated_window)
10035 w = updated_window;
10036 else
10037 w = XWINDOW (selected_window);
10038
10039 /* Set the output cursor. */
10040 output_cursor.hpos = hpos;
10041 output_cursor.vpos = vpos;
10042 output_cursor.x = x;
10043 output_cursor.y = y;
10044
10045 /* If not called as part of an update, really display the cursor.
10046 This will also set the cursor position of W. */
10047 if (updated_window == NULL)
10048 {
10049 BLOCK_INPUT;
10050 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10051 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10052 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10053 UNBLOCK_INPUT;
10054 }
10055 }
10056
10057 #endif /* HAVE_WINDOW_SYSTEM */
10058
10059 \f
10060 /***********************************************************************
10061 Tool-bars
10062 ***********************************************************************/
10063
10064 #ifdef HAVE_WINDOW_SYSTEM
10065
10066 /* Where the mouse was last time we reported a mouse event. */
10067
10068 FRAME_PTR last_mouse_frame;
10069
10070 /* Tool-bar item index of the item on which a mouse button was pressed
10071 or -1. */
10072
10073 int last_tool_bar_item;
10074
10075
10076 static Lisp_Object
10077 update_tool_bar_unwind (Lisp_Object frame)
10078 {
10079 selected_frame = frame;
10080 return Qnil;
10081 }
10082
10083 /* Update the tool-bar item list for frame F. This has to be done
10084 before we start to fill in any display lines. Called from
10085 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10086 and restore it here. */
10087
10088 static void
10089 update_tool_bar (struct frame *f, int save_match_data)
10090 {
10091 #if defined (USE_GTK) || defined (HAVE_NS)
10092 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10093 #else
10094 int do_update = WINDOWP (f->tool_bar_window)
10095 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10096 #endif
10097
10098 if (do_update)
10099 {
10100 Lisp_Object window;
10101 struct window *w;
10102
10103 window = FRAME_SELECTED_WINDOW (f);
10104 w = XWINDOW (window);
10105
10106 /* If the user has switched buffers or windows, we need to
10107 recompute to reflect the new bindings. But we'll
10108 recompute when update_mode_lines is set too; that means
10109 that people can use force-mode-line-update to request
10110 that the menu bar be recomputed. The adverse effect on
10111 the rest of the redisplay algorithm is about the same as
10112 windows_or_buffers_changed anyway. */
10113 if (windows_or_buffers_changed
10114 || !NILP (w->update_mode_line)
10115 || update_mode_lines
10116 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10117 < BUF_MODIFF (XBUFFER (w->buffer)))
10118 != !NILP (w->last_had_star))
10119 || ((!NILP (Vtransient_mark_mode)
10120 && !NILP (XBUFFER (w->buffer)->mark_active))
10121 != !NILP (w->region_showing)))
10122 {
10123 struct buffer *prev = current_buffer;
10124 int count = SPECPDL_INDEX ();
10125 Lisp_Object frame, new_tool_bar;
10126 int new_n_tool_bar;
10127 struct gcpro gcpro1;
10128
10129 /* Set current_buffer to the buffer of the selected
10130 window of the frame, so that we get the right local
10131 keymaps. */
10132 set_buffer_internal_1 (XBUFFER (w->buffer));
10133
10134 /* Save match data, if we must. */
10135 if (save_match_data)
10136 record_unwind_save_match_data ();
10137
10138 /* Make sure that we don't accidentally use bogus keymaps. */
10139 if (NILP (Voverriding_local_map_menu_flag))
10140 {
10141 specbind (Qoverriding_terminal_local_map, Qnil);
10142 specbind (Qoverriding_local_map, Qnil);
10143 }
10144
10145 GCPRO1 (new_tool_bar);
10146
10147 /* We must temporarily set the selected frame to this frame
10148 before calling tool_bar_items, because the calculation of
10149 the tool-bar keymap uses the selected frame (see
10150 `tool-bar-make-keymap' in tool-bar.el). */
10151 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10152 XSETFRAME (frame, f);
10153 selected_frame = frame;
10154
10155 /* Build desired tool-bar items from keymaps. */
10156 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10157 &new_n_tool_bar);
10158
10159 /* Redisplay the tool-bar if we changed it. */
10160 if (new_n_tool_bar != f->n_tool_bar_items
10161 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10162 {
10163 /* Redisplay that happens asynchronously due to an expose event
10164 may access f->tool_bar_items. Make sure we update both
10165 variables within BLOCK_INPUT so no such event interrupts. */
10166 BLOCK_INPUT;
10167 f->tool_bar_items = new_tool_bar;
10168 f->n_tool_bar_items = new_n_tool_bar;
10169 w->update_mode_line = Qt;
10170 UNBLOCK_INPUT;
10171 }
10172
10173 UNGCPRO;
10174
10175 unbind_to (count, Qnil);
10176 set_buffer_internal_1 (prev);
10177 }
10178 }
10179 }
10180
10181
10182 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10183 F's desired tool-bar contents. F->tool_bar_items must have
10184 been set up previously by calling prepare_menu_bars. */
10185
10186 static void
10187 build_desired_tool_bar_string (struct frame *f)
10188 {
10189 int i, size, size_needed;
10190 struct gcpro gcpro1, gcpro2, gcpro3;
10191 Lisp_Object image, plist, props;
10192
10193 image = plist = props = Qnil;
10194 GCPRO3 (image, plist, props);
10195
10196 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10197 Otherwise, make a new string. */
10198
10199 /* The size of the string we might be able to reuse. */
10200 size = (STRINGP (f->desired_tool_bar_string)
10201 ? SCHARS (f->desired_tool_bar_string)
10202 : 0);
10203
10204 /* We need one space in the string for each image. */
10205 size_needed = f->n_tool_bar_items;
10206
10207 /* Reuse f->desired_tool_bar_string, if possible. */
10208 if (size < size_needed || NILP (f->desired_tool_bar_string))
10209 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10210 make_number (' '));
10211 else
10212 {
10213 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10214 Fremove_text_properties (make_number (0), make_number (size),
10215 props, f->desired_tool_bar_string);
10216 }
10217
10218 /* Put a `display' property on the string for the images to display,
10219 put a `menu_item' property on tool-bar items with a value that
10220 is the index of the item in F's tool-bar item vector. */
10221 for (i = 0; i < f->n_tool_bar_items; ++i)
10222 {
10223 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10224
10225 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10226 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10227 int hmargin, vmargin, relief, idx, end;
10228 extern Lisp_Object QCrelief, QCmargin, QCconversion;
10229
10230 /* If image is a vector, choose the image according to the
10231 button state. */
10232 image = PROP (TOOL_BAR_ITEM_IMAGES);
10233 if (VECTORP (image))
10234 {
10235 if (enabled_p)
10236 idx = (selected_p
10237 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10238 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10239 else
10240 idx = (selected_p
10241 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10242 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10243
10244 xassert (ASIZE (image) >= idx);
10245 image = AREF (image, idx);
10246 }
10247 else
10248 idx = -1;
10249
10250 /* Ignore invalid image specifications. */
10251 if (!valid_image_p (image))
10252 continue;
10253
10254 /* Display the tool-bar button pressed, or depressed. */
10255 plist = Fcopy_sequence (XCDR (image));
10256
10257 /* Compute margin and relief to draw. */
10258 relief = (tool_bar_button_relief >= 0
10259 ? tool_bar_button_relief
10260 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10261 hmargin = vmargin = relief;
10262
10263 if (INTEGERP (Vtool_bar_button_margin)
10264 && XINT (Vtool_bar_button_margin) > 0)
10265 {
10266 hmargin += XFASTINT (Vtool_bar_button_margin);
10267 vmargin += XFASTINT (Vtool_bar_button_margin);
10268 }
10269 else if (CONSP (Vtool_bar_button_margin))
10270 {
10271 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10272 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10273 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10274
10275 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10276 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10277 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10278 }
10279
10280 if (auto_raise_tool_bar_buttons_p)
10281 {
10282 /* Add a `:relief' property to the image spec if the item is
10283 selected. */
10284 if (selected_p)
10285 {
10286 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10287 hmargin -= relief;
10288 vmargin -= relief;
10289 }
10290 }
10291 else
10292 {
10293 /* If image is selected, display it pressed, i.e. with a
10294 negative relief. If it's not selected, display it with a
10295 raised relief. */
10296 plist = Fplist_put (plist, QCrelief,
10297 (selected_p
10298 ? make_number (-relief)
10299 : make_number (relief)));
10300 hmargin -= relief;
10301 vmargin -= relief;
10302 }
10303
10304 /* Put a margin around the image. */
10305 if (hmargin || vmargin)
10306 {
10307 if (hmargin == vmargin)
10308 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10309 else
10310 plist = Fplist_put (plist, QCmargin,
10311 Fcons (make_number (hmargin),
10312 make_number (vmargin)));
10313 }
10314
10315 /* If button is not enabled, and we don't have special images
10316 for the disabled state, make the image appear disabled by
10317 applying an appropriate algorithm to it. */
10318 if (!enabled_p && idx < 0)
10319 plist = Fplist_put (plist, QCconversion, Qdisabled);
10320
10321 /* Put a `display' text property on the string for the image to
10322 display. Put a `menu-item' property on the string that gives
10323 the start of this item's properties in the tool-bar items
10324 vector. */
10325 image = Fcons (Qimage, plist);
10326 props = list4 (Qdisplay, image,
10327 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10328
10329 /* Let the last image hide all remaining spaces in the tool bar
10330 string. The string can be longer than needed when we reuse a
10331 previous string. */
10332 if (i + 1 == f->n_tool_bar_items)
10333 end = SCHARS (f->desired_tool_bar_string);
10334 else
10335 end = i + 1;
10336 Fadd_text_properties (make_number (i), make_number (end),
10337 props, f->desired_tool_bar_string);
10338 #undef PROP
10339 }
10340
10341 UNGCPRO;
10342 }
10343
10344
10345 /* Display one line of the tool-bar of frame IT->f.
10346
10347 HEIGHT specifies the desired height of the tool-bar line.
10348 If the actual height of the glyph row is less than HEIGHT, the
10349 row's height is increased to HEIGHT, and the icons are centered
10350 vertically in the new height.
10351
10352 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10353 count a final empty row in case the tool-bar width exactly matches
10354 the window width.
10355 */
10356
10357 static void
10358 display_tool_bar_line (struct it *it, int height)
10359 {
10360 struct glyph_row *row = it->glyph_row;
10361 int max_x = it->last_visible_x;
10362 struct glyph *last;
10363
10364 prepare_desired_row (row);
10365 row->y = it->current_y;
10366
10367 /* Note that this isn't made use of if the face hasn't a box,
10368 so there's no need to check the face here. */
10369 it->start_of_box_run_p = 1;
10370
10371 while (it->current_x < max_x)
10372 {
10373 int x, n_glyphs_before, i, nglyphs;
10374 struct it it_before;
10375
10376 /* Get the next display element. */
10377 if (!get_next_display_element (it))
10378 {
10379 /* Don't count empty row if we are counting needed tool-bar lines. */
10380 if (height < 0 && !it->hpos)
10381 return;
10382 break;
10383 }
10384
10385 /* Produce glyphs. */
10386 n_glyphs_before = row->used[TEXT_AREA];
10387 it_before = *it;
10388
10389 PRODUCE_GLYPHS (it);
10390
10391 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10392 i = 0;
10393 x = it_before.current_x;
10394 while (i < nglyphs)
10395 {
10396 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10397
10398 if (x + glyph->pixel_width > max_x)
10399 {
10400 /* Glyph doesn't fit on line. Backtrack. */
10401 row->used[TEXT_AREA] = n_glyphs_before;
10402 *it = it_before;
10403 /* If this is the only glyph on this line, it will never fit on the
10404 toolbar, so skip it. But ensure there is at least one glyph,
10405 so we don't accidentally disable the tool-bar. */
10406 if (n_glyphs_before == 0
10407 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10408 break;
10409 goto out;
10410 }
10411
10412 ++it->hpos;
10413 x += glyph->pixel_width;
10414 ++i;
10415 }
10416
10417 /* Stop at line ends. */
10418 if (ITERATOR_AT_END_OF_LINE_P (it))
10419 break;
10420
10421 set_iterator_to_next (it, 1);
10422 }
10423
10424 out:;
10425
10426 row->displays_text_p = row->used[TEXT_AREA] != 0;
10427
10428 /* Use default face for the border below the tool bar.
10429
10430 FIXME: When auto-resize-tool-bars is grow-only, there is
10431 no additional border below the possibly empty tool-bar lines.
10432 So to make the extra empty lines look "normal", we have to
10433 use the tool-bar face for the border too. */
10434 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10435 it->face_id = DEFAULT_FACE_ID;
10436
10437 extend_face_to_end_of_line (it);
10438 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10439 last->right_box_line_p = 1;
10440 if (last == row->glyphs[TEXT_AREA])
10441 last->left_box_line_p = 1;
10442
10443 /* Make line the desired height and center it vertically. */
10444 if ((height -= it->max_ascent + it->max_descent) > 0)
10445 {
10446 /* Don't add more than one line height. */
10447 height %= FRAME_LINE_HEIGHT (it->f);
10448 it->max_ascent += height / 2;
10449 it->max_descent += (height + 1) / 2;
10450 }
10451
10452 compute_line_metrics (it);
10453
10454 /* If line is empty, make it occupy the rest of the tool-bar. */
10455 if (!row->displays_text_p)
10456 {
10457 row->height = row->phys_height = it->last_visible_y - row->y;
10458 row->visible_height = row->height;
10459 row->ascent = row->phys_ascent = 0;
10460 row->extra_line_spacing = 0;
10461 }
10462
10463 row->full_width_p = 1;
10464 row->continued_p = 0;
10465 row->truncated_on_left_p = 0;
10466 row->truncated_on_right_p = 0;
10467
10468 it->current_x = it->hpos = 0;
10469 it->current_y += row->height;
10470 ++it->vpos;
10471 ++it->glyph_row;
10472 }
10473
10474
10475 /* Max tool-bar height. */
10476
10477 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10478 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10479
10480 /* Value is the number of screen lines needed to make all tool-bar
10481 items of frame F visible. The number of actual rows needed is
10482 returned in *N_ROWS if non-NULL. */
10483
10484 static int
10485 tool_bar_lines_needed (struct frame *f, int *n_rows)
10486 {
10487 struct window *w = XWINDOW (f->tool_bar_window);
10488 struct it it;
10489 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10490 the desired matrix, so use (unused) mode-line row as temporary row to
10491 avoid destroying the first tool-bar row. */
10492 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10493
10494 /* Initialize an iterator for iteration over
10495 F->desired_tool_bar_string in the tool-bar window of frame F. */
10496 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10497 it.first_visible_x = 0;
10498 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10499 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10500
10501 while (!ITERATOR_AT_END_P (&it))
10502 {
10503 clear_glyph_row (temp_row);
10504 it.glyph_row = temp_row;
10505 display_tool_bar_line (&it, -1);
10506 }
10507 clear_glyph_row (temp_row);
10508
10509 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10510 if (n_rows)
10511 *n_rows = it.vpos > 0 ? it.vpos : -1;
10512
10513 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10514 }
10515
10516
10517 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10518 0, 1, 0,
10519 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10520 (Lisp_Object frame)
10521 {
10522 struct frame *f;
10523 struct window *w;
10524 int nlines = 0;
10525
10526 if (NILP (frame))
10527 frame = selected_frame;
10528 else
10529 CHECK_FRAME (frame);
10530 f = XFRAME (frame);
10531
10532 if (WINDOWP (f->tool_bar_window)
10533 || (w = XWINDOW (f->tool_bar_window),
10534 WINDOW_TOTAL_LINES (w) > 0))
10535 {
10536 update_tool_bar (f, 1);
10537 if (f->n_tool_bar_items)
10538 {
10539 build_desired_tool_bar_string (f);
10540 nlines = tool_bar_lines_needed (f, NULL);
10541 }
10542 }
10543
10544 return make_number (nlines);
10545 }
10546
10547
10548 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10549 height should be changed. */
10550
10551 static int
10552 redisplay_tool_bar (struct frame *f)
10553 {
10554 struct window *w;
10555 struct it it;
10556 struct glyph_row *row;
10557
10558 #if defined (USE_GTK) || defined (HAVE_NS)
10559 if (FRAME_EXTERNAL_TOOL_BAR (f))
10560 update_frame_tool_bar (f);
10561 return 0;
10562 #endif
10563
10564 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10565 do anything. This means you must start with tool-bar-lines
10566 non-zero to get the auto-sizing effect. Or in other words, you
10567 can turn off tool-bars by specifying tool-bar-lines zero. */
10568 if (!WINDOWP (f->tool_bar_window)
10569 || (w = XWINDOW (f->tool_bar_window),
10570 WINDOW_TOTAL_LINES (w) == 0))
10571 return 0;
10572
10573 /* Set up an iterator for the tool-bar window. */
10574 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10575 it.first_visible_x = 0;
10576 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10577 row = it.glyph_row;
10578
10579 /* Build a string that represents the contents of the tool-bar. */
10580 build_desired_tool_bar_string (f);
10581 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10582
10583 if (f->n_tool_bar_rows == 0)
10584 {
10585 int nlines;
10586
10587 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10588 nlines != WINDOW_TOTAL_LINES (w)))
10589 {
10590 extern Lisp_Object Qtool_bar_lines;
10591 Lisp_Object frame;
10592 int old_height = WINDOW_TOTAL_LINES (w);
10593
10594 XSETFRAME (frame, f);
10595 Fmodify_frame_parameters (frame,
10596 Fcons (Fcons (Qtool_bar_lines,
10597 make_number (nlines)),
10598 Qnil));
10599 if (WINDOW_TOTAL_LINES (w) != old_height)
10600 {
10601 clear_glyph_matrix (w->desired_matrix);
10602 fonts_changed_p = 1;
10603 return 1;
10604 }
10605 }
10606 }
10607
10608 /* Display as many lines as needed to display all tool-bar items. */
10609
10610 if (f->n_tool_bar_rows > 0)
10611 {
10612 int border, rows, height, extra;
10613
10614 if (INTEGERP (Vtool_bar_border))
10615 border = XINT (Vtool_bar_border);
10616 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10617 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10618 else if (EQ (Vtool_bar_border, Qborder_width))
10619 border = f->border_width;
10620 else
10621 border = 0;
10622 if (border < 0)
10623 border = 0;
10624
10625 rows = f->n_tool_bar_rows;
10626 height = max (1, (it.last_visible_y - border) / rows);
10627 extra = it.last_visible_y - border - height * rows;
10628
10629 while (it.current_y < it.last_visible_y)
10630 {
10631 int h = 0;
10632 if (extra > 0 && rows-- > 0)
10633 {
10634 h = (extra + rows - 1) / rows;
10635 extra -= h;
10636 }
10637 display_tool_bar_line (&it, height + h);
10638 }
10639 }
10640 else
10641 {
10642 while (it.current_y < it.last_visible_y)
10643 display_tool_bar_line (&it, 0);
10644 }
10645
10646 /* It doesn't make much sense to try scrolling in the tool-bar
10647 window, so don't do it. */
10648 w->desired_matrix->no_scrolling_p = 1;
10649 w->must_be_updated_p = 1;
10650
10651 if (!NILP (Vauto_resize_tool_bars))
10652 {
10653 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10654 int change_height_p = 0;
10655
10656 /* If we couldn't display everything, change the tool-bar's
10657 height if there is room for more. */
10658 if (IT_STRING_CHARPOS (it) < it.end_charpos
10659 && it.current_y < max_tool_bar_height)
10660 change_height_p = 1;
10661
10662 row = it.glyph_row - 1;
10663
10664 /* If there are blank lines at the end, except for a partially
10665 visible blank line at the end that is smaller than
10666 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10667 if (!row->displays_text_p
10668 && row->height >= FRAME_LINE_HEIGHT (f))
10669 change_height_p = 1;
10670
10671 /* If row displays tool-bar items, but is partially visible,
10672 change the tool-bar's height. */
10673 if (row->displays_text_p
10674 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10675 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10676 change_height_p = 1;
10677
10678 /* Resize windows as needed by changing the `tool-bar-lines'
10679 frame parameter. */
10680 if (change_height_p)
10681 {
10682 extern Lisp_Object Qtool_bar_lines;
10683 Lisp_Object frame;
10684 int old_height = WINDOW_TOTAL_LINES (w);
10685 int nrows;
10686 int nlines = tool_bar_lines_needed (f, &nrows);
10687
10688 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10689 && !f->minimize_tool_bar_window_p)
10690 ? (nlines > old_height)
10691 : (nlines != old_height));
10692 f->minimize_tool_bar_window_p = 0;
10693
10694 if (change_height_p)
10695 {
10696 XSETFRAME (frame, f);
10697 Fmodify_frame_parameters (frame,
10698 Fcons (Fcons (Qtool_bar_lines,
10699 make_number (nlines)),
10700 Qnil));
10701 if (WINDOW_TOTAL_LINES (w) != old_height)
10702 {
10703 clear_glyph_matrix (w->desired_matrix);
10704 f->n_tool_bar_rows = nrows;
10705 fonts_changed_p = 1;
10706 return 1;
10707 }
10708 }
10709 }
10710 }
10711
10712 f->minimize_tool_bar_window_p = 0;
10713 return 0;
10714 }
10715
10716
10717 /* Get information about the tool-bar item which is displayed in GLYPH
10718 on frame F. Return in *PROP_IDX the index where tool-bar item
10719 properties start in F->tool_bar_items. Value is zero if
10720 GLYPH doesn't display a tool-bar item. */
10721
10722 static int
10723 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10724 {
10725 Lisp_Object prop;
10726 int success_p;
10727 int charpos;
10728
10729 /* This function can be called asynchronously, which means we must
10730 exclude any possibility that Fget_text_property signals an
10731 error. */
10732 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10733 charpos = max (0, charpos);
10734
10735 /* Get the text property `menu-item' at pos. The value of that
10736 property is the start index of this item's properties in
10737 F->tool_bar_items. */
10738 prop = Fget_text_property (make_number (charpos),
10739 Qmenu_item, f->current_tool_bar_string);
10740 if (INTEGERP (prop))
10741 {
10742 *prop_idx = XINT (prop);
10743 success_p = 1;
10744 }
10745 else
10746 success_p = 0;
10747
10748 return success_p;
10749 }
10750
10751 \f
10752 /* Get information about the tool-bar item at position X/Y on frame F.
10753 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10754 the current matrix of the tool-bar window of F, or NULL if not
10755 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10756 item in F->tool_bar_items. Value is
10757
10758 -1 if X/Y is not on a tool-bar item
10759 0 if X/Y is on the same item that was highlighted before.
10760 1 otherwise. */
10761
10762 static int
10763 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10764 int *hpos, int *vpos, int *prop_idx)
10765 {
10766 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10767 struct window *w = XWINDOW (f->tool_bar_window);
10768 int area;
10769
10770 /* Find the glyph under X/Y. */
10771 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10772 if (*glyph == NULL)
10773 return -1;
10774
10775 /* Get the start of this tool-bar item's properties in
10776 f->tool_bar_items. */
10777 if (!tool_bar_item_info (f, *glyph, prop_idx))
10778 return -1;
10779
10780 /* Is mouse on the highlighted item? */
10781 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10782 && *vpos >= dpyinfo->mouse_face_beg_row
10783 && *vpos <= dpyinfo->mouse_face_end_row
10784 && (*vpos > dpyinfo->mouse_face_beg_row
10785 || *hpos >= dpyinfo->mouse_face_beg_col)
10786 && (*vpos < dpyinfo->mouse_face_end_row
10787 || *hpos < dpyinfo->mouse_face_end_col
10788 || dpyinfo->mouse_face_past_end))
10789 return 0;
10790
10791 return 1;
10792 }
10793
10794
10795 /* EXPORT:
10796 Handle mouse button event on the tool-bar of frame F, at
10797 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10798 0 for button release. MODIFIERS is event modifiers for button
10799 release. */
10800
10801 void
10802 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10803 unsigned int modifiers)
10804 {
10805 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10806 struct window *w = XWINDOW (f->tool_bar_window);
10807 int hpos, vpos, prop_idx;
10808 struct glyph *glyph;
10809 Lisp_Object enabled_p;
10810
10811 /* If not on the highlighted tool-bar item, return. */
10812 frame_to_window_pixel_xy (w, &x, &y);
10813 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10814 return;
10815
10816 /* If item is disabled, do nothing. */
10817 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10818 if (NILP (enabled_p))
10819 return;
10820
10821 if (down_p)
10822 {
10823 /* Show item in pressed state. */
10824 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10825 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10826 last_tool_bar_item = prop_idx;
10827 }
10828 else
10829 {
10830 Lisp_Object key, frame;
10831 struct input_event event;
10832 EVENT_INIT (event);
10833
10834 /* Show item in released state. */
10835 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10836 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10837
10838 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10839
10840 XSETFRAME (frame, f);
10841 event.kind = TOOL_BAR_EVENT;
10842 event.frame_or_window = frame;
10843 event.arg = frame;
10844 kbd_buffer_store_event (&event);
10845
10846 event.kind = TOOL_BAR_EVENT;
10847 event.frame_or_window = frame;
10848 event.arg = key;
10849 event.modifiers = modifiers;
10850 kbd_buffer_store_event (&event);
10851 last_tool_bar_item = -1;
10852 }
10853 }
10854
10855
10856 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10857 tool-bar window-relative coordinates X/Y. Called from
10858 note_mouse_highlight. */
10859
10860 static void
10861 note_tool_bar_highlight (struct frame *f, int x, int y)
10862 {
10863 Lisp_Object window = f->tool_bar_window;
10864 struct window *w = XWINDOW (window);
10865 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10866 int hpos, vpos;
10867 struct glyph *glyph;
10868 struct glyph_row *row;
10869 int i;
10870 Lisp_Object enabled_p;
10871 int prop_idx;
10872 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10873 int mouse_down_p, rc;
10874
10875 /* Function note_mouse_highlight is called with negative x(y
10876 values when mouse moves outside of the frame. */
10877 if (x <= 0 || y <= 0)
10878 {
10879 clear_mouse_face (dpyinfo);
10880 return;
10881 }
10882
10883 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10884 if (rc < 0)
10885 {
10886 /* Not on tool-bar item. */
10887 clear_mouse_face (dpyinfo);
10888 return;
10889 }
10890 else if (rc == 0)
10891 /* On same tool-bar item as before. */
10892 goto set_help_echo;
10893
10894 clear_mouse_face (dpyinfo);
10895
10896 /* Mouse is down, but on different tool-bar item? */
10897 mouse_down_p = (dpyinfo->grabbed
10898 && f == last_mouse_frame
10899 && FRAME_LIVE_P (f));
10900 if (mouse_down_p
10901 && last_tool_bar_item != prop_idx)
10902 return;
10903
10904 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10905 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10906
10907 /* If tool-bar item is not enabled, don't highlight it. */
10908 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10909 if (!NILP (enabled_p))
10910 {
10911 /* Compute the x-position of the glyph. In front and past the
10912 image is a space. We include this in the highlighted area. */
10913 row = MATRIX_ROW (w->current_matrix, vpos);
10914 for (i = x = 0; i < hpos; ++i)
10915 x += row->glyphs[TEXT_AREA][i].pixel_width;
10916
10917 /* Record this as the current active region. */
10918 dpyinfo->mouse_face_beg_col = hpos;
10919 dpyinfo->mouse_face_beg_row = vpos;
10920 dpyinfo->mouse_face_beg_x = x;
10921 dpyinfo->mouse_face_beg_y = row->y;
10922 dpyinfo->mouse_face_past_end = 0;
10923
10924 dpyinfo->mouse_face_end_col = hpos + 1;
10925 dpyinfo->mouse_face_end_row = vpos;
10926 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10927 dpyinfo->mouse_face_end_y = row->y;
10928 dpyinfo->mouse_face_window = window;
10929 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10930
10931 /* Display it as active. */
10932 show_mouse_face (dpyinfo, draw);
10933 dpyinfo->mouse_face_image_state = draw;
10934 }
10935
10936 set_help_echo:
10937
10938 /* Set help_echo_string to a help string to display for this tool-bar item.
10939 XTread_socket does the rest. */
10940 help_echo_object = help_echo_window = Qnil;
10941 help_echo_pos = -1;
10942 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10943 if (NILP (help_echo_string))
10944 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10945 }
10946
10947 #endif /* HAVE_WINDOW_SYSTEM */
10948
10949
10950 \f
10951 /************************************************************************
10952 Horizontal scrolling
10953 ************************************************************************/
10954
10955 static int hscroll_window_tree (Lisp_Object);
10956 static int hscroll_windows (Lisp_Object);
10957
10958 /* For all leaf windows in the window tree rooted at WINDOW, set their
10959 hscroll value so that PT is (i) visible in the window, and (ii) so
10960 that it is not within a certain margin at the window's left and
10961 right border. Value is non-zero if any window's hscroll has been
10962 changed. */
10963
10964 static int
10965 hscroll_window_tree (Lisp_Object window)
10966 {
10967 int hscrolled_p = 0;
10968 int hscroll_relative_p = FLOATP (Vhscroll_step);
10969 int hscroll_step_abs = 0;
10970 double hscroll_step_rel = 0;
10971
10972 if (hscroll_relative_p)
10973 {
10974 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10975 if (hscroll_step_rel < 0)
10976 {
10977 hscroll_relative_p = 0;
10978 hscroll_step_abs = 0;
10979 }
10980 }
10981 else if (INTEGERP (Vhscroll_step))
10982 {
10983 hscroll_step_abs = XINT (Vhscroll_step);
10984 if (hscroll_step_abs < 0)
10985 hscroll_step_abs = 0;
10986 }
10987 else
10988 hscroll_step_abs = 0;
10989
10990 while (WINDOWP (window))
10991 {
10992 struct window *w = XWINDOW (window);
10993
10994 if (WINDOWP (w->hchild))
10995 hscrolled_p |= hscroll_window_tree (w->hchild);
10996 else if (WINDOWP (w->vchild))
10997 hscrolled_p |= hscroll_window_tree (w->vchild);
10998 else if (w->cursor.vpos >= 0)
10999 {
11000 int h_margin;
11001 int text_area_width;
11002 struct glyph_row *current_cursor_row
11003 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11004 struct glyph_row *desired_cursor_row
11005 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11006 struct glyph_row *cursor_row
11007 = (desired_cursor_row->enabled_p
11008 ? desired_cursor_row
11009 : current_cursor_row);
11010
11011 text_area_width = window_box_width (w, TEXT_AREA);
11012
11013 /* Scroll when cursor is inside this scroll margin. */
11014 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11015
11016 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11017 && ((XFASTINT (w->hscroll)
11018 && w->cursor.x <= h_margin)
11019 || (cursor_row->enabled_p
11020 && cursor_row->truncated_on_right_p
11021 && (w->cursor.x >= text_area_width - h_margin))))
11022 {
11023 struct it it;
11024 int hscroll;
11025 struct buffer *saved_current_buffer;
11026 int pt;
11027 int wanted_x;
11028
11029 /* Find point in a display of infinite width. */
11030 saved_current_buffer = current_buffer;
11031 current_buffer = XBUFFER (w->buffer);
11032
11033 if (w == XWINDOW (selected_window))
11034 pt = BUF_PT (current_buffer);
11035 else
11036 {
11037 pt = marker_position (w->pointm);
11038 pt = max (BEGV, pt);
11039 pt = min (ZV, pt);
11040 }
11041
11042 /* Move iterator to pt starting at cursor_row->start in
11043 a line with infinite width. */
11044 init_to_row_start (&it, w, cursor_row);
11045 it.last_visible_x = INFINITY;
11046 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11047 current_buffer = saved_current_buffer;
11048
11049 /* Position cursor in window. */
11050 if (!hscroll_relative_p && hscroll_step_abs == 0)
11051 hscroll = max (0, (it.current_x
11052 - (ITERATOR_AT_END_OF_LINE_P (&it)
11053 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11054 : (text_area_width / 2))))
11055 / FRAME_COLUMN_WIDTH (it.f);
11056 else if (w->cursor.x >= text_area_width - h_margin)
11057 {
11058 if (hscroll_relative_p)
11059 wanted_x = text_area_width * (1 - hscroll_step_rel)
11060 - h_margin;
11061 else
11062 wanted_x = text_area_width
11063 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11064 - h_margin;
11065 hscroll
11066 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11067 }
11068 else
11069 {
11070 if (hscroll_relative_p)
11071 wanted_x = text_area_width * hscroll_step_rel
11072 + h_margin;
11073 else
11074 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11075 + h_margin;
11076 hscroll
11077 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11078 }
11079 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11080
11081 /* Don't call Fset_window_hscroll if value hasn't
11082 changed because it will prevent redisplay
11083 optimizations. */
11084 if (XFASTINT (w->hscroll) != hscroll)
11085 {
11086 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11087 w->hscroll = make_number (hscroll);
11088 hscrolled_p = 1;
11089 }
11090 }
11091 }
11092
11093 window = w->next;
11094 }
11095
11096 /* Value is non-zero if hscroll of any leaf window has been changed. */
11097 return hscrolled_p;
11098 }
11099
11100
11101 /* Set hscroll so that cursor is visible and not inside horizontal
11102 scroll margins for all windows in the tree rooted at WINDOW. See
11103 also hscroll_window_tree above. Value is non-zero if any window's
11104 hscroll has been changed. If it has, desired matrices on the frame
11105 of WINDOW are cleared. */
11106
11107 static int
11108 hscroll_windows (Lisp_Object window)
11109 {
11110 int hscrolled_p = hscroll_window_tree (window);
11111 if (hscrolled_p)
11112 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11113 return hscrolled_p;
11114 }
11115
11116
11117 \f
11118 /************************************************************************
11119 Redisplay
11120 ************************************************************************/
11121
11122 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11123 to a non-zero value. This is sometimes handy to have in a debugger
11124 session. */
11125
11126 #if GLYPH_DEBUG
11127
11128 /* First and last unchanged row for try_window_id. */
11129
11130 int debug_first_unchanged_at_end_vpos;
11131 int debug_last_unchanged_at_beg_vpos;
11132
11133 /* Delta vpos and y. */
11134
11135 int debug_dvpos, debug_dy;
11136
11137 /* Delta in characters and bytes for try_window_id. */
11138
11139 int debug_delta, debug_delta_bytes;
11140
11141 /* Values of window_end_pos and window_end_vpos at the end of
11142 try_window_id. */
11143
11144 EMACS_INT debug_end_pos, debug_end_vpos;
11145
11146 /* Append a string to W->desired_matrix->method. FMT is a printf
11147 format string. A1...A9 are a supplement for a variable-length
11148 argument list. If trace_redisplay_p is non-zero also printf the
11149 resulting string to stderr. */
11150
11151 static void
11152 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11153 struct window *w;
11154 char *fmt;
11155 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11156 {
11157 char buffer[512];
11158 char *method = w->desired_matrix->method;
11159 int len = strlen (method);
11160 int size = sizeof w->desired_matrix->method;
11161 int remaining = size - len - 1;
11162
11163 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11164 if (len && remaining)
11165 {
11166 method[len] = '|';
11167 --remaining, ++len;
11168 }
11169
11170 strncpy (method + len, buffer, remaining);
11171
11172 if (trace_redisplay_p)
11173 fprintf (stderr, "%p (%s): %s\n",
11174 w,
11175 ((BUFFERP (w->buffer)
11176 && STRINGP (XBUFFER (w->buffer)->name))
11177 ? (char *) SDATA (XBUFFER (w->buffer)->name)
11178 : "no buffer"),
11179 buffer);
11180 }
11181
11182 #endif /* GLYPH_DEBUG */
11183
11184
11185 /* Value is non-zero if all changes in window W, which displays
11186 current_buffer, are in the text between START and END. START is a
11187 buffer position, END is given as a distance from Z. Used in
11188 redisplay_internal for display optimization. */
11189
11190 static INLINE int
11191 text_outside_line_unchanged_p (struct window *w, int start, int end)
11192 {
11193 int unchanged_p = 1;
11194
11195 /* If text or overlays have changed, see where. */
11196 if (XFASTINT (w->last_modified) < MODIFF
11197 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11198 {
11199 /* Gap in the line? */
11200 if (GPT < start || Z - GPT < end)
11201 unchanged_p = 0;
11202
11203 /* Changes start in front of the line, or end after it? */
11204 if (unchanged_p
11205 && (BEG_UNCHANGED < start - 1
11206 || END_UNCHANGED < end))
11207 unchanged_p = 0;
11208
11209 /* If selective display, can't optimize if changes start at the
11210 beginning of the line. */
11211 if (unchanged_p
11212 && INTEGERP (current_buffer->selective_display)
11213 && XINT (current_buffer->selective_display) > 0
11214 && (BEG_UNCHANGED < start || GPT <= start))
11215 unchanged_p = 0;
11216
11217 /* If there are overlays at the start or end of the line, these
11218 may have overlay strings with newlines in them. A change at
11219 START, for instance, may actually concern the display of such
11220 overlay strings as well, and they are displayed on different
11221 lines. So, quickly rule out this case. (For the future, it
11222 might be desirable to implement something more telling than
11223 just BEG/END_UNCHANGED.) */
11224 if (unchanged_p)
11225 {
11226 if (BEG + BEG_UNCHANGED == start
11227 && overlay_touches_p (start))
11228 unchanged_p = 0;
11229 if (END_UNCHANGED == end
11230 && overlay_touches_p (Z - end))
11231 unchanged_p = 0;
11232 }
11233
11234 /* Under bidi reordering, adding or deleting a character in the
11235 beginning of a paragraph, before the first strong directional
11236 character, can change the base direction of the paragraph (unless
11237 the buffer specifies a fixed paragraph direction), which will
11238 require to redisplay the whole paragraph. It might be worthwhile
11239 to find the paragraph limits and widen the range of redisplayed
11240 lines to that, but for now just give up this optimization. */
11241 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
11242 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
11243 unchanged_p = 0;
11244 }
11245
11246 return unchanged_p;
11247 }
11248
11249
11250 /* Do a frame update, taking possible shortcuts into account. This is
11251 the main external entry point for redisplay.
11252
11253 If the last redisplay displayed an echo area message and that message
11254 is no longer requested, we clear the echo area or bring back the
11255 mini-buffer if that is in use. */
11256
11257 void
11258 redisplay (void)
11259 {
11260 redisplay_internal (0);
11261 }
11262
11263
11264 static Lisp_Object
11265 overlay_arrow_string_or_property (Lisp_Object var)
11266 {
11267 Lisp_Object val;
11268
11269 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11270 return val;
11271
11272 return Voverlay_arrow_string;
11273 }
11274
11275 /* Return 1 if there are any overlay-arrows in current_buffer. */
11276 static int
11277 overlay_arrow_in_current_buffer_p (void)
11278 {
11279 Lisp_Object vlist;
11280
11281 for (vlist = Voverlay_arrow_variable_list;
11282 CONSP (vlist);
11283 vlist = XCDR (vlist))
11284 {
11285 Lisp_Object var = XCAR (vlist);
11286 Lisp_Object val;
11287
11288 if (!SYMBOLP (var))
11289 continue;
11290 val = find_symbol_value (var);
11291 if (MARKERP (val)
11292 && current_buffer == XMARKER (val)->buffer)
11293 return 1;
11294 }
11295 return 0;
11296 }
11297
11298
11299 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11300 has changed. */
11301
11302 static int
11303 overlay_arrows_changed_p (void)
11304 {
11305 Lisp_Object vlist;
11306
11307 for (vlist = Voverlay_arrow_variable_list;
11308 CONSP (vlist);
11309 vlist = XCDR (vlist))
11310 {
11311 Lisp_Object var = XCAR (vlist);
11312 Lisp_Object val, pstr;
11313
11314 if (!SYMBOLP (var))
11315 continue;
11316 val = find_symbol_value (var);
11317 if (!MARKERP (val))
11318 continue;
11319 if (! EQ (COERCE_MARKER (val),
11320 Fget (var, Qlast_arrow_position))
11321 || ! (pstr = overlay_arrow_string_or_property (var),
11322 EQ (pstr, Fget (var, Qlast_arrow_string))))
11323 return 1;
11324 }
11325 return 0;
11326 }
11327
11328 /* Mark overlay arrows to be updated on next redisplay. */
11329
11330 static void
11331 update_overlay_arrows (int up_to_date)
11332 {
11333 Lisp_Object vlist;
11334
11335 for (vlist = Voverlay_arrow_variable_list;
11336 CONSP (vlist);
11337 vlist = XCDR (vlist))
11338 {
11339 Lisp_Object var = XCAR (vlist);
11340
11341 if (!SYMBOLP (var))
11342 continue;
11343
11344 if (up_to_date > 0)
11345 {
11346 Lisp_Object val = find_symbol_value (var);
11347 Fput (var, Qlast_arrow_position,
11348 COERCE_MARKER (val));
11349 Fput (var, Qlast_arrow_string,
11350 overlay_arrow_string_or_property (var));
11351 }
11352 else if (up_to_date < 0
11353 || !NILP (Fget (var, Qlast_arrow_position)))
11354 {
11355 Fput (var, Qlast_arrow_position, Qt);
11356 Fput (var, Qlast_arrow_string, Qt);
11357 }
11358 }
11359 }
11360
11361
11362 /* Return overlay arrow string to display at row.
11363 Return integer (bitmap number) for arrow bitmap in left fringe.
11364 Return nil if no overlay arrow. */
11365
11366 static Lisp_Object
11367 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11368 {
11369 Lisp_Object vlist;
11370
11371 for (vlist = Voverlay_arrow_variable_list;
11372 CONSP (vlist);
11373 vlist = XCDR (vlist))
11374 {
11375 Lisp_Object var = XCAR (vlist);
11376 Lisp_Object val;
11377
11378 if (!SYMBOLP (var))
11379 continue;
11380
11381 val = find_symbol_value (var);
11382
11383 if (MARKERP (val)
11384 && current_buffer == XMARKER (val)->buffer
11385 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11386 {
11387 if (FRAME_WINDOW_P (it->f)
11388 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11389 {
11390 #ifdef HAVE_WINDOW_SYSTEM
11391 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11392 {
11393 int fringe_bitmap;
11394 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11395 return make_number (fringe_bitmap);
11396 }
11397 #endif
11398 return make_number (-1); /* Use default arrow bitmap */
11399 }
11400 return overlay_arrow_string_or_property (var);
11401 }
11402 }
11403
11404 return Qnil;
11405 }
11406
11407 /* Return 1 if point moved out of or into a composition. Otherwise
11408 return 0. PREV_BUF and PREV_PT are the last point buffer and
11409 position. BUF and PT are the current point buffer and position. */
11410
11411 int
11412 check_point_in_composition (struct buffer *prev_buf, int prev_pt,
11413 struct buffer *buf, int pt)
11414 {
11415 EMACS_INT start, end;
11416 Lisp_Object prop;
11417 Lisp_Object buffer;
11418
11419 XSETBUFFER (buffer, buf);
11420 /* Check a composition at the last point if point moved within the
11421 same buffer. */
11422 if (prev_buf == buf)
11423 {
11424 if (prev_pt == pt)
11425 /* Point didn't move. */
11426 return 0;
11427
11428 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11429 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11430 && COMPOSITION_VALID_P (start, end, prop)
11431 && start < prev_pt && end > prev_pt)
11432 /* The last point was within the composition. Return 1 iff
11433 point moved out of the composition. */
11434 return (pt <= start || pt >= end);
11435 }
11436
11437 /* Check a composition at the current point. */
11438 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11439 && find_composition (pt, -1, &start, &end, &prop, buffer)
11440 && COMPOSITION_VALID_P (start, end, prop)
11441 && start < pt && end > pt);
11442 }
11443
11444
11445 /* Reconsider the setting of B->clip_changed which is displayed
11446 in window W. */
11447
11448 static INLINE void
11449 reconsider_clip_changes (struct window *w, struct buffer *b)
11450 {
11451 if (b->clip_changed
11452 && !NILP (w->window_end_valid)
11453 && w->current_matrix->buffer == b
11454 && w->current_matrix->zv == BUF_ZV (b)
11455 && w->current_matrix->begv == BUF_BEGV (b))
11456 b->clip_changed = 0;
11457
11458 /* If display wasn't paused, and W is not a tool bar window, see if
11459 point has been moved into or out of a composition. In that case,
11460 we set b->clip_changed to 1 to force updating the screen. If
11461 b->clip_changed has already been set to 1, we can skip this
11462 check. */
11463 if (!b->clip_changed
11464 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11465 {
11466 int pt;
11467
11468 if (w == XWINDOW (selected_window))
11469 pt = BUF_PT (current_buffer);
11470 else
11471 pt = marker_position (w->pointm);
11472
11473 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11474 || pt != XINT (w->last_point))
11475 && check_point_in_composition (w->current_matrix->buffer,
11476 XINT (w->last_point),
11477 XBUFFER (w->buffer), pt))
11478 b->clip_changed = 1;
11479 }
11480 }
11481 \f
11482
11483 /* Select FRAME to forward the values of frame-local variables into C
11484 variables so that the redisplay routines can access those values
11485 directly. */
11486
11487 static void
11488 select_frame_for_redisplay (Lisp_Object frame)
11489 {
11490 Lisp_Object tail, tem;
11491 Lisp_Object old = selected_frame;
11492 struct Lisp_Symbol *sym;
11493
11494 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11495
11496 selected_frame = frame;
11497
11498 do {
11499 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11500 if (CONSP (XCAR (tail))
11501 && (tem = XCAR (XCAR (tail)),
11502 SYMBOLP (tem))
11503 && (sym = indirect_variable (XSYMBOL (tem)),
11504 sym->redirect == SYMBOL_LOCALIZED)
11505 && sym->val.blv->frame_local)
11506 /* Use find_symbol_value rather than Fsymbol_value
11507 to avoid an error if it is void. */
11508 find_symbol_value (tem);
11509 } while (!EQ (frame, old) && (frame = old, 1));
11510 }
11511
11512
11513 #define STOP_POLLING \
11514 do { if (! polling_stopped_here) stop_polling (); \
11515 polling_stopped_here = 1; } while (0)
11516
11517 #define RESUME_POLLING \
11518 do { if (polling_stopped_here) start_polling (); \
11519 polling_stopped_here = 0; } while (0)
11520
11521
11522 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11523 response to any user action; therefore, we should preserve the echo
11524 area. (Actually, our caller does that job.) Perhaps in the future
11525 avoid recentering windows if it is not necessary; currently that
11526 causes some problems. */
11527
11528 static void
11529 redisplay_internal (int preserve_echo_area)
11530 {
11531 struct window *w = XWINDOW (selected_window);
11532 struct frame *f;
11533 int pause;
11534 int must_finish = 0;
11535 struct text_pos tlbufpos, tlendpos;
11536 int number_of_visible_frames;
11537 int count, count1;
11538 struct frame *sf;
11539 int polling_stopped_here = 0;
11540 Lisp_Object old_frame = selected_frame;
11541
11542 /* Non-zero means redisplay has to consider all windows on all
11543 frames. Zero means, only selected_window is considered. */
11544 int consider_all_windows_p;
11545
11546 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11547
11548 /* No redisplay if running in batch mode or frame is not yet fully
11549 initialized, or redisplay is explicitly turned off by setting
11550 Vinhibit_redisplay. */
11551 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11552 || !NILP (Vinhibit_redisplay))
11553 return;
11554
11555 /* Don't examine these until after testing Vinhibit_redisplay.
11556 When Emacs is shutting down, perhaps because its connection to
11557 X has dropped, we should not look at them at all. */
11558 f = XFRAME (w->frame);
11559 sf = SELECTED_FRAME ();
11560
11561 if (!f->glyphs_initialized_p)
11562 return;
11563
11564 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11565 if (popup_activated ())
11566 return;
11567 #endif
11568
11569 /* I don't think this happens but let's be paranoid. */
11570 if (redisplaying_p)
11571 return;
11572
11573 /* Record a function that resets redisplaying_p to its old value
11574 when we leave this function. */
11575 count = SPECPDL_INDEX ();
11576 record_unwind_protect (unwind_redisplay,
11577 Fcons (make_number (redisplaying_p), selected_frame));
11578 ++redisplaying_p;
11579 specbind (Qinhibit_free_realized_faces, Qnil);
11580
11581 {
11582 Lisp_Object tail, frame;
11583
11584 FOR_EACH_FRAME (tail, frame)
11585 {
11586 struct frame *f = XFRAME (frame);
11587 f->already_hscrolled_p = 0;
11588 }
11589 }
11590
11591 retry:
11592 if (!EQ (old_frame, selected_frame)
11593 && FRAME_LIVE_P (XFRAME (old_frame)))
11594 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11595 selected_frame and selected_window to be temporarily out-of-sync so
11596 when we come back here via `goto retry', we need to resync because we
11597 may need to run Elisp code (via prepare_menu_bars). */
11598 select_frame_for_redisplay (old_frame);
11599
11600 pause = 0;
11601 reconsider_clip_changes (w, current_buffer);
11602 last_escape_glyph_frame = NULL;
11603 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11604
11605 /* If new fonts have been loaded that make a glyph matrix adjustment
11606 necessary, do it. */
11607 if (fonts_changed_p)
11608 {
11609 adjust_glyphs (NULL);
11610 ++windows_or_buffers_changed;
11611 fonts_changed_p = 0;
11612 }
11613
11614 /* If face_change_count is non-zero, init_iterator will free all
11615 realized faces, which includes the faces referenced from current
11616 matrices. So, we can't reuse current matrices in this case. */
11617 if (face_change_count)
11618 ++windows_or_buffers_changed;
11619
11620 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11621 && FRAME_TTY (sf)->previous_frame != sf)
11622 {
11623 /* Since frames on a single ASCII terminal share the same
11624 display area, displaying a different frame means redisplay
11625 the whole thing. */
11626 windows_or_buffers_changed++;
11627 SET_FRAME_GARBAGED (sf);
11628 #ifndef DOS_NT
11629 set_tty_color_mode (FRAME_TTY (sf), sf);
11630 #endif
11631 FRAME_TTY (sf)->previous_frame = sf;
11632 }
11633
11634 /* Set the visible flags for all frames. Do this before checking
11635 for resized or garbaged frames; they want to know if their frames
11636 are visible. See the comment in frame.h for
11637 FRAME_SAMPLE_VISIBILITY. */
11638 {
11639 Lisp_Object tail, frame;
11640
11641 number_of_visible_frames = 0;
11642
11643 FOR_EACH_FRAME (tail, frame)
11644 {
11645 struct frame *f = XFRAME (frame);
11646
11647 FRAME_SAMPLE_VISIBILITY (f);
11648 if (FRAME_VISIBLE_P (f))
11649 ++number_of_visible_frames;
11650 clear_desired_matrices (f);
11651 }
11652 }
11653
11654 /* Notice any pending interrupt request to change frame size. */
11655 do_pending_window_change (1);
11656
11657 /* Clear frames marked as garbaged. */
11658 if (frame_garbaged)
11659 clear_garbaged_frames ();
11660
11661 /* Build menubar and tool-bar items. */
11662 if (NILP (Vmemory_full))
11663 prepare_menu_bars ();
11664
11665 if (windows_or_buffers_changed)
11666 update_mode_lines++;
11667
11668 /* Detect case that we need to write or remove a star in the mode line. */
11669 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11670 {
11671 w->update_mode_line = Qt;
11672 if (buffer_shared > 1)
11673 update_mode_lines++;
11674 }
11675
11676 /* Avoid invocation of point motion hooks by `current_column' below. */
11677 count1 = SPECPDL_INDEX ();
11678 specbind (Qinhibit_point_motion_hooks, Qt);
11679
11680 /* If %c is in the mode line, update it if needed. */
11681 if (!NILP (w->column_number_displayed)
11682 /* This alternative quickly identifies a common case
11683 where no change is needed. */
11684 && !(PT == XFASTINT (w->last_point)
11685 && XFASTINT (w->last_modified) >= MODIFF
11686 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11687 && (XFASTINT (w->column_number_displayed)
11688 != (int) current_column ())) /* iftc */
11689 w->update_mode_line = Qt;
11690
11691 unbind_to (count1, Qnil);
11692
11693 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11694
11695 /* The variable buffer_shared is set in redisplay_window and
11696 indicates that we redisplay a buffer in different windows. See
11697 there. */
11698 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11699 || cursor_type_changed);
11700
11701 /* If specs for an arrow have changed, do thorough redisplay
11702 to ensure we remove any arrow that should no longer exist. */
11703 if (overlay_arrows_changed_p ())
11704 consider_all_windows_p = windows_or_buffers_changed = 1;
11705
11706 /* Normally the message* functions will have already displayed and
11707 updated the echo area, but the frame may have been trashed, or
11708 the update may have been preempted, so display the echo area
11709 again here. Checking message_cleared_p captures the case that
11710 the echo area should be cleared. */
11711 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11712 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11713 || (message_cleared_p
11714 && minibuf_level == 0
11715 /* If the mini-window is currently selected, this means the
11716 echo-area doesn't show through. */
11717 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11718 {
11719 int window_height_changed_p = echo_area_display (0);
11720 must_finish = 1;
11721
11722 /* If we don't display the current message, don't clear the
11723 message_cleared_p flag, because, if we did, we wouldn't clear
11724 the echo area in the next redisplay which doesn't preserve
11725 the echo area. */
11726 if (!display_last_displayed_message_p)
11727 message_cleared_p = 0;
11728
11729 if (fonts_changed_p)
11730 goto retry;
11731 else if (window_height_changed_p)
11732 {
11733 consider_all_windows_p = 1;
11734 ++update_mode_lines;
11735 ++windows_or_buffers_changed;
11736
11737 /* If window configuration was changed, frames may have been
11738 marked garbaged. Clear them or we will experience
11739 surprises wrt scrolling. */
11740 if (frame_garbaged)
11741 clear_garbaged_frames ();
11742 }
11743 }
11744 else if (EQ (selected_window, minibuf_window)
11745 && (current_buffer->clip_changed
11746 || XFASTINT (w->last_modified) < MODIFF
11747 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11748 && resize_mini_window (w, 0))
11749 {
11750 /* Resized active mini-window to fit the size of what it is
11751 showing if its contents might have changed. */
11752 must_finish = 1;
11753 /* FIXME: this causes all frames to be updated, which seems unnecessary
11754 since only the current frame needs to be considered. This function needs
11755 to be rewritten with two variables, consider_all_windows and
11756 consider_all_frames. */
11757 consider_all_windows_p = 1;
11758 ++windows_or_buffers_changed;
11759 ++update_mode_lines;
11760
11761 /* If window configuration was changed, frames may have been
11762 marked garbaged. Clear them or we will experience
11763 surprises wrt scrolling. */
11764 if (frame_garbaged)
11765 clear_garbaged_frames ();
11766 }
11767
11768
11769 /* If showing the region, and mark has changed, we must redisplay
11770 the whole window. The assignment to this_line_start_pos prevents
11771 the optimization directly below this if-statement. */
11772 if (((!NILP (Vtransient_mark_mode)
11773 && !NILP (XBUFFER (w->buffer)->mark_active))
11774 != !NILP (w->region_showing))
11775 || (!NILP (w->region_showing)
11776 && !EQ (w->region_showing,
11777 Fmarker_position (XBUFFER (w->buffer)->mark))))
11778 CHARPOS (this_line_start_pos) = 0;
11779
11780 /* Optimize the case that only the line containing the cursor in the
11781 selected window has changed. Variables starting with this_ are
11782 set in display_line and record information about the line
11783 containing the cursor. */
11784 tlbufpos = this_line_start_pos;
11785 tlendpos = this_line_end_pos;
11786 if (!consider_all_windows_p
11787 && CHARPOS (tlbufpos) > 0
11788 && NILP (w->update_mode_line)
11789 && !current_buffer->clip_changed
11790 && !current_buffer->prevent_redisplay_optimizations_p
11791 && FRAME_VISIBLE_P (XFRAME (w->frame))
11792 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11793 /* Make sure recorded data applies to current buffer, etc. */
11794 && this_line_buffer == current_buffer
11795 && current_buffer == XBUFFER (w->buffer)
11796 && NILP (w->force_start)
11797 && NILP (w->optional_new_start)
11798 /* Point must be on the line that we have info recorded about. */
11799 && PT >= CHARPOS (tlbufpos)
11800 && PT <= Z - CHARPOS (tlendpos)
11801 /* All text outside that line, including its final newline,
11802 must be unchanged. */
11803 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11804 CHARPOS (tlendpos)))
11805 {
11806 if (CHARPOS (tlbufpos) > BEGV
11807 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11808 && (CHARPOS (tlbufpos) == ZV
11809 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11810 /* Former continuation line has disappeared by becoming empty. */
11811 goto cancel;
11812 else if (XFASTINT (w->last_modified) < MODIFF
11813 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11814 || MINI_WINDOW_P (w))
11815 {
11816 /* We have to handle the case of continuation around a
11817 wide-column character (see the comment in indent.c around
11818 line 1340).
11819
11820 For instance, in the following case:
11821
11822 -------- Insert --------
11823 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11824 J_I_ ==> J_I_ `^^' are cursors.
11825 ^^ ^^
11826 -------- --------
11827
11828 As we have to redraw the line above, we cannot use this
11829 optimization. */
11830
11831 struct it it;
11832 int line_height_before = this_line_pixel_height;
11833
11834 /* Note that start_display will handle the case that the
11835 line starting at tlbufpos is a continuation line. */
11836 start_display (&it, w, tlbufpos);
11837
11838 /* Implementation note: It this still necessary? */
11839 if (it.current_x != this_line_start_x)
11840 goto cancel;
11841
11842 TRACE ((stderr, "trying display optimization 1\n"));
11843 w->cursor.vpos = -1;
11844 overlay_arrow_seen = 0;
11845 it.vpos = this_line_vpos;
11846 it.current_y = this_line_y;
11847 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11848 display_line (&it);
11849
11850 /* If line contains point, is not continued,
11851 and ends at same distance from eob as before, we win. */
11852 if (w->cursor.vpos >= 0
11853 /* Line is not continued, otherwise this_line_start_pos
11854 would have been set to 0 in display_line. */
11855 && CHARPOS (this_line_start_pos)
11856 /* Line ends as before. */
11857 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11858 /* Line has same height as before. Otherwise other lines
11859 would have to be shifted up or down. */
11860 && this_line_pixel_height == line_height_before)
11861 {
11862 /* If this is not the window's last line, we must adjust
11863 the charstarts of the lines below. */
11864 if (it.current_y < it.last_visible_y)
11865 {
11866 struct glyph_row *row
11867 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11868 int delta, delta_bytes;
11869
11870 /* We used to distinguish between two cases here,
11871 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11872 when the line ends in a newline or the end of the
11873 buffer's accessible portion. But both cases did
11874 the same, so they were collapsed. */
11875 delta = (Z
11876 - CHARPOS (tlendpos)
11877 - MATRIX_ROW_START_CHARPOS (row));
11878 delta_bytes = (Z_BYTE
11879 - BYTEPOS (tlendpos)
11880 - MATRIX_ROW_START_BYTEPOS (row));
11881
11882 increment_matrix_positions (w->current_matrix,
11883 this_line_vpos + 1,
11884 w->current_matrix->nrows,
11885 delta, delta_bytes);
11886 }
11887
11888 /* If this row displays text now but previously didn't,
11889 or vice versa, w->window_end_vpos may have to be
11890 adjusted. */
11891 if ((it.glyph_row - 1)->displays_text_p)
11892 {
11893 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11894 XSETINT (w->window_end_vpos, this_line_vpos);
11895 }
11896 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11897 && this_line_vpos > 0)
11898 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11899 w->window_end_valid = Qnil;
11900
11901 /* Update hint: No need to try to scroll in update_window. */
11902 w->desired_matrix->no_scrolling_p = 1;
11903
11904 #if GLYPH_DEBUG
11905 *w->desired_matrix->method = 0;
11906 debug_method_add (w, "optimization 1");
11907 #endif
11908 #ifdef HAVE_WINDOW_SYSTEM
11909 update_window_fringes (w, 0);
11910 #endif
11911 goto update;
11912 }
11913 else
11914 goto cancel;
11915 }
11916 else if (/* Cursor position hasn't changed. */
11917 PT == XFASTINT (w->last_point)
11918 /* Make sure the cursor was last displayed
11919 in this window. Otherwise we have to reposition it. */
11920 && 0 <= w->cursor.vpos
11921 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11922 {
11923 if (!must_finish)
11924 {
11925 do_pending_window_change (1);
11926
11927 /* We used to always goto end_of_redisplay here, but this
11928 isn't enough if we have a blinking cursor. */
11929 if (w->cursor_off_p == w->last_cursor_off_p)
11930 goto end_of_redisplay;
11931 }
11932 goto update;
11933 }
11934 /* If highlighting the region, or if the cursor is in the echo area,
11935 then we can't just move the cursor. */
11936 else if (! (!NILP (Vtransient_mark_mode)
11937 && !NILP (current_buffer->mark_active))
11938 && (EQ (selected_window, current_buffer->last_selected_window)
11939 || highlight_nonselected_windows)
11940 && NILP (w->region_showing)
11941 && NILP (Vshow_trailing_whitespace)
11942 && !cursor_in_echo_area)
11943 {
11944 struct it it;
11945 struct glyph_row *row;
11946
11947 /* Skip from tlbufpos to PT and see where it is. Note that
11948 PT may be in invisible text. If so, we will end at the
11949 next visible position. */
11950 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11951 NULL, DEFAULT_FACE_ID);
11952 it.current_x = this_line_start_x;
11953 it.current_y = this_line_y;
11954 it.vpos = this_line_vpos;
11955
11956 /* The call to move_it_to stops in front of PT, but
11957 moves over before-strings. */
11958 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11959
11960 if (it.vpos == this_line_vpos
11961 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11962 row->enabled_p))
11963 {
11964 xassert (this_line_vpos == it.vpos);
11965 xassert (this_line_y == it.current_y);
11966 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11967 #if GLYPH_DEBUG
11968 *w->desired_matrix->method = 0;
11969 debug_method_add (w, "optimization 3");
11970 #endif
11971 goto update;
11972 }
11973 else
11974 goto cancel;
11975 }
11976
11977 cancel:
11978 /* Text changed drastically or point moved off of line. */
11979 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11980 }
11981
11982 CHARPOS (this_line_start_pos) = 0;
11983 consider_all_windows_p |= buffer_shared > 1;
11984 ++clear_face_cache_count;
11985 #ifdef HAVE_WINDOW_SYSTEM
11986 ++clear_image_cache_count;
11987 #endif
11988
11989 /* Build desired matrices, and update the display. If
11990 consider_all_windows_p is non-zero, do it for all windows on all
11991 frames. Otherwise do it for selected_window, only. */
11992
11993 if (consider_all_windows_p)
11994 {
11995 Lisp_Object tail, frame;
11996
11997 FOR_EACH_FRAME (tail, frame)
11998 XFRAME (frame)->updated_p = 0;
11999
12000 /* Recompute # windows showing selected buffer. This will be
12001 incremented each time such a window is displayed. */
12002 buffer_shared = 0;
12003
12004 FOR_EACH_FRAME (tail, frame)
12005 {
12006 struct frame *f = XFRAME (frame);
12007
12008 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12009 {
12010 if (! EQ (frame, selected_frame))
12011 /* Select the frame, for the sake of frame-local
12012 variables. */
12013 select_frame_for_redisplay (frame);
12014
12015 /* Mark all the scroll bars to be removed; we'll redeem
12016 the ones we want when we redisplay their windows. */
12017 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12018 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12019
12020 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12021 redisplay_windows (FRAME_ROOT_WINDOW (f));
12022
12023 /* The X error handler may have deleted that frame. */
12024 if (!FRAME_LIVE_P (f))
12025 continue;
12026
12027 /* Any scroll bars which redisplay_windows should have
12028 nuked should now go away. */
12029 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12030 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12031
12032 /* If fonts changed, display again. */
12033 /* ??? rms: I suspect it is a mistake to jump all the way
12034 back to retry here. It should just retry this frame. */
12035 if (fonts_changed_p)
12036 goto retry;
12037
12038 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12039 {
12040 /* See if we have to hscroll. */
12041 if (!f->already_hscrolled_p)
12042 {
12043 f->already_hscrolled_p = 1;
12044 if (hscroll_windows (f->root_window))
12045 goto retry;
12046 }
12047
12048 /* Prevent various kinds of signals during display
12049 update. stdio is not robust about handling
12050 signals, which can cause an apparent I/O
12051 error. */
12052 if (interrupt_input)
12053 unrequest_sigio ();
12054 STOP_POLLING;
12055
12056 /* Update the display. */
12057 set_window_update_flags (XWINDOW (f->root_window), 1);
12058 pause |= update_frame (f, 0, 0);
12059 f->updated_p = 1;
12060 }
12061 }
12062 }
12063
12064 if (!EQ (old_frame, selected_frame)
12065 && FRAME_LIVE_P (XFRAME (old_frame)))
12066 /* We played a bit fast-and-loose above and allowed selected_frame
12067 and selected_window to be temporarily out-of-sync but let's make
12068 sure this stays contained. */
12069 select_frame_for_redisplay (old_frame);
12070 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12071
12072 if (!pause)
12073 {
12074 /* Do the mark_window_display_accurate after all windows have
12075 been redisplayed because this call resets flags in buffers
12076 which are needed for proper redisplay. */
12077 FOR_EACH_FRAME (tail, frame)
12078 {
12079 struct frame *f = XFRAME (frame);
12080 if (f->updated_p)
12081 {
12082 mark_window_display_accurate (f->root_window, 1);
12083 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12084 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12085 }
12086 }
12087 }
12088 }
12089 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12090 {
12091 Lisp_Object mini_window;
12092 struct frame *mini_frame;
12093
12094 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12095 /* Use list_of_error, not Qerror, so that
12096 we catch only errors and don't run the debugger. */
12097 internal_condition_case_1 (redisplay_window_1, selected_window,
12098 list_of_error,
12099 redisplay_window_error);
12100
12101 /* Compare desired and current matrices, perform output. */
12102
12103 update:
12104 /* If fonts changed, display again. */
12105 if (fonts_changed_p)
12106 goto retry;
12107
12108 /* Prevent various kinds of signals during display update.
12109 stdio is not robust about handling signals,
12110 which can cause an apparent I/O error. */
12111 if (interrupt_input)
12112 unrequest_sigio ();
12113 STOP_POLLING;
12114
12115 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12116 {
12117 if (hscroll_windows (selected_window))
12118 goto retry;
12119
12120 XWINDOW (selected_window)->must_be_updated_p = 1;
12121 pause = update_frame (sf, 0, 0);
12122 }
12123
12124 /* We may have called echo_area_display at the top of this
12125 function. If the echo area is on another frame, that may
12126 have put text on a frame other than the selected one, so the
12127 above call to update_frame would not have caught it. Catch
12128 it here. */
12129 mini_window = FRAME_MINIBUF_WINDOW (sf);
12130 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12131
12132 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12133 {
12134 XWINDOW (mini_window)->must_be_updated_p = 1;
12135 pause |= update_frame (mini_frame, 0, 0);
12136 if (!pause && hscroll_windows (mini_window))
12137 goto retry;
12138 }
12139 }
12140
12141 /* If display was paused because of pending input, make sure we do a
12142 thorough update the next time. */
12143 if (pause)
12144 {
12145 /* Prevent the optimization at the beginning of
12146 redisplay_internal that tries a single-line update of the
12147 line containing the cursor in the selected window. */
12148 CHARPOS (this_line_start_pos) = 0;
12149
12150 /* Let the overlay arrow be updated the next time. */
12151 update_overlay_arrows (0);
12152
12153 /* If we pause after scrolling, some rows in the current
12154 matrices of some windows are not valid. */
12155 if (!WINDOW_FULL_WIDTH_P (w)
12156 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12157 update_mode_lines = 1;
12158 }
12159 else
12160 {
12161 if (!consider_all_windows_p)
12162 {
12163 /* This has already been done above if
12164 consider_all_windows_p is set. */
12165 mark_window_display_accurate_1 (w, 1);
12166
12167 /* Say overlay arrows are up to date. */
12168 update_overlay_arrows (1);
12169
12170 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12171 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12172 }
12173
12174 update_mode_lines = 0;
12175 windows_or_buffers_changed = 0;
12176 cursor_type_changed = 0;
12177 }
12178
12179 /* Start SIGIO interrupts coming again. Having them off during the
12180 code above makes it less likely one will discard output, but not
12181 impossible, since there might be stuff in the system buffer here.
12182 But it is much hairier to try to do anything about that. */
12183 if (interrupt_input)
12184 request_sigio ();
12185 RESUME_POLLING;
12186
12187 /* If a frame has become visible which was not before, redisplay
12188 again, so that we display it. Expose events for such a frame
12189 (which it gets when becoming visible) don't call the parts of
12190 redisplay constructing glyphs, so simply exposing a frame won't
12191 display anything in this case. So, we have to display these
12192 frames here explicitly. */
12193 if (!pause)
12194 {
12195 Lisp_Object tail, frame;
12196 int new_count = 0;
12197
12198 FOR_EACH_FRAME (tail, frame)
12199 {
12200 int this_is_visible = 0;
12201
12202 if (XFRAME (frame)->visible)
12203 this_is_visible = 1;
12204 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12205 if (XFRAME (frame)->visible)
12206 this_is_visible = 1;
12207
12208 if (this_is_visible)
12209 new_count++;
12210 }
12211
12212 if (new_count != number_of_visible_frames)
12213 windows_or_buffers_changed++;
12214 }
12215
12216 /* Change frame size now if a change is pending. */
12217 do_pending_window_change (1);
12218
12219 /* If we just did a pending size change, or have additional
12220 visible frames, redisplay again. */
12221 if (windows_or_buffers_changed && !pause)
12222 goto retry;
12223
12224 /* Clear the face and image caches.
12225
12226 We used to do this only if consider_all_windows_p. But the cache
12227 needs to be cleared if a timer creates images in the current
12228 buffer (e.g. the test case in Bug#6230). */
12229
12230 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12231 {
12232 clear_face_cache (0);
12233 clear_face_cache_count = 0;
12234 }
12235
12236 #ifdef HAVE_WINDOW_SYSTEM
12237 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12238 {
12239 clear_image_caches (Qnil);
12240 clear_image_cache_count = 0;
12241 }
12242 #endif /* HAVE_WINDOW_SYSTEM */
12243
12244 end_of_redisplay:
12245 unbind_to (count, Qnil);
12246 RESUME_POLLING;
12247 }
12248
12249
12250 /* Redisplay, but leave alone any recent echo area message unless
12251 another message has been requested in its place.
12252
12253 This is useful in situations where you need to redisplay but no
12254 user action has occurred, making it inappropriate for the message
12255 area to be cleared. See tracking_off and
12256 wait_reading_process_output for examples of these situations.
12257
12258 FROM_WHERE is an integer saying from where this function was
12259 called. This is useful for debugging. */
12260
12261 void
12262 redisplay_preserve_echo_area (int from_where)
12263 {
12264 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12265
12266 if (!NILP (echo_area_buffer[1]))
12267 {
12268 /* We have a previously displayed message, but no current
12269 message. Redisplay the previous message. */
12270 display_last_displayed_message_p = 1;
12271 redisplay_internal (1);
12272 display_last_displayed_message_p = 0;
12273 }
12274 else
12275 redisplay_internal (1);
12276
12277 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12278 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12279 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12280 }
12281
12282
12283 /* Function registered with record_unwind_protect in
12284 redisplay_internal. Reset redisplaying_p to the value it had
12285 before redisplay_internal was called, and clear
12286 prevent_freeing_realized_faces_p. It also selects the previously
12287 selected frame, unless it has been deleted (by an X connection
12288 failure during redisplay, for example). */
12289
12290 static Lisp_Object
12291 unwind_redisplay (Lisp_Object val)
12292 {
12293 Lisp_Object old_redisplaying_p, old_frame;
12294
12295 old_redisplaying_p = XCAR (val);
12296 redisplaying_p = XFASTINT (old_redisplaying_p);
12297 old_frame = XCDR (val);
12298 if (! EQ (old_frame, selected_frame)
12299 && FRAME_LIVE_P (XFRAME (old_frame)))
12300 select_frame_for_redisplay (old_frame);
12301 return Qnil;
12302 }
12303
12304
12305 /* Mark the display of window W as accurate or inaccurate. If
12306 ACCURATE_P is non-zero mark display of W as accurate. If
12307 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12308 redisplay_internal is called. */
12309
12310 static void
12311 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12312 {
12313 if (BUFFERP (w->buffer))
12314 {
12315 struct buffer *b = XBUFFER (w->buffer);
12316
12317 w->last_modified
12318 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12319 w->last_overlay_modified
12320 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12321 w->last_had_star
12322 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12323
12324 if (accurate_p)
12325 {
12326 b->clip_changed = 0;
12327 b->prevent_redisplay_optimizations_p = 0;
12328
12329 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12330 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12331 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12332 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12333
12334 w->current_matrix->buffer = b;
12335 w->current_matrix->begv = BUF_BEGV (b);
12336 w->current_matrix->zv = BUF_ZV (b);
12337
12338 w->last_cursor = w->cursor;
12339 w->last_cursor_off_p = w->cursor_off_p;
12340
12341 if (w == XWINDOW (selected_window))
12342 w->last_point = make_number (BUF_PT (b));
12343 else
12344 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12345 }
12346 }
12347
12348 if (accurate_p)
12349 {
12350 w->window_end_valid = w->buffer;
12351 w->update_mode_line = Qnil;
12352 }
12353 }
12354
12355
12356 /* Mark the display of windows in the window tree rooted at WINDOW as
12357 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12358 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12359 be redisplayed the next time redisplay_internal is called. */
12360
12361 void
12362 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12363 {
12364 struct window *w;
12365
12366 for (; !NILP (window); window = w->next)
12367 {
12368 w = XWINDOW (window);
12369 mark_window_display_accurate_1 (w, accurate_p);
12370
12371 if (!NILP (w->vchild))
12372 mark_window_display_accurate (w->vchild, accurate_p);
12373 if (!NILP (w->hchild))
12374 mark_window_display_accurate (w->hchild, accurate_p);
12375 }
12376
12377 if (accurate_p)
12378 {
12379 update_overlay_arrows (1);
12380 }
12381 else
12382 {
12383 /* Force a thorough redisplay the next time by setting
12384 last_arrow_position and last_arrow_string to t, which is
12385 unequal to any useful value of Voverlay_arrow_... */
12386 update_overlay_arrows (-1);
12387 }
12388 }
12389
12390
12391 /* Return value in display table DP (Lisp_Char_Table *) for character
12392 C. Since a display table doesn't have any parent, we don't have to
12393 follow parent. Do not call this function directly but use the
12394 macro DISP_CHAR_VECTOR. */
12395
12396 Lisp_Object
12397 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12398 {
12399 Lisp_Object val;
12400
12401 if (ASCII_CHAR_P (c))
12402 {
12403 val = dp->ascii;
12404 if (SUB_CHAR_TABLE_P (val))
12405 val = XSUB_CHAR_TABLE (val)->contents[c];
12406 }
12407 else
12408 {
12409 Lisp_Object table;
12410
12411 XSETCHAR_TABLE (table, dp);
12412 val = char_table_ref (table, c);
12413 }
12414 if (NILP (val))
12415 val = dp->defalt;
12416 return val;
12417 }
12418
12419
12420 \f
12421 /***********************************************************************
12422 Window Redisplay
12423 ***********************************************************************/
12424
12425 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12426
12427 static void
12428 redisplay_windows (Lisp_Object window)
12429 {
12430 while (!NILP (window))
12431 {
12432 struct window *w = XWINDOW (window);
12433
12434 if (!NILP (w->hchild))
12435 redisplay_windows (w->hchild);
12436 else if (!NILP (w->vchild))
12437 redisplay_windows (w->vchild);
12438 else if (!NILP (w->buffer))
12439 {
12440 displayed_buffer = XBUFFER (w->buffer);
12441 /* Use list_of_error, not Qerror, so that
12442 we catch only errors and don't run the debugger. */
12443 internal_condition_case_1 (redisplay_window_0, window,
12444 list_of_error,
12445 redisplay_window_error);
12446 }
12447
12448 window = w->next;
12449 }
12450 }
12451
12452 static Lisp_Object
12453 redisplay_window_error (Lisp_Object ignore)
12454 {
12455 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12456 return Qnil;
12457 }
12458
12459 static Lisp_Object
12460 redisplay_window_0 (Lisp_Object window)
12461 {
12462 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12463 redisplay_window (window, 0);
12464 return Qnil;
12465 }
12466
12467 static Lisp_Object
12468 redisplay_window_1 (Lisp_Object window)
12469 {
12470 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12471 redisplay_window (window, 1);
12472 return Qnil;
12473 }
12474 \f
12475
12476 /* Increment GLYPH until it reaches END or CONDITION fails while
12477 adding (GLYPH)->pixel_width to X. */
12478
12479 #define SKIP_GLYPHS(glyph, end, x, condition) \
12480 do \
12481 { \
12482 (x) += (glyph)->pixel_width; \
12483 ++(glyph); \
12484 } \
12485 while ((glyph) < (end) && (condition))
12486
12487
12488 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12489 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12490 which positions recorded in ROW differ from current buffer
12491 positions.
12492
12493 Return 0 if cursor is not on this row, 1 otherwise. */
12494
12495 int
12496 set_cursor_from_row (struct window *w, struct glyph_row *row,
12497 struct glyph_matrix *matrix, int delta, int delta_bytes,
12498 int dy, int dvpos)
12499 {
12500 struct glyph *glyph = row->glyphs[TEXT_AREA];
12501 struct glyph *end = glyph + row->used[TEXT_AREA];
12502 struct glyph *cursor = NULL;
12503 /* The last known character position in row. */
12504 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12505 int x = row->x;
12506 EMACS_INT pt_old = PT - delta;
12507 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12508 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12509 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12510 /* A glyph beyond the edge of TEXT_AREA which we should never
12511 touch. */
12512 struct glyph *glyphs_end = end;
12513 /* Non-zero means we've found a match for cursor position, but that
12514 glyph has the avoid_cursor_p flag set. */
12515 int match_with_avoid_cursor = 0;
12516 /* Non-zero means we've seen at least one glyph that came from a
12517 display string. */
12518 int string_seen = 0;
12519 /* Largest buffer position seen so far during scan of glyph row. */
12520 EMACS_INT bpos_max = last_pos;
12521 /* Last buffer position covered by an overlay string with an integer
12522 `cursor' property. */
12523 EMACS_INT bpos_covered = 0;
12524
12525 /* Skip over glyphs not having an object at the start and the end of
12526 the row. These are special glyphs like truncation marks on
12527 terminal frames. */
12528 if (row->displays_text_p)
12529 {
12530 if (!row->reversed_p)
12531 {
12532 while (glyph < end
12533 && INTEGERP (glyph->object)
12534 && glyph->charpos < 0)
12535 {
12536 x += glyph->pixel_width;
12537 ++glyph;
12538 }
12539 while (end > glyph
12540 && INTEGERP ((end - 1)->object)
12541 /* CHARPOS is zero for blanks and stretch glyphs
12542 inserted by extend_face_to_end_of_line. */
12543 && (end - 1)->charpos <= 0)
12544 --end;
12545 glyph_before = glyph - 1;
12546 glyph_after = end;
12547 }
12548 else
12549 {
12550 struct glyph *g;
12551
12552 /* If the glyph row is reversed, we need to process it from back
12553 to front, so swap the edge pointers. */
12554 glyphs_end = end = glyph - 1;
12555 glyph += row->used[TEXT_AREA] - 1;
12556
12557 while (glyph > end + 1
12558 && INTEGERP (glyph->object)
12559 && glyph->charpos < 0)
12560 {
12561 --glyph;
12562 x -= glyph->pixel_width;
12563 }
12564 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12565 --glyph;
12566 /* By default, in reversed rows we put the cursor on the
12567 rightmost (first in the reading order) glyph. */
12568 for (g = end + 1; g < glyph; g++)
12569 x += g->pixel_width;
12570 while (end < glyph
12571 && INTEGERP ((end + 1)->object)
12572 && (end + 1)->charpos <= 0)
12573 ++end;
12574 glyph_before = glyph + 1;
12575 glyph_after = end;
12576 }
12577 }
12578 else if (row->reversed_p)
12579 {
12580 /* In R2L rows that don't display text, put the cursor on the
12581 rightmost glyph. Case in point: an empty last line that is
12582 part of an R2L paragraph. */
12583 cursor = end - 1;
12584 /* Avoid placing the cursor on the last glyph of the row, where
12585 on terminal frames we hold the vertical border between
12586 adjacent windows. */
12587 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12588 && !WINDOW_RIGHTMOST_P (w)
12589 && cursor == row->glyphs[LAST_AREA] - 1)
12590 cursor--;
12591 x = -1; /* will be computed below, at label compute_x */
12592 }
12593
12594 /* Step 1: Try to find the glyph whose character position
12595 corresponds to point. If that's not possible, find 2 glyphs
12596 whose character positions are the closest to point, one before
12597 point, the other after it. */
12598 if (!row->reversed_p)
12599 while (/* not marched to end of glyph row */
12600 glyph < end
12601 /* glyph was not inserted by redisplay for internal purposes */
12602 && !INTEGERP (glyph->object))
12603 {
12604 if (BUFFERP (glyph->object))
12605 {
12606 EMACS_INT dpos = glyph->charpos - pt_old;
12607
12608 if (glyph->charpos > bpos_max)
12609 bpos_max = glyph->charpos;
12610 if (!glyph->avoid_cursor_p)
12611 {
12612 /* If we hit point, we've found the glyph on which to
12613 display the cursor. */
12614 if (dpos == 0)
12615 {
12616 match_with_avoid_cursor = 0;
12617 break;
12618 }
12619 /* See if we've found a better approximation to
12620 POS_BEFORE or to POS_AFTER. Note that we want the
12621 first (leftmost) glyph of all those that are the
12622 closest from below, and the last (rightmost) of all
12623 those from above. */
12624 if (0 > dpos && dpos > pos_before - pt_old)
12625 {
12626 pos_before = glyph->charpos;
12627 glyph_before = glyph;
12628 }
12629 else if (0 < dpos && dpos <= pos_after - pt_old)
12630 {
12631 pos_after = glyph->charpos;
12632 glyph_after = glyph;
12633 }
12634 }
12635 else if (dpos == 0)
12636 match_with_avoid_cursor = 1;
12637 }
12638 else if (STRINGP (glyph->object))
12639 {
12640 Lisp_Object chprop;
12641 int glyph_pos = glyph->charpos;
12642
12643 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12644 glyph->object);
12645 if (INTEGERP (chprop))
12646 {
12647 bpos_covered = bpos_max + XINT (chprop);
12648 /* If the `cursor' property covers buffer positions up
12649 to and including point, we should display cursor on
12650 this glyph. Note that overlays and text properties
12651 with string values stop bidi reordering, so every
12652 buffer position to the left of the string is always
12653 smaller than any position to the right of the
12654 string. Therefore, if a `cursor' property on one
12655 of the string's characters has an integer value, we
12656 will break out of the loop below _before_ we get to
12657 the position match above. IOW, integer values of
12658 the `cursor' property override the "exact match for
12659 point" strategy of positioning the cursor. */
12660 /* Implementation note: bpos_max == pt_old when, e.g.,
12661 we are in an empty line, where bpos_max is set to
12662 MATRIX_ROW_START_CHARPOS, see above. */
12663 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12664 {
12665 cursor = glyph;
12666 break;
12667 }
12668 }
12669
12670 string_seen = 1;
12671 }
12672 x += glyph->pixel_width;
12673 ++glyph;
12674 }
12675 else if (glyph > end) /* row is reversed */
12676 while (!INTEGERP (glyph->object))
12677 {
12678 if (BUFFERP (glyph->object))
12679 {
12680 EMACS_INT dpos = glyph->charpos - pt_old;
12681
12682 if (glyph->charpos > bpos_max)
12683 bpos_max = glyph->charpos;
12684 if (!glyph->avoid_cursor_p)
12685 {
12686 if (dpos == 0)
12687 {
12688 match_with_avoid_cursor = 0;
12689 break;
12690 }
12691 if (0 > dpos && dpos > pos_before - pt_old)
12692 {
12693 pos_before = glyph->charpos;
12694 glyph_before = glyph;
12695 }
12696 else if (0 < dpos && dpos <= pos_after - pt_old)
12697 {
12698 pos_after = glyph->charpos;
12699 glyph_after = glyph;
12700 }
12701 }
12702 else if (dpos == 0)
12703 match_with_avoid_cursor = 1;
12704 }
12705 else if (STRINGP (glyph->object))
12706 {
12707 Lisp_Object chprop;
12708 int glyph_pos = glyph->charpos;
12709
12710 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12711 glyph->object);
12712 if (INTEGERP (chprop))
12713 {
12714 bpos_covered = bpos_max + XINT (chprop);
12715 /* If the `cursor' property covers buffer positions up
12716 to and including point, we should display cursor on
12717 this glyph. */
12718 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12719 {
12720 cursor = glyph;
12721 break;
12722 }
12723 }
12724 string_seen = 1;
12725 }
12726 --glyph;
12727 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12728 {
12729 x--; /* can't use any pixel_width */
12730 break;
12731 }
12732 x -= glyph->pixel_width;
12733 }
12734
12735 /* Step 2: If we didn't find an exact match for point, we need to
12736 look for a proper place to put the cursor among glyphs between
12737 GLYPH_BEFORE and GLYPH_AFTER. */
12738 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12739 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12740 && bpos_covered < pt_old)
12741 {
12742 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12743 {
12744 EMACS_INT ellipsis_pos;
12745
12746 /* Scan back over the ellipsis glyphs. */
12747 if (!row->reversed_p)
12748 {
12749 ellipsis_pos = (glyph - 1)->charpos;
12750 while (glyph > row->glyphs[TEXT_AREA]
12751 && (glyph - 1)->charpos == ellipsis_pos)
12752 glyph--, x -= glyph->pixel_width;
12753 /* That loop always goes one position too far, including
12754 the glyph before the ellipsis. So scan forward over
12755 that one. */
12756 x += glyph->pixel_width;
12757 glyph++;
12758 }
12759 else /* row is reversed */
12760 {
12761 ellipsis_pos = (glyph + 1)->charpos;
12762 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12763 && (glyph + 1)->charpos == ellipsis_pos)
12764 glyph++, x += glyph->pixel_width;
12765 x -= glyph->pixel_width;
12766 glyph--;
12767 }
12768 }
12769 else if (match_with_avoid_cursor
12770 /* zero-width characters produce no glyphs */
12771 || ((row->reversed_p
12772 ? glyph_after > glyphs_end
12773 : glyph_after < glyphs_end)
12774 && eabs (glyph_after - glyph_before) == 1))
12775 {
12776 cursor = glyph_after;
12777 x = -1;
12778 }
12779 else if (string_seen)
12780 {
12781 int incr = row->reversed_p ? -1 : +1;
12782
12783 /* Need to find the glyph that came out of a string which is
12784 present at point. That glyph is somewhere between
12785 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12786 positioned between POS_BEFORE and POS_AFTER in the
12787 buffer. */
12788 struct glyph *stop = glyph_after;
12789 EMACS_INT pos = pos_before;
12790
12791 x = -1;
12792 for (glyph = glyph_before + incr;
12793 row->reversed_p ? glyph > stop : glyph < stop; )
12794 {
12795
12796 /* Any glyphs that come from the buffer are here because
12797 of bidi reordering. Skip them, and only pay
12798 attention to glyphs that came from some string. */
12799 if (STRINGP (glyph->object))
12800 {
12801 Lisp_Object str;
12802 EMACS_INT tem;
12803
12804 str = glyph->object;
12805 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12806 if (tem == 0 /* from overlay */
12807 || pos <= tem)
12808 {
12809 /* If the string from which this glyph came is
12810 found in the buffer at point, then we've
12811 found the glyph we've been looking for. If
12812 it comes from an overlay (tem == 0), and it
12813 has the `cursor' property on one of its
12814 glyphs, record that glyph as a candidate for
12815 displaying the cursor. (As in the
12816 unidirectional version, we will display the
12817 cursor on the last candidate we find.) */
12818 if (tem == 0 || tem == pt_old)
12819 {
12820 /* The glyphs from this string could have
12821 been reordered. Find the one with the
12822 smallest string position. Or there could
12823 be a character in the string with the
12824 `cursor' property, which means display
12825 cursor on that character's glyph. */
12826 int strpos = glyph->charpos;
12827
12828 cursor = glyph;
12829 for (glyph += incr;
12830 (row->reversed_p ? glyph > stop : glyph < stop)
12831 && EQ (glyph->object, str);
12832 glyph += incr)
12833 {
12834 Lisp_Object cprop;
12835 int gpos = glyph->charpos;
12836
12837 cprop = Fget_char_property (make_number (gpos),
12838 Qcursor,
12839 glyph->object);
12840 if (!NILP (cprop))
12841 {
12842 cursor = glyph;
12843 break;
12844 }
12845 if (glyph->charpos < strpos)
12846 {
12847 strpos = glyph->charpos;
12848 cursor = glyph;
12849 }
12850 }
12851
12852 if (tem == pt_old)
12853 goto compute_x;
12854 }
12855 if (tem)
12856 pos = tem + 1; /* don't find previous instances */
12857 }
12858 /* This string is not what we want; skip all of the
12859 glyphs that came from it. */
12860 do
12861 glyph += incr;
12862 while ((row->reversed_p ? glyph > stop : glyph < stop)
12863 && EQ (glyph->object, str));
12864 }
12865 else
12866 glyph += incr;
12867 }
12868
12869 /* If we reached the end of the line, and END was from a string,
12870 the cursor is not on this line. */
12871 if (cursor == NULL
12872 && (row->reversed_p ? glyph <= end : glyph >= end)
12873 && STRINGP (end->object)
12874 && row->continued_p)
12875 return 0;
12876 }
12877 }
12878
12879 compute_x:
12880 if (cursor != NULL)
12881 glyph = cursor;
12882 if (x < 0)
12883 {
12884 struct glyph *g;
12885
12886 /* Need to compute x that corresponds to GLYPH. */
12887 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12888 {
12889 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12890 abort ();
12891 x += g->pixel_width;
12892 }
12893 }
12894
12895 /* ROW could be part of a continued line, which, under bidi
12896 reordering, might have other rows whose start and end charpos
12897 occlude point. Only set w->cursor if we found a better
12898 approximation to the cursor position than we have from previously
12899 examined candidate rows belonging to the same continued line. */
12900 if (/* we already have a candidate row */
12901 w->cursor.vpos >= 0
12902 /* that candidate is not the row we are processing */
12903 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12904 /* the row we are processing is part of a continued line */
12905 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12906 /* Make sure cursor.vpos specifies a row whose start and end
12907 charpos occlude point. This is because some callers of this
12908 function leave cursor.vpos at the row where the cursor was
12909 displayed during the last redisplay cycle. */
12910 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12911 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12912 {
12913 struct glyph *g1 =
12914 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12915
12916 /* Don't consider glyphs that are outside TEXT_AREA. */
12917 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12918 return 0;
12919 /* Keep the candidate whose buffer position is the closest to
12920 point. */
12921 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12922 w->cursor.hpos >= 0
12923 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12924 && BUFFERP (g1->object)
12925 && (g1->charpos == pt_old /* an exact match always wins */
12926 || (BUFFERP (glyph->object)
12927 && eabs (g1->charpos - pt_old)
12928 < eabs (glyph->charpos - pt_old))))
12929 return 0;
12930 /* If this candidate gives an exact match, use that. */
12931 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12932 /* Otherwise, keep the candidate that comes from a row
12933 spanning less buffer positions. This may win when one or
12934 both candidate positions are on glyphs that came from
12935 display strings, for which we cannot compare buffer
12936 positions. */
12937 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12938 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12939 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12940 return 0;
12941 }
12942 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12943 w->cursor.x = x;
12944 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12945 w->cursor.y = row->y + dy;
12946
12947 if (w == XWINDOW (selected_window))
12948 {
12949 if (!row->continued_p
12950 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12951 && row->x == 0)
12952 {
12953 this_line_buffer = XBUFFER (w->buffer);
12954
12955 CHARPOS (this_line_start_pos)
12956 = MATRIX_ROW_START_CHARPOS (row) + delta;
12957 BYTEPOS (this_line_start_pos)
12958 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12959
12960 CHARPOS (this_line_end_pos)
12961 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12962 BYTEPOS (this_line_end_pos)
12963 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12964
12965 this_line_y = w->cursor.y;
12966 this_line_pixel_height = row->height;
12967 this_line_vpos = w->cursor.vpos;
12968 this_line_start_x = row->x;
12969 }
12970 else
12971 CHARPOS (this_line_start_pos) = 0;
12972 }
12973
12974 return 1;
12975 }
12976
12977
12978 /* Run window scroll functions, if any, for WINDOW with new window
12979 start STARTP. Sets the window start of WINDOW to that position.
12980
12981 We assume that the window's buffer is really current. */
12982
12983 static INLINE struct text_pos
12984 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
12985 {
12986 struct window *w = XWINDOW (window);
12987 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12988
12989 if (current_buffer != XBUFFER (w->buffer))
12990 abort ();
12991
12992 if (!NILP (Vwindow_scroll_functions))
12993 {
12994 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12995 make_number (CHARPOS (startp)));
12996 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12997 /* In case the hook functions switch buffers. */
12998 if (current_buffer != XBUFFER (w->buffer))
12999 set_buffer_internal_1 (XBUFFER (w->buffer));
13000 }
13001
13002 return startp;
13003 }
13004
13005
13006 /* Make sure the line containing the cursor is fully visible.
13007 A value of 1 means there is nothing to be done.
13008 (Either the line is fully visible, or it cannot be made so,
13009 or we cannot tell.)
13010
13011 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13012 is higher than window.
13013
13014 A value of 0 means the caller should do scrolling
13015 as if point had gone off the screen. */
13016
13017 static int
13018 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13019 {
13020 struct glyph_matrix *matrix;
13021 struct glyph_row *row;
13022 int window_height;
13023
13024 if (!make_cursor_line_fully_visible_p)
13025 return 1;
13026
13027 /* It's not always possible to find the cursor, e.g, when a window
13028 is full of overlay strings. Don't do anything in that case. */
13029 if (w->cursor.vpos < 0)
13030 return 1;
13031
13032 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13033 row = MATRIX_ROW (matrix, w->cursor.vpos);
13034
13035 /* If the cursor row is not partially visible, there's nothing to do. */
13036 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13037 return 1;
13038
13039 /* If the row the cursor is in is taller than the window's height,
13040 it's not clear what to do, so do nothing. */
13041 window_height = window_box_height (w);
13042 if (row->height >= window_height)
13043 {
13044 if (!force_p || MINI_WINDOW_P (w)
13045 || w->vscroll || w->cursor.vpos == 0)
13046 return 1;
13047 }
13048 return 0;
13049 }
13050
13051
13052 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13053 non-zero means only WINDOW is redisplayed in redisplay_internal.
13054 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13055 in redisplay_window to bring a partially visible line into view in
13056 the case that only the cursor has moved.
13057
13058 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13059 last screen line's vertical height extends past the end of the screen.
13060
13061 Value is
13062
13063 1 if scrolling succeeded
13064
13065 0 if scrolling didn't find point.
13066
13067 -1 if new fonts have been loaded so that we must interrupt
13068 redisplay, adjust glyph matrices, and try again. */
13069
13070 enum
13071 {
13072 SCROLLING_SUCCESS,
13073 SCROLLING_FAILED,
13074 SCROLLING_NEED_LARGER_MATRICES
13075 };
13076
13077 static int
13078 try_scrolling (Lisp_Object window, int just_this_one_p,
13079 EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
13080 int temp_scroll_step, int last_line_misfit)
13081 {
13082 struct window *w = XWINDOW (window);
13083 struct frame *f = XFRAME (w->frame);
13084 struct text_pos pos, startp;
13085 struct it it;
13086 int this_scroll_margin, scroll_max, rc, height;
13087 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13088 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13089 Lisp_Object aggressive;
13090 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
13091
13092 #if GLYPH_DEBUG
13093 debug_method_add (w, "try_scrolling");
13094 #endif
13095
13096 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13097
13098 /* Compute scroll margin height in pixels. We scroll when point is
13099 within this distance from the top or bottom of the window. */
13100 if (scroll_margin > 0)
13101 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13102 * FRAME_LINE_HEIGHT (f);
13103 else
13104 this_scroll_margin = 0;
13105
13106 /* Force scroll_conservatively to have a reasonable value, to avoid
13107 overflow while computing how much to scroll. Note that the user
13108 can supply scroll-conservatively equal to `most-positive-fixnum',
13109 which can be larger than INT_MAX. */
13110 if (scroll_conservatively > scroll_limit)
13111 {
13112 scroll_conservatively = scroll_limit;
13113 scroll_max = INT_MAX;
13114 }
13115 else if (scroll_step || scroll_conservatively || temp_scroll_step)
13116 /* Compute how much we should try to scroll maximally to bring
13117 point into view. */
13118 scroll_max = (max (scroll_step,
13119 max (scroll_conservatively, temp_scroll_step))
13120 * FRAME_LINE_HEIGHT (f));
13121 else if (NUMBERP (current_buffer->scroll_down_aggressively)
13122 || NUMBERP (current_buffer->scroll_up_aggressively))
13123 /* We're trying to scroll because of aggressive scrolling but no
13124 scroll_step is set. Choose an arbitrary one. */
13125 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13126 else
13127 scroll_max = 0;
13128
13129 too_near_end:
13130
13131 /* Decide whether to scroll down. */
13132 if (PT > CHARPOS (startp))
13133 {
13134 int scroll_margin_y;
13135
13136 /* Compute the pixel ypos of the scroll margin, then move it to
13137 either that ypos or PT, whichever comes first. */
13138 start_display (&it, w, startp);
13139 scroll_margin_y = it.last_visible_y - this_scroll_margin
13140 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13141 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13142 (MOVE_TO_POS | MOVE_TO_Y));
13143
13144 if (PT > CHARPOS (it.current.pos))
13145 {
13146 int y0 = line_bottom_y (&it);
13147 /* Compute how many pixels below window bottom to stop searching
13148 for PT. This avoids costly search for PT that is far away if
13149 the user limited scrolling by a small number of lines, but
13150 always finds PT if scroll_conservatively is set to a large
13151 number, such as most-positive-fixnum. */
13152 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13153 int y_to_move =
13154 slack >= INT_MAX - it.last_visible_y
13155 ? INT_MAX
13156 : it.last_visible_y + slack;
13157
13158 /* Compute the distance from the scroll margin to PT or to
13159 the scroll limit, whichever comes first. This should
13160 include the height of the cursor line, to make that line
13161 fully visible. */
13162 move_it_to (&it, PT, -1, y_to_move,
13163 -1, MOVE_TO_POS | MOVE_TO_Y);
13164 dy = line_bottom_y (&it) - y0;
13165
13166 if (dy > scroll_max)
13167 return SCROLLING_FAILED;
13168
13169 scroll_down_p = 1;
13170 }
13171 }
13172
13173 if (scroll_down_p)
13174 {
13175 /* Point is in or below the bottom scroll margin, so move the
13176 window start down. If scrolling conservatively, move it just
13177 enough down to make point visible. If scroll_step is set,
13178 move it down by scroll_step. */
13179 if (scroll_conservatively)
13180 amount_to_scroll
13181 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13182 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
13183 else if (scroll_step || temp_scroll_step)
13184 amount_to_scroll = scroll_max;
13185 else
13186 {
13187 aggressive = current_buffer->scroll_up_aggressively;
13188 height = WINDOW_BOX_TEXT_HEIGHT (w);
13189 if (NUMBERP (aggressive))
13190 {
13191 double float_amount = XFLOATINT (aggressive) * height;
13192 amount_to_scroll = float_amount;
13193 if (amount_to_scroll == 0 && float_amount > 0)
13194 amount_to_scroll = 1;
13195 }
13196 }
13197
13198 if (amount_to_scroll <= 0)
13199 return SCROLLING_FAILED;
13200
13201 start_display (&it, w, startp);
13202 if (scroll_max < INT_MAX)
13203 move_it_vertically (&it, amount_to_scroll);
13204 else
13205 {
13206 /* Extra precision for users who set scroll-conservatively
13207 to most-positive-fixnum: make sure the amount we scroll
13208 the window start is never less than amount_to_scroll,
13209 which was computed as distance from window bottom to
13210 point. This matters when lines at window top and lines
13211 below window bottom have different height. */
13212 struct it it1 = it;
13213 /* We use a temporary it1 because line_bottom_y can modify
13214 its argument, if it moves one line down; see there. */
13215 int start_y = line_bottom_y (&it1);
13216
13217 do {
13218 move_it_by_lines (&it, 1, 1);
13219 it1 = it;
13220 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13221 }
13222
13223 /* If STARTP is unchanged, move it down another screen line. */
13224 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13225 move_it_by_lines (&it, 1, 1);
13226 startp = it.current.pos;
13227 }
13228 else
13229 {
13230 struct text_pos scroll_margin_pos = startp;
13231
13232 /* See if point is inside the scroll margin at the top of the
13233 window. */
13234 if (this_scroll_margin)
13235 {
13236 start_display (&it, w, startp);
13237 move_it_vertically (&it, this_scroll_margin);
13238 scroll_margin_pos = it.current.pos;
13239 }
13240
13241 if (PT < CHARPOS (scroll_margin_pos))
13242 {
13243 /* Point is in the scroll margin at the top of the window or
13244 above what is displayed in the window. */
13245 int y0;
13246
13247 /* Compute the vertical distance from PT to the scroll
13248 margin position. Give up if distance is greater than
13249 scroll_max. */
13250 SET_TEXT_POS (pos, PT, PT_BYTE);
13251 start_display (&it, w, pos);
13252 y0 = it.current_y;
13253 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13254 it.last_visible_y, -1,
13255 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13256 dy = it.current_y - y0;
13257 if (dy > scroll_max)
13258 return SCROLLING_FAILED;
13259
13260 /* Compute new window start. */
13261 start_display (&it, w, startp);
13262
13263 if (scroll_conservatively)
13264 amount_to_scroll
13265 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
13266 else if (scroll_step || temp_scroll_step)
13267 amount_to_scroll = scroll_max;
13268 else
13269 {
13270 aggressive = current_buffer->scroll_down_aggressively;
13271 height = WINDOW_BOX_TEXT_HEIGHT (w);
13272 if (NUMBERP (aggressive))
13273 {
13274 double float_amount = XFLOATINT (aggressive) * height;
13275 amount_to_scroll = float_amount;
13276 if (amount_to_scroll == 0 && float_amount > 0)
13277 amount_to_scroll = 1;
13278 }
13279 }
13280
13281 if (amount_to_scroll <= 0)
13282 return SCROLLING_FAILED;
13283
13284 move_it_vertically_backward (&it, amount_to_scroll);
13285 startp = it.current.pos;
13286 }
13287 }
13288
13289 /* Run window scroll functions. */
13290 startp = run_window_scroll_functions (window, startp);
13291
13292 /* Display the window. Give up if new fonts are loaded, or if point
13293 doesn't appear. */
13294 if (!try_window (window, startp, 0))
13295 rc = SCROLLING_NEED_LARGER_MATRICES;
13296 else if (w->cursor.vpos < 0)
13297 {
13298 clear_glyph_matrix (w->desired_matrix);
13299 rc = SCROLLING_FAILED;
13300 }
13301 else
13302 {
13303 /* Maybe forget recorded base line for line number display. */
13304 if (!just_this_one_p
13305 || current_buffer->clip_changed
13306 || BEG_UNCHANGED < CHARPOS (startp))
13307 w->base_line_number = Qnil;
13308
13309 /* If cursor ends up on a partially visible line,
13310 treat that as being off the bottom of the screen. */
13311 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
13312 {
13313 clear_glyph_matrix (w->desired_matrix);
13314 ++extra_scroll_margin_lines;
13315 goto too_near_end;
13316 }
13317 rc = SCROLLING_SUCCESS;
13318 }
13319
13320 return rc;
13321 }
13322
13323
13324 /* Compute a suitable window start for window W if display of W starts
13325 on a continuation line. Value is non-zero if a new window start
13326 was computed.
13327
13328 The new window start will be computed, based on W's width, starting
13329 from the start of the continued line. It is the start of the
13330 screen line with the minimum distance from the old start W->start. */
13331
13332 static int
13333 compute_window_start_on_continuation_line (struct window *w)
13334 {
13335 struct text_pos pos, start_pos;
13336 int window_start_changed_p = 0;
13337
13338 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13339
13340 /* If window start is on a continuation line... Window start may be
13341 < BEGV in case there's invisible text at the start of the
13342 buffer (M-x rmail, for example). */
13343 if (CHARPOS (start_pos) > BEGV
13344 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13345 {
13346 struct it it;
13347 struct glyph_row *row;
13348
13349 /* Handle the case that the window start is out of range. */
13350 if (CHARPOS (start_pos) < BEGV)
13351 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13352 else if (CHARPOS (start_pos) > ZV)
13353 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13354
13355 /* Find the start of the continued line. This should be fast
13356 because scan_buffer is fast (newline cache). */
13357 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13358 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13359 row, DEFAULT_FACE_ID);
13360 reseat_at_previous_visible_line_start (&it);
13361
13362 /* If the line start is "too far" away from the window start,
13363 say it takes too much time to compute a new window start. */
13364 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13365 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13366 {
13367 int min_distance, distance;
13368
13369 /* Move forward by display lines to find the new window
13370 start. If window width was enlarged, the new start can
13371 be expected to be > the old start. If window width was
13372 decreased, the new window start will be < the old start.
13373 So, we're looking for the display line start with the
13374 minimum distance from the old window start. */
13375 pos = it.current.pos;
13376 min_distance = INFINITY;
13377 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13378 distance < min_distance)
13379 {
13380 min_distance = distance;
13381 pos = it.current.pos;
13382 move_it_by_lines (&it, 1, 0);
13383 }
13384
13385 /* Set the window start there. */
13386 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13387 window_start_changed_p = 1;
13388 }
13389 }
13390
13391 return window_start_changed_p;
13392 }
13393
13394
13395 /* Try cursor movement in case text has not changed in window WINDOW,
13396 with window start STARTP. Value is
13397
13398 CURSOR_MOVEMENT_SUCCESS if successful
13399
13400 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13401
13402 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13403 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13404 we want to scroll as if scroll-step were set to 1. See the code.
13405
13406 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13407 which case we have to abort this redisplay, and adjust matrices
13408 first. */
13409
13410 enum
13411 {
13412 CURSOR_MOVEMENT_SUCCESS,
13413 CURSOR_MOVEMENT_CANNOT_BE_USED,
13414 CURSOR_MOVEMENT_MUST_SCROLL,
13415 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13416 };
13417
13418 static int
13419 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13420 {
13421 struct window *w = XWINDOW (window);
13422 struct frame *f = XFRAME (w->frame);
13423 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13424
13425 #if GLYPH_DEBUG
13426 if (inhibit_try_cursor_movement)
13427 return rc;
13428 #endif
13429
13430 /* Handle case where text has not changed, only point, and it has
13431 not moved off the frame. */
13432 if (/* Point may be in this window. */
13433 PT >= CHARPOS (startp)
13434 /* Selective display hasn't changed. */
13435 && !current_buffer->clip_changed
13436 /* Function force-mode-line-update is used to force a thorough
13437 redisplay. It sets either windows_or_buffers_changed or
13438 update_mode_lines. So don't take a shortcut here for these
13439 cases. */
13440 && !update_mode_lines
13441 && !windows_or_buffers_changed
13442 && !cursor_type_changed
13443 /* Can't use this case if highlighting a region. When a
13444 region exists, cursor movement has to do more than just
13445 set the cursor. */
13446 && !(!NILP (Vtransient_mark_mode)
13447 && !NILP (current_buffer->mark_active))
13448 && NILP (w->region_showing)
13449 && NILP (Vshow_trailing_whitespace)
13450 /* Right after splitting windows, last_point may be nil. */
13451 && INTEGERP (w->last_point)
13452 /* This code is not used for mini-buffer for the sake of the case
13453 of redisplaying to replace an echo area message; since in
13454 that case the mini-buffer contents per se are usually
13455 unchanged. This code is of no real use in the mini-buffer
13456 since the handling of this_line_start_pos, etc., in redisplay
13457 handles the same cases. */
13458 && !EQ (window, minibuf_window)
13459 /* When splitting windows or for new windows, it happens that
13460 redisplay is called with a nil window_end_vpos or one being
13461 larger than the window. This should really be fixed in
13462 window.c. I don't have this on my list, now, so we do
13463 approximately the same as the old redisplay code. --gerd. */
13464 && INTEGERP (w->window_end_vpos)
13465 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13466 && (FRAME_WINDOW_P (f)
13467 || !overlay_arrow_in_current_buffer_p ()))
13468 {
13469 int this_scroll_margin, top_scroll_margin;
13470 struct glyph_row *row = NULL;
13471
13472 #if GLYPH_DEBUG
13473 debug_method_add (w, "cursor movement");
13474 #endif
13475
13476 /* Scroll if point within this distance from the top or bottom
13477 of the window. This is a pixel value. */
13478 if (scroll_margin > 0)
13479 {
13480 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13481 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13482 }
13483 else
13484 this_scroll_margin = 0;
13485
13486 top_scroll_margin = this_scroll_margin;
13487 if (WINDOW_WANTS_HEADER_LINE_P (w))
13488 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13489
13490 /* Start with the row the cursor was displayed during the last
13491 not paused redisplay. Give up if that row is not valid. */
13492 if (w->last_cursor.vpos < 0
13493 || w->last_cursor.vpos >= w->current_matrix->nrows)
13494 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13495 else
13496 {
13497 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13498 if (row->mode_line_p)
13499 ++row;
13500 if (!row->enabled_p)
13501 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13502 }
13503
13504 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13505 {
13506 int scroll_p = 0, must_scroll = 0;
13507 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13508
13509 if (PT > XFASTINT (w->last_point))
13510 {
13511 /* Point has moved forward. */
13512 while (MATRIX_ROW_END_CHARPOS (row) < PT
13513 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13514 {
13515 xassert (row->enabled_p);
13516 ++row;
13517 }
13518
13519 /* If the end position of a row equals the start
13520 position of the next row, and PT is at that position,
13521 we would rather display cursor in the next line. */
13522 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13523 && MATRIX_ROW_END_CHARPOS (row) == PT
13524 && row < w->current_matrix->rows
13525 + w->current_matrix->nrows - 1
13526 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13527 && !cursor_row_p (w, row))
13528 ++row;
13529
13530 /* If within the scroll margin, scroll. Note that
13531 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13532 the next line would be drawn, and that
13533 this_scroll_margin can be zero. */
13534 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13535 || PT > MATRIX_ROW_END_CHARPOS (row)
13536 /* Line is completely visible last line in window
13537 and PT is to be set in the next line. */
13538 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13539 && PT == MATRIX_ROW_END_CHARPOS (row)
13540 && !row->ends_at_zv_p
13541 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13542 scroll_p = 1;
13543 }
13544 else if (PT < XFASTINT (w->last_point))
13545 {
13546 /* Cursor has to be moved backward. Note that PT >=
13547 CHARPOS (startp) because of the outer if-statement. */
13548 while (!row->mode_line_p
13549 && (MATRIX_ROW_START_CHARPOS (row) > PT
13550 || (MATRIX_ROW_START_CHARPOS (row) == PT
13551 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13552 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13553 row > w->current_matrix->rows
13554 && (row-1)->ends_in_newline_from_string_p))))
13555 && (row->y > top_scroll_margin
13556 || CHARPOS (startp) == BEGV))
13557 {
13558 xassert (row->enabled_p);
13559 --row;
13560 }
13561
13562 /* Consider the following case: Window starts at BEGV,
13563 there is invisible, intangible text at BEGV, so that
13564 display starts at some point START > BEGV. It can
13565 happen that we are called with PT somewhere between
13566 BEGV and START. Try to handle that case. */
13567 if (row < w->current_matrix->rows
13568 || row->mode_line_p)
13569 {
13570 row = w->current_matrix->rows;
13571 if (row->mode_line_p)
13572 ++row;
13573 }
13574
13575 /* Due to newlines in overlay strings, we may have to
13576 skip forward over overlay strings. */
13577 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13578 && MATRIX_ROW_END_CHARPOS (row) == PT
13579 && !cursor_row_p (w, row))
13580 ++row;
13581
13582 /* If within the scroll margin, scroll. */
13583 if (row->y < top_scroll_margin
13584 && CHARPOS (startp) != BEGV)
13585 scroll_p = 1;
13586 }
13587 else
13588 {
13589 /* Cursor did not move. So don't scroll even if cursor line
13590 is partially visible, as it was so before. */
13591 rc = CURSOR_MOVEMENT_SUCCESS;
13592 }
13593
13594 if (PT < MATRIX_ROW_START_CHARPOS (row)
13595 || PT > MATRIX_ROW_END_CHARPOS (row))
13596 {
13597 /* if PT is not in the glyph row, give up. */
13598 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13599 must_scroll = 1;
13600 }
13601 else if (rc != CURSOR_MOVEMENT_SUCCESS
13602 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13603 {
13604 /* If rows are bidi-reordered and point moved, back up
13605 until we find a row that does not belong to a
13606 continuation line. This is because we must consider
13607 all rows of a continued line as candidates for the
13608 new cursor positioning, since row start and end
13609 positions change non-linearly with vertical position
13610 in such rows. */
13611 /* FIXME: Revisit this when glyph ``spilling'' in
13612 continuation lines' rows is implemented for
13613 bidi-reordered rows. */
13614 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13615 {
13616 xassert (row->enabled_p);
13617 --row;
13618 /* If we hit the beginning of the displayed portion
13619 without finding the first row of a continued
13620 line, give up. */
13621 if (row <= w->current_matrix->rows)
13622 {
13623 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13624 break;
13625 }
13626
13627 }
13628 }
13629 if (must_scroll)
13630 ;
13631 else if (rc != CURSOR_MOVEMENT_SUCCESS
13632 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13633 && make_cursor_line_fully_visible_p)
13634 {
13635 if (PT == MATRIX_ROW_END_CHARPOS (row)
13636 && !row->ends_at_zv_p
13637 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13638 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13639 else if (row->height > window_box_height (w))
13640 {
13641 /* If we end up in a partially visible line, let's
13642 make it fully visible, except when it's taller
13643 than the window, in which case we can't do much
13644 about it. */
13645 *scroll_step = 1;
13646 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13647 }
13648 else
13649 {
13650 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13651 if (!cursor_row_fully_visible_p (w, 0, 1))
13652 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13653 else
13654 rc = CURSOR_MOVEMENT_SUCCESS;
13655 }
13656 }
13657 else if (scroll_p)
13658 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13659 else if (rc != CURSOR_MOVEMENT_SUCCESS
13660 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13661 {
13662 /* With bidi-reordered rows, there could be more than
13663 one candidate row whose start and end positions
13664 occlude point. We need to let set_cursor_from_row
13665 find the best candidate. */
13666 /* FIXME: Revisit this when glyph ``spilling'' in
13667 continuation lines' rows is implemented for
13668 bidi-reordered rows. */
13669 int rv = 0;
13670
13671 do
13672 {
13673 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13674 && PT <= MATRIX_ROW_END_CHARPOS (row)
13675 && cursor_row_p (w, row))
13676 rv |= set_cursor_from_row (w, row, w->current_matrix,
13677 0, 0, 0, 0);
13678 /* As soon as we've found the first suitable row
13679 whose ends_at_zv_p flag is set, we are done. */
13680 if (rv
13681 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13682 {
13683 rc = CURSOR_MOVEMENT_SUCCESS;
13684 break;
13685 }
13686 ++row;
13687 }
13688 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13689 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13690 || (MATRIX_ROW_START_CHARPOS (row) == PT
13691 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13692 /* If we didn't find any candidate rows, or exited the
13693 loop before all the candidates were examined, signal
13694 to the caller that this method failed. */
13695 if (rc != CURSOR_MOVEMENT_SUCCESS
13696 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13697 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13698 else if (rv)
13699 rc = CURSOR_MOVEMENT_SUCCESS;
13700 }
13701 else
13702 {
13703 do
13704 {
13705 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13706 {
13707 rc = CURSOR_MOVEMENT_SUCCESS;
13708 break;
13709 }
13710 ++row;
13711 }
13712 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13713 && MATRIX_ROW_START_CHARPOS (row) == PT
13714 && cursor_row_p (w, row));
13715 }
13716 }
13717 }
13718
13719 return rc;
13720 }
13721
13722 void
13723 set_vertical_scroll_bar (struct window *w)
13724 {
13725 int start, end, whole;
13726
13727 /* Calculate the start and end positions for the current window.
13728 At some point, it would be nice to choose between scrollbars
13729 which reflect the whole buffer size, with special markers
13730 indicating narrowing, and scrollbars which reflect only the
13731 visible region.
13732
13733 Note that mini-buffers sometimes aren't displaying any text. */
13734 if (!MINI_WINDOW_P (w)
13735 || (w == XWINDOW (minibuf_window)
13736 && NILP (echo_area_buffer[0])))
13737 {
13738 struct buffer *buf = XBUFFER (w->buffer);
13739 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13740 start = marker_position (w->start) - BUF_BEGV (buf);
13741 /* I don't think this is guaranteed to be right. For the
13742 moment, we'll pretend it is. */
13743 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13744
13745 if (end < start)
13746 end = start;
13747 if (whole < (end - start))
13748 whole = end - start;
13749 }
13750 else
13751 start = end = whole = 0;
13752
13753 /* Indicate what this scroll bar ought to be displaying now. */
13754 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13755 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13756 (w, end - start, whole, start);
13757 }
13758
13759
13760 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13761 selected_window is redisplayed.
13762
13763 We can return without actually redisplaying the window if
13764 fonts_changed_p is nonzero. In that case, redisplay_internal will
13765 retry. */
13766
13767 static void
13768 redisplay_window (Lisp_Object window, int just_this_one_p)
13769 {
13770 struct window *w = XWINDOW (window);
13771 struct frame *f = XFRAME (w->frame);
13772 struct buffer *buffer = XBUFFER (w->buffer);
13773 struct buffer *old = current_buffer;
13774 struct text_pos lpoint, opoint, startp;
13775 int update_mode_line;
13776 int tem;
13777 struct it it;
13778 /* Record it now because it's overwritten. */
13779 int current_matrix_up_to_date_p = 0;
13780 int used_current_matrix_p = 0;
13781 /* This is less strict than current_matrix_up_to_date_p.
13782 It indictes that the buffer contents and narrowing are unchanged. */
13783 int buffer_unchanged_p = 0;
13784 int temp_scroll_step = 0;
13785 int count = SPECPDL_INDEX ();
13786 int rc;
13787 int centering_position = -1;
13788 int last_line_misfit = 0;
13789 int beg_unchanged, end_unchanged;
13790
13791 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13792 opoint = lpoint;
13793
13794 /* W must be a leaf window here. */
13795 xassert (!NILP (w->buffer));
13796 #if GLYPH_DEBUG
13797 *w->desired_matrix->method = 0;
13798 #endif
13799
13800 restart:
13801 reconsider_clip_changes (w, buffer);
13802
13803 /* Has the mode line to be updated? */
13804 update_mode_line = (!NILP (w->update_mode_line)
13805 || update_mode_lines
13806 || buffer->clip_changed
13807 || buffer->prevent_redisplay_optimizations_p);
13808
13809 if (MINI_WINDOW_P (w))
13810 {
13811 if (w == XWINDOW (echo_area_window)
13812 && !NILP (echo_area_buffer[0]))
13813 {
13814 if (update_mode_line)
13815 /* We may have to update a tty frame's menu bar or a
13816 tool-bar. Example `M-x C-h C-h C-g'. */
13817 goto finish_menu_bars;
13818 else
13819 /* We've already displayed the echo area glyphs in this window. */
13820 goto finish_scroll_bars;
13821 }
13822 else if ((w != XWINDOW (minibuf_window)
13823 || minibuf_level == 0)
13824 /* When buffer is nonempty, redisplay window normally. */
13825 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13826 /* Quail displays non-mini buffers in minibuffer window.
13827 In that case, redisplay the window normally. */
13828 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13829 {
13830 /* W is a mini-buffer window, but it's not active, so clear
13831 it. */
13832 int yb = window_text_bottom_y (w);
13833 struct glyph_row *row;
13834 int y;
13835
13836 for (y = 0, row = w->desired_matrix->rows;
13837 y < yb;
13838 y += row->height, ++row)
13839 blank_row (w, row, y);
13840 goto finish_scroll_bars;
13841 }
13842
13843 clear_glyph_matrix (w->desired_matrix);
13844 }
13845
13846 /* Otherwise set up data on this window; select its buffer and point
13847 value. */
13848 /* Really select the buffer, for the sake of buffer-local
13849 variables. */
13850 set_buffer_internal_1 (XBUFFER (w->buffer));
13851
13852 current_matrix_up_to_date_p
13853 = (!NILP (w->window_end_valid)
13854 && !current_buffer->clip_changed
13855 && !current_buffer->prevent_redisplay_optimizations_p
13856 && XFASTINT (w->last_modified) >= MODIFF
13857 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13858
13859 /* Run the window-bottom-change-functions
13860 if it is possible that the text on the screen has changed
13861 (either due to modification of the text, or any other reason). */
13862 if (!current_matrix_up_to_date_p
13863 && !NILP (Vwindow_text_change_functions))
13864 {
13865 safe_run_hooks (Qwindow_text_change_functions);
13866 goto restart;
13867 }
13868
13869 beg_unchanged = BEG_UNCHANGED;
13870 end_unchanged = END_UNCHANGED;
13871
13872 SET_TEXT_POS (opoint, PT, PT_BYTE);
13873
13874 specbind (Qinhibit_point_motion_hooks, Qt);
13875
13876 buffer_unchanged_p
13877 = (!NILP (w->window_end_valid)
13878 && !current_buffer->clip_changed
13879 && XFASTINT (w->last_modified) >= MODIFF
13880 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13881
13882 /* When windows_or_buffers_changed is non-zero, we can't rely on
13883 the window end being valid, so set it to nil there. */
13884 if (windows_or_buffers_changed)
13885 {
13886 /* If window starts on a continuation line, maybe adjust the
13887 window start in case the window's width changed. */
13888 if (XMARKER (w->start)->buffer == current_buffer)
13889 compute_window_start_on_continuation_line (w);
13890
13891 w->window_end_valid = Qnil;
13892 }
13893
13894 /* Some sanity checks. */
13895 CHECK_WINDOW_END (w);
13896 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13897 abort ();
13898 if (BYTEPOS (opoint) < CHARPOS (opoint))
13899 abort ();
13900
13901 /* If %c is in mode line, update it if needed. */
13902 if (!NILP (w->column_number_displayed)
13903 /* This alternative quickly identifies a common case
13904 where no change is needed. */
13905 && !(PT == XFASTINT (w->last_point)
13906 && XFASTINT (w->last_modified) >= MODIFF
13907 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13908 && (XFASTINT (w->column_number_displayed)
13909 != (int) current_column ())) /* iftc */
13910 update_mode_line = 1;
13911
13912 /* Count number of windows showing the selected buffer. An indirect
13913 buffer counts as its base buffer. */
13914 if (!just_this_one_p)
13915 {
13916 struct buffer *current_base, *window_base;
13917 current_base = current_buffer;
13918 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13919 if (current_base->base_buffer)
13920 current_base = current_base->base_buffer;
13921 if (window_base->base_buffer)
13922 window_base = window_base->base_buffer;
13923 if (current_base == window_base)
13924 buffer_shared++;
13925 }
13926
13927 /* Point refers normally to the selected window. For any other
13928 window, set up appropriate value. */
13929 if (!EQ (window, selected_window))
13930 {
13931 int new_pt = XMARKER (w->pointm)->charpos;
13932 int new_pt_byte = marker_byte_position (w->pointm);
13933 if (new_pt < BEGV)
13934 {
13935 new_pt = BEGV;
13936 new_pt_byte = BEGV_BYTE;
13937 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13938 }
13939 else if (new_pt > (ZV - 1))
13940 {
13941 new_pt = ZV;
13942 new_pt_byte = ZV_BYTE;
13943 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13944 }
13945
13946 /* We don't use SET_PT so that the point-motion hooks don't run. */
13947 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13948 }
13949
13950 /* If any of the character widths specified in the display table
13951 have changed, invalidate the width run cache. It's true that
13952 this may be a bit late to catch such changes, but the rest of
13953 redisplay goes (non-fatally) haywire when the display table is
13954 changed, so why should we worry about doing any better? */
13955 if (current_buffer->width_run_cache)
13956 {
13957 struct Lisp_Char_Table *disptab = buffer_display_table ();
13958
13959 if (! disptab_matches_widthtab (disptab,
13960 XVECTOR (current_buffer->width_table)))
13961 {
13962 invalidate_region_cache (current_buffer,
13963 current_buffer->width_run_cache,
13964 BEG, Z);
13965 recompute_width_table (current_buffer, disptab);
13966 }
13967 }
13968
13969 /* If window-start is screwed up, choose a new one. */
13970 if (XMARKER (w->start)->buffer != current_buffer)
13971 goto recenter;
13972
13973 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13974
13975 /* If someone specified a new starting point but did not insist,
13976 check whether it can be used. */
13977 if (!NILP (w->optional_new_start)
13978 && CHARPOS (startp) >= BEGV
13979 && CHARPOS (startp) <= ZV)
13980 {
13981 w->optional_new_start = Qnil;
13982 start_display (&it, w, startp);
13983 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13984 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13985 if (IT_CHARPOS (it) == PT)
13986 w->force_start = Qt;
13987 /* IT may overshoot PT if text at PT is invisible. */
13988 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13989 w->force_start = Qt;
13990 }
13991
13992 force_start:
13993
13994 /* Handle case where place to start displaying has been specified,
13995 unless the specified location is outside the accessible range. */
13996 if (!NILP (w->force_start)
13997 || w->frozen_window_start_p)
13998 {
13999 /* We set this later on if we have to adjust point. */
14000 int new_vpos = -1;
14001
14002 w->force_start = Qnil;
14003 w->vscroll = 0;
14004 w->window_end_valid = Qnil;
14005
14006 /* Forget any recorded base line for line number display. */
14007 if (!buffer_unchanged_p)
14008 w->base_line_number = Qnil;
14009
14010 /* Redisplay the mode line. Select the buffer properly for that.
14011 Also, run the hook window-scroll-functions
14012 because we have scrolled. */
14013 /* Note, we do this after clearing force_start because
14014 if there's an error, it is better to forget about force_start
14015 than to get into an infinite loop calling the hook functions
14016 and having them get more errors. */
14017 if (!update_mode_line
14018 || ! NILP (Vwindow_scroll_functions))
14019 {
14020 update_mode_line = 1;
14021 w->update_mode_line = Qt;
14022 startp = run_window_scroll_functions (window, startp);
14023 }
14024
14025 w->last_modified = make_number (0);
14026 w->last_overlay_modified = make_number (0);
14027 if (CHARPOS (startp) < BEGV)
14028 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14029 else if (CHARPOS (startp) > ZV)
14030 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14031
14032 /* Redisplay, then check if cursor has been set during the
14033 redisplay. Give up if new fonts were loaded. */
14034 /* We used to issue a CHECK_MARGINS argument to try_window here,
14035 but this causes scrolling to fail when point begins inside
14036 the scroll margin (bug#148) -- cyd */
14037 if (!try_window (window, startp, 0))
14038 {
14039 w->force_start = Qt;
14040 clear_glyph_matrix (w->desired_matrix);
14041 goto need_larger_matrices;
14042 }
14043
14044 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14045 {
14046 /* If point does not appear, try to move point so it does
14047 appear. The desired matrix has been built above, so we
14048 can use it here. */
14049 new_vpos = window_box_height (w) / 2;
14050 }
14051
14052 if (!cursor_row_fully_visible_p (w, 0, 0))
14053 {
14054 /* Point does appear, but on a line partly visible at end of window.
14055 Move it back to a fully-visible line. */
14056 new_vpos = window_box_height (w);
14057 }
14058
14059 /* If we need to move point for either of the above reasons,
14060 now actually do it. */
14061 if (new_vpos >= 0)
14062 {
14063 struct glyph_row *row;
14064
14065 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14066 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14067 ++row;
14068
14069 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14070 MATRIX_ROW_START_BYTEPOS (row));
14071
14072 if (w != XWINDOW (selected_window))
14073 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14074 else if (current_buffer == old)
14075 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14076
14077 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14078
14079 /* If we are highlighting the region, then we just changed
14080 the region, so redisplay to show it. */
14081 if (!NILP (Vtransient_mark_mode)
14082 && !NILP (current_buffer->mark_active))
14083 {
14084 clear_glyph_matrix (w->desired_matrix);
14085 if (!try_window (window, startp, 0))
14086 goto need_larger_matrices;
14087 }
14088 }
14089
14090 #if GLYPH_DEBUG
14091 debug_method_add (w, "forced window start");
14092 #endif
14093 goto done;
14094 }
14095
14096 /* Handle case where text has not changed, only point, and it has
14097 not moved off the frame, and we are not retrying after hscroll.
14098 (current_matrix_up_to_date_p is nonzero when retrying.) */
14099 if (current_matrix_up_to_date_p
14100 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14101 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14102 {
14103 switch (rc)
14104 {
14105 case CURSOR_MOVEMENT_SUCCESS:
14106 used_current_matrix_p = 1;
14107 goto done;
14108
14109 case CURSOR_MOVEMENT_MUST_SCROLL:
14110 goto try_to_scroll;
14111
14112 default:
14113 abort ();
14114 }
14115 }
14116 /* If current starting point was originally the beginning of a line
14117 but no longer is, find a new starting point. */
14118 else if (!NILP (w->start_at_line_beg)
14119 && !(CHARPOS (startp) <= BEGV
14120 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14121 {
14122 #if GLYPH_DEBUG
14123 debug_method_add (w, "recenter 1");
14124 #endif
14125 goto recenter;
14126 }
14127
14128 /* Try scrolling with try_window_id. Value is > 0 if update has
14129 been done, it is -1 if we know that the same window start will
14130 not work. It is 0 if unsuccessful for some other reason. */
14131 else if ((tem = try_window_id (w)) != 0)
14132 {
14133 #if GLYPH_DEBUG
14134 debug_method_add (w, "try_window_id %d", tem);
14135 #endif
14136
14137 if (fonts_changed_p)
14138 goto need_larger_matrices;
14139 if (tem > 0)
14140 goto done;
14141
14142 /* Otherwise try_window_id has returned -1 which means that we
14143 don't want the alternative below this comment to execute. */
14144 }
14145 else if (CHARPOS (startp) >= BEGV
14146 && CHARPOS (startp) <= ZV
14147 && PT >= CHARPOS (startp)
14148 && (CHARPOS (startp) < ZV
14149 /* Avoid starting at end of buffer. */
14150 || CHARPOS (startp) == BEGV
14151 || (XFASTINT (w->last_modified) >= MODIFF
14152 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14153 {
14154
14155 /* If first window line is a continuation line, and window start
14156 is inside the modified region, but the first change is before
14157 current window start, we must select a new window start.
14158
14159 However, if this is the result of a down-mouse event (e.g. by
14160 extending the mouse-drag-overlay), we don't want to select a
14161 new window start, since that would change the position under
14162 the mouse, resulting in an unwanted mouse-movement rather
14163 than a simple mouse-click. */
14164 if (NILP (w->start_at_line_beg)
14165 && NILP (do_mouse_tracking)
14166 && CHARPOS (startp) > BEGV
14167 && CHARPOS (startp) > BEG + beg_unchanged
14168 && CHARPOS (startp) <= Z - end_unchanged
14169 /* Even if w->start_at_line_beg is nil, a new window may
14170 start at a line_beg, since that's how set_buffer_window
14171 sets it. So, we need to check the return value of
14172 compute_window_start_on_continuation_line. (See also
14173 bug#197). */
14174 && XMARKER (w->start)->buffer == current_buffer
14175 && compute_window_start_on_continuation_line (w))
14176 {
14177 w->force_start = Qt;
14178 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14179 goto force_start;
14180 }
14181
14182 #if GLYPH_DEBUG
14183 debug_method_add (w, "same window start");
14184 #endif
14185
14186 /* Try to redisplay starting at same place as before.
14187 If point has not moved off frame, accept the results. */
14188 if (!current_matrix_up_to_date_p
14189 /* Don't use try_window_reusing_current_matrix in this case
14190 because a window scroll function can have changed the
14191 buffer. */
14192 || !NILP (Vwindow_scroll_functions)
14193 || MINI_WINDOW_P (w)
14194 || !(used_current_matrix_p
14195 = try_window_reusing_current_matrix (w)))
14196 {
14197 IF_DEBUG (debug_method_add (w, "1"));
14198 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14199 /* -1 means we need to scroll.
14200 0 means we need new matrices, but fonts_changed_p
14201 is set in that case, so we will detect it below. */
14202 goto try_to_scroll;
14203 }
14204
14205 if (fonts_changed_p)
14206 goto need_larger_matrices;
14207
14208 if (w->cursor.vpos >= 0)
14209 {
14210 if (!just_this_one_p
14211 || current_buffer->clip_changed
14212 || BEG_UNCHANGED < CHARPOS (startp))
14213 /* Forget any recorded base line for line number display. */
14214 w->base_line_number = Qnil;
14215
14216 if (!cursor_row_fully_visible_p (w, 1, 0))
14217 {
14218 clear_glyph_matrix (w->desired_matrix);
14219 last_line_misfit = 1;
14220 }
14221 /* Drop through and scroll. */
14222 else
14223 goto done;
14224 }
14225 else
14226 clear_glyph_matrix (w->desired_matrix);
14227 }
14228
14229 try_to_scroll:
14230
14231 w->last_modified = make_number (0);
14232 w->last_overlay_modified = make_number (0);
14233
14234 /* Redisplay the mode line. Select the buffer properly for that. */
14235 if (!update_mode_line)
14236 {
14237 update_mode_line = 1;
14238 w->update_mode_line = Qt;
14239 }
14240
14241 /* Try to scroll by specified few lines. */
14242 if ((scroll_conservatively
14243 || scroll_step
14244 || temp_scroll_step
14245 || NUMBERP (current_buffer->scroll_up_aggressively)
14246 || NUMBERP (current_buffer->scroll_down_aggressively))
14247 && !current_buffer->clip_changed
14248 && CHARPOS (startp) >= BEGV
14249 && CHARPOS (startp) <= ZV)
14250 {
14251 /* The function returns -1 if new fonts were loaded, 1 if
14252 successful, 0 if not successful. */
14253 int rc = try_scrolling (window, just_this_one_p,
14254 scroll_conservatively,
14255 scroll_step,
14256 temp_scroll_step, last_line_misfit);
14257 switch (rc)
14258 {
14259 case SCROLLING_SUCCESS:
14260 goto done;
14261
14262 case SCROLLING_NEED_LARGER_MATRICES:
14263 goto need_larger_matrices;
14264
14265 case SCROLLING_FAILED:
14266 break;
14267
14268 default:
14269 abort ();
14270 }
14271 }
14272
14273 /* Finally, just choose place to start which centers point */
14274
14275 recenter:
14276 if (centering_position < 0)
14277 centering_position = window_box_height (w) / 2;
14278
14279 #if GLYPH_DEBUG
14280 debug_method_add (w, "recenter");
14281 #endif
14282
14283 /* w->vscroll = 0; */
14284
14285 /* Forget any previously recorded base line for line number display. */
14286 if (!buffer_unchanged_p)
14287 w->base_line_number = Qnil;
14288
14289 /* Move backward half the height of the window. */
14290 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14291 it.current_y = it.last_visible_y;
14292 move_it_vertically_backward (&it, centering_position);
14293 xassert (IT_CHARPOS (it) >= BEGV);
14294
14295 /* The function move_it_vertically_backward may move over more
14296 than the specified y-distance. If it->w is small, e.g. a
14297 mini-buffer window, we may end up in front of the window's
14298 display area. Start displaying at the start of the line
14299 containing PT in this case. */
14300 if (it.current_y <= 0)
14301 {
14302 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14303 move_it_vertically_backward (&it, 0);
14304 it.current_y = 0;
14305 }
14306
14307 it.current_x = it.hpos = 0;
14308
14309 /* Set startp here explicitly in case that helps avoid an infinite loop
14310 in case the window-scroll-functions functions get errors. */
14311 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14312
14313 /* Run scroll hooks. */
14314 startp = run_window_scroll_functions (window, it.current.pos);
14315
14316 /* Redisplay the window. */
14317 if (!current_matrix_up_to_date_p
14318 || windows_or_buffers_changed
14319 || cursor_type_changed
14320 /* Don't use try_window_reusing_current_matrix in this case
14321 because it can have changed the buffer. */
14322 || !NILP (Vwindow_scroll_functions)
14323 || !just_this_one_p
14324 || MINI_WINDOW_P (w)
14325 || !(used_current_matrix_p
14326 = try_window_reusing_current_matrix (w)))
14327 try_window (window, startp, 0);
14328
14329 /* If new fonts have been loaded (due to fontsets), give up. We
14330 have to start a new redisplay since we need to re-adjust glyph
14331 matrices. */
14332 if (fonts_changed_p)
14333 goto need_larger_matrices;
14334
14335 /* If cursor did not appear assume that the middle of the window is
14336 in the first line of the window. Do it again with the next line.
14337 (Imagine a window of height 100, displaying two lines of height
14338 60. Moving back 50 from it->last_visible_y will end in the first
14339 line.) */
14340 if (w->cursor.vpos < 0)
14341 {
14342 if (!NILP (w->window_end_valid)
14343 && PT >= Z - XFASTINT (w->window_end_pos))
14344 {
14345 clear_glyph_matrix (w->desired_matrix);
14346 move_it_by_lines (&it, 1, 0);
14347 try_window (window, it.current.pos, 0);
14348 }
14349 else if (PT < IT_CHARPOS (it))
14350 {
14351 clear_glyph_matrix (w->desired_matrix);
14352 move_it_by_lines (&it, -1, 0);
14353 try_window (window, it.current.pos, 0);
14354 }
14355 else
14356 {
14357 /* Not much we can do about it. */
14358 }
14359 }
14360
14361 /* Consider the following case: Window starts at BEGV, there is
14362 invisible, intangible text at BEGV, so that display starts at
14363 some point START > BEGV. It can happen that we are called with
14364 PT somewhere between BEGV and START. Try to handle that case. */
14365 if (w->cursor.vpos < 0)
14366 {
14367 struct glyph_row *row = w->current_matrix->rows;
14368 if (row->mode_line_p)
14369 ++row;
14370 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14371 }
14372
14373 if (!cursor_row_fully_visible_p (w, 0, 0))
14374 {
14375 /* If vscroll is enabled, disable it and try again. */
14376 if (w->vscroll)
14377 {
14378 w->vscroll = 0;
14379 clear_glyph_matrix (w->desired_matrix);
14380 goto recenter;
14381 }
14382
14383 /* If centering point failed to make the whole line visible,
14384 put point at the top instead. That has to make the whole line
14385 visible, if it can be done. */
14386 if (centering_position == 0)
14387 goto done;
14388
14389 clear_glyph_matrix (w->desired_matrix);
14390 centering_position = 0;
14391 goto recenter;
14392 }
14393
14394 done:
14395
14396 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14397 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14398 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14399 ? Qt : Qnil);
14400
14401 /* Display the mode line, if we must. */
14402 if ((update_mode_line
14403 /* If window not full width, must redo its mode line
14404 if (a) the window to its side is being redone and
14405 (b) we do a frame-based redisplay. This is a consequence
14406 of how inverted lines are drawn in frame-based redisplay. */
14407 || (!just_this_one_p
14408 && !FRAME_WINDOW_P (f)
14409 && !WINDOW_FULL_WIDTH_P (w))
14410 /* Line number to display. */
14411 || INTEGERP (w->base_line_pos)
14412 /* Column number is displayed and different from the one displayed. */
14413 || (!NILP (w->column_number_displayed)
14414 && (XFASTINT (w->column_number_displayed)
14415 != (int) current_column ()))) /* iftc */
14416 /* This means that the window has a mode line. */
14417 && (WINDOW_WANTS_MODELINE_P (w)
14418 || WINDOW_WANTS_HEADER_LINE_P (w)))
14419 {
14420 display_mode_lines (w);
14421
14422 /* If mode line height has changed, arrange for a thorough
14423 immediate redisplay using the correct mode line height. */
14424 if (WINDOW_WANTS_MODELINE_P (w)
14425 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14426 {
14427 fonts_changed_p = 1;
14428 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14429 = DESIRED_MODE_LINE_HEIGHT (w);
14430 }
14431
14432 /* If header line height has changed, arrange for a thorough
14433 immediate redisplay using the correct header line height. */
14434 if (WINDOW_WANTS_HEADER_LINE_P (w)
14435 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14436 {
14437 fonts_changed_p = 1;
14438 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14439 = DESIRED_HEADER_LINE_HEIGHT (w);
14440 }
14441
14442 if (fonts_changed_p)
14443 goto need_larger_matrices;
14444 }
14445
14446 if (!line_number_displayed
14447 && !BUFFERP (w->base_line_pos))
14448 {
14449 w->base_line_pos = Qnil;
14450 w->base_line_number = Qnil;
14451 }
14452
14453 finish_menu_bars:
14454
14455 /* When we reach a frame's selected window, redo the frame's menu bar. */
14456 if (update_mode_line
14457 && EQ (FRAME_SELECTED_WINDOW (f), window))
14458 {
14459 int redisplay_menu_p = 0;
14460 int redisplay_tool_bar_p = 0;
14461
14462 if (FRAME_WINDOW_P (f))
14463 {
14464 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14465 || defined (HAVE_NS) || defined (USE_GTK)
14466 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14467 #else
14468 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14469 #endif
14470 }
14471 else
14472 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14473
14474 if (redisplay_menu_p)
14475 display_menu_bar (w);
14476
14477 #ifdef HAVE_WINDOW_SYSTEM
14478 if (FRAME_WINDOW_P (f))
14479 {
14480 #if defined (USE_GTK) || defined (HAVE_NS)
14481 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14482 #else
14483 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14484 && (FRAME_TOOL_BAR_LINES (f) > 0
14485 || !NILP (Vauto_resize_tool_bars));
14486 #endif
14487
14488 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14489 {
14490 extern int ignore_mouse_drag_p;
14491 ignore_mouse_drag_p = 1;
14492 }
14493 }
14494 #endif
14495 }
14496
14497 #ifdef HAVE_WINDOW_SYSTEM
14498 if (FRAME_WINDOW_P (f)
14499 && update_window_fringes (w, (just_this_one_p
14500 || (!used_current_matrix_p && !overlay_arrow_seen)
14501 || w->pseudo_window_p)))
14502 {
14503 update_begin (f);
14504 BLOCK_INPUT;
14505 if (draw_window_fringes (w, 1))
14506 x_draw_vertical_border (w);
14507 UNBLOCK_INPUT;
14508 update_end (f);
14509 }
14510 #endif /* HAVE_WINDOW_SYSTEM */
14511
14512 /* We go to this label, with fonts_changed_p nonzero,
14513 if it is necessary to try again using larger glyph matrices.
14514 We have to redeem the scroll bar even in this case,
14515 because the loop in redisplay_internal expects that. */
14516 need_larger_matrices:
14517 ;
14518 finish_scroll_bars:
14519
14520 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14521 {
14522 /* Set the thumb's position and size. */
14523 set_vertical_scroll_bar (w);
14524
14525 /* Note that we actually used the scroll bar attached to this
14526 window, so it shouldn't be deleted at the end of redisplay. */
14527 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14528 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14529 }
14530
14531 /* Restore current_buffer and value of point in it. The window
14532 update may have changed the buffer, so first make sure `opoint'
14533 is still valid (Bug#6177). */
14534 if (CHARPOS (opoint) < BEGV)
14535 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14536 else if (CHARPOS (opoint) > ZV)
14537 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14538 else
14539 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14540
14541 set_buffer_internal_1 (old);
14542 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14543 shorter. This can be caused by log truncation in *Messages*. */
14544 if (CHARPOS (lpoint) <= ZV)
14545 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14546
14547 unbind_to (count, Qnil);
14548 }
14549
14550
14551 /* Build the complete desired matrix of WINDOW with a window start
14552 buffer position POS.
14553
14554 Value is 1 if successful. It is zero if fonts were loaded during
14555 redisplay which makes re-adjusting glyph matrices necessary, and -1
14556 if point would appear in the scroll margins.
14557 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14558 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14559 set in FLAGS.) */
14560
14561 int
14562 try_window (Lisp_Object window, struct text_pos pos, int flags)
14563 {
14564 struct window *w = XWINDOW (window);
14565 struct it it;
14566 struct glyph_row *last_text_row = NULL;
14567 struct frame *f = XFRAME (w->frame);
14568
14569 /* Make POS the new window start. */
14570 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14571
14572 /* Mark cursor position as unknown. No overlay arrow seen. */
14573 w->cursor.vpos = -1;
14574 overlay_arrow_seen = 0;
14575
14576 /* Initialize iterator and info to start at POS. */
14577 start_display (&it, w, pos);
14578
14579 /* Display all lines of W. */
14580 while (it.current_y < it.last_visible_y)
14581 {
14582 if (display_line (&it))
14583 last_text_row = it.glyph_row - 1;
14584 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14585 return 0;
14586 }
14587
14588 /* Don't let the cursor end in the scroll margins. */
14589 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14590 && !MINI_WINDOW_P (w))
14591 {
14592 int this_scroll_margin;
14593
14594 if (scroll_margin > 0)
14595 {
14596 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14597 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14598 }
14599 else
14600 this_scroll_margin = 0;
14601
14602 if ((w->cursor.y >= 0 /* not vscrolled */
14603 && w->cursor.y < this_scroll_margin
14604 && CHARPOS (pos) > BEGV
14605 && IT_CHARPOS (it) < ZV)
14606 /* rms: considering make_cursor_line_fully_visible_p here
14607 seems to give wrong results. We don't want to recenter
14608 when the last line is partly visible, we want to allow
14609 that case to be handled in the usual way. */
14610 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14611 {
14612 w->cursor.vpos = -1;
14613 clear_glyph_matrix (w->desired_matrix);
14614 return -1;
14615 }
14616 }
14617
14618 /* If bottom moved off end of frame, change mode line percentage. */
14619 if (XFASTINT (w->window_end_pos) <= 0
14620 && Z != IT_CHARPOS (it))
14621 w->update_mode_line = Qt;
14622
14623 /* Set window_end_pos to the offset of the last character displayed
14624 on the window from the end of current_buffer. Set
14625 window_end_vpos to its row number. */
14626 if (last_text_row)
14627 {
14628 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14629 w->window_end_bytepos
14630 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14631 w->window_end_pos
14632 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14633 w->window_end_vpos
14634 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14635 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14636 ->displays_text_p);
14637 }
14638 else
14639 {
14640 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14641 w->window_end_pos = make_number (Z - ZV);
14642 w->window_end_vpos = make_number (0);
14643 }
14644
14645 /* But that is not valid info until redisplay finishes. */
14646 w->window_end_valid = Qnil;
14647 return 1;
14648 }
14649
14650
14651 \f
14652 /************************************************************************
14653 Window redisplay reusing current matrix when buffer has not changed
14654 ************************************************************************/
14655
14656 /* Try redisplay of window W showing an unchanged buffer with a
14657 different window start than the last time it was displayed by
14658 reusing its current matrix. Value is non-zero if successful.
14659 W->start is the new window start. */
14660
14661 static int
14662 try_window_reusing_current_matrix (struct window *w)
14663 {
14664 struct frame *f = XFRAME (w->frame);
14665 struct glyph_row *row, *bottom_row;
14666 struct it it;
14667 struct run run;
14668 struct text_pos start, new_start;
14669 int nrows_scrolled, i;
14670 struct glyph_row *last_text_row;
14671 struct glyph_row *last_reused_text_row;
14672 struct glyph_row *start_row;
14673 int start_vpos, min_y, max_y;
14674
14675 #if GLYPH_DEBUG
14676 if (inhibit_try_window_reusing)
14677 return 0;
14678 #endif
14679
14680 if (/* This function doesn't handle terminal frames. */
14681 !FRAME_WINDOW_P (f)
14682 /* Don't try to reuse the display if windows have been split
14683 or such. */
14684 || windows_or_buffers_changed
14685 || cursor_type_changed)
14686 return 0;
14687
14688 /* Can't do this if region may have changed. */
14689 if ((!NILP (Vtransient_mark_mode)
14690 && !NILP (current_buffer->mark_active))
14691 || !NILP (w->region_showing)
14692 || !NILP (Vshow_trailing_whitespace))
14693 return 0;
14694
14695 /* If top-line visibility has changed, give up. */
14696 if (WINDOW_WANTS_HEADER_LINE_P (w)
14697 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14698 return 0;
14699
14700 /* Give up if old or new display is scrolled vertically. We could
14701 make this function handle this, but right now it doesn't. */
14702 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14703 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14704 return 0;
14705
14706 /* The variable new_start now holds the new window start. The old
14707 start `start' can be determined from the current matrix. */
14708 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14709 start = start_row->minpos;
14710 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14711
14712 /* Clear the desired matrix for the display below. */
14713 clear_glyph_matrix (w->desired_matrix);
14714
14715 if (CHARPOS (new_start) <= CHARPOS (start))
14716 {
14717 int first_row_y;
14718
14719 /* Don't use this method if the display starts with an ellipsis
14720 displayed for invisible text. It's not easy to handle that case
14721 below, and it's certainly not worth the effort since this is
14722 not a frequent case. */
14723 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14724 return 0;
14725
14726 IF_DEBUG (debug_method_add (w, "twu1"));
14727
14728 /* Display up to a row that can be reused. The variable
14729 last_text_row is set to the last row displayed that displays
14730 text. Note that it.vpos == 0 if or if not there is a
14731 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14732 start_display (&it, w, new_start);
14733 first_row_y = it.current_y;
14734 w->cursor.vpos = -1;
14735 last_text_row = last_reused_text_row = NULL;
14736
14737 while (it.current_y < it.last_visible_y
14738 && !fonts_changed_p)
14739 {
14740 /* If we have reached into the characters in the START row,
14741 that means the line boundaries have changed. So we
14742 can't start copying with the row START. Maybe it will
14743 work to start copying with the following row. */
14744 while (IT_CHARPOS (it) > CHARPOS (start))
14745 {
14746 /* Advance to the next row as the "start". */
14747 start_row++;
14748 start = start_row->minpos;
14749 /* If there are no more rows to try, or just one, give up. */
14750 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14751 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14752 || CHARPOS (start) == ZV)
14753 {
14754 clear_glyph_matrix (w->desired_matrix);
14755 return 0;
14756 }
14757
14758 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14759 }
14760 /* If we have reached alignment,
14761 we can copy the rest of the rows. */
14762 if (IT_CHARPOS (it) == CHARPOS (start))
14763 break;
14764
14765 if (display_line (&it))
14766 last_text_row = it.glyph_row - 1;
14767 }
14768
14769 /* A value of current_y < last_visible_y means that we stopped
14770 at the previous window start, which in turn means that we
14771 have at least one reusable row. */
14772 if (it.current_y < it.last_visible_y)
14773 {
14774 /* IT.vpos always starts from 0; it counts text lines. */
14775 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14776
14777 /* Find PT if not already found in the lines displayed. */
14778 if (w->cursor.vpos < 0)
14779 {
14780 int dy = it.current_y - start_row->y;
14781
14782 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14783 row = row_containing_pos (w, PT, row, NULL, dy);
14784 if (row)
14785 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14786 dy, nrows_scrolled);
14787 else
14788 {
14789 clear_glyph_matrix (w->desired_matrix);
14790 return 0;
14791 }
14792 }
14793
14794 /* Scroll the display. Do it before the current matrix is
14795 changed. The problem here is that update has not yet
14796 run, i.e. part of the current matrix is not up to date.
14797 scroll_run_hook will clear the cursor, and use the
14798 current matrix to get the height of the row the cursor is
14799 in. */
14800 run.current_y = start_row->y;
14801 run.desired_y = it.current_y;
14802 run.height = it.last_visible_y - it.current_y;
14803
14804 if (run.height > 0 && run.current_y != run.desired_y)
14805 {
14806 update_begin (f);
14807 FRAME_RIF (f)->update_window_begin_hook (w);
14808 FRAME_RIF (f)->clear_window_mouse_face (w);
14809 FRAME_RIF (f)->scroll_run_hook (w, &run);
14810 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14811 update_end (f);
14812 }
14813
14814 /* Shift current matrix down by nrows_scrolled lines. */
14815 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14816 rotate_matrix (w->current_matrix,
14817 start_vpos,
14818 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14819 nrows_scrolled);
14820
14821 /* Disable lines that must be updated. */
14822 for (i = 0; i < nrows_scrolled; ++i)
14823 (start_row + i)->enabled_p = 0;
14824
14825 /* Re-compute Y positions. */
14826 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14827 max_y = it.last_visible_y;
14828 for (row = start_row + nrows_scrolled;
14829 row < bottom_row;
14830 ++row)
14831 {
14832 row->y = it.current_y;
14833 row->visible_height = row->height;
14834
14835 if (row->y < min_y)
14836 row->visible_height -= min_y - row->y;
14837 if (row->y + row->height > max_y)
14838 row->visible_height -= row->y + row->height - max_y;
14839 row->redraw_fringe_bitmaps_p = 1;
14840
14841 it.current_y += row->height;
14842
14843 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14844 last_reused_text_row = row;
14845 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14846 break;
14847 }
14848
14849 /* Disable lines in the current matrix which are now
14850 below the window. */
14851 for (++row; row < bottom_row; ++row)
14852 row->enabled_p = row->mode_line_p = 0;
14853 }
14854
14855 /* Update window_end_pos etc.; last_reused_text_row is the last
14856 reused row from the current matrix containing text, if any.
14857 The value of last_text_row is the last displayed line
14858 containing text. */
14859 if (last_reused_text_row)
14860 {
14861 w->window_end_bytepos
14862 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14863 w->window_end_pos
14864 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14865 w->window_end_vpos
14866 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14867 w->current_matrix));
14868 }
14869 else if (last_text_row)
14870 {
14871 w->window_end_bytepos
14872 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14873 w->window_end_pos
14874 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14875 w->window_end_vpos
14876 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14877 }
14878 else
14879 {
14880 /* This window must be completely empty. */
14881 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14882 w->window_end_pos = make_number (Z - ZV);
14883 w->window_end_vpos = make_number (0);
14884 }
14885 w->window_end_valid = Qnil;
14886
14887 /* Update hint: don't try scrolling again in update_window. */
14888 w->desired_matrix->no_scrolling_p = 1;
14889
14890 #if GLYPH_DEBUG
14891 debug_method_add (w, "try_window_reusing_current_matrix 1");
14892 #endif
14893 return 1;
14894 }
14895 else if (CHARPOS (new_start) > CHARPOS (start))
14896 {
14897 struct glyph_row *pt_row, *row;
14898 struct glyph_row *first_reusable_row;
14899 struct glyph_row *first_row_to_display;
14900 int dy;
14901 int yb = window_text_bottom_y (w);
14902
14903 /* Find the row starting at new_start, if there is one. Don't
14904 reuse a partially visible line at the end. */
14905 first_reusable_row = start_row;
14906 while (first_reusable_row->enabled_p
14907 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14908 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14909 < CHARPOS (new_start)))
14910 ++first_reusable_row;
14911
14912 /* Give up if there is no row to reuse. */
14913 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14914 || !first_reusable_row->enabled_p
14915 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14916 != CHARPOS (new_start)))
14917 return 0;
14918
14919 /* We can reuse fully visible rows beginning with
14920 first_reusable_row to the end of the window. Set
14921 first_row_to_display to the first row that cannot be reused.
14922 Set pt_row to the row containing point, if there is any. */
14923 pt_row = NULL;
14924 for (first_row_to_display = first_reusable_row;
14925 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14926 ++first_row_to_display)
14927 {
14928 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14929 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14930 pt_row = first_row_to_display;
14931 }
14932
14933 /* Start displaying at the start of first_row_to_display. */
14934 xassert (first_row_to_display->y < yb);
14935 init_to_row_start (&it, w, first_row_to_display);
14936
14937 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14938 - start_vpos);
14939 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14940 - nrows_scrolled);
14941 it.current_y = (first_row_to_display->y - first_reusable_row->y
14942 + WINDOW_HEADER_LINE_HEIGHT (w));
14943
14944 /* Display lines beginning with first_row_to_display in the
14945 desired matrix. Set last_text_row to the last row displayed
14946 that displays text. */
14947 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14948 if (pt_row == NULL)
14949 w->cursor.vpos = -1;
14950 last_text_row = NULL;
14951 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14952 if (display_line (&it))
14953 last_text_row = it.glyph_row - 1;
14954
14955 /* If point is in a reused row, adjust y and vpos of the cursor
14956 position. */
14957 if (pt_row)
14958 {
14959 w->cursor.vpos -= nrows_scrolled;
14960 w->cursor.y -= first_reusable_row->y - start_row->y;
14961 }
14962
14963 /* Give up if point isn't in a row displayed or reused. (This
14964 also handles the case where w->cursor.vpos < nrows_scrolled
14965 after the calls to display_line, which can happen with scroll
14966 margins. See bug#1295.) */
14967 if (w->cursor.vpos < 0)
14968 {
14969 clear_glyph_matrix (w->desired_matrix);
14970 return 0;
14971 }
14972
14973 /* Scroll the display. */
14974 run.current_y = first_reusable_row->y;
14975 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14976 run.height = it.last_visible_y - run.current_y;
14977 dy = run.current_y - run.desired_y;
14978
14979 if (run.height)
14980 {
14981 update_begin (f);
14982 FRAME_RIF (f)->update_window_begin_hook (w);
14983 FRAME_RIF (f)->clear_window_mouse_face (w);
14984 FRAME_RIF (f)->scroll_run_hook (w, &run);
14985 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14986 update_end (f);
14987 }
14988
14989 /* Adjust Y positions of reused rows. */
14990 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14991 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14992 max_y = it.last_visible_y;
14993 for (row = first_reusable_row; row < first_row_to_display; ++row)
14994 {
14995 row->y -= dy;
14996 row->visible_height = row->height;
14997 if (row->y < min_y)
14998 row->visible_height -= min_y - row->y;
14999 if (row->y + row->height > max_y)
15000 row->visible_height -= row->y + row->height - max_y;
15001 row->redraw_fringe_bitmaps_p = 1;
15002 }
15003
15004 /* Scroll the current matrix. */
15005 xassert (nrows_scrolled > 0);
15006 rotate_matrix (w->current_matrix,
15007 start_vpos,
15008 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15009 -nrows_scrolled);
15010
15011 /* Disable rows not reused. */
15012 for (row -= nrows_scrolled; row < bottom_row; ++row)
15013 row->enabled_p = 0;
15014
15015 /* Point may have moved to a different line, so we cannot assume that
15016 the previous cursor position is valid; locate the correct row. */
15017 if (pt_row)
15018 {
15019 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15020 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15021 row++)
15022 {
15023 w->cursor.vpos++;
15024 w->cursor.y = row->y;
15025 }
15026 if (row < bottom_row)
15027 {
15028 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15029 struct glyph *end = glyph + row->used[TEXT_AREA];
15030
15031 /* Can't use this optimization with bidi-reordered glyph
15032 rows, unless cursor is already at point. */
15033 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15034 {
15035 if (!(w->cursor.hpos >= 0
15036 && w->cursor.hpos < row->used[TEXT_AREA]
15037 && BUFFERP (glyph->object)
15038 && glyph->charpos == PT))
15039 return 0;
15040 }
15041 else
15042 for (; glyph < end
15043 && (!BUFFERP (glyph->object)
15044 || glyph->charpos < PT);
15045 glyph++)
15046 {
15047 w->cursor.hpos++;
15048 w->cursor.x += glyph->pixel_width;
15049 }
15050 }
15051 }
15052
15053 /* Adjust window end. A null value of last_text_row means that
15054 the window end is in reused rows which in turn means that
15055 only its vpos can have changed. */
15056 if (last_text_row)
15057 {
15058 w->window_end_bytepos
15059 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15060 w->window_end_pos
15061 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15062 w->window_end_vpos
15063 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15064 }
15065 else
15066 {
15067 w->window_end_vpos
15068 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15069 }
15070
15071 w->window_end_valid = Qnil;
15072 w->desired_matrix->no_scrolling_p = 1;
15073
15074 #if GLYPH_DEBUG
15075 debug_method_add (w, "try_window_reusing_current_matrix 2");
15076 #endif
15077 return 1;
15078 }
15079
15080 return 0;
15081 }
15082
15083
15084 \f
15085 /************************************************************************
15086 Window redisplay reusing current matrix when buffer has changed
15087 ************************************************************************/
15088
15089 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15090 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15091 int *, int *);
15092 static struct glyph_row *
15093 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15094 struct glyph_row *);
15095
15096
15097 /* Return the last row in MATRIX displaying text. If row START is
15098 non-null, start searching with that row. IT gives the dimensions
15099 of the display. Value is null if matrix is empty; otherwise it is
15100 a pointer to the row found. */
15101
15102 static struct glyph_row *
15103 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15104 struct glyph_row *start)
15105 {
15106 struct glyph_row *row, *row_found;
15107
15108 /* Set row_found to the last row in IT->w's current matrix
15109 displaying text. The loop looks funny but think of partially
15110 visible lines. */
15111 row_found = NULL;
15112 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15113 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15114 {
15115 xassert (row->enabled_p);
15116 row_found = row;
15117 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15118 break;
15119 ++row;
15120 }
15121
15122 return row_found;
15123 }
15124
15125
15126 /* Return the last row in the current matrix of W that is not affected
15127 by changes at the start of current_buffer that occurred since W's
15128 current matrix was built. Value is null if no such row exists.
15129
15130 BEG_UNCHANGED us the number of characters unchanged at the start of
15131 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15132 first changed character in current_buffer. Characters at positions <
15133 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15134 when the current matrix was built. */
15135
15136 static struct glyph_row *
15137 find_last_unchanged_at_beg_row (struct window *w)
15138 {
15139 int first_changed_pos = BEG + BEG_UNCHANGED;
15140 struct glyph_row *row;
15141 struct glyph_row *row_found = NULL;
15142 int yb = window_text_bottom_y (w);
15143
15144 /* Find the last row displaying unchanged text. */
15145 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15146 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15147 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15148 ++row)
15149 {
15150 if (/* If row ends before first_changed_pos, it is unchanged,
15151 except in some case. */
15152 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15153 /* When row ends in ZV and we write at ZV it is not
15154 unchanged. */
15155 && !row->ends_at_zv_p
15156 /* When first_changed_pos is the end of a continued line,
15157 row is not unchanged because it may be no longer
15158 continued. */
15159 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15160 && (row->continued_p
15161 || row->exact_window_width_line_p)))
15162 row_found = row;
15163
15164 /* Stop if last visible row. */
15165 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15166 break;
15167 }
15168
15169 return row_found;
15170 }
15171
15172
15173 /* Find the first glyph row in the current matrix of W that is not
15174 affected by changes at the end of current_buffer since the
15175 time W's current matrix was built.
15176
15177 Return in *DELTA the number of chars by which buffer positions in
15178 unchanged text at the end of current_buffer must be adjusted.
15179
15180 Return in *DELTA_BYTES the corresponding number of bytes.
15181
15182 Value is null if no such row exists, i.e. all rows are affected by
15183 changes. */
15184
15185 static struct glyph_row *
15186 find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
15187 {
15188 struct glyph_row *row;
15189 struct glyph_row *row_found = NULL;
15190
15191 *delta = *delta_bytes = 0;
15192
15193 /* Display must not have been paused, otherwise the current matrix
15194 is not up to date. */
15195 eassert (!NILP (w->window_end_valid));
15196
15197 /* A value of window_end_pos >= END_UNCHANGED means that the window
15198 end is in the range of changed text. If so, there is no
15199 unchanged row at the end of W's current matrix. */
15200 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15201 return NULL;
15202
15203 /* Set row to the last row in W's current matrix displaying text. */
15204 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15205
15206 /* If matrix is entirely empty, no unchanged row exists. */
15207 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15208 {
15209 /* The value of row is the last glyph row in the matrix having a
15210 meaningful buffer position in it. The end position of row
15211 corresponds to window_end_pos. This allows us to translate
15212 buffer positions in the current matrix to current buffer
15213 positions for characters not in changed text. */
15214 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15215 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15216 int last_unchanged_pos, last_unchanged_pos_old;
15217 struct glyph_row *first_text_row
15218 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15219
15220 *delta = Z - Z_old;
15221 *delta_bytes = Z_BYTE - Z_BYTE_old;
15222
15223 /* Set last_unchanged_pos to the buffer position of the last
15224 character in the buffer that has not been changed. Z is the
15225 index + 1 of the last character in current_buffer, i.e. by
15226 subtracting END_UNCHANGED we get the index of the last
15227 unchanged character, and we have to add BEG to get its buffer
15228 position. */
15229 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15230 last_unchanged_pos_old = last_unchanged_pos - *delta;
15231
15232 /* Search backward from ROW for a row displaying a line that
15233 starts at a minimum position >= last_unchanged_pos_old. */
15234 for (; row > first_text_row; --row)
15235 {
15236 /* This used to abort, but it can happen.
15237 It is ok to just stop the search instead here. KFS. */
15238 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15239 break;
15240
15241 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15242 row_found = row;
15243 }
15244 }
15245
15246 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15247
15248 return row_found;
15249 }
15250
15251
15252 /* Make sure that glyph rows in the current matrix of window W
15253 reference the same glyph memory as corresponding rows in the
15254 frame's frame matrix. This function is called after scrolling W's
15255 current matrix on a terminal frame in try_window_id and
15256 try_window_reusing_current_matrix. */
15257
15258 static void
15259 sync_frame_with_window_matrix_rows (struct window *w)
15260 {
15261 struct frame *f = XFRAME (w->frame);
15262 struct glyph_row *window_row, *window_row_end, *frame_row;
15263
15264 /* Preconditions: W must be a leaf window and full-width. Its frame
15265 must have a frame matrix. */
15266 xassert (NILP (w->hchild) && NILP (w->vchild));
15267 xassert (WINDOW_FULL_WIDTH_P (w));
15268 xassert (!FRAME_WINDOW_P (f));
15269
15270 /* If W is a full-width window, glyph pointers in W's current matrix
15271 have, by definition, to be the same as glyph pointers in the
15272 corresponding frame matrix. Note that frame matrices have no
15273 marginal areas (see build_frame_matrix). */
15274 window_row = w->current_matrix->rows;
15275 window_row_end = window_row + w->current_matrix->nrows;
15276 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15277 while (window_row < window_row_end)
15278 {
15279 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15280 struct glyph *end = window_row->glyphs[LAST_AREA];
15281
15282 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15283 frame_row->glyphs[TEXT_AREA] = start;
15284 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15285 frame_row->glyphs[LAST_AREA] = end;
15286
15287 /* Disable frame rows whose corresponding window rows have
15288 been disabled in try_window_id. */
15289 if (!window_row->enabled_p)
15290 frame_row->enabled_p = 0;
15291
15292 ++window_row, ++frame_row;
15293 }
15294 }
15295
15296
15297 /* Find the glyph row in window W containing CHARPOS. Consider all
15298 rows between START and END (not inclusive). END null means search
15299 all rows to the end of the display area of W. Value is the row
15300 containing CHARPOS or null. */
15301
15302 struct glyph_row *
15303 row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
15304 struct glyph_row *end, int dy)
15305 {
15306 struct glyph_row *row = start;
15307 struct glyph_row *best_row = NULL;
15308 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15309 int last_y;
15310
15311 /* If we happen to start on a header-line, skip that. */
15312 if (row->mode_line_p)
15313 ++row;
15314
15315 if ((end && row >= end) || !row->enabled_p)
15316 return NULL;
15317
15318 last_y = window_text_bottom_y (w) - dy;
15319
15320 while (1)
15321 {
15322 /* Give up if we have gone too far. */
15323 if (end && row >= end)
15324 return NULL;
15325 /* This formerly returned if they were equal.
15326 I think that both quantities are of a "last plus one" type;
15327 if so, when they are equal, the row is within the screen. -- rms. */
15328 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15329 return NULL;
15330
15331 /* If it is in this row, return this row. */
15332 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15333 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15334 /* The end position of a row equals the start
15335 position of the next row. If CHARPOS is there, we
15336 would rather display it in the next line, except
15337 when this line ends in ZV. */
15338 && !row->ends_at_zv_p
15339 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15340 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15341 {
15342 struct glyph *g;
15343
15344 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15345 return row;
15346 /* In bidi-reordered rows, there could be several rows
15347 occluding point. We need to find the one which fits
15348 CHARPOS the best. */
15349 for (g = row->glyphs[TEXT_AREA];
15350 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15351 g++)
15352 {
15353 if (!STRINGP (g->object))
15354 {
15355 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15356 {
15357 mindif = eabs (g->charpos - charpos);
15358 best_row = row;
15359 }
15360 }
15361 }
15362 }
15363 else if (best_row)
15364 return best_row;
15365 ++row;
15366 }
15367 }
15368
15369
15370 /* Try to redisplay window W by reusing its existing display. W's
15371 current matrix must be up to date when this function is called,
15372 i.e. window_end_valid must not be nil.
15373
15374 Value is
15375
15376 1 if display has been updated
15377 0 if otherwise unsuccessful
15378 -1 if redisplay with same window start is known not to succeed
15379
15380 The following steps are performed:
15381
15382 1. Find the last row in the current matrix of W that is not
15383 affected by changes at the start of current_buffer. If no such row
15384 is found, give up.
15385
15386 2. Find the first row in W's current matrix that is not affected by
15387 changes at the end of current_buffer. Maybe there is no such row.
15388
15389 3. Display lines beginning with the row + 1 found in step 1 to the
15390 row found in step 2 or, if step 2 didn't find a row, to the end of
15391 the window.
15392
15393 4. If cursor is not known to appear on the window, give up.
15394
15395 5. If display stopped at the row found in step 2, scroll the
15396 display and current matrix as needed.
15397
15398 6. Maybe display some lines at the end of W, if we must. This can
15399 happen under various circumstances, like a partially visible line
15400 becoming fully visible, or because newly displayed lines are displayed
15401 in smaller font sizes.
15402
15403 7. Update W's window end information. */
15404
15405 static int
15406 try_window_id (struct window *w)
15407 {
15408 struct frame *f = XFRAME (w->frame);
15409 struct glyph_matrix *current_matrix = w->current_matrix;
15410 struct glyph_matrix *desired_matrix = w->desired_matrix;
15411 struct glyph_row *last_unchanged_at_beg_row;
15412 struct glyph_row *first_unchanged_at_end_row;
15413 struct glyph_row *row;
15414 struct glyph_row *bottom_row;
15415 int bottom_vpos;
15416 struct it it;
15417 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
15418 struct text_pos start_pos;
15419 struct run run;
15420 int first_unchanged_at_end_vpos = 0;
15421 struct glyph_row *last_text_row, *last_text_row_at_end;
15422 struct text_pos start;
15423 int first_changed_charpos, last_changed_charpos;
15424
15425 #if GLYPH_DEBUG
15426 if (inhibit_try_window_id)
15427 return 0;
15428 #endif
15429
15430 /* This is handy for debugging. */
15431 #if 0
15432 #define GIVE_UP(X) \
15433 do { \
15434 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15435 return 0; \
15436 } while (0)
15437 #else
15438 #define GIVE_UP(X) return 0
15439 #endif
15440
15441 SET_TEXT_POS_FROM_MARKER (start, w->start);
15442
15443 /* Don't use this for mini-windows because these can show
15444 messages and mini-buffers, and we don't handle that here. */
15445 if (MINI_WINDOW_P (w))
15446 GIVE_UP (1);
15447
15448 /* This flag is used to prevent redisplay optimizations. */
15449 if (windows_or_buffers_changed || cursor_type_changed)
15450 GIVE_UP (2);
15451
15452 /* Verify that narrowing has not changed.
15453 Also verify that we were not told to prevent redisplay optimizations.
15454 It would be nice to further
15455 reduce the number of cases where this prevents try_window_id. */
15456 if (current_buffer->clip_changed
15457 || current_buffer->prevent_redisplay_optimizations_p)
15458 GIVE_UP (3);
15459
15460 /* Window must either use window-based redisplay or be full width. */
15461 if (!FRAME_WINDOW_P (f)
15462 && (!FRAME_LINE_INS_DEL_OK (f)
15463 || !WINDOW_FULL_WIDTH_P (w)))
15464 GIVE_UP (4);
15465
15466 /* Give up if point is known NOT to appear in W. */
15467 if (PT < CHARPOS (start))
15468 GIVE_UP (5);
15469
15470 /* Another way to prevent redisplay optimizations. */
15471 if (XFASTINT (w->last_modified) == 0)
15472 GIVE_UP (6);
15473
15474 /* Verify that window is not hscrolled. */
15475 if (XFASTINT (w->hscroll) != 0)
15476 GIVE_UP (7);
15477
15478 /* Verify that display wasn't paused. */
15479 if (NILP (w->window_end_valid))
15480 GIVE_UP (8);
15481
15482 /* Can't use this if highlighting a region because a cursor movement
15483 will do more than just set the cursor. */
15484 if (!NILP (Vtransient_mark_mode)
15485 && !NILP (current_buffer->mark_active))
15486 GIVE_UP (9);
15487
15488 /* Likewise if highlighting trailing whitespace. */
15489 if (!NILP (Vshow_trailing_whitespace))
15490 GIVE_UP (11);
15491
15492 /* Likewise if showing a region. */
15493 if (!NILP (w->region_showing))
15494 GIVE_UP (10);
15495
15496 /* Can't use this if overlay arrow position and/or string have
15497 changed. */
15498 if (overlay_arrows_changed_p ())
15499 GIVE_UP (12);
15500
15501 /* When word-wrap is on, adding a space to the first word of a
15502 wrapped line can change the wrap position, altering the line
15503 above it. It might be worthwhile to handle this more
15504 intelligently, but for now just redisplay from scratch. */
15505 if (!NILP (XBUFFER (w->buffer)->word_wrap))
15506 GIVE_UP (21);
15507
15508 /* Under bidi reordering, adding or deleting a character in the
15509 beginning of a paragraph, before the first strong directional
15510 character, can change the base direction of the paragraph (unless
15511 the buffer specifies a fixed paragraph direction), which will
15512 require to redisplay the whole paragraph. It might be worthwhile
15513 to find the paragraph limits and widen the range of redisplayed
15514 lines to that, but for now just give up this optimization and
15515 redisplay from scratch. */
15516 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15517 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
15518 GIVE_UP (22);
15519
15520 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15521 only if buffer has really changed. The reason is that the gap is
15522 initially at Z for freshly visited files. The code below would
15523 set end_unchanged to 0 in that case. */
15524 if (MODIFF > SAVE_MODIFF
15525 /* This seems to happen sometimes after saving a buffer. */
15526 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15527 {
15528 if (GPT - BEG < BEG_UNCHANGED)
15529 BEG_UNCHANGED = GPT - BEG;
15530 if (Z - GPT < END_UNCHANGED)
15531 END_UNCHANGED = Z - GPT;
15532 }
15533
15534 /* The position of the first and last character that has been changed. */
15535 first_changed_charpos = BEG + BEG_UNCHANGED;
15536 last_changed_charpos = Z - END_UNCHANGED;
15537
15538 /* If window starts after a line end, and the last change is in
15539 front of that newline, then changes don't affect the display.
15540 This case happens with stealth-fontification. Note that although
15541 the display is unchanged, glyph positions in the matrix have to
15542 be adjusted, of course. */
15543 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15544 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15545 && ((last_changed_charpos < CHARPOS (start)
15546 && CHARPOS (start) == BEGV)
15547 || (last_changed_charpos < CHARPOS (start) - 1
15548 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15549 {
15550 int Z_old, delta, Z_BYTE_old, delta_bytes;
15551 struct glyph_row *r0;
15552
15553 /* Compute how many chars/bytes have been added to or removed
15554 from the buffer. */
15555 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15556 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15557 delta = Z - Z_old;
15558 delta_bytes = Z_BYTE - Z_BYTE_old;
15559
15560 /* Give up if PT is not in the window. Note that it already has
15561 been checked at the start of try_window_id that PT is not in
15562 front of the window start. */
15563 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
15564 GIVE_UP (13);
15565
15566 /* If window start is unchanged, we can reuse the whole matrix
15567 as is, after adjusting glyph positions. No need to compute
15568 the window end again, since its offset from Z hasn't changed. */
15569 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15570 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
15571 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
15572 /* PT must not be in a partially visible line. */
15573 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
15574 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15575 {
15576 /* Adjust positions in the glyph matrix. */
15577 if (delta || delta_bytes)
15578 {
15579 struct glyph_row *r1
15580 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15581 increment_matrix_positions (w->current_matrix,
15582 MATRIX_ROW_VPOS (r0, current_matrix),
15583 MATRIX_ROW_VPOS (r1, current_matrix),
15584 delta, delta_bytes);
15585 }
15586
15587 /* Set the cursor. */
15588 row = row_containing_pos (w, PT, r0, NULL, 0);
15589 if (row)
15590 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15591 else
15592 abort ();
15593 return 1;
15594 }
15595 }
15596
15597 /* Handle the case that changes are all below what is displayed in
15598 the window, and that PT is in the window. This shortcut cannot
15599 be taken if ZV is visible in the window, and text has been added
15600 there that is visible in the window. */
15601 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15602 /* ZV is not visible in the window, or there are no
15603 changes at ZV, actually. */
15604 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15605 || first_changed_charpos == last_changed_charpos))
15606 {
15607 struct glyph_row *r0;
15608
15609 /* Give up if PT is not in the window. Note that it already has
15610 been checked at the start of try_window_id that PT is not in
15611 front of the window start. */
15612 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15613 GIVE_UP (14);
15614
15615 /* If window start is unchanged, we can reuse the whole matrix
15616 as is, without changing glyph positions since no text has
15617 been added/removed in front of the window end. */
15618 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15619 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15620 /* PT must not be in a partially visible line. */
15621 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15622 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15623 {
15624 /* We have to compute the window end anew since text
15625 could have been added/removed after it. */
15626 w->window_end_pos
15627 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15628 w->window_end_bytepos
15629 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15630
15631 /* Set the cursor. */
15632 row = row_containing_pos (w, PT, r0, NULL, 0);
15633 if (row)
15634 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15635 else
15636 abort ();
15637 return 2;
15638 }
15639 }
15640
15641 /* Give up if window start is in the changed area.
15642
15643 The condition used to read
15644
15645 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15646
15647 but why that was tested escapes me at the moment. */
15648 if (CHARPOS (start) >= first_changed_charpos
15649 && CHARPOS (start) <= last_changed_charpos)
15650 GIVE_UP (15);
15651
15652 /* Check that window start agrees with the start of the first glyph
15653 row in its current matrix. Check this after we know the window
15654 start is not in changed text, otherwise positions would not be
15655 comparable. */
15656 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15657 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15658 GIVE_UP (16);
15659
15660 /* Give up if the window ends in strings. Overlay strings
15661 at the end are difficult to handle, so don't try. */
15662 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15663 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15664 GIVE_UP (20);
15665
15666 /* Compute the position at which we have to start displaying new
15667 lines. Some of the lines at the top of the window might be
15668 reusable because they are not displaying changed text. Find the
15669 last row in W's current matrix not affected by changes at the
15670 start of current_buffer. Value is null if changes start in the
15671 first line of window. */
15672 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15673 if (last_unchanged_at_beg_row)
15674 {
15675 /* Avoid starting to display in the moddle of a character, a TAB
15676 for instance. This is easier than to set up the iterator
15677 exactly, and it's not a frequent case, so the additional
15678 effort wouldn't really pay off. */
15679 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15680 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15681 && last_unchanged_at_beg_row > w->current_matrix->rows)
15682 --last_unchanged_at_beg_row;
15683
15684 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15685 GIVE_UP (17);
15686
15687 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15688 GIVE_UP (18);
15689 start_pos = it.current.pos;
15690
15691 /* Start displaying new lines in the desired matrix at the same
15692 vpos we would use in the current matrix, i.e. below
15693 last_unchanged_at_beg_row. */
15694 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15695 current_matrix);
15696 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15697 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15698
15699 xassert (it.hpos == 0 && it.current_x == 0);
15700 }
15701 else
15702 {
15703 /* There are no reusable lines at the start of the window.
15704 Start displaying in the first text line. */
15705 start_display (&it, w, start);
15706 it.vpos = it.first_vpos;
15707 start_pos = it.current.pos;
15708 }
15709
15710 /* Find the first row that is not affected by changes at the end of
15711 the buffer. Value will be null if there is no unchanged row, in
15712 which case we must redisplay to the end of the window. delta
15713 will be set to the value by which buffer positions beginning with
15714 first_unchanged_at_end_row have to be adjusted due to text
15715 changes. */
15716 first_unchanged_at_end_row
15717 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15718 IF_DEBUG (debug_delta = delta);
15719 IF_DEBUG (debug_delta_bytes = delta_bytes);
15720
15721 /* Set stop_pos to the buffer position up to which we will have to
15722 display new lines. If first_unchanged_at_end_row != NULL, this
15723 is the buffer position of the start of the line displayed in that
15724 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15725 that we don't stop at a buffer position. */
15726 stop_pos = 0;
15727 if (first_unchanged_at_end_row)
15728 {
15729 xassert (last_unchanged_at_beg_row == NULL
15730 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15731
15732 /* If this is a continuation line, move forward to the next one
15733 that isn't. Changes in lines above affect this line.
15734 Caution: this may move first_unchanged_at_end_row to a row
15735 not displaying text. */
15736 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15737 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15738 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15739 < it.last_visible_y))
15740 ++first_unchanged_at_end_row;
15741
15742 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15743 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15744 >= it.last_visible_y))
15745 first_unchanged_at_end_row = NULL;
15746 else
15747 {
15748 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15749 + delta);
15750 first_unchanged_at_end_vpos
15751 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15752 xassert (stop_pos >= Z - END_UNCHANGED);
15753 }
15754 }
15755 else if (last_unchanged_at_beg_row == NULL)
15756 GIVE_UP (19);
15757
15758
15759 #if GLYPH_DEBUG
15760
15761 /* Either there is no unchanged row at the end, or the one we have
15762 now displays text. This is a necessary condition for the window
15763 end pos calculation at the end of this function. */
15764 xassert (first_unchanged_at_end_row == NULL
15765 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15766
15767 debug_last_unchanged_at_beg_vpos
15768 = (last_unchanged_at_beg_row
15769 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15770 : -1);
15771 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15772
15773 #endif /* GLYPH_DEBUG != 0 */
15774
15775
15776 /* Display new lines. Set last_text_row to the last new line
15777 displayed which has text on it, i.e. might end up as being the
15778 line where the window_end_vpos is. */
15779 w->cursor.vpos = -1;
15780 last_text_row = NULL;
15781 overlay_arrow_seen = 0;
15782 while (it.current_y < it.last_visible_y
15783 && !fonts_changed_p
15784 && (first_unchanged_at_end_row == NULL
15785 || IT_CHARPOS (it) < stop_pos))
15786 {
15787 if (display_line (&it))
15788 last_text_row = it.glyph_row - 1;
15789 }
15790
15791 if (fonts_changed_p)
15792 return -1;
15793
15794
15795 /* Compute differences in buffer positions, y-positions etc. for
15796 lines reused at the bottom of the window. Compute what we can
15797 scroll. */
15798 if (first_unchanged_at_end_row
15799 /* No lines reused because we displayed everything up to the
15800 bottom of the window. */
15801 && it.current_y < it.last_visible_y)
15802 {
15803 dvpos = (it.vpos
15804 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15805 current_matrix));
15806 dy = it.current_y - first_unchanged_at_end_row->y;
15807 run.current_y = first_unchanged_at_end_row->y;
15808 run.desired_y = run.current_y + dy;
15809 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15810 }
15811 else
15812 {
15813 delta = delta_bytes = dvpos = dy
15814 = run.current_y = run.desired_y = run.height = 0;
15815 first_unchanged_at_end_row = NULL;
15816 }
15817 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15818
15819
15820 /* Find the cursor if not already found. We have to decide whether
15821 PT will appear on this window (it sometimes doesn't, but this is
15822 not a very frequent case.) This decision has to be made before
15823 the current matrix is altered. A value of cursor.vpos < 0 means
15824 that PT is either in one of the lines beginning at
15825 first_unchanged_at_end_row or below the window. Don't care for
15826 lines that might be displayed later at the window end; as
15827 mentioned, this is not a frequent case. */
15828 if (w->cursor.vpos < 0)
15829 {
15830 /* Cursor in unchanged rows at the top? */
15831 if (PT < CHARPOS (start_pos)
15832 && last_unchanged_at_beg_row)
15833 {
15834 row = row_containing_pos (w, PT,
15835 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15836 last_unchanged_at_beg_row + 1, 0);
15837 if (row)
15838 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15839 }
15840
15841 /* Start from first_unchanged_at_end_row looking for PT. */
15842 else if (first_unchanged_at_end_row)
15843 {
15844 row = row_containing_pos (w, PT - delta,
15845 first_unchanged_at_end_row, NULL, 0);
15846 if (row)
15847 set_cursor_from_row (w, row, w->current_matrix, delta,
15848 delta_bytes, dy, dvpos);
15849 }
15850
15851 /* Give up if cursor was not found. */
15852 if (w->cursor.vpos < 0)
15853 {
15854 clear_glyph_matrix (w->desired_matrix);
15855 return -1;
15856 }
15857 }
15858
15859 /* Don't let the cursor end in the scroll margins. */
15860 {
15861 int this_scroll_margin, cursor_height;
15862
15863 this_scroll_margin = max (0, scroll_margin);
15864 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15865 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15866 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15867
15868 if ((w->cursor.y < this_scroll_margin
15869 && CHARPOS (start) > BEGV)
15870 /* Old redisplay didn't take scroll margin into account at the bottom,
15871 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15872 || (w->cursor.y + (make_cursor_line_fully_visible_p
15873 ? cursor_height + this_scroll_margin
15874 : 1)) > it.last_visible_y)
15875 {
15876 w->cursor.vpos = -1;
15877 clear_glyph_matrix (w->desired_matrix);
15878 return -1;
15879 }
15880 }
15881
15882 /* Scroll the display. Do it before changing the current matrix so
15883 that xterm.c doesn't get confused about where the cursor glyph is
15884 found. */
15885 if (dy && run.height)
15886 {
15887 update_begin (f);
15888
15889 if (FRAME_WINDOW_P (f))
15890 {
15891 FRAME_RIF (f)->update_window_begin_hook (w);
15892 FRAME_RIF (f)->clear_window_mouse_face (w);
15893 FRAME_RIF (f)->scroll_run_hook (w, &run);
15894 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15895 }
15896 else
15897 {
15898 /* Terminal frame. In this case, dvpos gives the number of
15899 lines to scroll by; dvpos < 0 means scroll up. */
15900 int first_unchanged_at_end_vpos
15901 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15902 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15903 int end = (WINDOW_TOP_EDGE_LINE (w)
15904 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15905 + window_internal_height (w));
15906
15907 /* Perform the operation on the screen. */
15908 if (dvpos > 0)
15909 {
15910 /* Scroll last_unchanged_at_beg_row to the end of the
15911 window down dvpos lines. */
15912 set_terminal_window (f, end);
15913
15914 /* On dumb terminals delete dvpos lines at the end
15915 before inserting dvpos empty lines. */
15916 if (!FRAME_SCROLL_REGION_OK (f))
15917 ins_del_lines (f, end - dvpos, -dvpos);
15918
15919 /* Insert dvpos empty lines in front of
15920 last_unchanged_at_beg_row. */
15921 ins_del_lines (f, from, dvpos);
15922 }
15923 else if (dvpos < 0)
15924 {
15925 /* Scroll up last_unchanged_at_beg_vpos to the end of
15926 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15927 set_terminal_window (f, end);
15928
15929 /* Delete dvpos lines in front of
15930 last_unchanged_at_beg_vpos. ins_del_lines will set
15931 the cursor to the given vpos and emit |dvpos| delete
15932 line sequences. */
15933 ins_del_lines (f, from + dvpos, dvpos);
15934
15935 /* On a dumb terminal insert dvpos empty lines at the
15936 end. */
15937 if (!FRAME_SCROLL_REGION_OK (f))
15938 ins_del_lines (f, end + dvpos, -dvpos);
15939 }
15940
15941 set_terminal_window (f, 0);
15942 }
15943
15944 update_end (f);
15945 }
15946
15947 /* Shift reused rows of the current matrix to the right position.
15948 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15949 text. */
15950 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15951 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15952 if (dvpos < 0)
15953 {
15954 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15955 bottom_vpos, dvpos);
15956 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15957 bottom_vpos, 0);
15958 }
15959 else if (dvpos > 0)
15960 {
15961 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15962 bottom_vpos, dvpos);
15963 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15964 first_unchanged_at_end_vpos + dvpos, 0);
15965 }
15966
15967 /* For frame-based redisplay, make sure that current frame and window
15968 matrix are in sync with respect to glyph memory. */
15969 if (!FRAME_WINDOW_P (f))
15970 sync_frame_with_window_matrix_rows (w);
15971
15972 /* Adjust buffer positions in reused rows. */
15973 if (delta || delta_bytes)
15974 increment_matrix_positions (current_matrix,
15975 first_unchanged_at_end_vpos + dvpos,
15976 bottom_vpos, delta, delta_bytes);
15977
15978 /* Adjust Y positions. */
15979 if (dy)
15980 shift_glyph_matrix (w, current_matrix,
15981 first_unchanged_at_end_vpos + dvpos,
15982 bottom_vpos, dy);
15983
15984 if (first_unchanged_at_end_row)
15985 {
15986 first_unchanged_at_end_row += dvpos;
15987 if (first_unchanged_at_end_row->y >= it.last_visible_y
15988 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15989 first_unchanged_at_end_row = NULL;
15990 }
15991
15992 /* If scrolling up, there may be some lines to display at the end of
15993 the window. */
15994 last_text_row_at_end = NULL;
15995 if (dy < 0)
15996 {
15997 /* Scrolling up can leave for example a partially visible line
15998 at the end of the window to be redisplayed. */
15999 /* Set last_row to the glyph row in the current matrix where the
16000 window end line is found. It has been moved up or down in
16001 the matrix by dvpos. */
16002 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16003 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16004
16005 /* If last_row is the window end line, it should display text. */
16006 xassert (last_row->displays_text_p);
16007
16008 /* If window end line was partially visible before, begin
16009 displaying at that line. Otherwise begin displaying with the
16010 line following it. */
16011 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16012 {
16013 init_to_row_start (&it, w, last_row);
16014 it.vpos = last_vpos;
16015 it.current_y = last_row->y;
16016 }
16017 else
16018 {
16019 init_to_row_end (&it, w, last_row);
16020 it.vpos = 1 + last_vpos;
16021 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16022 ++last_row;
16023 }
16024
16025 /* We may start in a continuation line. If so, we have to
16026 get the right continuation_lines_width and current_x. */
16027 it.continuation_lines_width = last_row->continuation_lines_width;
16028 it.hpos = it.current_x = 0;
16029
16030 /* Display the rest of the lines at the window end. */
16031 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16032 while (it.current_y < it.last_visible_y
16033 && !fonts_changed_p)
16034 {
16035 /* Is it always sure that the display agrees with lines in
16036 the current matrix? I don't think so, so we mark rows
16037 displayed invalid in the current matrix by setting their
16038 enabled_p flag to zero. */
16039 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16040 if (display_line (&it))
16041 last_text_row_at_end = it.glyph_row - 1;
16042 }
16043 }
16044
16045 /* Update window_end_pos and window_end_vpos. */
16046 if (first_unchanged_at_end_row
16047 && !last_text_row_at_end)
16048 {
16049 /* Window end line if one of the preserved rows from the current
16050 matrix. Set row to the last row displaying text in current
16051 matrix starting at first_unchanged_at_end_row, after
16052 scrolling. */
16053 xassert (first_unchanged_at_end_row->displays_text_p);
16054 row = find_last_row_displaying_text (w->current_matrix, &it,
16055 first_unchanged_at_end_row);
16056 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16057
16058 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16059 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16060 w->window_end_vpos
16061 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16062 xassert (w->window_end_bytepos >= 0);
16063 IF_DEBUG (debug_method_add (w, "A"));
16064 }
16065 else if (last_text_row_at_end)
16066 {
16067 w->window_end_pos
16068 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16069 w->window_end_bytepos
16070 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16071 w->window_end_vpos
16072 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16073 xassert (w->window_end_bytepos >= 0);
16074 IF_DEBUG (debug_method_add (w, "B"));
16075 }
16076 else if (last_text_row)
16077 {
16078 /* We have displayed either to the end of the window or at the
16079 end of the window, i.e. the last row with text is to be found
16080 in the desired matrix. */
16081 w->window_end_pos
16082 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16083 w->window_end_bytepos
16084 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16085 w->window_end_vpos
16086 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16087 xassert (w->window_end_bytepos >= 0);
16088 }
16089 else if (first_unchanged_at_end_row == NULL
16090 && last_text_row == NULL
16091 && last_text_row_at_end == NULL)
16092 {
16093 /* Displayed to end of window, but no line containing text was
16094 displayed. Lines were deleted at the end of the window. */
16095 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16096 int vpos = XFASTINT (w->window_end_vpos);
16097 struct glyph_row *current_row = current_matrix->rows + vpos;
16098 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16099
16100 for (row = NULL;
16101 row == NULL && vpos >= first_vpos;
16102 --vpos, --current_row, --desired_row)
16103 {
16104 if (desired_row->enabled_p)
16105 {
16106 if (desired_row->displays_text_p)
16107 row = desired_row;
16108 }
16109 else if (current_row->displays_text_p)
16110 row = current_row;
16111 }
16112
16113 xassert (row != NULL);
16114 w->window_end_vpos = make_number (vpos + 1);
16115 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16116 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16117 xassert (w->window_end_bytepos >= 0);
16118 IF_DEBUG (debug_method_add (w, "C"));
16119 }
16120 else
16121 abort ();
16122
16123 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16124 debug_end_vpos = XFASTINT (w->window_end_vpos));
16125
16126 /* Record that display has not been completed. */
16127 w->window_end_valid = Qnil;
16128 w->desired_matrix->no_scrolling_p = 1;
16129 return 3;
16130
16131 #undef GIVE_UP
16132 }
16133
16134
16135 \f
16136 /***********************************************************************
16137 More debugging support
16138 ***********************************************************************/
16139
16140 #if GLYPH_DEBUG
16141
16142 void dump_glyph_row (struct glyph_row *, int, int);
16143 void dump_glyph_matrix (struct glyph_matrix *, int);
16144 void dump_glyph (struct glyph_row *, struct glyph *, int);
16145
16146
16147 /* Dump the contents of glyph matrix MATRIX on stderr.
16148
16149 GLYPHS 0 means don't show glyph contents.
16150 GLYPHS 1 means show glyphs in short form
16151 GLYPHS > 1 means show glyphs in long form. */
16152
16153 void
16154 dump_glyph_matrix (matrix, glyphs)
16155 struct glyph_matrix *matrix;
16156 int glyphs;
16157 {
16158 int i;
16159 for (i = 0; i < matrix->nrows; ++i)
16160 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16161 }
16162
16163
16164 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16165 the glyph row and area where the glyph comes from. */
16166
16167 void
16168 dump_glyph (row, glyph, area)
16169 struct glyph_row *row;
16170 struct glyph *glyph;
16171 int area;
16172 {
16173 if (glyph->type == CHAR_GLYPH)
16174 {
16175 fprintf (stderr,
16176 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16177 glyph - row->glyphs[TEXT_AREA],
16178 'C',
16179 glyph->charpos,
16180 (BUFFERP (glyph->object)
16181 ? 'B'
16182 : (STRINGP (glyph->object)
16183 ? 'S'
16184 : '-')),
16185 glyph->pixel_width,
16186 glyph->u.ch,
16187 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16188 ? glyph->u.ch
16189 : '.'),
16190 glyph->face_id,
16191 glyph->left_box_line_p,
16192 glyph->right_box_line_p);
16193 }
16194 else if (glyph->type == STRETCH_GLYPH)
16195 {
16196 fprintf (stderr,
16197 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16198 glyph - row->glyphs[TEXT_AREA],
16199 'S',
16200 glyph->charpos,
16201 (BUFFERP (glyph->object)
16202 ? 'B'
16203 : (STRINGP (glyph->object)
16204 ? 'S'
16205 : '-')),
16206 glyph->pixel_width,
16207 0,
16208 '.',
16209 glyph->face_id,
16210 glyph->left_box_line_p,
16211 glyph->right_box_line_p);
16212 }
16213 else if (glyph->type == IMAGE_GLYPH)
16214 {
16215 fprintf (stderr,
16216 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16217 glyph - row->glyphs[TEXT_AREA],
16218 'I',
16219 glyph->charpos,
16220 (BUFFERP (glyph->object)
16221 ? 'B'
16222 : (STRINGP (glyph->object)
16223 ? 'S'
16224 : '-')),
16225 glyph->pixel_width,
16226 glyph->u.img_id,
16227 '.',
16228 glyph->face_id,
16229 glyph->left_box_line_p,
16230 glyph->right_box_line_p);
16231 }
16232 else if (glyph->type == COMPOSITE_GLYPH)
16233 {
16234 fprintf (stderr,
16235 " %5d %4c %6d %c %3d 0x%05x",
16236 glyph - row->glyphs[TEXT_AREA],
16237 '+',
16238 glyph->charpos,
16239 (BUFFERP (glyph->object)
16240 ? 'B'
16241 : (STRINGP (glyph->object)
16242 ? 'S'
16243 : '-')),
16244 glyph->pixel_width,
16245 glyph->u.cmp.id);
16246 if (glyph->u.cmp.automatic)
16247 fprintf (stderr,
16248 "[%d-%d]",
16249 glyph->u.cmp.from, glyph->u.cmp.to);
16250 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16251 glyph->face_id,
16252 glyph->left_box_line_p,
16253 glyph->right_box_line_p);
16254 }
16255 }
16256
16257
16258 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16259 GLYPHS 0 means don't show glyph contents.
16260 GLYPHS 1 means show glyphs in short form
16261 GLYPHS > 1 means show glyphs in long form. */
16262
16263 void
16264 dump_glyph_row (row, vpos, glyphs)
16265 struct glyph_row *row;
16266 int vpos, glyphs;
16267 {
16268 if (glyphs != 1)
16269 {
16270 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16271 fprintf (stderr, "======================================================================\n");
16272
16273 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16274 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16275 vpos,
16276 MATRIX_ROW_START_CHARPOS (row),
16277 MATRIX_ROW_END_CHARPOS (row),
16278 row->used[TEXT_AREA],
16279 row->contains_overlapping_glyphs_p,
16280 row->enabled_p,
16281 row->truncated_on_left_p,
16282 row->truncated_on_right_p,
16283 row->continued_p,
16284 MATRIX_ROW_CONTINUATION_LINE_P (row),
16285 row->displays_text_p,
16286 row->ends_at_zv_p,
16287 row->fill_line_p,
16288 row->ends_in_middle_of_char_p,
16289 row->starts_in_middle_of_char_p,
16290 row->mouse_face_p,
16291 row->x,
16292 row->y,
16293 row->pixel_width,
16294 row->height,
16295 row->visible_height,
16296 row->ascent,
16297 row->phys_ascent);
16298 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16299 row->end.overlay_string_index,
16300 row->continuation_lines_width);
16301 fprintf (stderr, "%9d %5d\n",
16302 CHARPOS (row->start.string_pos),
16303 CHARPOS (row->end.string_pos));
16304 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16305 row->end.dpvec_index);
16306 }
16307
16308 if (glyphs > 1)
16309 {
16310 int area;
16311
16312 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16313 {
16314 struct glyph *glyph = row->glyphs[area];
16315 struct glyph *glyph_end = glyph + row->used[area];
16316
16317 /* Glyph for a line end in text. */
16318 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16319 ++glyph_end;
16320
16321 if (glyph < glyph_end)
16322 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16323
16324 for (; glyph < glyph_end; ++glyph)
16325 dump_glyph (row, glyph, area);
16326 }
16327 }
16328 else if (glyphs == 1)
16329 {
16330 int area;
16331
16332 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16333 {
16334 char *s = (char *) alloca (row->used[area] + 1);
16335 int i;
16336
16337 for (i = 0; i < row->used[area]; ++i)
16338 {
16339 struct glyph *glyph = row->glyphs[area] + i;
16340 if (glyph->type == CHAR_GLYPH
16341 && glyph->u.ch < 0x80
16342 && glyph->u.ch >= ' ')
16343 s[i] = glyph->u.ch;
16344 else
16345 s[i] = '.';
16346 }
16347
16348 s[i] = '\0';
16349 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16350 }
16351 }
16352 }
16353
16354
16355 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16356 Sdump_glyph_matrix, 0, 1, "p",
16357 doc: /* Dump the current matrix of the selected window to stderr.
16358 Shows contents of glyph row structures. With non-nil
16359 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16360 glyphs in short form, otherwise show glyphs in long form. */)
16361 (Lisp_Object glyphs)
16362 {
16363 struct window *w = XWINDOW (selected_window);
16364 struct buffer *buffer = XBUFFER (w->buffer);
16365
16366 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16367 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16368 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16369 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16370 fprintf (stderr, "=============================================\n");
16371 dump_glyph_matrix (w->current_matrix,
16372 NILP (glyphs) ? 0 : XINT (glyphs));
16373 return Qnil;
16374 }
16375
16376
16377 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16378 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16379 (void)
16380 {
16381 struct frame *f = XFRAME (selected_frame);
16382 dump_glyph_matrix (f->current_matrix, 1);
16383 return Qnil;
16384 }
16385
16386
16387 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16388 doc: /* Dump glyph row ROW to stderr.
16389 GLYPH 0 means don't dump glyphs.
16390 GLYPH 1 means dump glyphs in short form.
16391 GLYPH > 1 or omitted means dump glyphs in long form. */)
16392 (Lisp_Object row, Lisp_Object glyphs)
16393 {
16394 struct glyph_matrix *matrix;
16395 int vpos;
16396
16397 CHECK_NUMBER (row);
16398 matrix = XWINDOW (selected_window)->current_matrix;
16399 vpos = XINT (row);
16400 if (vpos >= 0 && vpos < matrix->nrows)
16401 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16402 vpos,
16403 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16404 return Qnil;
16405 }
16406
16407
16408 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16409 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16410 GLYPH 0 means don't dump glyphs.
16411 GLYPH 1 means dump glyphs in short form.
16412 GLYPH > 1 or omitted means dump glyphs in long form. */)
16413 (Lisp_Object row, Lisp_Object glyphs)
16414 {
16415 struct frame *sf = SELECTED_FRAME ();
16416 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16417 int vpos;
16418
16419 CHECK_NUMBER (row);
16420 vpos = XINT (row);
16421 if (vpos >= 0 && vpos < m->nrows)
16422 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16423 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16424 return Qnil;
16425 }
16426
16427
16428 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16429 doc: /* Toggle tracing of redisplay.
16430 With ARG, turn tracing on if and only if ARG is positive. */)
16431 (Lisp_Object arg)
16432 {
16433 if (NILP (arg))
16434 trace_redisplay_p = !trace_redisplay_p;
16435 else
16436 {
16437 arg = Fprefix_numeric_value (arg);
16438 trace_redisplay_p = XINT (arg) > 0;
16439 }
16440
16441 return Qnil;
16442 }
16443
16444
16445 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16446 doc: /* Like `format', but print result to stderr.
16447 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16448 (int nargs, Lisp_Object *args)
16449 {
16450 Lisp_Object s = Fformat (nargs, args);
16451 fprintf (stderr, "%s", SDATA (s));
16452 return Qnil;
16453 }
16454
16455 #endif /* GLYPH_DEBUG */
16456
16457
16458 \f
16459 /***********************************************************************
16460 Building Desired Matrix Rows
16461 ***********************************************************************/
16462
16463 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16464 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16465
16466 static struct glyph_row *
16467 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16468 {
16469 struct frame *f = XFRAME (WINDOW_FRAME (w));
16470 struct buffer *buffer = XBUFFER (w->buffer);
16471 struct buffer *old = current_buffer;
16472 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16473 int arrow_len = SCHARS (overlay_arrow_string);
16474 const unsigned char *arrow_end = arrow_string + arrow_len;
16475 const unsigned char *p;
16476 struct it it;
16477 int multibyte_p;
16478 int n_glyphs_before;
16479
16480 set_buffer_temp (buffer);
16481 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16482 it.glyph_row->used[TEXT_AREA] = 0;
16483 SET_TEXT_POS (it.position, 0, 0);
16484
16485 multibyte_p = !NILP (buffer->enable_multibyte_characters);
16486 p = arrow_string;
16487 while (p < arrow_end)
16488 {
16489 Lisp_Object face, ilisp;
16490
16491 /* Get the next character. */
16492 if (multibyte_p)
16493 it.c = string_char_and_length (p, &it.len);
16494 else
16495 it.c = *p, it.len = 1;
16496 p += it.len;
16497
16498 /* Get its face. */
16499 ilisp = make_number (p - arrow_string);
16500 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16501 it.face_id = compute_char_face (f, it.c, face);
16502
16503 /* Compute its width, get its glyphs. */
16504 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16505 SET_TEXT_POS (it.position, -1, -1);
16506 PRODUCE_GLYPHS (&it);
16507
16508 /* If this character doesn't fit any more in the line, we have
16509 to remove some glyphs. */
16510 if (it.current_x > it.last_visible_x)
16511 {
16512 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16513 break;
16514 }
16515 }
16516
16517 set_buffer_temp (old);
16518 return it.glyph_row;
16519 }
16520
16521
16522 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16523 glyphs are only inserted for terminal frames since we can't really
16524 win with truncation glyphs when partially visible glyphs are
16525 involved. Which glyphs to insert is determined by
16526 produce_special_glyphs. */
16527
16528 static void
16529 insert_left_trunc_glyphs (struct it *it)
16530 {
16531 struct it truncate_it;
16532 struct glyph *from, *end, *to, *toend;
16533
16534 xassert (!FRAME_WINDOW_P (it->f));
16535
16536 /* Get the truncation glyphs. */
16537 truncate_it = *it;
16538 truncate_it.current_x = 0;
16539 truncate_it.face_id = DEFAULT_FACE_ID;
16540 truncate_it.glyph_row = &scratch_glyph_row;
16541 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16542 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16543 truncate_it.object = make_number (0);
16544 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16545
16546 /* Overwrite glyphs from IT with truncation glyphs. */
16547 if (!it->glyph_row->reversed_p)
16548 {
16549 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16550 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16551 to = it->glyph_row->glyphs[TEXT_AREA];
16552 toend = to + it->glyph_row->used[TEXT_AREA];
16553
16554 while (from < end)
16555 *to++ = *from++;
16556
16557 /* There may be padding glyphs left over. Overwrite them too. */
16558 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16559 {
16560 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16561 while (from < end)
16562 *to++ = *from++;
16563 }
16564
16565 if (to > toend)
16566 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16567 }
16568 else
16569 {
16570 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16571 that back to front. */
16572 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16573 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16574 toend = it->glyph_row->glyphs[TEXT_AREA];
16575 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16576
16577 while (from >= end && to >= toend)
16578 *to-- = *from--;
16579 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16580 {
16581 from =
16582 truncate_it.glyph_row->glyphs[TEXT_AREA]
16583 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16584 while (from >= end && to >= toend)
16585 *to-- = *from--;
16586 }
16587 if (from >= end)
16588 {
16589 /* Need to free some room before prepending additional
16590 glyphs. */
16591 int move_by = from - end + 1;
16592 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16593 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16594
16595 for ( ; g >= g0; g--)
16596 g[move_by] = *g;
16597 while (from >= end)
16598 *to-- = *from--;
16599 it->glyph_row->used[TEXT_AREA] += move_by;
16600 }
16601 }
16602 }
16603
16604
16605 /* Compute the pixel height and width of IT->glyph_row.
16606
16607 Most of the time, ascent and height of a display line will be equal
16608 to the max_ascent and max_height values of the display iterator
16609 structure. This is not the case if
16610
16611 1. We hit ZV without displaying anything. In this case, max_ascent
16612 and max_height will be zero.
16613
16614 2. We have some glyphs that don't contribute to the line height.
16615 (The glyph row flag contributes_to_line_height_p is for future
16616 pixmap extensions).
16617
16618 The first case is easily covered by using default values because in
16619 these cases, the line height does not really matter, except that it
16620 must not be zero. */
16621
16622 static void
16623 compute_line_metrics (struct it *it)
16624 {
16625 struct glyph_row *row = it->glyph_row;
16626 int area, i;
16627
16628 if (FRAME_WINDOW_P (it->f))
16629 {
16630 int i, min_y, max_y;
16631
16632 /* The line may consist of one space only, that was added to
16633 place the cursor on it. If so, the row's height hasn't been
16634 computed yet. */
16635 if (row->height == 0)
16636 {
16637 if (it->max_ascent + it->max_descent == 0)
16638 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16639 row->ascent = it->max_ascent;
16640 row->height = it->max_ascent + it->max_descent;
16641 row->phys_ascent = it->max_phys_ascent;
16642 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16643 row->extra_line_spacing = it->max_extra_line_spacing;
16644 }
16645
16646 /* Compute the width of this line. */
16647 row->pixel_width = row->x;
16648 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16649 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16650
16651 xassert (row->pixel_width >= 0);
16652 xassert (row->ascent >= 0 && row->height > 0);
16653
16654 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16655 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16656
16657 /* If first line's physical ascent is larger than its logical
16658 ascent, use the physical ascent, and make the row taller.
16659 This makes accented characters fully visible. */
16660 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16661 && row->phys_ascent > row->ascent)
16662 {
16663 row->height += row->phys_ascent - row->ascent;
16664 row->ascent = row->phys_ascent;
16665 }
16666
16667 /* Compute how much of the line is visible. */
16668 row->visible_height = row->height;
16669
16670 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16671 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16672
16673 if (row->y < min_y)
16674 row->visible_height -= min_y - row->y;
16675 if (row->y + row->height > max_y)
16676 row->visible_height -= row->y + row->height - max_y;
16677 }
16678 else
16679 {
16680 row->pixel_width = row->used[TEXT_AREA];
16681 if (row->continued_p)
16682 row->pixel_width -= it->continuation_pixel_width;
16683 else if (row->truncated_on_right_p)
16684 row->pixel_width -= it->truncation_pixel_width;
16685 row->ascent = row->phys_ascent = 0;
16686 row->height = row->phys_height = row->visible_height = 1;
16687 row->extra_line_spacing = 0;
16688 }
16689
16690 /* Compute a hash code for this row. */
16691 row->hash = 0;
16692 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16693 for (i = 0; i < row->used[area]; ++i)
16694 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16695 + row->glyphs[area][i].u.val
16696 + row->glyphs[area][i].face_id
16697 + row->glyphs[area][i].padding_p
16698 + (row->glyphs[area][i].type << 2));
16699
16700 it->max_ascent = it->max_descent = 0;
16701 it->max_phys_ascent = it->max_phys_descent = 0;
16702 }
16703
16704
16705 /* Append one space to the glyph row of iterator IT if doing a
16706 window-based redisplay. The space has the same face as
16707 IT->face_id. Value is non-zero if a space was added.
16708
16709 This function is called to make sure that there is always one glyph
16710 at the end of a glyph row that the cursor can be set on under
16711 window-systems. (If there weren't such a glyph we would not know
16712 how wide and tall a box cursor should be displayed).
16713
16714 At the same time this space let's a nicely handle clearing to the
16715 end of the line if the row ends in italic text. */
16716
16717 static int
16718 append_space_for_newline (struct it *it, int default_face_p)
16719 {
16720 if (FRAME_WINDOW_P (it->f))
16721 {
16722 int n = it->glyph_row->used[TEXT_AREA];
16723
16724 if (it->glyph_row->glyphs[TEXT_AREA] + n
16725 < it->glyph_row->glyphs[1 + TEXT_AREA])
16726 {
16727 /* Save some values that must not be changed.
16728 Must save IT->c and IT->len because otherwise
16729 ITERATOR_AT_END_P wouldn't work anymore after
16730 append_space_for_newline has been called. */
16731 enum display_element_type saved_what = it->what;
16732 int saved_c = it->c, saved_len = it->len;
16733 int saved_x = it->current_x;
16734 int saved_face_id = it->face_id;
16735 struct text_pos saved_pos;
16736 Lisp_Object saved_object;
16737 struct face *face;
16738
16739 saved_object = it->object;
16740 saved_pos = it->position;
16741
16742 it->what = IT_CHARACTER;
16743 memset (&it->position, 0, sizeof it->position);
16744 it->object = make_number (0);
16745 it->c = ' ';
16746 it->len = 1;
16747
16748 if (default_face_p)
16749 it->face_id = DEFAULT_FACE_ID;
16750 else if (it->face_before_selective_p)
16751 it->face_id = it->saved_face_id;
16752 face = FACE_FROM_ID (it->f, it->face_id);
16753 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16754
16755 PRODUCE_GLYPHS (it);
16756
16757 it->override_ascent = -1;
16758 it->constrain_row_ascent_descent_p = 0;
16759 it->current_x = saved_x;
16760 it->object = saved_object;
16761 it->position = saved_pos;
16762 it->what = saved_what;
16763 it->face_id = saved_face_id;
16764 it->len = saved_len;
16765 it->c = saved_c;
16766 return 1;
16767 }
16768 }
16769
16770 return 0;
16771 }
16772
16773
16774 /* Extend the face of the last glyph in the text area of IT->glyph_row
16775 to the end of the display line. Called from display_line. If the
16776 glyph row is empty, add a space glyph to it so that we know the
16777 face to draw. Set the glyph row flag fill_line_p. If the glyph
16778 row is R2L, prepend a stretch glyph to cover the empty space to the
16779 left of the leftmost glyph. */
16780
16781 static void
16782 extend_face_to_end_of_line (struct it *it)
16783 {
16784 struct face *face;
16785 struct frame *f = it->f;
16786
16787 /* If line is already filled, do nothing. Non window-system frames
16788 get a grace of one more ``pixel'' because their characters are
16789 1-``pixel'' wide, so they hit the equality too early. This grace
16790 is needed only for R2L rows that are not continued, to produce
16791 one extra blank where we could display the cursor. */
16792 if (it->current_x >= it->last_visible_x
16793 + (!FRAME_WINDOW_P (f)
16794 && it->glyph_row->reversed_p
16795 && !it->glyph_row->continued_p))
16796 return;
16797
16798 /* Face extension extends the background and box of IT->face_id
16799 to the end of the line. If the background equals the background
16800 of the frame, we don't have to do anything. */
16801 if (it->face_before_selective_p)
16802 face = FACE_FROM_ID (f, it->saved_face_id);
16803 else
16804 face = FACE_FROM_ID (f, it->face_id);
16805
16806 if (FRAME_WINDOW_P (f)
16807 && it->glyph_row->displays_text_p
16808 && face->box == FACE_NO_BOX
16809 && face->background == FRAME_BACKGROUND_PIXEL (f)
16810 && !face->stipple
16811 && !it->glyph_row->reversed_p)
16812 return;
16813
16814 /* Set the glyph row flag indicating that the face of the last glyph
16815 in the text area has to be drawn to the end of the text area. */
16816 it->glyph_row->fill_line_p = 1;
16817
16818 /* If current character of IT is not ASCII, make sure we have the
16819 ASCII face. This will be automatically undone the next time
16820 get_next_display_element returns a multibyte character. Note
16821 that the character will always be single byte in unibyte
16822 text. */
16823 if (!ASCII_CHAR_P (it->c))
16824 {
16825 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16826 }
16827
16828 if (FRAME_WINDOW_P (f))
16829 {
16830 /* If the row is empty, add a space with the current face of IT,
16831 so that we know which face to draw. */
16832 if (it->glyph_row->used[TEXT_AREA] == 0)
16833 {
16834 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16835 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16836 it->glyph_row->used[TEXT_AREA] = 1;
16837 }
16838 #ifdef HAVE_WINDOW_SYSTEM
16839 if (it->glyph_row->reversed_p)
16840 {
16841 /* Prepend a stretch glyph to the row, such that the
16842 rightmost glyph will be drawn flushed all the way to the
16843 right margin of the window. The stretch glyph that will
16844 occupy the empty space, if any, to the left of the
16845 glyphs. */
16846 struct font *font = face->font ? face->font : FRAME_FONT (f);
16847 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16848 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16849 struct glyph *g;
16850 int row_width, stretch_ascent, stretch_width;
16851 struct text_pos saved_pos;
16852 int saved_face_id, saved_avoid_cursor;
16853
16854 for (row_width = 0, g = row_start; g < row_end; g++)
16855 row_width += g->pixel_width;
16856 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16857 if (stretch_width > 0)
16858 {
16859 stretch_ascent =
16860 (((it->ascent + it->descent)
16861 * FONT_BASE (font)) / FONT_HEIGHT (font));
16862 saved_pos = it->position;
16863 memset (&it->position, 0, sizeof it->position);
16864 saved_avoid_cursor = it->avoid_cursor_p;
16865 it->avoid_cursor_p = 1;
16866 saved_face_id = it->face_id;
16867 /* The last row's stretch glyph should get the default
16868 face, to avoid painting the rest of the window with
16869 the region face, if the region ends at ZV. */
16870 if (it->glyph_row->ends_at_zv_p)
16871 it->face_id = DEFAULT_FACE_ID;
16872 else
16873 it->face_id = face->id;
16874 append_stretch_glyph (it, make_number (0), stretch_width,
16875 it->ascent + it->descent, stretch_ascent);
16876 it->position = saved_pos;
16877 it->avoid_cursor_p = saved_avoid_cursor;
16878 it->face_id = saved_face_id;
16879 }
16880 }
16881 #endif /* HAVE_WINDOW_SYSTEM */
16882 }
16883 else
16884 {
16885 /* Save some values that must not be changed. */
16886 int saved_x = it->current_x;
16887 struct text_pos saved_pos;
16888 Lisp_Object saved_object;
16889 enum display_element_type saved_what = it->what;
16890 int saved_face_id = it->face_id;
16891
16892 saved_object = it->object;
16893 saved_pos = it->position;
16894
16895 it->what = IT_CHARACTER;
16896 memset (&it->position, 0, sizeof it->position);
16897 it->object = make_number (0);
16898 it->c = ' ';
16899 it->len = 1;
16900 /* The last row's blank glyphs should get the default face, to
16901 avoid painting the rest of the window with the region face,
16902 if the region ends at ZV. */
16903 if (it->glyph_row->ends_at_zv_p)
16904 it->face_id = DEFAULT_FACE_ID;
16905 else
16906 it->face_id = face->id;
16907
16908 PRODUCE_GLYPHS (it);
16909
16910 while (it->current_x <= it->last_visible_x)
16911 PRODUCE_GLYPHS (it);
16912
16913 /* Don't count these blanks really. It would let us insert a left
16914 truncation glyph below and make us set the cursor on them, maybe. */
16915 it->current_x = saved_x;
16916 it->object = saved_object;
16917 it->position = saved_pos;
16918 it->what = saved_what;
16919 it->face_id = saved_face_id;
16920 }
16921 }
16922
16923
16924 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16925 trailing whitespace. */
16926
16927 static int
16928 trailing_whitespace_p (int charpos)
16929 {
16930 int bytepos = CHAR_TO_BYTE (charpos);
16931 int c = 0;
16932
16933 while (bytepos < ZV_BYTE
16934 && (c = FETCH_CHAR (bytepos),
16935 c == ' ' || c == '\t'))
16936 ++bytepos;
16937
16938 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16939 {
16940 if (bytepos != PT_BYTE)
16941 return 1;
16942 }
16943 return 0;
16944 }
16945
16946
16947 /* Highlight trailing whitespace, if any, in ROW. */
16948
16949 void
16950 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
16951 {
16952 int used = row->used[TEXT_AREA];
16953
16954 if (used)
16955 {
16956 struct glyph *start = row->glyphs[TEXT_AREA];
16957 struct glyph *glyph = start + used - 1;
16958
16959 if (row->reversed_p)
16960 {
16961 /* Right-to-left rows need to be processed in the opposite
16962 direction, so swap the edge pointers. */
16963 glyph = start;
16964 start = row->glyphs[TEXT_AREA] + used - 1;
16965 }
16966
16967 /* Skip over glyphs inserted to display the cursor at the
16968 end of a line, for extending the face of the last glyph
16969 to the end of the line on terminals, and for truncation
16970 and continuation glyphs. */
16971 if (!row->reversed_p)
16972 {
16973 while (glyph >= start
16974 && glyph->type == CHAR_GLYPH
16975 && INTEGERP (glyph->object))
16976 --glyph;
16977 }
16978 else
16979 {
16980 while (glyph <= start
16981 && glyph->type == CHAR_GLYPH
16982 && INTEGERP (glyph->object))
16983 ++glyph;
16984 }
16985
16986 /* If last glyph is a space or stretch, and it's trailing
16987 whitespace, set the face of all trailing whitespace glyphs in
16988 IT->glyph_row to `trailing-whitespace'. */
16989 if ((row->reversed_p ? glyph <= start : glyph >= start)
16990 && BUFFERP (glyph->object)
16991 && (glyph->type == STRETCH_GLYPH
16992 || (glyph->type == CHAR_GLYPH
16993 && glyph->u.ch == ' '))
16994 && trailing_whitespace_p (glyph->charpos))
16995 {
16996 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16997 if (face_id < 0)
16998 return;
16999
17000 if (!row->reversed_p)
17001 {
17002 while (glyph >= start
17003 && BUFFERP (glyph->object)
17004 && (glyph->type == STRETCH_GLYPH
17005 || (glyph->type == CHAR_GLYPH
17006 && glyph->u.ch == ' ')))
17007 (glyph--)->face_id = face_id;
17008 }
17009 else
17010 {
17011 while (glyph <= start
17012 && BUFFERP (glyph->object)
17013 && (glyph->type == STRETCH_GLYPH
17014 || (glyph->type == CHAR_GLYPH
17015 && glyph->u.ch == ' ')))
17016 (glyph++)->face_id = face_id;
17017 }
17018 }
17019 }
17020 }
17021
17022
17023 /* Value is non-zero if glyph row ROW in window W should be
17024 used to hold the cursor. */
17025
17026 static int
17027 cursor_row_p (struct window *w, struct glyph_row *row)
17028 {
17029 int cursor_row_p = 1;
17030
17031 if (PT == CHARPOS (row->end.pos))
17032 {
17033 /* Suppose the row ends on a string.
17034 Unless the row is continued, that means it ends on a newline
17035 in the string. If it's anything other than a display string
17036 (e.g. a before-string from an overlay), we don't want the
17037 cursor there. (This heuristic seems to give the optimal
17038 behavior for the various types of multi-line strings.) */
17039 if (CHARPOS (row->end.string_pos) >= 0)
17040 {
17041 if (row->continued_p)
17042 cursor_row_p = 1;
17043 else
17044 {
17045 /* Check for `display' property. */
17046 struct glyph *beg = row->glyphs[TEXT_AREA];
17047 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17048 struct glyph *glyph;
17049
17050 cursor_row_p = 0;
17051 for (glyph = end; glyph >= beg; --glyph)
17052 if (STRINGP (glyph->object))
17053 {
17054 Lisp_Object prop
17055 = Fget_char_property (make_number (PT),
17056 Qdisplay, Qnil);
17057 cursor_row_p =
17058 (!NILP (prop)
17059 && display_prop_string_p (prop, glyph->object));
17060 break;
17061 }
17062 }
17063 }
17064 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17065 {
17066 /* If the row ends in middle of a real character,
17067 and the line is continued, we want the cursor here.
17068 That's because CHARPOS (ROW->end.pos) would equal
17069 PT if PT is before the character. */
17070 if (!row->ends_in_ellipsis_p)
17071 cursor_row_p = row->continued_p;
17072 else
17073 /* If the row ends in an ellipsis, then
17074 CHARPOS (ROW->end.pos) will equal point after the
17075 invisible text. We want that position to be displayed
17076 after the ellipsis. */
17077 cursor_row_p = 0;
17078 }
17079 /* If the row ends at ZV, display the cursor at the end of that
17080 row instead of at the start of the row below. */
17081 else if (row->ends_at_zv_p)
17082 cursor_row_p = 1;
17083 else
17084 cursor_row_p = 0;
17085 }
17086
17087 return cursor_row_p;
17088 }
17089
17090 \f
17091
17092 /* Push the display property PROP so that it will be rendered at the
17093 current position in IT. Return 1 if PROP was successfully pushed,
17094 0 otherwise. */
17095
17096 static int
17097 push_display_prop (struct it *it, Lisp_Object prop)
17098 {
17099 push_it (it);
17100
17101 if (STRINGP (prop))
17102 {
17103 if (SCHARS (prop) == 0)
17104 {
17105 pop_it (it);
17106 return 0;
17107 }
17108
17109 it->string = prop;
17110 it->multibyte_p = STRING_MULTIBYTE (it->string);
17111 it->current.overlay_string_index = -1;
17112 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17113 it->end_charpos = it->string_nchars = SCHARS (it->string);
17114 it->method = GET_FROM_STRING;
17115 it->stop_charpos = 0;
17116 }
17117 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17118 {
17119 it->method = GET_FROM_STRETCH;
17120 it->object = prop;
17121 }
17122 #ifdef HAVE_WINDOW_SYSTEM
17123 else if (IMAGEP (prop))
17124 {
17125 it->what = IT_IMAGE;
17126 it->image_id = lookup_image (it->f, prop);
17127 it->method = GET_FROM_IMAGE;
17128 }
17129 #endif /* HAVE_WINDOW_SYSTEM */
17130 else
17131 {
17132 pop_it (it); /* bogus display property, give up */
17133 return 0;
17134 }
17135
17136 return 1;
17137 }
17138
17139 /* Return the character-property PROP at the current position in IT. */
17140
17141 static Lisp_Object
17142 get_it_property (struct it *it, Lisp_Object prop)
17143 {
17144 Lisp_Object position;
17145
17146 if (STRINGP (it->object))
17147 position = make_number (IT_STRING_CHARPOS (*it));
17148 else if (BUFFERP (it->object))
17149 position = make_number (IT_CHARPOS (*it));
17150 else
17151 return Qnil;
17152
17153 return Fget_char_property (position, prop, it->object);
17154 }
17155
17156 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17157
17158 static void
17159 handle_line_prefix (struct it *it)
17160 {
17161 Lisp_Object prefix;
17162 if (it->continuation_lines_width > 0)
17163 {
17164 prefix = get_it_property (it, Qwrap_prefix);
17165 if (NILP (prefix))
17166 prefix = Vwrap_prefix;
17167 }
17168 else
17169 {
17170 prefix = get_it_property (it, Qline_prefix);
17171 if (NILP (prefix))
17172 prefix = Vline_prefix;
17173 }
17174 if (! NILP (prefix) && push_display_prop (it, prefix))
17175 {
17176 /* If the prefix is wider than the window, and we try to wrap
17177 it, it would acquire its own wrap prefix, and so on till the
17178 iterator stack overflows. So, don't wrap the prefix. */
17179 it->line_wrap = TRUNCATE;
17180 it->avoid_cursor_p = 1;
17181 }
17182 }
17183
17184 \f
17185
17186 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17187 only for R2L lines from display_line, when it decides that too many
17188 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17189 continued. */
17190 static void
17191 unproduce_glyphs (struct it *it, int n)
17192 {
17193 struct glyph *glyph, *end;
17194
17195 xassert (it->glyph_row);
17196 xassert (it->glyph_row->reversed_p);
17197 xassert (it->area == TEXT_AREA);
17198 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17199
17200 if (n > it->glyph_row->used[TEXT_AREA])
17201 n = it->glyph_row->used[TEXT_AREA];
17202 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17203 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17204 for ( ; glyph < end; glyph++)
17205 glyph[-n] = *glyph;
17206 }
17207
17208 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17209 and ROW->maxpos. */
17210 static void
17211 find_row_edges (struct it *it, struct glyph_row *row,
17212 EMACS_INT min_pos, EMACS_INT min_bpos,
17213 EMACS_INT max_pos, EMACS_INT max_bpos)
17214 {
17215 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17216 lines' rows is implemented for bidi-reordered rows. */
17217
17218 /* ROW->minpos is the value of min_pos, the minimal buffer position
17219 we have in ROW. */
17220 if (min_pos <= ZV)
17221 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17222 else
17223 {
17224 /* We didn't find _any_ valid buffer positions in any of the
17225 glyphs, so we must trust the iterator's computed
17226 positions. */
17227 row->minpos = row->start.pos;
17228 max_pos = CHARPOS (it->current.pos);
17229 max_bpos = BYTEPOS (it->current.pos);
17230 }
17231
17232 if (!max_pos)
17233 abort ();
17234
17235 /* Here are the various use-cases for ending the row, and the
17236 corresponding values for ROW->maxpos:
17237
17238 Line ends in a newline from buffer eol_pos + 1
17239 Line is continued from buffer max_pos + 1
17240 Line is truncated on right it->current.pos
17241 Line ends in a newline from string max_pos
17242 Line is continued from string max_pos
17243 Line is continued from display vector max_pos
17244 Line is entirely from a string min_pos == max_pos
17245 Line is entirely from a display vector min_pos == max_pos
17246 Line that ends at ZV ZV
17247
17248 If you discover other use-cases, please add them here as
17249 appropriate. */
17250 if (row->ends_at_zv_p)
17251 row->maxpos = it->current.pos;
17252 else if (row->used[TEXT_AREA])
17253 {
17254 if (row->ends_in_newline_from_string_p)
17255 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17256 else if (CHARPOS (it->eol_pos) > 0)
17257 SET_TEXT_POS (row->maxpos,
17258 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17259 else if (row->continued_p)
17260 {
17261 /* If max_pos is different from IT's current position, it
17262 means IT->method does not belong to the display element
17263 at max_pos. However, it also means that the display
17264 element at max_pos was displayed in its entirety on this
17265 line, which is equivalent to saying that the next line
17266 starts at the next buffer position. */
17267 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17268 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17269 else
17270 {
17271 INC_BOTH (max_pos, max_bpos);
17272 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17273 }
17274 }
17275 else if (row->truncated_on_right_p)
17276 /* display_line already called reseat_at_next_visible_line_start,
17277 which puts the iterator at the beginning of the next line, in
17278 the logical order. */
17279 row->maxpos = it->current.pos;
17280 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17281 /* A line that is entirely from a string/image/stretch... */
17282 row->maxpos = row->minpos;
17283 else
17284 abort ();
17285 }
17286 else
17287 row->maxpos = it->current.pos;
17288 }
17289
17290 /* Construct the glyph row IT->glyph_row in the desired matrix of
17291 IT->w from text at the current position of IT. See dispextern.h
17292 for an overview of struct it. Value is non-zero if
17293 IT->glyph_row displays text, as opposed to a line displaying ZV
17294 only. */
17295
17296 static int
17297 display_line (struct it *it)
17298 {
17299 struct glyph_row *row = it->glyph_row;
17300 Lisp_Object overlay_arrow_string;
17301 struct it wrap_it;
17302 int may_wrap = 0, wrap_x;
17303 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
17304 int wrap_row_phys_ascent, wrap_row_phys_height;
17305 int wrap_row_extra_line_spacing;
17306 EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
17307 EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
17308 int cvpos;
17309 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
17310
17311 /* We always start displaying at hpos zero even if hscrolled. */
17312 xassert (it->hpos == 0 && it->current_x == 0);
17313
17314 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17315 >= it->w->desired_matrix->nrows)
17316 {
17317 it->w->nrows_scale_factor++;
17318 fonts_changed_p = 1;
17319 return 0;
17320 }
17321
17322 /* Is IT->w showing the region? */
17323 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17324
17325 /* Clear the result glyph row and enable it. */
17326 prepare_desired_row (row);
17327
17328 row->y = it->current_y;
17329 row->start = it->start;
17330 row->continuation_lines_width = it->continuation_lines_width;
17331 row->displays_text_p = 1;
17332 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17333 it->starts_in_middle_of_char_p = 0;
17334
17335 /* Arrange the overlays nicely for our purposes. Usually, we call
17336 display_line on only one line at a time, in which case this
17337 can't really hurt too much, or we call it on lines which appear
17338 one after another in the buffer, in which case all calls to
17339 recenter_overlay_lists but the first will be pretty cheap. */
17340 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17341
17342 /* Move over display elements that are not visible because we are
17343 hscrolled. This may stop at an x-position < IT->first_visible_x
17344 if the first glyph is partially visible or if we hit a line end. */
17345 if (it->current_x < it->first_visible_x)
17346 {
17347 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17348 MOVE_TO_POS | MOVE_TO_X);
17349 }
17350 else
17351 {
17352 /* We only do this when not calling `move_it_in_display_line_to'
17353 above, because move_it_in_display_line_to calls
17354 handle_line_prefix itself. */
17355 handle_line_prefix (it);
17356 }
17357
17358 /* Get the initial row height. This is either the height of the
17359 text hscrolled, if there is any, or zero. */
17360 row->ascent = it->max_ascent;
17361 row->height = it->max_ascent + it->max_descent;
17362 row->phys_ascent = it->max_phys_ascent;
17363 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17364 row->extra_line_spacing = it->max_extra_line_spacing;
17365
17366 /* Utility macro to record max and min buffer positions seen until now. */
17367 #define RECORD_MAX_MIN_POS(IT) \
17368 do \
17369 { \
17370 if (IT_CHARPOS (*(IT)) < min_pos) \
17371 { \
17372 min_pos = IT_CHARPOS (*(IT)); \
17373 min_bpos = IT_BYTEPOS (*(IT)); \
17374 } \
17375 if (IT_CHARPOS (*(IT)) > max_pos) \
17376 { \
17377 max_pos = IT_CHARPOS (*(IT)); \
17378 max_bpos = IT_BYTEPOS (*(IT)); \
17379 } \
17380 } \
17381 while (0)
17382
17383 /* Loop generating characters. The loop is left with IT on the next
17384 character to display. */
17385 while (1)
17386 {
17387 int n_glyphs_before, hpos_before, x_before;
17388 int x, i, nglyphs;
17389 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17390
17391 /* Retrieve the next thing to display. Value is zero if end of
17392 buffer reached. */
17393 if (!get_next_display_element (it))
17394 {
17395 /* Maybe add a space at the end of this line that is used to
17396 display the cursor there under X. Set the charpos of the
17397 first glyph of blank lines not corresponding to any text
17398 to -1. */
17399 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17400 row->exact_window_width_line_p = 1;
17401 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17402 || row->used[TEXT_AREA] == 0)
17403 {
17404 row->glyphs[TEXT_AREA]->charpos = -1;
17405 row->displays_text_p = 0;
17406
17407 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
17408 && (!MINI_WINDOW_P (it->w)
17409 || (minibuf_level && EQ (it->window, minibuf_window))))
17410 row->indicate_empty_line_p = 1;
17411 }
17412
17413 it->continuation_lines_width = 0;
17414 row->ends_at_zv_p = 1;
17415 /* A row that displays right-to-left text must always have
17416 its last face extended all the way to the end of line,
17417 even if this row ends in ZV, because we still write to th
17418 screen left to right. */
17419 if (row->reversed_p)
17420 extend_face_to_end_of_line (it);
17421 break;
17422 }
17423
17424 /* Now, get the metrics of what we want to display. This also
17425 generates glyphs in `row' (which is IT->glyph_row). */
17426 n_glyphs_before = row->used[TEXT_AREA];
17427 x = it->current_x;
17428
17429 /* Remember the line height so far in case the next element doesn't
17430 fit on the line. */
17431 if (it->line_wrap != TRUNCATE)
17432 {
17433 ascent = it->max_ascent;
17434 descent = it->max_descent;
17435 phys_ascent = it->max_phys_ascent;
17436 phys_descent = it->max_phys_descent;
17437
17438 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17439 {
17440 if (IT_DISPLAYING_WHITESPACE (it))
17441 may_wrap = 1;
17442 else if (may_wrap)
17443 {
17444 wrap_it = *it;
17445 wrap_x = x;
17446 wrap_row_used = row->used[TEXT_AREA];
17447 wrap_row_ascent = row->ascent;
17448 wrap_row_height = row->height;
17449 wrap_row_phys_ascent = row->phys_ascent;
17450 wrap_row_phys_height = row->phys_height;
17451 wrap_row_extra_line_spacing = row->extra_line_spacing;
17452 wrap_row_min_pos = min_pos;
17453 wrap_row_min_bpos = min_bpos;
17454 wrap_row_max_pos = max_pos;
17455 wrap_row_max_bpos = max_bpos;
17456 may_wrap = 0;
17457 }
17458 }
17459 }
17460
17461 PRODUCE_GLYPHS (it);
17462
17463 /* If this display element was in marginal areas, continue with
17464 the next one. */
17465 if (it->area != TEXT_AREA)
17466 {
17467 row->ascent = max (row->ascent, it->max_ascent);
17468 row->height = max (row->height, it->max_ascent + it->max_descent);
17469 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17470 row->phys_height = max (row->phys_height,
17471 it->max_phys_ascent + it->max_phys_descent);
17472 row->extra_line_spacing = max (row->extra_line_spacing,
17473 it->max_extra_line_spacing);
17474 set_iterator_to_next (it, 1);
17475 continue;
17476 }
17477
17478 /* Does the display element fit on the line? If we truncate
17479 lines, we should draw past the right edge of the window. If
17480 we don't truncate, we want to stop so that we can display the
17481 continuation glyph before the right margin. If lines are
17482 continued, there are two possible strategies for characters
17483 resulting in more than 1 glyph (e.g. tabs): Display as many
17484 glyphs as possible in this line and leave the rest for the
17485 continuation line, or display the whole element in the next
17486 line. Original redisplay did the former, so we do it also. */
17487 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17488 hpos_before = it->hpos;
17489 x_before = x;
17490
17491 if (/* Not a newline. */
17492 nglyphs > 0
17493 /* Glyphs produced fit entirely in the line. */
17494 && it->current_x < it->last_visible_x)
17495 {
17496 it->hpos += nglyphs;
17497 row->ascent = max (row->ascent, it->max_ascent);
17498 row->height = max (row->height, it->max_ascent + it->max_descent);
17499 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17500 row->phys_height = max (row->phys_height,
17501 it->max_phys_ascent + it->max_phys_descent);
17502 row->extra_line_spacing = max (row->extra_line_spacing,
17503 it->max_extra_line_spacing);
17504 if (it->current_x - it->pixel_width < it->first_visible_x)
17505 row->x = x - it->first_visible_x;
17506 /* Record the maximum and minimum buffer positions seen so
17507 far in glyphs that will be displayed by this row. */
17508 if (it->bidi_p)
17509 RECORD_MAX_MIN_POS (it);
17510 }
17511 else
17512 {
17513 int new_x;
17514 struct glyph *glyph;
17515
17516 for (i = 0; i < nglyphs; ++i, x = new_x)
17517 {
17518 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17519 new_x = x + glyph->pixel_width;
17520
17521 if (/* Lines are continued. */
17522 it->line_wrap != TRUNCATE
17523 && (/* Glyph doesn't fit on the line. */
17524 new_x > it->last_visible_x
17525 /* Or it fits exactly on a window system frame. */
17526 || (new_x == it->last_visible_x
17527 && FRAME_WINDOW_P (it->f))))
17528 {
17529 /* End of a continued line. */
17530
17531 if (it->hpos == 0
17532 || (new_x == it->last_visible_x
17533 && FRAME_WINDOW_P (it->f)))
17534 {
17535 /* Current glyph is the only one on the line or
17536 fits exactly on the line. We must continue
17537 the line because we can't draw the cursor
17538 after the glyph. */
17539 row->continued_p = 1;
17540 it->current_x = new_x;
17541 it->continuation_lines_width += new_x;
17542 ++it->hpos;
17543 /* Record the maximum and minimum buffer
17544 positions seen so far in glyphs that will be
17545 displayed by this row. */
17546 if (it->bidi_p)
17547 RECORD_MAX_MIN_POS (it);
17548 if (i == nglyphs - 1)
17549 {
17550 /* If line-wrap is on, check if a previous
17551 wrap point was found. */
17552 if (wrap_row_used > 0
17553 /* Even if there is a previous wrap
17554 point, continue the line here as
17555 usual, if (i) the previous character
17556 was a space or tab AND (ii) the
17557 current character is not. */
17558 && (!may_wrap
17559 || IT_DISPLAYING_WHITESPACE (it)))
17560 goto back_to_wrap;
17561
17562 set_iterator_to_next (it, 1);
17563 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17564 {
17565 if (!get_next_display_element (it))
17566 {
17567 row->exact_window_width_line_p = 1;
17568 it->continuation_lines_width = 0;
17569 row->continued_p = 0;
17570 row->ends_at_zv_p = 1;
17571 }
17572 else if (ITERATOR_AT_END_OF_LINE_P (it))
17573 {
17574 row->continued_p = 0;
17575 row->exact_window_width_line_p = 1;
17576 }
17577 }
17578 }
17579 }
17580 else if (CHAR_GLYPH_PADDING_P (*glyph)
17581 && !FRAME_WINDOW_P (it->f))
17582 {
17583 /* A padding glyph that doesn't fit on this line.
17584 This means the whole character doesn't fit
17585 on the line. */
17586 if (row->reversed_p)
17587 unproduce_glyphs (it, row->used[TEXT_AREA]
17588 - n_glyphs_before);
17589 row->used[TEXT_AREA] = n_glyphs_before;
17590
17591 /* Fill the rest of the row with continuation
17592 glyphs like in 20.x. */
17593 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17594 < row->glyphs[1 + TEXT_AREA])
17595 produce_special_glyphs (it, IT_CONTINUATION);
17596
17597 row->continued_p = 1;
17598 it->current_x = x_before;
17599 it->continuation_lines_width += x_before;
17600
17601 /* Restore the height to what it was before the
17602 element not fitting on the line. */
17603 it->max_ascent = ascent;
17604 it->max_descent = descent;
17605 it->max_phys_ascent = phys_ascent;
17606 it->max_phys_descent = phys_descent;
17607 }
17608 else if (wrap_row_used > 0)
17609 {
17610 back_to_wrap:
17611 if (row->reversed_p)
17612 unproduce_glyphs (it,
17613 row->used[TEXT_AREA] - wrap_row_used);
17614 *it = wrap_it;
17615 it->continuation_lines_width += wrap_x;
17616 row->used[TEXT_AREA] = wrap_row_used;
17617 row->ascent = wrap_row_ascent;
17618 row->height = wrap_row_height;
17619 row->phys_ascent = wrap_row_phys_ascent;
17620 row->phys_height = wrap_row_phys_height;
17621 row->extra_line_spacing = wrap_row_extra_line_spacing;
17622 min_pos = wrap_row_min_pos;
17623 min_bpos = wrap_row_min_bpos;
17624 max_pos = wrap_row_max_pos;
17625 max_bpos = wrap_row_max_bpos;
17626 row->continued_p = 1;
17627 row->ends_at_zv_p = 0;
17628 row->exact_window_width_line_p = 0;
17629 it->continuation_lines_width += x;
17630
17631 /* Make sure that a non-default face is extended
17632 up to the right margin of the window. */
17633 extend_face_to_end_of_line (it);
17634 }
17635 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17636 {
17637 /* A TAB that extends past the right edge of the
17638 window. This produces a single glyph on
17639 window system frames. We leave the glyph in
17640 this row and let it fill the row, but don't
17641 consume the TAB. */
17642 it->continuation_lines_width += it->last_visible_x;
17643 row->ends_in_middle_of_char_p = 1;
17644 row->continued_p = 1;
17645 glyph->pixel_width = it->last_visible_x - x;
17646 it->starts_in_middle_of_char_p = 1;
17647 }
17648 else
17649 {
17650 /* Something other than a TAB that draws past
17651 the right edge of the window. Restore
17652 positions to values before the element. */
17653 if (row->reversed_p)
17654 unproduce_glyphs (it, row->used[TEXT_AREA]
17655 - (n_glyphs_before + i));
17656 row->used[TEXT_AREA] = n_glyphs_before + i;
17657
17658 /* Display continuation glyphs. */
17659 if (!FRAME_WINDOW_P (it->f))
17660 produce_special_glyphs (it, IT_CONTINUATION);
17661 row->continued_p = 1;
17662
17663 it->current_x = x_before;
17664 it->continuation_lines_width += x;
17665 extend_face_to_end_of_line (it);
17666
17667 if (nglyphs > 1 && i > 0)
17668 {
17669 row->ends_in_middle_of_char_p = 1;
17670 it->starts_in_middle_of_char_p = 1;
17671 }
17672
17673 /* Restore the height to what it was before the
17674 element not fitting on the line. */
17675 it->max_ascent = ascent;
17676 it->max_descent = descent;
17677 it->max_phys_ascent = phys_ascent;
17678 it->max_phys_descent = phys_descent;
17679 }
17680
17681 break;
17682 }
17683 else if (new_x > it->first_visible_x)
17684 {
17685 /* Increment number of glyphs actually displayed. */
17686 ++it->hpos;
17687
17688 /* Record the maximum and minimum buffer positions
17689 seen so far in glyphs that will be displayed by
17690 this row. */
17691 if (it->bidi_p)
17692 RECORD_MAX_MIN_POS (it);
17693
17694 if (x < it->first_visible_x)
17695 /* Glyph is partially visible, i.e. row starts at
17696 negative X position. */
17697 row->x = x - it->first_visible_x;
17698 }
17699 else
17700 {
17701 /* Glyph is completely off the left margin of the
17702 window. This should not happen because of the
17703 move_it_in_display_line at the start of this
17704 function, unless the text display area of the
17705 window is empty. */
17706 xassert (it->first_visible_x <= it->last_visible_x);
17707 }
17708 }
17709
17710 row->ascent = max (row->ascent, it->max_ascent);
17711 row->height = max (row->height, it->max_ascent + it->max_descent);
17712 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17713 row->phys_height = max (row->phys_height,
17714 it->max_phys_ascent + it->max_phys_descent);
17715 row->extra_line_spacing = max (row->extra_line_spacing,
17716 it->max_extra_line_spacing);
17717
17718 /* End of this display line if row is continued. */
17719 if (row->continued_p || row->ends_at_zv_p)
17720 break;
17721 }
17722
17723 at_end_of_line:
17724 /* Is this a line end? If yes, we're also done, after making
17725 sure that a non-default face is extended up to the right
17726 margin of the window. */
17727 if (ITERATOR_AT_END_OF_LINE_P (it))
17728 {
17729 int used_before = row->used[TEXT_AREA];
17730
17731 row->ends_in_newline_from_string_p = STRINGP (it->object);
17732
17733 /* Add a space at the end of the line that is used to
17734 display the cursor there. */
17735 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17736 append_space_for_newline (it, 0);
17737
17738 /* Extend the face to the end of the line. */
17739 extend_face_to_end_of_line (it);
17740
17741 /* Make sure we have the position. */
17742 if (used_before == 0)
17743 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17744
17745 /* Record the position of the newline, for use in
17746 find_row_edges. */
17747 it->eol_pos = it->current.pos;
17748
17749 /* Consume the line end. This skips over invisible lines. */
17750 set_iterator_to_next (it, 1);
17751 it->continuation_lines_width = 0;
17752 break;
17753 }
17754
17755 /* Proceed with next display element. Note that this skips
17756 over lines invisible because of selective display. */
17757 set_iterator_to_next (it, 1);
17758
17759 /* If we truncate lines, we are done when the last displayed
17760 glyphs reach past the right margin of the window. */
17761 if (it->line_wrap == TRUNCATE
17762 && (FRAME_WINDOW_P (it->f)
17763 ? (it->current_x >= it->last_visible_x)
17764 : (it->current_x > it->last_visible_x)))
17765 {
17766 /* Maybe add truncation glyphs. */
17767 if (!FRAME_WINDOW_P (it->f))
17768 {
17769 int i, n;
17770
17771 if (!row->reversed_p)
17772 {
17773 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17774 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17775 break;
17776 }
17777 else
17778 {
17779 for (i = 0; i < row->used[TEXT_AREA]; i++)
17780 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17781 break;
17782 /* Remove any padding glyphs at the front of ROW, to
17783 make room for the truncation glyphs we will be
17784 adding below. The loop below always inserts at
17785 least one truncation glyph, so also remove the
17786 last glyph added to ROW. */
17787 unproduce_glyphs (it, i + 1);
17788 /* Adjust i for the loop below. */
17789 i = row->used[TEXT_AREA] - (i + 1);
17790 }
17791
17792 for (n = row->used[TEXT_AREA]; i < n; ++i)
17793 {
17794 row->used[TEXT_AREA] = i;
17795 produce_special_glyphs (it, IT_TRUNCATION);
17796 }
17797 }
17798 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17799 {
17800 /* Don't truncate if we can overflow newline into fringe. */
17801 if (!get_next_display_element (it))
17802 {
17803 it->continuation_lines_width = 0;
17804 row->ends_at_zv_p = 1;
17805 row->exact_window_width_line_p = 1;
17806 break;
17807 }
17808 if (ITERATOR_AT_END_OF_LINE_P (it))
17809 {
17810 row->exact_window_width_line_p = 1;
17811 goto at_end_of_line;
17812 }
17813 }
17814
17815 row->truncated_on_right_p = 1;
17816 it->continuation_lines_width = 0;
17817 reseat_at_next_visible_line_start (it, 0);
17818 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17819 it->hpos = hpos_before;
17820 it->current_x = x_before;
17821 break;
17822 }
17823 }
17824
17825 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17826 at the left window margin. */
17827 if (it->first_visible_x
17828 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17829 {
17830 if (!FRAME_WINDOW_P (it->f))
17831 insert_left_trunc_glyphs (it);
17832 row->truncated_on_left_p = 1;
17833 }
17834
17835 /* If the start of this line is the overlay arrow-position, then
17836 mark this glyph row as the one containing the overlay arrow.
17837 This is clearly a mess with variable size fonts. It would be
17838 better to let it be displayed like cursors under X. */
17839 if ((row->displays_text_p || !overlay_arrow_seen)
17840 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17841 !NILP (overlay_arrow_string)))
17842 {
17843 /* Overlay arrow in window redisplay is a fringe bitmap. */
17844 if (STRINGP (overlay_arrow_string))
17845 {
17846 struct glyph_row *arrow_row
17847 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17848 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17849 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17850 struct glyph *p = row->glyphs[TEXT_AREA];
17851 struct glyph *p2, *end;
17852
17853 /* Copy the arrow glyphs. */
17854 while (glyph < arrow_end)
17855 *p++ = *glyph++;
17856
17857 /* Throw away padding glyphs. */
17858 p2 = p;
17859 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17860 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
17861 ++p2;
17862 if (p2 > p)
17863 {
17864 while (p2 < end)
17865 *p++ = *p2++;
17866 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
17867 }
17868 }
17869 else
17870 {
17871 xassert (INTEGERP (overlay_arrow_string));
17872 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
17873 }
17874 overlay_arrow_seen = 1;
17875 }
17876
17877 /* Compute pixel dimensions of this line. */
17878 compute_line_metrics (it);
17879
17880 /* Remember the position at which this line ends. */
17881 row->end = it->current;
17882 if (!it->bidi_p)
17883 {
17884 row->minpos = row->start.pos;
17885 row->maxpos = row->end.pos;
17886 }
17887 else
17888 {
17889 /* ROW->minpos and ROW->maxpos must be the smallest and
17890 `1 + the largest' buffer positions in ROW. But if ROW was
17891 bidi-reordered, these two positions can be anywhere in the
17892 row, so we must determine them now. */
17893 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17894 }
17895
17896 /* Record whether this row ends inside an ellipsis. */
17897 row->ends_in_ellipsis_p
17898 = (it->method == GET_FROM_DISPLAY_VECTOR
17899 && it->ellipsis_p);
17900
17901 /* Save fringe bitmaps in this row. */
17902 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17903 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17904 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17905 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17906
17907 it->left_user_fringe_bitmap = 0;
17908 it->left_user_fringe_face_id = 0;
17909 it->right_user_fringe_bitmap = 0;
17910 it->right_user_fringe_face_id = 0;
17911
17912 /* Maybe set the cursor. */
17913 cvpos = it->w->cursor.vpos;
17914 if ((cvpos < 0
17915 /* In bidi-reordered rows, keep checking for proper cursor
17916 position even if one has been found already, because buffer
17917 positions in such rows change non-linearly with ROW->VPOS,
17918 when a line is continued. One exception: when we are at ZV,
17919 display cursor on the first suitable glyph row, since all
17920 the empty rows after that also have their position set to ZV. */
17921 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17922 lines' rows is implemented for bidi-reordered rows. */
17923 || (it->bidi_p
17924 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
17925 && PT >= MATRIX_ROW_START_CHARPOS (row)
17926 && PT <= MATRIX_ROW_END_CHARPOS (row)
17927 && cursor_row_p (it->w, row))
17928 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17929
17930 /* Highlight trailing whitespace. */
17931 if (!NILP (Vshow_trailing_whitespace))
17932 highlight_trailing_whitespace (it->f, it->glyph_row);
17933
17934 /* Prepare for the next line. This line starts horizontally at (X
17935 HPOS) = (0 0). Vertical positions are incremented. As a
17936 convenience for the caller, IT->glyph_row is set to the next
17937 row to be used. */
17938 it->current_x = it->hpos = 0;
17939 it->current_y += row->height;
17940 SET_TEXT_POS (it->eol_pos, 0, 0);
17941 ++it->vpos;
17942 ++it->glyph_row;
17943 /* The next row should by default use the same value of the
17944 reversed_p flag as this one. set_iterator_to_next decides when
17945 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17946 the flag accordingly. */
17947 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
17948 it->glyph_row->reversed_p = row->reversed_p;
17949 it->start = row->end;
17950 return row->displays_text_p;
17951
17952 #undef RECORD_MAX_MIN_POS
17953 }
17954
17955 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
17956 Scurrent_bidi_paragraph_direction, 0, 1, 0,
17957 doc: /* Return paragraph direction at point in BUFFER.
17958 Value is either `left-to-right' or `right-to-left'.
17959 If BUFFER is omitted or nil, it defaults to the current buffer.
17960
17961 Paragraph direction determines how the text in the paragraph is displayed.
17962 In left-to-right paragraphs, text begins at the left margin of the window
17963 and the reading direction is generally left to right. In right-to-left
17964 paragraphs, text begins at the right margin and is read from right to left.
17965
17966 See also `bidi-paragraph-direction'. */)
17967 (Lisp_Object buffer)
17968 {
17969 struct buffer *buf;
17970 struct buffer *old;
17971
17972 if (NILP (buffer))
17973 buf = current_buffer;
17974 else
17975 {
17976 CHECK_BUFFER (buffer);
17977 buf = XBUFFER (buffer);
17978 old = current_buffer;
17979 }
17980
17981 if (NILP (buf->bidi_display_reordering))
17982 return Qleft_to_right;
17983 else if (!NILP (buf->bidi_paragraph_direction))
17984 return buf->bidi_paragraph_direction;
17985 else
17986 {
17987 /* Determine the direction from buffer text. We could try to
17988 use current_matrix if it is up to date, but this seems fast
17989 enough as it is. */
17990 struct bidi_it itb;
17991 EMACS_INT pos = BUF_PT (buf);
17992 EMACS_INT bytepos = BUF_PT_BYTE (buf);
17993
17994 if (buf != current_buffer)
17995 set_buffer_temp (buf);
17996 /* Find previous non-empty line. */
17997 if (pos >= ZV && pos > BEGV)
17998 {
17999 pos--;
18000 bytepos = CHAR_TO_BYTE (pos);
18001 }
18002 while (FETCH_BYTE (bytepos) == '\n')
18003 {
18004 if (bytepos <= BEGV_BYTE)
18005 break;
18006 bytepos--;
18007 pos--;
18008 }
18009 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18010 bytepos--;
18011 itb.charpos = pos;
18012 itb.bytepos = bytepos;
18013 itb.first_elt = 1;
18014
18015 bidi_paragraph_init (NEUTRAL_DIR, &itb);
18016 if (buf != current_buffer)
18017 set_buffer_temp (old);
18018 switch (itb.paragraph_dir)
18019 {
18020 case L2R:
18021 return Qleft_to_right;
18022 break;
18023 case R2L:
18024 return Qright_to_left;
18025 break;
18026 default:
18027 abort ();
18028 }
18029 }
18030 }
18031
18032
18033 \f
18034 /***********************************************************************
18035 Menu Bar
18036 ***********************************************************************/
18037
18038 /* Redisplay the menu bar in the frame for window W.
18039
18040 The menu bar of X frames that don't have X toolkit support is
18041 displayed in a special window W->frame->menu_bar_window.
18042
18043 The menu bar of terminal frames is treated specially as far as
18044 glyph matrices are concerned. Menu bar lines are not part of
18045 windows, so the update is done directly on the frame matrix rows
18046 for the menu bar. */
18047
18048 static void
18049 display_menu_bar (struct window *w)
18050 {
18051 struct frame *f = XFRAME (WINDOW_FRAME (w));
18052 struct it it;
18053 Lisp_Object items;
18054 int i;
18055
18056 /* Don't do all this for graphical frames. */
18057 #ifdef HAVE_NTGUI
18058 if (FRAME_W32_P (f))
18059 return;
18060 #endif
18061 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18062 if (FRAME_X_P (f))
18063 return;
18064 #endif
18065
18066 #ifdef HAVE_NS
18067 if (FRAME_NS_P (f))
18068 return;
18069 #endif /* HAVE_NS */
18070
18071 #ifdef USE_X_TOOLKIT
18072 xassert (!FRAME_WINDOW_P (f));
18073 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18074 it.first_visible_x = 0;
18075 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18076 #else /* not USE_X_TOOLKIT */
18077 if (FRAME_WINDOW_P (f))
18078 {
18079 /* Menu bar lines are displayed in the desired matrix of the
18080 dummy window menu_bar_window. */
18081 struct window *menu_w;
18082 xassert (WINDOWP (f->menu_bar_window));
18083 menu_w = XWINDOW (f->menu_bar_window);
18084 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18085 MENU_FACE_ID);
18086 it.first_visible_x = 0;
18087 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18088 }
18089 else
18090 {
18091 /* This is a TTY frame, i.e. character hpos/vpos are used as
18092 pixel x/y. */
18093 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18094 MENU_FACE_ID);
18095 it.first_visible_x = 0;
18096 it.last_visible_x = FRAME_COLS (f);
18097 }
18098 #endif /* not USE_X_TOOLKIT */
18099
18100 if (! mode_line_inverse_video)
18101 /* Force the menu-bar to be displayed in the default face. */
18102 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18103
18104 /* Clear all rows of the menu bar. */
18105 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18106 {
18107 struct glyph_row *row = it.glyph_row + i;
18108 clear_glyph_row (row);
18109 row->enabled_p = 1;
18110 row->full_width_p = 1;
18111 }
18112
18113 /* Display all items of the menu bar. */
18114 items = FRAME_MENU_BAR_ITEMS (it.f);
18115 for (i = 0; i < XVECTOR (items)->size; i += 4)
18116 {
18117 Lisp_Object string;
18118
18119 /* Stop at nil string. */
18120 string = AREF (items, i + 1);
18121 if (NILP (string))
18122 break;
18123
18124 /* Remember where item was displayed. */
18125 ASET (items, i + 3, make_number (it.hpos));
18126
18127 /* Display the item, pad with one space. */
18128 if (it.current_x < it.last_visible_x)
18129 display_string (NULL, string, Qnil, 0, 0, &it,
18130 SCHARS (string) + 1, 0, 0, -1);
18131 }
18132
18133 /* Fill out the line with spaces. */
18134 if (it.current_x < it.last_visible_x)
18135 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18136
18137 /* Compute the total height of the lines. */
18138 compute_line_metrics (&it);
18139 }
18140
18141
18142 \f
18143 /***********************************************************************
18144 Mode Line
18145 ***********************************************************************/
18146
18147 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18148 FORCE is non-zero, redisplay mode lines unconditionally.
18149 Otherwise, redisplay only mode lines that are garbaged. Value is
18150 the number of windows whose mode lines were redisplayed. */
18151
18152 static int
18153 redisplay_mode_lines (Lisp_Object window, int force)
18154 {
18155 int nwindows = 0;
18156
18157 while (!NILP (window))
18158 {
18159 struct window *w = XWINDOW (window);
18160
18161 if (WINDOWP (w->hchild))
18162 nwindows += redisplay_mode_lines (w->hchild, force);
18163 else if (WINDOWP (w->vchild))
18164 nwindows += redisplay_mode_lines (w->vchild, force);
18165 else if (force
18166 || FRAME_GARBAGED_P (XFRAME (w->frame))
18167 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18168 {
18169 struct text_pos lpoint;
18170 struct buffer *old = current_buffer;
18171
18172 /* Set the window's buffer for the mode line display. */
18173 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18174 set_buffer_internal_1 (XBUFFER (w->buffer));
18175
18176 /* Point refers normally to the selected window. For any
18177 other window, set up appropriate value. */
18178 if (!EQ (window, selected_window))
18179 {
18180 struct text_pos pt;
18181
18182 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18183 if (CHARPOS (pt) < BEGV)
18184 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18185 else if (CHARPOS (pt) > (ZV - 1))
18186 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18187 else
18188 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18189 }
18190
18191 /* Display mode lines. */
18192 clear_glyph_matrix (w->desired_matrix);
18193 if (display_mode_lines (w))
18194 {
18195 ++nwindows;
18196 w->must_be_updated_p = 1;
18197 }
18198
18199 /* Restore old settings. */
18200 set_buffer_internal_1 (old);
18201 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18202 }
18203
18204 window = w->next;
18205 }
18206
18207 return nwindows;
18208 }
18209
18210
18211 /* Display the mode and/or header line of window W. Value is the
18212 sum number of mode lines and header lines displayed. */
18213
18214 static int
18215 display_mode_lines (struct window *w)
18216 {
18217 Lisp_Object old_selected_window, old_selected_frame;
18218 int n = 0;
18219
18220 old_selected_frame = selected_frame;
18221 selected_frame = w->frame;
18222 old_selected_window = selected_window;
18223 XSETWINDOW (selected_window, w);
18224
18225 /* These will be set while the mode line specs are processed. */
18226 line_number_displayed = 0;
18227 w->column_number_displayed = Qnil;
18228
18229 if (WINDOW_WANTS_MODELINE_P (w))
18230 {
18231 struct window *sel_w = XWINDOW (old_selected_window);
18232
18233 /* Select mode line face based on the real selected window. */
18234 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18235 current_buffer->mode_line_format);
18236 ++n;
18237 }
18238
18239 if (WINDOW_WANTS_HEADER_LINE_P (w))
18240 {
18241 display_mode_line (w, HEADER_LINE_FACE_ID,
18242 current_buffer->header_line_format);
18243 ++n;
18244 }
18245
18246 selected_frame = old_selected_frame;
18247 selected_window = old_selected_window;
18248 return n;
18249 }
18250
18251
18252 /* Display mode or header line of window W. FACE_ID specifies which
18253 line to display; it is either MODE_LINE_FACE_ID or
18254 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18255 display. Value is the pixel height of the mode/header line
18256 displayed. */
18257
18258 static int
18259 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18260 {
18261 struct it it;
18262 struct face *face;
18263 int count = SPECPDL_INDEX ();
18264
18265 init_iterator (&it, w, -1, -1, NULL, face_id);
18266 /* Don't extend on a previously drawn mode-line.
18267 This may happen if called from pos_visible_p. */
18268 it.glyph_row->enabled_p = 0;
18269 prepare_desired_row (it.glyph_row);
18270
18271 it.glyph_row->mode_line_p = 1;
18272
18273 if (! mode_line_inverse_video)
18274 /* Force the mode-line to be displayed in the default face. */
18275 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18276
18277 record_unwind_protect (unwind_format_mode_line,
18278 format_mode_line_unwind_data (NULL, Qnil, 0));
18279
18280 mode_line_target = MODE_LINE_DISPLAY;
18281
18282 /* Temporarily make frame's keyboard the current kboard so that
18283 kboard-local variables in the mode_line_format will get the right
18284 values. */
18285 push_kboard (FRAME_KBOARD (it.f));
18286 record_unwind_save_match_data ();
18287 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18288 pop_kboard ();
18289
18290 unbind_to (count, Qnil);
18291
18292 /* Fill up with spaces. */
18293 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18294
18295 compute_line_metrics (&it);
18296 it.glyph_row->full_width_p = 1;
18297 it.glyph_row->continued_p = 0;
18298 it.glyph_row->truncated_on_left_p = 0;
18299 it.glyph_row->truncated_on_right_p = 0;
18300
18301 /* Make a 3D mode-line have a shadow at its right end. */
18302 face = FACE_FROM_ID (it.f, face_id);
18303 extend_face_to_end_of_line (&it);
18304 if (face->box != FACE_NO_BOX)
18305 {
18306 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18307 + it.glyph_row->used[TEXT_AREA] - 1);
18308 last->right_box_line_p = 1;
18309 }
18310
18311 return it.glyph_row->height;
18312 }
18313
18314 /* Move element ELT in LIST to the front of LIST.
18315 Return the updated list. */
18316
18317 static Lisp_Object
18318 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18319 {
18320 register Lisp_Object tail, prev;
18321 register Lisp_Object tem;
18322
18323 tail = list;
18324 prev = Qnil;
18325 while (CONSP (tail))
18326 {
18327 tem = XCAR (tail);
18328
18329 if (EQ (elt, tem))
18330 {
18331 /* Splice out the link TAIL. */
18332 if (NILP (prev))
18333 list = XCDR (tail);
18334 else
18335 Fsetcdr (prev, XCDR (tail));
18336
18337 /* Now make it the first. */
18338 Fsetcdr (tail, list);
18339 return tail;
18340 }
18341 else
18342 prev = tail;
18343 tail = XCDR (tail);
18344 QUIT;
18345 }
18346
18347 /* Not found--return unchanged LIST. */
18348 return list;
18349 }
18350
18351 /* Contribute ELT to the mode line for window IT->w. How it
18352 translates into text depends on its data type.
18353
18354 IT describes the display environment in which we display, as usual.
18355
18356 DEPTH is the depth in recursion. It is used to prevent
18357 infinite recursion here.
18358
18359 FIELD_WIDTH is the number of characters the display of ELT should
18360 occupy in the mode line, and PRECISION is the maximum number of
18361 characters to display from ELT's representation. See
18362 display_string for details.
18363
18364 Returns the hpos of the end of the text generated by ELT.
18365
18366 PROPS is a property list to add to any string we encounter.
18367
18368 If RISKY is nonzero, remove (disregard) any properties in any string
18369 we encounter, and ignore :eval and :propertize.
18370
18371 The global variable `mode_line_target' determines whether the
18372 output is passed to `store_mode_line_noprop',
18373 `store_mode_line_string', or `display_string'. */
18374
18375 static int
18376 display_mode_element (struct it *it, int depth, int field_width, int precision,
18377 Lisp_Object elt, Lisp_Object props, int risky)
18378 {
18379 int n = 0, field, prec;
18380 int literal = 0;
18381
18382 tail_recurse:
18383 if (depth > 100)
18384 elt = build_string ("*too-deep*");
18385
18386 depth++;
18387
18388 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18389 {
18390 case Lisp_String:
18391 {
18392 /* A string: output it and check for %-constructs within it. */
18393 unsigned char c;
18394 int offset = 0;
18395
18396 if (SCHARS (elt) > 0
18397 && (!NILP (props) || risky))
18398 {
18399 Lisp_Object oprops, aelt;
18400 oprops = Ftext_properties_at (make_number (0), elt);
18401
18402 /* If the starting string's properties are not what
18403 we want, translate the string. Also, if the string
18404 is risky, do that anyway. */
18405
18406 if (NILP (Fequal (props, oprops)) || risky)
18407 {
18408 /* If the starting string has properties,
18409 merge the specified ones onto the existing ones. */
18410 if (! NILP (oprops) && !risky)
18411 {
18412 Lisp_Object tem;
18413
18414 oprops = Fcopy_sequence (oprops);
18415 tem = props;
18416 while (CONSP (tem))
18417 {
18418 oprops = Fplist_put (oprops, XCAR (tem),
18419 XCAR (XCDR (tem)));
18420 tem = XCDR (XCDR (tem));
18421 }
18422 props = oprops;
18423 }
18424
18425 aelt = Fassoc (elt, mode_line_proptrans_alist);
18426 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18427 {
18428 /* AELT is what we want. Move it to the front
18429 without consing. */
18430 elt = XCAR (aelt);
18431 mode_line_proptrans_alist
18432 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18433 }
18434 else
18435 {
18436 Lisp_Object tem;
18437
18438 /* If AELT has the wrong props, it is useless.
18439 so get rid of it. */
18440 if (! NILP (aelt))
18441 mode_line_proptrans_alist
18442 = Fdelq (aelt, mode_line_proptrans_alist);
18443
18444 elt = Fcopy_sequence (elt);
18445 Fset_text_properties (make_number (0), Flength (elt),
18446 props, elt);
18447 /* Add this item to mode_line_proptrans_alist. */
18448 mode_line_proptrans_alist
18449 = Fcons (Fcons (elt, props),
18450 mode_line_proptrans_alist);
18451 /* Truncate mode_line_proptrans_alist
18452 to at most 50 elements. */
18453 tem = Fnthcdr (make_number (50),
18454 mode_line_proptrans_alist);
18455 if (! NILP (tem))
18456 XSETCDR (tem, Qnil);
18457 }
18458 }
18459 }
18460
18461 offset = 0;
18462
18463 if (literal)
18464 {
18465 prec = precision - n;
18466 switch (mode_line_target)
18467 {
18468 case MODE_LINE_NOPROP:
18469 case MODE_LINE_TITLE:
18470 n += store_mode_line_noprop (SDATA (elt), -1, prec);
18471 break;
18472 case MODE_LINE_STRING:
18473 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18474 break;
18475 case MODE_LINE_DISPLAY:
18476 n += display_string (NULL, elt, Qnil, 0, 0, it,
18477 0, prec, 0, STRING_MULTIBYTE (elt));
18478 break;
18479 }
18480
18481 break;
18482 }
18483
18484 /* Handle the non-literal case. */
18485
18486 while ((precision <= 0 || n < precision)
18487 && SREF (elt, offset) != 0
18488 && (mode_line_target != MODE_LINE_DISPLAY
18489 || it->current_x < it->last_visible_x))
18490 {
18491 int last_offset = offset;
18492
18493 /* Advance to end of string or next format specifier. */
18494 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18495 ;
18496
18497 if (offset - 1 != last_offset)
18498 {
18499 int nchars, nbytes;
18500
18501 /* Output to end of string or up to '%'. Field width
18502 is length of string. Don't output more than
18503 PRECISION allows us. */
18504 offset--;
18505
18506 prec = c_string_width (SDATA (elt) + last_offset,
18507 offset - last_offset, precision - n,
18508 &nchars, &nbytes);
18509
18510 switch (mode_line_target)
18511 {
18512 case MODE_LINE_NOPROP:
18513 case MODE_LINE_TITLE:
18514 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
18515 break;
18516 case MODE_LINE_STRING:
18517 {
18518 int bytepos = last_offset;
18519 int charpos = string_byte_to_char (elt, bytepos);
18520 int endpos = (precision <= 0
18521 ? string_byte_to_char (elt, offset)
18522 : charpos + nchars);
18523
18524 n += store_mode_line_string (NULL,
18525 Fsubstring (elt, make_number (charpos),
18526 make_number (endpos)),
18527 0, 0, 0, Qnil);
18528 }
18529 break;
18530 case MODE_LINE_DISPLAY:
18531 {
18532 int bytepos = last_offset;
18533 int charpos = string_byte_to_char (elt, bytepos);
18534
18535 if (precision <= 0)
18536 nchars = string_byte_to_char (elt, offset) - charpos;
18537 n += display_string (NULL, elt, Qnil, 0, charpos,
18538 it, 0, nchars, 0,
18539 STRING_MULTIBYTE (elt));
18540 }
18541 break;
18542 }
18543 }
18544 else /* c == '%' */
18545 {
18546 int percent_position = offset;
18547
18548 /* Get the specified minimum width. Zero means
18549 don't pad. */
18550 field = 0;
18551 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18552 field = field * 10 + c - '0';
18553
18554 /* Don't pad beyond the total padding allowed. */
18555 if (field_width - n > 0 && field > field_width - n)
18556 field = field_width - n;
18557
18558 /* Note that either PRECISION <= 0 or N < PRECISION. */
18559 prec = precision - n;
18560
18561 if (c == 'M')
18562 n += display_mode_element (it, depth, field, prec,
18563 Vglobal_mode_string, props,
18564 risky);
18565 else if (c != 0)
18566 {
18567 int multibyte;
18568 int bytepos, charpos;
18569 unsigned char *spec;
18570 Lisp_Object string;
18571
18572 bytepos = percent_position;
18573 charpos = (STRING_MULTIBYTE (elt)
18574 ? string_byte_to_char (elt, bytepos)
18575 : bytepos);
18576 spec = decode_mode_spec (it->w, c, field, prec, &string);
18577 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18578
18579 switch (mode_line_target)
18580 {
18581 case MODE_LINE_NOPROP:
18582 case MODE_LINE_TITLE:
18583 n += store_mode_line_noprop (spec, field, prec);
18584 break;
18585 case MODE_LINE_STRING:
18586 {
18587 int len = strlen (spec);
18588 Lisp_Object tem = make_string (spec, len);
18589 props = Ftext_properties_at (make_number (charpos), elt);
18590 /* Should only keep face property in props */
18591 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18592 }
18593 break;
18594 case MODE_LINE_DISPLAY:
18595 {
18596 int nglyphs_before, nwritten;
18597
18598 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18599 nwritten = display_string (spec, string, elt,
18600 charpos, 0, it,
18601 field, prec, 0,
18602 multibyte);
18603
18604 /* Assign to the glyphs written above the
18605 string where the `%x' came from, position
18606 of the `%'. */
18607 if (nwritten > 0)
18608 {
18609 struct glyph *glyph
18610 = (it->glyph_row->glyphs[TEXT_AREA]
18611 + nglyphs_before);
18612 int i;
18613
18614 for (i = 0; i < nwritten; ++i)
18615 {
18616 glyph[i].object = elt;
18617 glyph[i].charpos = charpos;
18618 }
18619
18620 n += nwritten;
18621 }
18622 }
18623 break;
18624 }
18625 }
18626 else /* c == 0 */
18627 break;
18628 }
18629 }
18630 }
18631 break;
18632
18633 case Lisp_Symbol:
18634 /* A symbol: process the value of the symbol recursively
18635 as if it appeared here directly. Avoid error if symbol void.
18636 Special case: if value of symbol is a string, output the string
18637 literally. */
18638 {
18639 register Lisp_Object tem;
18640
18641 /* If the variable is not marked as risky to set
18642 then its contents are risky to use. */
18643 if (NILP (Fget (elt, Qrisky_local_variable)))
18644 risky = 1;
18645
18646 tem = Fboundp (elt);
18647 if (!NILP (tem))
18648 {
18649 tem = Fsymbol_value (elt);
18650 /* If value is a string, output that string literally:
18651 don't check for % within it. */
18652 if (STRINGP (tem))
18653 literal = 1;
18654
18655 if (!EQ (tem, elt))
18656 {
18657 /* Give up right away for nil or t. */
18658 elt = tem;
18659 goto tail_recurse;
18660 }
18661 }
18662 }
18663 break;
18664
18665 case Lisp_Cons:
18666 {
18667 register Lisp_Object car, tem;
18668
18669 /* A cons cell: five distinct cases.
18670 If first element is :eval or :propertize, do something special.
18671 If first element is a string or a cons, process all the elements
18672 and effectively concatenate them.
18673 If first element is a negative number, truncate displaying cdr to
18674 at most that many characters. If positive, pad (with spaces)
18675 to at least that many characters.
18676 If first element is a symbol, process the cadr or caddr recursively
18677 according to whether the symbol's value is non-nil or nil. */
18678 car = XCAR (elt);
18679 if (EQ (car, QCeval))
18680 {
18681 /* An element of the form (:eval FORM) means evaluate FORM
18682 and use the result as mode line elements. */
18683
18684 if (risky)
18685 break;
18686
18687 if (CONSP (XCDR (elt)))
18688 {
18689 Lisp_Object spec;
18690 spec = safe_eval (XCAR (XCDR (elt)));
18691 n += display_mode_element (it, depth, field_width - n,
18692 precision - n, spec, props,
18693 risky);
18694 }
18695 }
18696 else if (EQ (car, QCpropertize))
18697 {
18698 /* An element of the form (:propertize ELT PROPS...)
18699 means display ELT but applying properties PROPS. */
18700
18701 if (risky)
18702 break;
18703
18704 if (CONSP (XCDR (elt)))
18705 n += display_mode_element (it, depth, field_width - n,
18706 precision - n, XCAR (XCDR (elt)),
18707 XCDR (XCDR (elt)), risky);
18708 }
18709 else if (SYMBOLP (car))
18710 {
18711 tem = Fboundp (car);
18712 elt = XCDR (elt);
18713 if (!CONSP (elt))
18714 goto invalid;
18715 /* elt is now the cdr, and we know it is a cons cell.
18716 Use its car if CAR has a non-nil value. */
18717 if (!NILP (tem))
18718 {
18719 tem = Fsymbol_value (car);
18720 if (!NILP (tem))
18721 {
18722 elt = XCAR (elt);
18723 goto tail_recurse;
18724 }
18725 }
18726 /* Symbol's value is nil (or symbol is unbound)
18727 Get the cddr of the original list
18728 and if possible find the caddr and use that. */
18729 elt = XCDR (elt);
18730 if (NILP (elt))
18731 break;
18732 else if (!CONSP (elt))
18733 goto invalid;
18734 elt = XCAR (elt);
18735 goto tail_recurse;
18736 }
18737 else if (INTEGERP (car))
18738 {
18739 register int lim = XINT (car);
18740 elt = XCDR (elt);
18741 if (lim < 0)
18742 {
18743 /* Negative int means reduce maximum width. */
18744 if (precision <= 0)
18745 precision = -lim;
18746 else
18747 precision = min (precision, -lim);
18748 }
18749 else if (lim > 0)
18750 {
18751 /* Padding specified. Don't let it be more than
18752 current maximum. */
18753 if (precision > 0)
18754 lim = min (precision, lim);
18755
18756 /* If that's more padding than already wanted, queue it.
18757 But don't reduce padding already specified even if
18758 that is beyond the current truncation point. */
18759 field_width = max (lim, field_width);
18760 }
18761 goto tail_recurse;
18762 }
18763 else if (STRINGP (car) || CONSP (car))
18764 {
18765 Lisp_Object halftail = elt;
18766 int len = 0;
18767
18768 while (CONSP (elt)
18769 && (precision <= 0 || n < precision))
18770 {
18771 n += display_mode_element (it, depth,
18772 /* Do padding only after the last
18773 element in the list. */
18774 (! CONSP (XCDR (elt))
18775 ? field_width - n
18776 : 0),
18777 precision - n, XCAR (elt),
18778 props, risky);
18779 elt = XCDR (elt);
18780 len++;
18781 if ((len & 1) == 0)
18782 halftail = XCDR (halftail);
18783 /* Check for cycle. */
18784 if (EQ (halftail, elt))
18785 break;
18786 }
18787 }
18788 }
18789 break;
18790
18791 default:
18792 invalid:
18793 elt = build_string ("*invalid*");
18794 goto tail_recurse;
18795 }
18796
18797 /* Pad to FIELD_WIDTH. */
18798 if (field_width > 0 && n < field_width)
18799 {
18800 switch (mode_line_target)
18801 {
18802 case MODE_LINE_NOPROP:
18803 case MODE_LINE_TITLE:
18804 n += store_mode_line_noprop ("", field_width - n, 0);
18805 break;
18806 case MODE_LINE_STRING:
18807 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18808 break;
18809 case MODE_LINE_DISPLAY:
18810 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18811 0, 0, 0);
18812 break;
18813 }
18814 }
18815
18816 return n;
18817 }
18818
18819 /* Store a mode-line string element in mode_line_string_list.
18820
18821 If STRING is non-null, display that C string. Otherwise, the Lisp
18822 string LISP_STRING is displayed.
18823
18824 FIELD_WIDTH is the minimum number of output glyphs to produce.
18825 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18826 with spaces. FIELD_WIDTH <= 0 means don't pad.
18827
18828 PRECISION is the maximum number of characters to output from
18829 STRING. PRECISION <= 0 means don't truncate the string.
18830
18831 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18832 properties to the string.
18833
18834 PROPS are the properties to add to the string.
18835 The mode_line_string_face face property is always added to the string.
18836 */
18837
18838 static int
18839 store_mode_line_string (char *string, Lisp_Object lisp_string, int copy_string,
18840 int field_width, int precision, Lisp_Object props)
18841 {
18842 int len;
18843 int n = 0;
18844
18845 if (string != NULL)
18846 {
18847 len = strlen (string);
18848 if (precision > 0 && len > precision)
18849 len = precision;
18850 lisp_string = make_string (string, len);
18851 if (NILP (props))
18852 props = mode_line_string_face_prop;
18853 else if (!NILP (mode_line_string_face))
18854 {
18855 Lisp_Object face = Fplist_get (props, Qface);
18856 props = Fcopy_sequence (props);
18857 if (NILP (face))
18858 face = mode_line_string_face;
18859 else
18860 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18861 props = Fplist_put (props, Qface, face);
18862 }
18863 Fadd_text_properties (make_number (0), make_number (len),
18864 props, lisp_string);
18865 }
18866 else
18867 {
18868 len = XFASTINT (Flength (lisp_string));
18869 if (precision > 0 && len > precision)
18870 {
18871 len = precision;
18872 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
18873 precision = -1;
18874 }
18875 if (!NILP (mode_line_string_face))
18876 {
18877 Lisp_Object face;
18878 if (NILP (props))
18879 props = Ftext_properties_at (make_number (0), lisp_string);
18880 face = Fplist_get (props, Qface);
18881 if (NILP (face))
18882 face = mode_line_string_face;
18883 else
18884 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18885 props = Fcons (Qface, Fcons (face, Qnil));
18886 if (copy_string)
18887 lisp_string = Fcopy_sequence (lisp_string);
18888 }
18889 if (!NILP (props))
18890 Fadd_text_properties (make_number (0), make_number (len),
18891 props, lisp_string);
18892 }
18893
18894 if (len > 0)
18895 {
18896 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18897 n += len;
18898 }
18899
18900 if (field_width > len)
18901 {
18902 field_width -= len;
18903 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
18904 if (!NILP (props))
18905 Fadd_text_properties (make_number (0), make_number (field_width),
18906 props, lisp_string);
18907 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18908 n += field_width;
18909 }
18910
18911 return n;
18912 }
18913
18914
18915 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
18916 1, 4, 0,
18917 doc: /* Format a string out of a mode line format specification.
18918 First arg FORMAT specifies the mode line format (see `mode-line-format'
18919 for details) to use.
18920
18921 Optional second arg FACE specifies the face property to put
18922 on all characters for which no face is specified.
18923 The value t means whatever face the window's mode line currently uses
18924 \(either `mode-line' or `mode-line-inactive', depending).
18925 A value of nil means the default is no face property.
18926 If FACE is an integer, the value string has no text properties.
18927
18928 Optional third and fourth args WINDOW and BUFFER specify the window
18929 and buffer to use as the context for the formatting (defaults
18930 are the selected window and the window's buffer). */)
18931 (Lisp_Object format, Lisp_Object face, Lisp_Object window, Lisp_Object buffer)
18932 {
18933 struct it it;
18934 int len;
18935 struct window *w;
18936 struct buffer *old_buffer = NULL;
18937 int face_id = -1;
18938 int no_props = INTEGERP (face);
18939 int count = SPECPDL_INDEX ();
18940 Lisp_Object str;
18941 int string_start = 0;
18942
18943 if (NILP (window))
18944 window = selected_window;
18945 CHECK_WINDOW (window);
18946 w = XWINDOW (window);
18947
18948 if (NILP (buffer))
18949 buffer = w->buffer;
18950 CHECK_BUFFER (buffer);
18951
18952 /* Make formatting the modeline a non-op when noninteractive, otherwise
18953 there will be problems later caused by a partially initialized frame. */
18954 if (NILP (format) || noninteractive)
18955 return empty_unibyte_string;
18956
18957 if (no_props)
18958 face = Qnil;
18959
18960 if (!NILP (face))
18961 {
18962 if (EQ (face, Qt))
18963 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
18964 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
18965 }
18966
18967 if (face_id < 0)
18968 face_id = DEFAULT_FACE_ID;
18969
18970 if (XBUFFER (buffer) != current_buffer)
18971 old_buffer = current_buffer;
18972
18973 /* Save things including mode_line_proptrans_alist,
18974 and set that to nil so that we don't alter the outer value. */
18975 record_unwind_protect (unwind_format_mode_line,
18976 format_mode_line_unwind_data
18977 (old_buffer, selected_window, 1));
18978 mode_line_proptrans_alist = Qnil;
18979
18980 Fselect_window (window, Qt);
18981 if (old_buffer)
18982 set_buffer_internal_1 (XBUFFER (buffer));
18983
18984 init_iterator (&it, w, -1, -1, NULL, face_id);
18985
18986 if (no_props)
18987 {
18988 mode_line_target = MODE_LINE_NOPROP;
18989 mode_line_string_face_prop = Qnil;
18990 mode_line_string_list = Qnil;
18991 string_start = MODE_LINE_NOPROP_LEN (0);
18992 }
18993 else
18994 {
18995 mode_line_target = MODE_LINE_STRING;
18996 mode_line_string_list = Qnil;
18997 mode_line_string_face = face;
18998 mode_line_string_face_prop
18999 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19000 }
19001
19002 push_kboard (FRAME_KBOARD (it.f));
19003 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19004 pop_kboard ();
19005
19006 if (no_props)
19007 {
19008 len = MODE_LINE_NOPROP_LEN (string_start);
19009 str = make_string (mode_line_noprop_buf + string_start, len);
19010 }
19011 else
19012 {
19013 mode_line_string_list = Fnreverse (mode_line_string_list);
19014 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19015 empty_unibyte_string);
19016 }
19017
19018 unbind_to (count, Qnil);
19019 return str;
19020 }
19021
19022 /* Write a null-terminated, right justified decimal representation of
19023 the positive integer D to BUF using a minimal field width WIDTH. */
19024
19025 static void
19026 pint2str (register char *buf, register int width, register int d)
19027 {
19028 register char *p = buf;
19029
19030 if (d <= 0)
19031 *p++ = '0';
19032 else
19033 {
19034 while (d > 0)
19035 {
19036 *p++ = d % 10 + '0';
19037 d /= 10;
19038 }
19039 }
19040
19041 for (width -= (int) (p - buf); width > 0; --width)
19042 *p++ = ' ';
19043 *p-- = '\0';
19044 while (p > buf)
19045 {
19046 d = *buf;
19047 *buf++ = *p;
19048 *p-- = d;
19049 }
19050 }
19051
19052 /* Write a null-terminated, right justified decimal and "human
19053 readable" representation of the nonnegative integer D to BUF using
19054 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19055
19056 static const char power_letter[] =
19057 {
19058 0, /* not used */
19059 'k', /* kilo */
19060 'M', /* mega */
19061 'G', /* giga */
19062 'T', /* tera */
19063 'P', /* peta */
19064 'E', /* exa */
19065 'Z', /* zetta */
19066 'Y' /* yotta */
19067 };
19068
19069 static void
19070 pint2hrstr (char *buf, int width, int d)
19071 {
19072 /* We aim to represent the nonnegative integer D as
19073 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19074 int quotient = d;
19075 int remainder = 0;
19076 /* -1 means: do not use TENTHS. */
19077 int tenths = -1;
19078 int exponent = 0;
19079
19080 /* Length of QUOTIENT.TENTHS as a string. */
19081 int length;
19082
19083 char * psuffix;
19084 char * p;
19085
19086 if (1000 <= quotient)
19087 {
19088 /* Scale to the appropriate EXPONENT. */
19089 do
19090 {
19091 remainder = quotient % 1000;
19092 quotient /= 1000;
19093 exponent++;
19094 }
19095 while (1000 <= quotient);
19096
19097 /* Round to nearest and decide whether to use TENTHS or not. */
19098 if (quotient <= 9)
19099 {
19100 tenths = remainder / 100;
19101 if (50 <= remainder % 100)
19102 {
19103 if (tenths < 9)
19104 tenths++;
19105 else
19106 {
19107 quotient++;
19108 if (quotient == 10)
19109 tenths = -1;
19110 else
19111 tenths = 0;
19112 }
19113 }
19114 }
19115 else
19116 if (500 <= remainder)
19117 {
19118 if (quotient < 999)
19119 quotient++;
19120 else
19121 {
19122 quotient = 1;
19123 exponent++;
19124 tenths = 0;
19125 }
19126 }
19127 }
19128
19129 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19130 if (tenths == -1 && quotient <= 99)
19131 if (quotient <= 9)
19132 length = 1;
19133 else
19134 length = 2;
19135 else
19136 length = 3;
19137 p = psuffix = buf + max (width, length);
19138
19139 /* Print EXPONENT. */
19140 if (exponent)
19141 *psuffix++ = power_letter[exponent];
19142 *psuffix = '\0';
19143
19144 /* Print TENTHS. */
19145 if (tenths >= 0)
19146 {
19147 *--p = '0' + tenths;
19148 *--p = '.';
19149 }
19150
19151 /* Print QUOTIENT. */
19152 do
19153 {
19154 int digit = quotient % 10;
19155 *--p = '0' + digit;
19156 }
19157 while ((quotient /= 10) != 0);
19158
19159 /* Print leading spaces. */
19160 while (buf < p)
19161 *--p = ' ';
19162 }
19163
19164 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19165 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19166 type of CODING_SYSTEM. Return updated pointer into BUF. */
19167
19168 static unsigned char invalid_eol_type[] = "(*invalid*)";
19169
19170 static char *
19171 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19172 {
19173 Lisp_Object val;
19174 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
19175 const unsigned char *eol_str;
19176 int eol_str_len;
19177 /* The EOL conversion we are using. */
19178 Lisp_Object eoltype;
19179
19180 val = CODING_SYSTEM_SPEC (coding_system);
19181 eoltype = Qnil;
19182
19183 if (!VECTORP (val)) /* Not yet decided. */
19184 {
19185 if (multibyte)
19186 *buf++ = '-';
19187 if (eol_flag)
19188 eoltype = eol_mnemonic_undecided;
19189 /* Don't mention EOL conversion if it isn't decided. */
19190 }
19191 else
19192 {
19193 Lisp_Object attrs;
19194 Lisp_Object eolvalue;
19195
19196 attrs = AREF (val, 0);
19197 eolvalue = AREF (val, 2);
19198
19199 if (multibyte)
19200 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19201
19202 if (eol_flag)
19203 {
19204 /* The EOL conversion that is normal on this system. */
19205
19206 if (NILP (eolvalue)) /* Not yet decided. */
19207 eoltype = eol_mnemonic_undecided;
19208 else if (VECTORP (eolvalue)) /* Not yet decided. */
19209 eoltype = eol_mnemonic_undecided;
19210 else /* eolvalue is Qunix, Qdos, or Qmac. */
19211 eoltype = (EQ (eolvalue, Qunix)
19212 ? eol_mnemonic_unix
19213 : (EQ (eolvalue, Qdos) == 1
19214 ? eol_mnemonic_dos : eol_mnemonic_mac));
19215 }
19216 }
19217
19218 if (eol_flag)
19219 {
19220 /* Mention the EOL conversion if it is not the usual one. */
19221 if (STRINGP (eoltype))
19222 {
19223 eol_str = SDATA (eoltype);
19224 eol_str_len = SBYTES (eoltype);
19225 }
19226 else if (CHARACTERP (eoltype))
19227 {
19228 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19229 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19230 eol_str = tmp;
19231 }
19232 else
19233 {
19234 eol_str = invalid_eol_type;
19235 eol_str_len = sizeof (invalid_eol_type) - 1;
19236 }
19237 memcpy (buf, eol_str, eol_str_len);
19238 buf += eol_str_len;
19239 }
19240
19241 return buf;
19242 }
19243
19244 /* Return a string for the output of a mode line %-spec for window W,
19245 generated by character C. PRECISION >= 0 means don't return a
19246 string longer than that value. FIELD_WIDTH > 0 means pad the
19247 string returned with spaces to that value. Return a Lisp string in
19248 *STRING if the resulting string is taken from that Lisp string.
19249
19250 Note we operate on the current buffer for most purposes,
19251 the exception being w->base_line_pos. */
19252
19253 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19254
19255 static char *
19256 decode_mode_spec (struct window *w, register int c, int field_width,
19257 int precision, Lisp_Object *string)
19258 {
19259 Lisp_Object obj;
19260 struct frame *f = XFRAME (WINDOW_FRAME (w));
19261 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19262 struct buffer *b = current_buffer;
19263
19264 obj = Qnil;
19265 *string = Qnil;
19266
19267 switch (c)
19268 {
19269 case '*':
19270 if (!NILP (b->read_only))
19271 return "%";
19272 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19273 return "*";
19274 return "-";
19275
19276 case '+':
19277 /* This differs from %* only for a modified read-only buffer. */
19278 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19279 return "*";
19280 if (!NILP (b->read_only))
19281 return "%";
19282 return "-";
19283
19284 case '&':
19285 /* This differs from %* in ignoring read-only-ness. */
19286 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19287 return "*";
19288 return "-";
19289
19290 case '%':
19291 return "%";
19292
19293 case '[':
19294 {
19295 int i;
19296 char *p;
19297
19298 if (command_loop_level > 5)
19299 return "[[[... ";
19300 p = decode_mode_spec_buf;
19301 for (i = 0; i < command_loop_level; i++)
19302 *p++ = '[';
19303 *p = 0;
19304 return decode_mode_spec_buf;
19305 }
19306
19307 case ']':
19308 {
19309 int i;
19310 char *p;
19311
19312 if (command_loop_level > 5)
19313 return " ...]]]";
19314 p = decode_mode_spec_buf;
19315 for (i = 0; i < command_loop_level; i++)
19316 *p++ = ']';
19317 *p = 0;
19318 return decode_mode_spec_buf;
19319 }
19320
19321 case '-':
19322 {
19323 register int i;
19324
19325 /* Let lots_of_dashes be a string of infinite length. */
19326 if (mode_line_target == MODE_LINE_NOPROP ||
19327 mode_line_target == MODE_LINE_STRING)
19328 return "--";
19329 if (field_width <= 0
19330 || field_width > sizeof (lots_of_dashes))
19331 {
19332 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19333 decode_mode_spec_buf[i] = '-';
19334 decode_mode_spec_buf[i] = '\0';
19335 return decode_mode_spec_buf;
19336 }
19337 else
19338 return lots_of_dashes;
19339 }
19340
19341 case 'b':
19342 obj = b->name;
19343 break;
19344
19345 case 'c':
19346 /* %c and %l are ignored in `frame-title-format'.
19347 (In redisplay_internal, the frame title is drawn _before_ the
19348 windows are updated, so the stuff which depends on actual
19349 window contents (such as %l) may fail to render properly, or
19350 even crash emacs.) */
19351 if (mode_line_target == MODE_LINE_TITLE)
19352 return "";
19353 else
19354 {
19355 int col = (int) current_column (); /* iftc */
19356 w->column_number_displayed = make_number (col);
19357 pint2str (decode_mode_spec_buf, field_width, col);
19358 return decode_mode_spec_buf;
19359 }
19360
19361 case 'e':
19362 #ifndef SYSTEM_MALLOC
19363 {
19364 if (NILP (Vmemory_full))
19365 return "";
19366 else
19367 return "!MEM FULL! ";
19368 }
19369 #else
19370 return "";
19371 #endif
19372
19373 case 'F':
19374 /* %F displays the frame name. */
19375 if (!NILP (f->title))
19376 return (char *) SDATA (f->title);
19377 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19378 return (char *) SDATA (f->name);
19379 return "Emacs";
19380
19381 case 'f':
19382 obj = b->filename;
19383 break;
19384
19385 case 'i':
19386 {
19387 int size = ZV - BEGV;
19388 pint2str (decode_mode_spec_buf, field_width, size);
19389 return decode_mode_spec_buf;
19390 }
19391
19392 case 'I':
19393 {
19394 int size = ZV - BEGV;
19395 pint2hrstr (decode_mode_spec_buf, field_width, size);
19396 return decode_mode_spec_buf;
19397 }
19398
19399 case 'l':
19400 {
19401 int startpos, startpos_byte, line, linepos, linepos_byte;
19402 int topline, nlines, junk, height;
19403
19404 /* %c and %l are ignored in `frame-title-format'. */
19405 if (mode_line_target == MODE_LINE_TITLE)
19406 return "";
19407
19408 startpos = XMARKER (w->start)->charpos;
19409 startpos_byte = marker_byte_position (w->start);
19410 height = WINDOW_TOTAL_LINES (w);
19411
19412 /* If we decided that this buffer isn't suitable for line numbers,
19413 don't forget that too fast. */
19414 if (EQ (w->base_line_pos, w->buffer))
19415 goto no_value;
19416 /* But do forget it, if the window shows a different buffer now. */
19417 else if (BUFFERP (w->base_line_pos))
19418 w->base_line_pos = Qnil;
19419
19420 /* If the buffer is very big, don't waste time. */
19421 if (INTEGERP (Vline_number_display_limit)
19422 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19423 {
19424 w->base_line_pos = Qnil;
19425 w->base_line_number = Qnil;
19426 goto no_value;
19427 }
19428
19429 if (INTEGERP (w->base_line_number)
19430 && INTEGERP (w->base_line_pos)
19431 && XFASTINT (w->base_line_pos) <= startpos)
19432 {
19433 line = XFASTINT (w->base_line_number);
19434 linepos = XFASTINT (w->base_line_pos);
19435 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19436 }
19437 else
19438 {
19439 line = 1;
19440 linepos = BUF_BEGV (b);
19441 linepos_byte = BUF_BEGV_BYTE (b);
19442 }
19443
19444 /* Count lines from base line to window start position. */
19445 nlines = display_count_lines (linepos, linepos_byte,
19446 startpos_byte,
19447 startpos, &junk);
19448
19449 topline = nlines + line;
19450
19451 /* Determine a new base line, if the old one is too close
19452 or too far away, or if we did not have one.
19453 "Too close" means it's plausible a scroll-down would
19454 go back past it. */
19455 if (startpos == BUF_BEGV (b))
19456 {
19457 w->base_line_number = make_number (topline);
19458 w->base_line_pos = make_number (BUF_BEGV (b));
19459 }
19460 else if (nlines < height + 25 || nlines > height * 3 + 50
19461 || linepos == BUF_BEGV (b))
19462 {
19463 int limit = BUF_BEGV (b);
19464 int limit_byte = BUF_BEGV_BYTE (b);
19465 int position;
19466 int distance = (height * 2 + 30) * line_number_display_limit_width;
19467
19468 if (startpos - distance > limit)
19469 {
19470 limit = startpos - distance;
19471 limit_byte = CHAR_TO_BYTE (limit);
19472 }
19473
19474 nlines = display_count_lines (startpos, startpos_byte,
19475 limit_byte,
19476 - (height * 2 + 30),
19477 &position);
19478 /* If we couldn't find the lines we wanted within
19479 line_number_display_limit_width chars per line,
19480 give up on line numbers for this window. */
19481 if (position == limit_byte && limit == startpos - distance)
19482 {
19483 w->base_line_pos = w->buffer;
19484 w->base_line_number = Qnil;
19485 goto no_value;
19486 }
19487
19488 w->base_line_number = make_number (topline - nlines);
19489 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19490 }
19491
19492 /* Now count lines from the start pos to point. */
19493 nlines = display_count_lines (startpos, startpos_byte,
19494 PT_BYTE, PT, &junk);
19495
19496 /* Record that we did display the line number. */
19497 line_number_displayed = 1;
19498
19499 /* Make the string to show. */
19500 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19501 return decode_mode_spec_buf;
19502 no_value:
19503 {
19504 char* p = decode_mode_spec_buf;
19505 int pad = field_width - 2;
19506 while (pad-- > 0)
19507 *p++ = ' ';
19508 *p++ = '?';
19509 *p++ = '?';
19510 *p = '\0';
19511 return decode_mode_spec_buf;
19512 }
19513 }
19514 break;
19515
19516 case 'm':
19517 obj = b->mode_name;
19518 break;
19519
19520 case 'n':
19521 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19522 return " Narrow";
19523 break;
19524
19525 case 'p':
19526 {
19527 int pos = marker_position (w->start);
19528 int total = BUF_ZV (b) - BUF_BEGV (b);
19529
19530 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19531 {
19532 if (pos <= BUF_BEGV (b))
19533 return "All";
19534 else
19535 return "Bottom";
19536 }
19537 else if (pos <= BUF_BEGV (b))
19538 return "Top";
19539 else
19540 {
19541 if (total > 1000000)
19542 /* Do it differently for a large value, to avoid overflow. */
19543 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19544 else
19545 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19546 /* We can't normally display a 3-digit number,
19547 so get us a 2-digit number that is close. */
19548 if (total == 100)
19549 total = 99;
19550 sprintf (decode_mode_spec_buf, "%2d%%", total);
19551 return decode_mode_spec_buf;
19552 }
19553 }
19554
19555 /* Display percentage of size above the bottom of the screen. */
19556 case 'P':
19557 {
19558 int toppos = marker_position (w->start);
19559 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19560 int total = BUF_ZV (b) - BUF_BEGV (b);
19561
19562 if (botpos >= BUF_ZV (b))
19563 {
19564 if (toppos <= BUF_BEGV (b))
19565 return "All";
19566 else
19567 return "Bottom";
19568 }
19569 else
19570 {
19571 if (total > 1000000)
19572 /* Do it differently for a large value, to avoid overflow. */
19573 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19574 else
19575 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19576 /* We can't normally display a 3-digit number,
19577 so get us a 2-digit number that is close. */
19578 if (total == 100)
19579 total = 99;
19580 if (toppos <= BUF_BEGV (b))
19581 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
19582 else
19583 sprintf (decode_mode_spec_buf, "%2d%%", total);
19584 return decode_mode_spec_buf;
19585 }
19586 }
19587
19588 case 's':
19589 /* status of process */
19590 obj = Fget_buffer_process (Fcurrent_buffer ());
19591 if (NILP (obj))
19592 return "no process";
19593 #ifndef MSDOS
19594 obj = Fsymbol_name (Fprocess_status (obj));
19595 #endif
19596 break;
19597
19598 case '@':
19599 {
19600 int count = inhibit_garbage_collection ();
19601 Lisp_Object val = call1 (intern ("file-remote-p"),
19602 current_buffer->directory);
19603 unbind_to (count, Qnil);
19604
19605 if (NILP (val))
19606 return "-";
19607 else
19608 return "@";
19609 }
19610
19611 case 't': /* indicate TEXT or BINARY */
19612 #ifdef MODE_LINE_BINARY_TEXT
19613 return MODE_LINE_BINARY_TEXT (b);
19614 #else
19615 return "T";
19616 #endif
19617
19618 case 'z':
19619 /* coding-system (not including end-of-line format) */
19620 case 'Z':
19621 /* coding-system (including end-of-line type) */
19622 {
19623 int eol_flag = (c == 'Z');
19624 char *p = decode_mode_spec_buf;
19625
19626 if (! FRAME_WINDOW_P (f))
19627 {
19628 /* No need to mention EOL here--the terminal never needs
19629 to do EOL conversion. */
19630 p = decode_mode_spec_coding (CODING_ID_NAME
19631 (FRAME_KEYBOARD_CODING (f)->id),
19632 p, 0);
19633 p = decode_mode_spec_coding (CODING_ID_NAME
19634 (FRAME_TERMINAL_CODING (f)->id),
19635 p, 0);
19636 }
19637 p = decode_mode_spec_coding (b->buffer_file_coding_system,
19638 p, eol_flag);
19639
19640 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19641 #ifdef subprocesses
19642 obj = Fget_buffer_process (Fcurrent_buffer ());
19643 if (PROCESSP (obj))
19644 {
19645 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19646 p, eol_flag);
19647 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19648 p, eol_flag);
19649 }
19650 #endif /* subprocesses */
19651 #endif /* 0 */
19652 *p = 0;
19653 return decode_mode_spec_buf;
19654 }
19655 }
19656
19657 if (STRINGP (obj))
19658 {
19659 *string = obj;
19660 return (char *) SDATA (obj);
19661 }
19662 else
19663 return "";
19664 }
19665
19666
19667 /* Count up to COUNT lines starting from START / START_BYTE.
19668 But don't go beyond LIMIT_BYTE.
19669 Return the number of lines thus found (always nonnegative).
19670
19671 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19672
19673 static int
19674 display_count_lines (int start, int start_byte, int limit_byte, int count,
19675 int *byte_pos_ptr)
19676 {
19677 register unsigned char *cursor;
19678 unsigned char *base;
19679
19680 register int ceiling;
19681 register unsigned char *ceiling_addr;
19682 int orig_count = count;
19683
19684 /* If we are not in selective display mode,
19685 check only for newlines. */
19686 int selective_display = (!NILP (current_buffer->selective_display)
19687 && !INTEGERP (current_buffer->selective_display));
19688
19689 if (count > 0)
19690 {
19691 while (start_byte < limit_byte)
19692 {
19693 ceiling = BUFFER_CEILING_OF (start_byte);
19694 ceiling = min (limit_byte - 1, ceiling);
19695 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19696 base = (cursor = BYTE_POS_ADDR (start_byte));
19697 while (1)
19698 {
19699 if (selective_display)
19700 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19701 ;
19702 else
19703 while (*cursor != '\n' && ++cursor != ceiling_addr)
19704 ;
19705
19706 if (cursor != ceiling_addr)
19707 {
19708 if (--count == 0)
19709 {
19710 start_byte += cursor - base + 1;
19711 *byte_pos_ptr = start_byte;
19712 return orig_count;
19713 }
19714 else
19715 if (++cursor == ceiling_addr)
19716 break;
19717 }
19718 else
19719 break;
19720 }
19721 start_byte += cursor - base;
19722 }
19723 }
19724 else
19725 {
19726 while (start_byte > limit_byte)
19727 {
19728 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19729 ceiling = max (limit_byte, ceiling);
19730 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19731 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19732 while (1)
19733 {
19734 if (selective_display)
19735 while (--cursor != ceiling_addr
19736 && *cursor != '\n' && *cursor != 015)
19737 ;
19738 else
19739 while (--cursor != ceiling_addr && *cursor != '\n')
19740 ;
19741
19742 if (cursor != ceiling_addr)
19743 {
19744 if (++count == 0)
19745 {
19746 start_byte += cursor - base + 1;
19747 *byte_pos_ptr = start_byte;
19748 /* When scanning backwards, we should
19749 not count the newline posterior to which we stop. */
19750 return - orig_count - 1;
19751 }
19752 }
19753 else
19754 break;
19755 }
19756 /* Here we add 1 to compensate for the last decrement
19757 of CURSOR, which took it past the valid range. */
19758 start_byte += cursor - base + 1;
19759 }
19760 }
19761
19762 *byte_pos_ptr = limit_byte;
19763
19764 if (count < 0)
19765 return - orig_count + count;
19766 return orig_count - count;
19767
19768 }
19769
19770
19771 \f
19772 /***********************************************************************
19773 Displaying strings
19774 ***********************************************************************/
19775
19776 /* Display a NUL-terminated string, starting with index START.
19777
19778 If STRING is non-null, display that C string. Otherwise, the Lisp
19779 string LISP_STRING is displayed. There's a case that STRING is
19780 non-null and LISP_STRING is not nil. It means STRING is a string
19781 data of LISP_STRING. In that case, we display LISP_STRING while
19782 ignoring its text properties.
19783
19784 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19785 FACE_STRING. Display STRING or LISP_STRING with the face at
19786 FACE_STRING_POS in FACE_STRING:
19787
19788 Display the string in the environment given by IT, but use the
19789 standard display table, temporarily.
19790
19791 FIELD_WIDTH is the minimum number of output glyphs to produce.
19792 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19793 with spaces. If STRING has more characters, more than FIELD_WIDTH
19794 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19795
19796 PRECISION is the maximum number of characters to output from
19797 STRING. PRECISION < 0 means don't truncate the string.
19798
19799 This is roughly equivalent to printf format specifiers:
19800
19801 FIELD_WIDTH PRECISION PRINTF
19802 ----------------------------------------
19803 -1 -1 %s
19804 -1 10 %.10s
19805 10 -1 %10s
19806 20 10 %20.10s
19807
19808 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19809 display them, and < 0 means obey the current buffer's value of
19810 enable_multibyte_characters.
19811
19812 Value is the number of columns displayed. */
19813
19814 static int
19815 display_string (unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19816 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19817 int field_width, int precision, int max_x, int multibyte)
19818 {
19819 int hpos_at_start = it->hpos;
19820 int saved_face_id = it->face_id;
19821 struct glyph_row *row = it->glyph_row;
19822
19823 /* Initialize the iterator IT for iteration over STRING beginning
19824 with index START. */
19825 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19826 precision, field_width, multibyte);
19827 if (string && STRINGP (lisp_string))
19828 /* LISP_STRING is the one returned by decode_mode_spec. We should
19829 ignore its text properties. */
19830 it->stop_charpos = -1;
19831
19832 /* If displaying STRING, set up the face of the iterator
19833 from LISP_STRING, if that's given. */
19834 if (STRINGP (face_string))
19835 {
19836 EMACS_INT endptr;
19837 struct face *face;
19838
19839 it->face_id
19840 = face_at_string_position (it->w, face_string, face_string_pos,
19841 0, it->region_beg_charpos,
19842 it->region_end_charpos,
19843 &endptr, it->base_face_id, 0);
19844 face = FACE_FROM_ID (it->f, it->face_id);
19845 it->face_box_p = face->box != FACE_NO_BOX;
19846 }
19847
19848 /* Set max_x to the maximum allowed X position. Don't let it go
19849 beyond the right edge of the window. */
19850 if (max_x <= 0)
19851 max_x = it->last_visible_x;
19852 else
19853 max_x = min (max_x, it->last_visible_x);
19854
19855 /* Skip over display elements that are not visible. because IT->w is
19856 hscrolled. */
19857 if (it->current_x < it->first_visible_x)
19858 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19859 MOVE_TO_POS | MOVE_TO_X);
19860
19861 row->ascent = it->max_ascent;
19862 row->height = it->max_ascent + it->max_descent;
19863 row->phys_ascent = it->max_phys_ascent;
19864 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19865 row->extra_line_spacing = it->max_extra_line_spacing;
19866
19867 /* This condition is for the case that we are called with current_x
19868 past last_visible_x. */
19869 while (it->current_x < max_x)
19870 {
19871 int x_before, x, n_glyphs_before, i, nglyphs;
19872
19873 /* Get the next display element. */
19874 if (!get_next_display_element (it))
19875 break;
19876
19877 /* Produce glyphs. */
19878 x_before = it->current_x;
19879 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
19880 PRODUCE_GLYPHS (it);
19881
19882 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
19883 i = 0;
19884 x = x_before;
19885 while (i < nglyphs)
19886 {
19887 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19888
19889 if (it->line_wrap != TRUNCATE
19890 && x + glyph->pixel_width > max_x)
19891 {
19892 /* End of continued line or max_x reached. */
19893 if (CHAR_GLYPH_PADDING_P (*glyph))
19894 {
19895 /* A wide character is unbreakable. */
19896 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
19897 it->current_x = x_before;
19898 }
19899 else
19900 {
19901 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
19902 it->current_x = x;
19903 }
19904 break;
19905 }
19906 else if (x + glyph->pixel_width >= it->first_visible_x)
19907 {
19908 /* Glyph is at least partially visible. */
19909 ++it->hpos;
19910 if (x < it->first_visible_x)
19911 it->glyph_row->x = x - it->first_visible_x;
19912 }
19913 else
19914 {
19915 /* Glyph is off the left margin of the display area.
19916 Should not happen. */
19917 abort ();
19918 }
19919
19920 row->ascent = max (row->ascent, it->max_ascent);
19921 row->height = max (row->height, it->max_ascent + it->max_descent);
19922 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19923 row->phys_height = max (row->phys_height,
19924 it->max_phys_ascent + it->max_phys_descent);
19925 row->extra_line_spacing = max (row->extra_line_spacing,
19926 it->max_extra_line_spacing);
19927 x += glyph->pixel_width;
19928 ++i;
19929 }
19930
19931 /* Stop if max_x reached. */
19932 if (i < nglyphs)
19933 break;
19934
19935 /* Stop at line ends. */
19936 if (ITERATOR_AT_END_OF_LINE_P (it))
19937 {
19938 it->continuation_lines_width = 0;
19939 break;
19940 }
19941
19942 set_iterator_to_next (it, 1);
19943
19944 /* Stop if truncating at the right edge. */
19945 if (it->line_wrap == TRUNCATE
19946 && it->current_x >= it->last_visible_x)
19947 {
19948 /* Add truncation mark, but don't do it if the line is
19949 truncated at a padding space. */
19950 if (IT_CHARPOS (*it) < it->string_nchars)
19951 {
19952 if (!FRAME_WINDOW_P (it->f))
19953 {
19954 int i, n;
19955
19956 if (it->current_x > it->last_visible_x)
19957 {
19958 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19959 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19960 break;
19961 for (n = row->used[TEXT_AREA]; i < n; ++i)
19962 {
19963 row->used[TEXT_AREA] = i;
19964 produce_special_glyphs (it, IT_TRUNCATION);
19965 }
19966 }
19967 produce_special_glyphs (it, IT_TRUNCATION);
19968 }
19969 it->glyph_row->truncated_on_right_p = 1;
19970 }
19971 break;
19972 }
19973 }
19974
19975 /* Maybe insert a truncation at the left. */
19976 if (it->first_visible_x
19977 && IT_CHARPOS (*it) > 0)
19978 {
19979 if (!FRAME_WINDOW_P (it->f))
19980 insert_left_trunc_glyphs (it);
19981 it->glyph_row->truncated_on_left_p = 1;
19982 }
19983
19984 it->face_id = saved_face_id;
19985
19986 /* Value is number of columns displayed. */
19987 return it->hpos - hpos_at_start;
19988 }
19989
19990
19991 \f
19992 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19993 appears as an element of LIST or as the car of an element of LIST.
19994 If PROPVAL is a list, compare each element against LIST in that
19995 way, and return 1/2 if any element of PROPVAL is found in LIST.
19996 Otherwise return 0. This function cannot quit.
19997 The return value is 2 if the text is invisible but with an ellipsis
19998 and 1 if it's invisible and without an ellipsis. */
19999
20000 int
20001 invisible_p (register Lisp_Object propval, Lisp_Object list)
20002 {
20003 register Lisp_Object tail, proptail;
20004
20005 for (tail = list; CONSP (tail); tail = XCDR (tail))
20006 {
20007 register Lisp_Object tem;
20008 tem = XCAR (tail);
20009 if (EQ (propval, tem))
20010 return 1;
20011 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20012 return NILP (XCDR (tem)) ? 1 : 2;
20013 }
20014
20015 if (CONSP (propval))
20016 {
20017 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20018 {
20019 Lisp_Object propelt;
20020 propelt = XCAR (proptail);
20021 for (tail = list; CONSP (tail); tail = XCDR (tail))
20022 {
20023 register Lisp_Object tem;
20024 tem = XCAR (tail);
20025 if (EQ (propelt, tem))
20026 return 1;
20027 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20028 return NILP (XCDR (tem)) ? 1 : 2;
20029 }
20030 }
20031 }
20032
20033 return 0;
20034 }
20035
20036 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20037 doc: /* Non-nil if the property makes the text invisible.
20038 POS-OR-PROP can be a marker or number, in which case it is taken to be
20039 a position in the current buffer and the value of the `invisible' property
20040 is checked; or it can be some other value, which is then presumed to be the
20041 value of the `invisible' property of the text of interest.
20042 The non-nil value returned can be t for truly invisible text or something
20043 else if the text is replaced by an ellipsis. */)
20044 (Lisp_Object pos_or_prop)
20045 {
20046 Lisp_Object prop
20047 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20048 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20049 : pos_or_prop);
20050 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20051 return (invis == 0 ? Qnil
20052 : invis == 1 ? Qt
20053 : make_number (invis));
20054 }
20055
20056 /* Calculate a width or height in pixels from a specification using
20057 the following elements:
20058
20059 SPEC ::=
20060 NUM - a (fractional) multiple of the default font width/height
20061 (NUM) - specifies exactly NUM pixels
20062 UNIT - a fixed number of pixels, see below.
20063 ELEMENT - size of a display element in pixels, see below.
20064 (NUM . SPEC) - equals NUM * SPEC
20065 (+ SPEC SPEC ...) - add pixel values
20066 (- SPEC SPEC ...) - subtract pixel values
20067 (- SPEC) - negate pixel value
20068
20069 NUM ::=
20070 INT or FLOAT - a number constant
20071 SYMBOL - use symbol's (buffer local) variable binding.
20072
20073 UNIT ::=
20074 in - pixels per inch *)
20075 mm - pixels per 1/1000 meter *)
20076 cm - pixels per 1/100 meter *)
20077 width - width of current font in pixels.
20078 height - height of current font in pixels.
20079
20080 *) using the ratio(s) defined in display-pixels-per-inch.
20081
20082 ELEMENT ::=
20083
20084 left-fringe - left fringe width in pixels
20085 right-fringe - right fringe width in pixels
20086
20087 left-margin - left margin width in pixels
20088 right-margin - right margin width in pixels
20089
20090 scroll-bar - scroll-bar area width in pixels
20091
20092 Examples:
20093
20094 Pixels corresponding to 5 inches:
20095 (5 . in)
20096
20097 Total width of non-text areas on left side of window (if scroll-bar is on left):
20098 '(space :width (+ left-fringe left-margin scroll-bar))
20099
20100 Align to first text column (in header line):
20101 '(space :align-to 0)
20102
20103 Align to middle of text area minus half the width of variable `my-image'
20104 containing a loaded image:
20105 '(space :align-to (0.5 . (- text my-image)))
20106
20107 Width of left margin minus width of 1 character in the default font:
20108 '(space :width (- left-margin 1))
20109
20110 Width of left margin minus width of 2 characters in the current font:
20111 '(space :width (- left-margin (2 . width)))
20112
20113 Center 1 character over left-margin (in header line):
20114 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20115
20116 Different ways to express width of left fringe plus left margin minus one pixel:
20117 '(space :width (- (+ left-fringe left-margin) (1)))
20118 '(space :width (+ left-fringe left-margin (- (1))))
20119 '(space :width (+ left-fringe left-margin (-1)))
20120
20121 */
20122
20123 #define NUMVAL(X) \
20124 ((INTEGERP (X) || FLOATP (X)) \
20125 ? XFLOATINT (X) \
20126 : - 1)
20127
20128 int
20129 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20130 struct font *font, int width_p, int *align_to)
20131 {
20132 double pixels;
20133
20134 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20135 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20136
20137 if (NILP (prop))
20138 return OK_PIXELS (0);
20139
20140 xassert (FRAME_LIVE_P (it->f));
20141
20142 if (SYMBOLP (prop))
20143 {
20144 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20145 {
20146 char *unit = SDATA (SYMBOL_NAME (prop));
20147
20148 if (unit[0] == 'i' && unit[1] == 'n')
20149 pixels = 1.0;
20150 else if (unit[0] == 'm' && unit[1] == 'm')
20151 pixels = 25.4;
20152 else if (unit[0] == 'c' && unit[1] == 'm')
20153 pixels = 2.54;
20154 else
20155 pixels = 0;
20156 if (pixels > 0)
20157 {
20158 double ppi;
20159 #ifdef HAVE_WINDOW_SYSTEM
20160 if (FRAME_WINDOW_P (it->f)
20161 && (ppi = (width_p
20162 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20163 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20164 ppi > 0))
20165 return OK_PIXELS (ppi / pixels);
20166 #endif
20167
20168 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20169 || (CONSP (Vdisplay_pixels_per_inch)
20170 && (ppi = (width_p
20171 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20172 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20173 ppi > 0)))
20174 return OK_PIXELS (ppi / pixels);
20175
20176 return 0;
20177 }
20178 }
20179
20180 #ifdef HAVE_WINDOW_SYSTEM
20181 if (EQ (prop, Qheight))
20182 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20183 if (EQ (prop, Qwidth))
20184 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20185 #else
20186 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20187 return OK_PIXELS (1);
20188 #endif
20189
20190 if (EQ (prop, Qtext))
20191 return OK_PIXELS (width_p
20192 ? window_box_width (it->w, TEXT_AREA)
20193 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20194
20195 if (align_to && *align_to < 0)
20196 {
20197 *res = 0;
20198 if (EQ (prop, Qleft))
20199 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20200 if (EQ (prop, Qright))
20201 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20202 if (EQ (prop, Qcenter))
20203 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20204 + window_box_width (it->w, TEXT_AREA) / 2);
20205 if (EQ (prop, Qleft_fringe))
20206 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20207 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20208 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20209 if (EQ (prop, Qright_fringe))
20210 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20211 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20212 : window_box_right_offset (it->w, TEXT_AREA));
20213 if (EQ (prop, Qleft_margin))
20214 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20215 if (EQ (prop, Qright_margin))
20216 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20217 if (EQ (prop, Qscroll_bar))
20218 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20219 ? 0
20220 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20221 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20222 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20223 : 0)));
20224 }
20225 else
20226 {
20227 if (EQ (prop, Qleft_fringe))
20228 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20229 if (EQ (prop, Qright_fringe))
20230 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20231 if (EQ (prop, Qleft_margin))
20232 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20233 if (EQ (prop, Qright_margin))
20234 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20235 if (EQ (prop, Qscroll_bar))
20236 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20237 }
20238
20239 prop = Fbuffer_local_value (prop, it->w->buffer);
20240 }
20241
20242 if (INTEGERP (prop) || FLOATP (prop))
20243 {
20244 int base_unit = (width_p
20245 ? FRAME_COLUMN_WIDTH (it->f)
20246 : FRAME_LINE_HEIGHT (it->f));
20247 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20248 }
20249
20250 if (CONSP (prop))
20251 {
20252 Lisp_Object car = XCAR (prop);
20253 Lisp_Object cdr = XCDR (prop);
20254
20255 if (SYMBOLP (car))
20256 {
20257 #ifdef HAVE_WINDOW_SYSTEM
20258 if (FRAME_WINDOW_P (it->f)
20259 && valid_image_p (prop))
20260 {
20261 int id = lookup_image (it->f, prop);
20262 struct image *img = IMAGE_FROM_ID (it->f, id);
20263
20264 return OK_PIXELS (width_p ? img->width : img->height);
20265 }
20266 #endif
20267 if (EQ (car, Qplus) || EQ (car, Qminus))
20268 {
20269 int first = 1;
20270 double px;
20271
20272 pixels = 0;
20273 while (CONSP (cdr))
20274 {
20275 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20276 font, width_p, align_to))
20277 return 0;
20278 if (first)
20279 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20280 else
20281 pixels += px;
20282 cdr = XCDR (cdr);
20283 }
20284 if (EQ (car, Qminus))
20285 pixels = -pixels;
20286 return OK_PIXELS (pixels);
20287 }
20288
20289 car = Fbuffer_local_value (car, it->w->buffer);
20290 }
20291
20292 if (INTEGERP (car) || FLOATP (car))
20293 {
20294 double fact;
20295 pixels = XFLOATINT (car);
20296 if (NILP (cdr))
20297 return OK_PIXELS (pixels);
20298 if (calc_pixel_width_or_height (&fact, it, cdr,
20299 font, width_p, align_to))
20300 return OK_PIXELS (pixels * fact);
20301 return 0;
20302 }
20303
20304 return 0;
20305 }
20306
20307 return 0;
20308 }
20309
20310 \f
20311 /***********************************************************************
20312 Glyph Display
20313 ***********************************************************************/
20314
20315 #ifdef HAVE_WINDOW_SYSTEM
20316
20317 #if GLYPH_DEBUG
20318
20319 void
20320 dump_glyph_string (s)
20321 struct glyph_string *s;
20322 {
20323 fprintf (stderr, "glyph string\n");
20324 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20325 s->x, s->y, s->width, s->height);
20326 fprintf (stderr, " ybase = %d\n", s->ybase);
20327 fprintf (stderr, " hl = %d\n", s->hl);
20328 fprintf (stderr, " left overhang = %d, right = %d\n",
20329 s->left_overhang, s->right_overhang);
20330 fprintf (stderr, " nchars = %d\n", s->nchars);
20331 fprintf (stderr, " extends to end of line = %d\n",
20332 s->extends_to_end_of_line_p);
20333 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20334 fprintf (stderr, " bg width = %d\n", s->background_width);
20335 }
20336
20337 #endif /* GLYPH_DEBUG */
20338
20339 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20340 of XChar2b structures for S; it can't be allocated in
20341 init_glyph_string because it must be allocated via `alloca'. W
20342 is the window on which S is drawn. ROW and AREA are the glyph row
20343 and area within the row from which S is constructed. START is the
20344 index of the first glyph structure covered by S. HL is a
20345 face-override for drawing S. */
20346
20347 #ifdef HAVE_NTGUI
20348 #define OPTIONAL_HDC(hdc) HDC hdc,
20349 #define DECLARE_HDC(hdc) HDC hdc;
20350 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20351 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20352 #endif
20353
20354 #ifndef OPTIONAL_HDC
20355 #define OPTIONAL_HDC(hdc)
20356 #define DECLARE_HDC(hdc)
20357 #define ALLOCATE_HDC(hdc, f)
20358 #define RELEASE_HDC(hdc, f)
20359 #endif
20360
20361 static void
20362 init_glyph_string (struct glyph_string *s,
20363 OPTIONAL_HDC (hdc)
20364 XChar2b *char2b, struct window *w, struct glyph_row *row,
20365 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20366 {
20367 memset (s, 0, sizeof *s);
20368 s->w = w;
20369 s->f = XFRAME (w->frame);
20370 #ifdef HAVE_NTGUI
20371 s->hdc = hdc;
20372 #endif
20373 s->display = FRAME_X_DISPLAY (s->f);
20374 s->window = FRAME_X_WINDOW (s->f);
20375 s->char2b = char2b;
20376 s->hl = hl;
20377 s->row = row;
20378 s->area = area;
20379 s->first_glyph = row->glyphs[area] + start;
20380 s->height = row->height;
20381 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20382 s->ybase = s->y + row->ascent;
20383 }
20384
20385
20386 /* Append the list of glyph strings with head H and tail T to the list
20387 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20388
20389 static INLINE void
20390 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20391 struct glyph_string *h, struct glyph_string *t)
20392 {
20393 if (h)
20394 {
20395 if (*head)
20396 (*tail)->next = h;
20397 else
20398 *head = h;
20399 h->prev = *tail;
20400 *tail = t;
20401 }
20402 }
20403
20404
20405 /* Prepend the list of glyph strings with head H and tail T to the
20406 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20407 result. */
20408
20409 static INLINE void
20410 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20411 struct glyph_string *h, struct glyph_string *t)
20412 {
20413 if (h)
20414 {
20415 if (*head)
20416 (*head)->prev = t;
20417 else
20418 *tail = t;
20419 t->next = *head;
20420 *head = h;
20421 }
20422 }
20423
20424
20425 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20426 Set *HEAD and *TAIL to the resulting list. */
20427
20428 static INLINE void
20429 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20430 struct glyph_string *s)
20431 {
20432 s->next = s->prev = NULL;
20433 append_glyph_string_lists (head, tail, s, s);
20434 }
20435
20436
20437 /* Get face and two-byte form of character C in face FACE_ID on frame
20438 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20439 means we want to display multibyte text. DISPLAY_P non-zero means
20440 make sure that X resources for the face returned are allocated.
20441 Value is a pointer to a realized face that is ready for display if
20442 DISPLAY_P is non-zero. */
20443
20444 static INLINE struct face *
20445 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20446 XChar2b *char2b, int multibyte_p, int display_p)
20447 {
20448 struct face *face = FACE_FROM_ID (f, face_id);
20449
20450 if (face->font)
20451 {
20452 unsigned code = face->font->driver->encode_char (face->font, c);
20453
20454 if (code != FONT_INVALID_CODE)
20455 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20456 else
20457 STORE_XCHAR2B (char2b, 0, 0);
20458 }
20459
20460 /* Make sure X resources of the face are allocated. */
20461 #ifdef HAVE_X_WINDOWS
20462 if (display_p)
20463 #endif
20464 {
20465 xassert (face != NULL);
20466 PREPARE_FACE_FOR_DISPLAY (f, face);
20467 }
20468
20469 return face;
20470 }
20471
20472
20473 /* Get face and two-byte form of character glyph GLYPH on frame F.
20474 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20475 a pointer to a realized face that is ready for display. */
20476
20477 static INLINE struct face *
20478 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20479 XChar2b *char2b, int *two_byte_p)
20480 {
20481 struct face *face;
20482
20483 xassert (glyph->type == CHAR_GLYPH);
20484 face = FACE_FROM_ID (f, glyph->face_id);
20485
20486 if (two_byte_p)
20487 *two_byte_p = 0;
20488
20489 if (face->font)
20490 {
20491 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
20492
20493 if (code != FONT_INVALID_CODE)
20494 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20495 else
20496 STORE_XCHAR2B (char2b, 0, 0);
20497 }
20498
20499 /* Make sure X resources of the face are allocated. */
20500 xassert (face != NULL);
20501 PREPARE_FACE_FOR_DISPLAY (f, face);
20502 return face;
20503 }
20504
20505
20506 /* Fill glyph string S with composition components specified by S->cmp.
20507
20508 BASE_FACE is the base face of the composition.
20509 S->cmp_from is the index of the first component for S.
20510
20511 OVERLAPS non-zero means S should draw the foreground only, and use
20512 its physical height for clipping. See also draw_glyphs.
20513
20514 Value is the index of a component not in S. */
20515
20516 static int
20517 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20518 int overlaps)
20519 {
20520 int i;
20521 /* For all glyphs of this composition, starting at the offset
20522 S->cmp_from, until we reach the end of the definition or encounter a
20523 glyph that requires the different face, add it to S. */
20524 struct face *face;
20525
20526 xassert (s);
20527
20528 s->for_overlaps = overlaps;
20529 s->face = NULL;
20530 s->font = NULL;
20531 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20532 {
20533 int c = COMPOSITION_GLYPH (s->cmp, i);
20534
20535 if (c != '\t')
20536 {
20537 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20538 -1, Qnil);
20539
20540 face = get_char_face_and_encoding (s->f, c, face_id,
20541 s->char2b + i, 1, 1);
20542 if (face)
20543 {
20544 if (! s->face)
20545 {
20546 s->face = face;
20547 s->font = s->face->font;
20548 }
20549 else if (s->face != face)
20550 break;
20551 }
20552 }
20553 ++s->nchars;
20554 }
20555 s->cmp_to = i;
20556
20557 /* All glyph strings for the same composition has the same width,
20558 i.e. the width set for the first component of the composition. */
20559 s->width = s->first_glyph->pixel_width;
20560
20561 /* If the specified font could not be loaded, use the frame's
20562 default font, but record the fact that we couldn't load it in
20563 the glyph string so that we can draw rectangles for the
20564 characters of the glyph string. */
20565 if (s->font == NULL)
20566 {
20567 s->font_not_found_p = 1;
20568 s->font = FRAME_FONT (s->f);
20569 }
20570
20571 /* Adjust base line for subscript/superscript text. */
20572 s->ybase += s->first_glyph->voffset;
20573
20574 /* This glyph string must always be drawn with 16-bit functions. */
20575 s->two_byte_p = 1;
20576
20577 return s->cmp_to;
20578 }
20579
20580 static int
20581 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20582 int start, int end, int overlaps)
20583 {
20584 struct glyph *glyph, *last;
20585 Lisp_Object lgstring;
20586 int i;
20587
20588 s->for_overlaps = overlaps;
20589 glyph = s->row->glyphs[s->area] + start;
20590 last = s->row->glyphs[s->area] + end;
20591 s->cmp_id = glyph->u.cmp.id;
20592 s->cmp_from = glyph->u.cmp.from;
20593 s->cmp_to = glyph->u.cmp.to + 1;
20594 s->face = FACE_FROM_ID (s->f, face_id);
20595 lgstring = composition_gstring_from_id (s->cmp_id);
20596 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20597 glyph++;
20598 while (glyph < last
20599 && glyph->u.cmp.automatic
20600 && glyph->u.cmp.id == s->cmp_id
20601 && s->cmp_to == glyph->u.cmp.from)
20602 s->cmp_to = (glyph++)->u.cmp.to + 1;
20603
20604 for (i = s->cmp_from; i < s->cmp_to; i++)
20605 {
20606 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20607 unsigned code = LGLYPH_CODE (lglyph);
20608
20609 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20610 }
20611 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20612 return glyph - s->row->glyphs[s->area];
20613 }
20614
20615
20616 /* Fill glyph string S from a sequence of character glyphs.
20617
20618 FACE_ID is the face id of the string. START is the index of the
20619 first glyph to consider, END is the index of the last + 1.
20620 OVERLAPS non-zero means S should draw the foreground only, and use
20621 its physical height for clipping. See also draw_glyphs.
20622
20623 Value is the index of the first glyph not in S. */
20624
20625 static int
20626 fill_glyph_string (struct glyph_string *s, int face_id,
20627 int start, int end, int overlaps)
20628 {
20629 struct glyph *glyph, *last;
20630 int voffset;
20631 int glyph_not_available_p;
20632
20633 xassert (s->f == XFRAME (s->w->frame));
20634 xassert (s->nchars == 0);
20635 xassert (start >= 0 && end > start);
20636
20637 s->for_overlaps = overlaps;
20638 glyph = s->row->glyphs[s->area] + start;
20639 last = s->row->glyphs[s->area] + end;
20640 voffset = glyph->voffset;
20641 s->padding_p = glyph->padding_p;
20642 glyph_not_available_p = glyph->glyph_not_available_p;
20643
20644 while (glyph < last
20645 && glyph->type == CHAR_GLYPH
20646 && glyph->voffset == voffset
20647 /* Same face id implies same font, nowadays. */
20648 && glyph->face_id == face_id
20649 && glyph->glyph_not_available_p == glyph_not_available_p)
20650 {
20651 int two_byte_p;
20652
20653 s->face = get_glyph_face_and_encoding (s->f, glyph,
20654 s->char2b + s->nchars,
20655 &two_byte_p);
20656 s->two_byte_p = two_byte_p;
20657 ++s->nchars;
20658 xassert (s->nchars <= end - start);
20659 s->width += glyph->pixel_width;
20660 if (glyph++->padding_p != s->padding_p)
20661 break;
20662 }
20663
20664 s->font = s->face->font;
20665
20666 /* If the specified font could not be loaded, use the frame's font,
20667 but record the fact that we couldn't load it in
20668 S->font_not_found_p so that we can draw rectangles for the
20669 characters of the glyph string. */
20670 if (s->font == NULL || glyph_not_available_p)
20671 {
20672 s->font_not_found_p = 1;
20673 s->font = FRAME_FONT (s->f);
20674 }
20675
20676 /* Adjust base line for subscript/superscript text. */
20677 s->ybase += voffset;
20678
20679 xassert (s->face && s->face->gc);
20680 return glyph - s->row->glyphs[s->area];
20681 }
20682
20683
20684 /* Fill glyph string S from image glyph S->first_glyph. */
20685
20686 static void
20687 fill_image_glyph_string (struct glyph_string *s)
20688 {
20689 xassert (s->first_glyph->type == IMAGE_GLYPH);
20690 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20691 xassert (s->img);
20692 s->slice = s->first_glyph->slice;
20693 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20694 s->font = s->face->font;
20695 s->width = s->first_glyph->pixel_width;
20696
20697 /* Adjust base line for subscript/superscript text. */
20698 s->ybase += s->first_glyph->voffset;
20699 }
20700
20701
20702 /* Fill glyph string S from a sequence of stretch glyphs.
20703
20704 ROW is the glyph row in which the glyphs are found, AREA is the
20705 area within the row. START is the index of the first glyph to
20706 consider, END is the index of the last + 1.
20707
20708 Value is the index of the first glyph not in S. */
20709
20710 static int
20711 fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
20712 enum glyph_row_area area, int start, int end)
20713 {
20714 struct glyph *glyph, *last;
20715 int voffset, face_id;
20716
20717 xassert (s->first_glyph->type == STRETCH_GLYPH);
20718
20719 glyph = s->row->glyphs[s->area] + start;
20720 last = s->row->glyphs[s->area] + end;
20721 face_id = glyph->face_id;
20722 s->face = FACE_FROM_ID (s->f, face_id);
20723 s->font = s->face->font;
20724 s->width = glyph->pixel_width;
20725 s->nchars = 1;
20726 voffset = glyph->voffset;
20727
20728 for (++glyph;
20729 (glyph < last
20730 && glyph->type == STRETCH_GLYPH
20731 && glyph->voffset == voffset
20732 && glyph->face_id == face_id);
20733 ++glyph)
20734 s->width += glyph->pixel_width;
20735
20736 /* Adjust base line for subscript/superscript text. */
20737 s->ybase += voffset;
20738
20739 /* The case that face->gc == 0 is handled when drawing the glyph
20740 string by calling PREPARE_FACE_FOR_DISPLAY. */
20741 xassert (s->face);
20742 return glyph - s->row->glyphs[s->area];
20743 }
20744
20745 static struct font_metrics *
20746 get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
20747 {
20748 static struct font_metrics metrics;
20749 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20750
20751 if (! font || code == FONT_INVALID_CODE)
20752 return NULL;
20753 font->driver->text_extents (font, &code, 1, &metrics);
20754 return &metrics;
20755 }
20756
20757 /* EXPORT for RIF:
20758 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20759 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20760 assumed to be zero. */
20761
20762 void
20763 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20764 {
20765 *left = *right = 0;
20766
20767 if (glyph->type == CHAR_GLYPH)
20768 {
20769 struct face *face;
20770 XChar2b char2b;
20771 struct font_metrics *pcm;
20772
20773 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20774 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
20775 {
20776 if (pcm->rbearing > pcm->width)
20777 *right = pcm->rbearing - pcm->width;
20778 if (pcm->lbearing < 0)
20779 *left = -pcm->lbearing;
20780 }
20781 }
20782 else if (glyph->type == COMPOSITE_GLYPH)
20783 {
20784 if (! glyph->u.cmp.automatic)
20785 {
20786 struct composition *cmp = composition_table[glyph->u.cmp.id];
20787
20788 if (cmp->rbearing > cmp->pixel_width)
20789 *right = cmp->rbearing - cmp->pixel_width;
20790 if (cmp->lbearing < 0)
20791 *left = - cmp->lbearing;
20792 }
20793 else
20794 {
20795 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20796 struct font_metrics metrics;
20797
20798 composition_gstring_width (gstring, glyph->u.cmp.from,
20799 glyph->u.cmp.to + 1, &metrics);
20800 if (metrics.rbearing > metrics.width)
20801 *right = metrics.rbearing - metrics.width;
20802 if (metrics.lbearing < 0)
20803 *left = - metrics.lbearing;
20804 }
20805 }
20806 }
20807
20808
20809 /* Return the index of the first glyph preceding glyph string S that
20810 is overwritten by S because of S's left overhang. Value is -1
20811 if no glyphs are overwritten. */
20812
20813 static int
20814 left_overwritten (struct glyph_string *s)
20815 {
20816 int k;
20817
20818 if (s->left_overhang)
20819 {
20820 int x = 0, i;
20821 struct glyph *glyphs = s->row->glyphs[s->area];
20822 int first = s->first_glyph - glyphs;
20823
20824 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
20825 x -= glyphs[i].pixel_width;
20826
20827 k = i + 1;
20828 }
20829 else
20830 k = -1;
20831
20832 return k;
20833 }
20834
20835
20836 /* Return the index of the first glyph preceding glyph string S that
20837 is overwriting S because of its right overhang. Value is -1 if no
20838 glyph in front of S overwrites S. */
20839
20840 static int
20841 left_overwriting (struct glyph_string *s)
20842 {
20843 int i, k, x;
20844 struct glyph *glyphs = s->row->glyphs[s->area];
20845 int first = s->first_glyph - glyphs;
20846
20847 k = -1;
20848 x = 0;
20849 for (i = first - 1; i >= 0; --i)
20850 {
20851 int left, right;
20852 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20853 if (x + right > 0)
20854 k = i;
20855 x -= glyphs[i].pixel_width;
20856 }
20857
20858 return k;
20859 }
20860
20861
20862 /* Return the index of the last glyph following glyph string S that is
20863 overwritten by S because of S's right overhang. Value is -1 if
20864 no such glyph is found. */
20865
20866 static int
20867 right_overwritten (struct glyph_string *s)
20868 {
20869 int k = -1;
20870
20871 if (s->right_overhang)
20872 {
20873 int x = 0, i;
20874 struct glyph *glyphs = s->row->glyphs[s->area];
20875 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20876 int end = s->row->used[s->area];
20877
20878 for (i = first; i < end && s->right_overhang > x; ++i)
20879 x += glyphs[i].pixel_width;
20880
20881 k = i;
20882 }
20883
20884 return k;
20885 }
20886
20887
20888 /* Return the index of the last glyph following glyph string S that
20889 overwrites S because of its left overhang. Value is negative
20890 if no such glyph is found. */
20891
20892 static int
20893 right_overwriting (struct glyph_string *s)
20894 {
20895 int i, k, x;
20896 int end = s->row->used[s->area];
20897 struct glyph *glyphs = s->row->glyphs[s->area];
20898 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20899
20900 k = -1;
20901 x = 0;
20902 for (i = first; i < end; ++i)
20903 {
20904 int left, right;
20905 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20906 if (x - left < 0)
20907 k = i;
20908 x += glyphs[i].pixel_width;
20909 }
20910
20911 return k;
20912 }
20913
20914
20915 /* Set background width of glyph string S. START is the index of the
20916 first glyph following S. LAST_X is the right-most x-position + 1
20917 in the drawing area. */
20918
20919 static INLINE void
20920 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
20921 {
20922 /* If the face of this glyph string has to be drawn to the end of
20923 the drawing area, set S->extends_to_end_of_line_p. */
20924
20925 if (start == s->row->used[s->area]
20926 && s->area == TEXT_AREA
20927 && ((s->row->fill_line_p
20928 && (s->hl == DRAW_NORMAL_TEXT
20929 || s->hl == DRAW_IMAGE_RAISED
20930 || s->hl == DRAW_IMAGE_SUNKEN))
20931 || s->hl == DRAW_MOUSE_FACE))
20932 s->extends_to_end_of_line_p = 1;
20933
20934 /* If S extends its face to the end of the line, set its
20935 background_width to the distance to the right edge of the drawing
20936 area. */
20937 if (s->extends_to_end_of_line_p)
20938 s->background_width = last_x - s->x + 1;
20939 else
20940 s->background_width = s->width;
20941 }
20942
20943
20944 /* Compute overhangs and x-positions for glyph string S and its
20945 predecessors, or successors. X is the starting x-position for S.
20946 BACKWARD_P non-zero means process predecessors. */
20947
20948 static void
20949 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
20950 {
20951 if (backward_p)
20952 {
20953 while (s)
20954 {
20955 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20956 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20957 x -= s->width;
20958 s->x = x;
20959 s = s->prev;
20960 }
20961 }
20962 else
20963 {
20964 while (s)
20965 {
20966 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20967 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20968 s->x = x;
20969 x += s->width;
20970 s = s->next;
20971 }
20972 }
20973 }
20974
20975
20976
20977 /* The following macros are only called from draw_glyphs below.
20978 They reference the following parameters of that function directly:
20979 `w', `row', `area', and `overlap_p'
20980 as well as the following local variables:
20981 `s', `f', and `hdc' (in W32) */
20982
20983 #ifdef HAVE_NTGUI
20984 /* On W32, silently add local `hdc' variable to argument list of
20985 init_glyph_string. */
20986 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20987 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20988 #else
20989 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20990 init_glyph_string (s, char2b, w, row, area, start, hl)
20991 #endif
20992
20993 /* Add a glyph string for a stretch glyph to the list of strings
20994 between HEAD and TAIL. START is the index of the stretch glyph in
20995 row area AREA of glyph row ROW. END is the index of the last glyph
20996 in that glyph row area. X is the current output position assigned
20997 to the new glyph string constructed. HL overrides that face of the
20998 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20999 is the right-most x-position of the drawing area. */
21000
21001 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21002 and below -- keep them on one line. */
21003 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21004 do \
21005 { \
21006 s = (struct glyph_string *) alloca (sizeof *s); \
21007 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21008 START = fill_stretch_glyph_string (s, row, area, START, END); \
21009 append_glyph_string (&HEAD, &TAIL, s); \
21010 s->x = (X); \
21011 } \
21012 while (0)
21013
21014
21015 /* Add a glyph string for an image glyph to the list of strings
21016 between HEAD and TAIL. START is the index of the image glyph in
21017 row area AREA of glyph row ROW. END is the index of the last glyph
21018 in that glyph row area. X is the current output position assigned
21019 to the new glyph string constructed. HL overrides that face of the
21020 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21021 is the right-most x-position of the drawing area. */
21022
21023 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21024 do \
21025 { \
21026 s = (struct glyph_string *) alloca (sizeof *s); \
21027 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21028 fill_image_glyph_string (s); \
21029 append_glyph_string (&HEAD, &TAIL, s); \
21030 ++START; \
21031 s->x = (X); \
21032 } \
21033 while (0)
21034
21035
21036 /* Add a glyph string for a sequence of character glyphs to the list
21037 of strings between HEAD and TAIL. START is the index of the first
21038 glyph in row area AREA of glyph row ROW that is part of the new
21039 glyph string. END is the index of the last glyph in that glyph row
21040 area. X is the current output position assigned to the new glyph
21041 string constructed. HL overrides that face of the glyph; e.g. it
21042 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21043 right-most x-position of the drawing area. */
21044
21045 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21046 do \
21047 { \
21048 int face_id; \
21049 XChar2b *char2b; \
21050 \
21051 face_id = (row)->glyphs[area][START].face_id; \
21052 \
21053 s = (struct glyph_string *) alloca (sizeof *s); \
21054 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21055 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21056 append_glyph_string (&HEAD, &TAIL, s); \
21057 s->x = (X); \
21058 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21059 } \
21060 while (0)
21061
21062
21063 /* Add a glyph string for a composite sequence to the list of strings
21064 between HEAD and TAIL. START is the index of the first glyph in
21065 row area AREA of glyph row ROW that is part of the new glyph
21066 string. END is the index of the last glyph in that glyph row area.
21067 X is the current output position assigned to the new glyph string
21068 constructed. HL overrides that face of the glyph; e.g. it is
21069 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21070 x-position of the drawing area. */
21071
21072 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21073 do { \
21074 int face_id = (row)->glyphs[area][START].face_id; \
21075 struct face *base_face = FACE_FROM_ID (f, face_id); \
21076 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21077 struct composition *cmp = composition_table[cmp_id]; \
21078 XChar2b *char2b; \
21079 struct glyph_string *first_s; \
21080 int n; \
21081 \
21082 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21083 \
21084 /* Make glyph_strings for each glyph sequence that is drawable by \
21085 the same face, and append them to HEAD/TAIL. */ \
21086 for (n = 0; n < cmp->glyph_len;) \
21087 { \
21088 s = (struct glyph_string *) alloca (sizeof *s); \
21089 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21090 append_glyph_string (&(HEAD), &(TAIL), s); \
21091 s->cmp = cmp; \
21092 s->cmp_from = n; \
21093 s->x = (X); \
21094 if (n == 0) \
21095 first_s = s; \
21096 n = fill_composite_glyph_string (s, base_face, overlaps); \
21097 } \
21098 \
21099 ++START; \
21100 s = first_s; \
21101 } while (0)
21102
21103
21104 /* Add a glyph string for a glyph-string sequence to the list of strings
21105 between HEAD and TAIL. */
21106
21107 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21108 do { \
21109 int face_id; \
21110 XChar2b *char2b; \
21111 Lisp_Object gstring; \
21112 \
21113 face_id = (row)->glyphs[area][START].face_id; \
21114 gstring = (composition_gstring_from_id \
21115 ((row)->glyphs[area][START].u.cmp.id)); \
21116 s = (struct glyph_string *) alloca (sizeof *s); \
21117 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21118 * LGSTRING_GLYPH_LEN (gstring)); \
21119 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21120 append_glyph_string (&(HEAD), &(TAIL), s); \
21121 s->x = (X); \
21122 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21123 } while (0)
21124
21125
21126 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21127 of AREA of glyph row ROW on window W between indices START and END.
21128 HL overrides the face for drawing glyph strings, e.g. it is
21129 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21130 x-positions of the drawing area.
21131
21132 This is an ugly monster macro construct because we must use alloca
21133 to allocate glyph strings (because draw_glyphs can be called
21134 asynchronously). */
21135
21136 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21137 do \
21138 { \
21139 HEAD = TAIL = NULL; \
21140 while (START < END) \
21141 { \
21142 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21143 switch (first_glyph->type) \
21144 { \
21145 case CHAR_GLYPH: \
21146 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21147 HL, X, LAST_X); \
21148 break; \
21149 \
21150 case COMPOSITE_GLYPH: \
21151 if (first_glyph->u.cmp.automatic) \
21152 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21153 HL, X, LAST_X); \
21154 else \
21155 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21156 HL, X, LAST_X); \
21157 break; \
21158 \
21159 case STRETCH_GLYPH: \
21160 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21161 HL, X, LAST_X); \
21162 break; \
21163 \
21164 case IMAGE_GLYPH: \
21165 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21166 HL, X, LAST_X); \
21167 break; \
21168 \
21169 default: \
21170 abort (); \
21171 } \
21172 \
21173 if (s) \
21174 { \
21175 set_glyph_string_background_width (s, START, LAST_X); \
21176 (X) += s->width; \
21177 } \
21178 } \
21179 } while (0)
21180
21181
21182 /* Draw glyphs between START and END in AREA of ROW on window W,
21183 starting at x-position X. X is relative to AREA in W. HL is a
21184 face-override with the following meaning:
21185
21186 DRAW_NORMAL_TEXT draw normally
21187 DRAW_CURSOR draw in cursor face
21188 DRAW_MOUSE_FACE draw in mouse face.
21189 DRAW_INVERSE_VIDEO draw in mode line face
21190 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21191 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21192
21193 If OVERLAPS is non-zero, draw only the foreground of characters and
21194 clip to the physical height of ROW. Non-zero value also defines
21195 the overlapping part to be drawn:
21196
21197 OVERLAPS_PRED overlap with preceding rows
21198 OVERLAPS_SUCC overlap with succeeding rows
21199 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21200 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21201
21202 Value is the x-position reached, relative to AREA of W. */
21203
21204 static int
21205 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21206 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21207 enum draw_glyphs_face hl, int overlaps)
21208 {
21209 struct glyph_string *head, *tail;
21210 struct glyph_string *s;
21211 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21212 int i, j, x_reached, last_x, area_left = 0;
21213 struct frame *f = XFRAME (WINDOW_FRAME (w));
21214 DECLARE_HDC (hdc);
21215
21216 ALLOCATE_HDC (hdc, f);
21217
21218 /* Let's rather be paranoid than getting a SEGV. */
21219 end = min (end, row->used[area]);
21220 start = max (0, start);
21221 start = min (end, start);
21222
21223 /* Translate X to frame coordinates. Set last_x to the right
21224 end of the drawing area. */
21225 if (row->full_width_p)
21226 {
21227 /* X is relative to the left edge of W, without scroll bars
21228 or fringes. */
21229 area_left = WINDOW_LEFT_EDGE_X (w);
21230 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21231 }
21232 else
21233 {
21234 area_left = window_box_left (w, area);
21235 last_x = area_left + window_box_width (w, area);
21236 }
21237 x += area_left;
21238
21239 /* Build a doubly-linked list of glyph_string structures between
21240 head and tail from what we have to draw. Note that the macro
21241 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21242 the reason we use a separate variable `i'. */
21243 i = start;
21244 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21245 if (tail)
21246 x_reached = tail->x + tail->background_width;
21247 else
21248 x_reached = x;
21249
21250 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21251 the row, redraw some glyphs in front or following the glyph
21252 strings built above. */
21253 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21254 {
21255 struct glyph_string *h, *t;
21256 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21257 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21258 int dummy_x = 0;
21259
21260 /* If mouse highlighting is on, we may need to draw adjacent
21261 glyphs using mouse-face highlighting. */
21262 if (area == TEXT_AREA && row->mouse_face_p)
21263 {
21264 struct glyph_row *mouse_beg_row, *mouse_end_row;
21265
21266 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21267 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21268
21269 if (row >= mouse_beg_row && row <= mouse_end_row)
21270 {
21271 check_mouse_face = 1;
21272 mouse_beg_col = (row == mouse_beg_row)
21273 ? dpyinfo->mouse_face_beg_col : 0;
21274 mouse_end_col = (row == mouse_end_row)
21275 ? dpyinfo->mouse_face_end_col
21276 : row->used[TEXT_AREA];
21277 }
21278 }
21279
21280 /* Compute overhangs for all glyph strings. */
21281 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21282 for (s = head; s; s = s->next)
21283 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21284
21285 /* Prepend glyph strings for glyphs in front of the first glyph
21286 string that are overwritten because of the first glyph
21287 string's left overhang. The background of all strings
21288 prepended must be drawn because the first glyph string
21289 draws over it. */
21290 i = left_overwritten (head);
21291 if (i >= 0)
21292 {
21293 enum draw_glyphs_face overlap_hl;
21294
21295 /* If this row contains mouse highlighting, attempt to draw
21296 the overlapped glyphs with the correct highlight. This
21297 code fails if the overlap encompasses more than one glyph
21298 and mouse-highlight spans only some of these glyphs.
21299 However, making it work perfectly involves a lot more
21300 code, and I don't know if the pathological case occurs in
21301 practice, so we'll stick to this for now. --- cyd */
21302 if (check_mouse_face
21303 && mouse_beg_col < start && mouse_end_col > i)
21304 overlap_hl = DRAW_MOUSE_FACE;
21305 else
21306 overlap_hl = DRAW_NORMAL_TEXT;
21307
21308 j = i;
21309 BUILD_GLYPH_STRINGS (j, start, h, t,
21310 overlap_hl, dummy_x, last_x);
21311 start = i;
21312 compute_overhangs_and_x (t, head->x, 1);
21313 prepend_glyph_string_lists (&head, &tail, h, t);
21314 clip_head = head;
21315 }
21316
21317 /* Prepend glyph strings for glyphs in front of the first glyph
21318 string that overwrite that glyph string because of their
21319 right overhang. For these strings, only the foreground must
21320 be drawn, because it draws over the glyph string at `head'.
21321 The background must not be drawn because this would overwrite
21322 right overhangs of preceding glyphs for which no glyph
21323 strings exist. */
21324 i = left_overwriting (head);
21325 if (i >= 0)
21326 {
21327 enum draw_glyphs_face overlap_hl;
21328
21329 if (check_mouse_face
21330 && mouse_beg_col < start && mouse_end_col > i)
21331 overlap_hl = DRAW_MOUSE_FACE;
21332 else
21333 overlap_hl = DRAW_NORMAL_TEXT;
21334
21335 clip_head = head;
21336 BUILD_GLYPH_STRINGS (i, start, h, t,
21337 overlap_hl, dummy_x, last_x);
21338 for (s = h; s; s = s->next)
21339 s->background_filled_p = 1;
21340 compute_overhangs_and_x (t, head->x, 1);
21341 prepend_glyph_string_lists (&head, &tail, h, t);
21342 }
21343
21344 /* Append glyphs strings for glyphs following the last glyph
21345 string tail that are overwritten by tail. The background of
21346 these strings has to be drawn because tail's foreground draws
21347 over it. */
21348 i = right_overwritten (tail);
21349 if (i >= 0)
21350 {
21351 enum draw_glyphs_face overlap_hl;
21352
21353 if (check_mouse_face
21354 && mouse_beg_col < i && mouse_end_col > end)
21355 overlap_hl = DRAW_MOUSE_FACE;
21356 else
21357 overlap_hl = DRAW_NORMAL_TEXT;
21358
21359 BUILD_GLYPH_STRINGS (end, i, h, t,
21360 overlap_hl, x, last_x);
21361 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21362 we don't have `end = i;' here. */
21363 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21364 append_glyph_string_lists (&head, &tail, h, t);
21365 clip_tail = tail;
21366 }
21367
21368 /* Append glyph strings for glyphs following the last glyph
21369 string tail that overwrite tail. The foreground of such
21370 glyphs has to be drawn because it writes into the background
21371 of tail. The background must not be drawn because it could
21372 paint over the foreground of following glyphs. */
21373 i = right_overwriting (tail);
21374 if (i >= 0)
21375 {
21376 enum draw_glyphs_face overlap_hl;
21377 if (check_mouse_face
21378 && mouse_beg_col < i && mouse_end_col > end)
21379 overlap_hl = DRAW_MOUSE_FACE;
21380 else
21381 overlap_hl = DRAW_NORMAL_TEXT;
21382
21383 clip_tail = tail;
21384 i++; /* We must include the Ith glyph. */
21385 BUILD_GLYPH_STRINGS (end, i, h, t,
21386 overlap_hl, x, last_x);
21387 for (s = h; s; s = s->next)
21388 s->background_filled_p = 1;
21389 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21390 append_glyph_string_lists (&head, &tail, h, t);
21391 }
21392 if (clip_head || clip_tail)
21393 for (s = head; s; s = s->next)
21394 {
21395 s->clip_head = clip_head;
21396 s->clip_tail = clip_tail;
21397 }
21398 }
21399
21400 /* Draw all strings. */
21401 for (s = head; s; s = s->next)
21402 FRAME_RIF (f)->draw_glyph_string (s);
21403
21404 #ifndef HAVE_NS
21405 /* When focus a sole frame and move horizontally, this sets on_p to 0
21406 causing a failure to erase prev cursor position. */
21407 if (area == TEXT_AREA
21408 && !row->full_width_p
21409 /* When drawing overlapping rows, only the glyph strings'
21410 foreground is drawn, which doesn't erase a cursor
21411 completely. */
21412 && !overlaps)
21413 {
21414 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21415 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21416 : (tail ? tail->x + tail->background_width : x));
21417 x0 -= area_left;
21418 x1 -= area_left;
21419
21420 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21421 row->y, MATRIX_ROW_BOTTOM_Y (row));
21422 }
21423 #endif
21424
21425 /* Value is the x-position up to which drawn, relative to AREA of W.
21426 This doesn't include parts drawn because of overhangs. */
21427 if (row->full_width_p)
21428 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21429 else
21430 x_reached -= area_left;
21431
21432 RELEASE_HDC (hdc, f);
21433
21434 return x_reached;
21435 }
21436
21437 /* Expand row matrix if too narrow. Don't expand if area
21438 is not present. */
21439
21440 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21441 { \
21442 if (!fonts_changed_p \
21443 && (it->glyph_row->glyphs[area] \
21444 < it->glyph_row->glyphs[area + 1])) \
21445 { \
21446 it->w->ncols_scale_factor++; \
21447 fonts_changed_p = 1; \
21448 } \
21449 }
21450
21451 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21452 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21453
21454 static INLINE void
21455 append_glyph (struct it *it)
21456 {
21457 struct glyph *glyph;
21458 enum glyph_row_area area = it->area;
21459
21460 xassert (it->glyph_row);
21461 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21462
21463 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21464 if (glyph < it->glyph_row->glyphs[area + 1])
21465 {
21466 /* If the glyph row is reversed, we need to prepend the glyph
21467 rather than append it. */
21468 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21469 {
21470 struct glyph *g;
21471
21472 /* Make room for the additional glyph. */
21473 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21474 g[1] = *g;
21475 glyph = it->glyph_row->glyphs[area];
21476 }
21477 glyph->charpos = CHARPOS (it->position);
21478 glyph->object = it->object;
21479 if (it->pixel_width > 0)
21480 {
21481 glyph->pixel_width = it->pixel_width;
21482 glyph->padding_p = 0;
21483 }
21484 else
21485 {
21486 /* Assure at least 1-pixel width. Otherwise, cursor can't
21487 be displayed correctly. */
21488 glyph->pixel_width = 1;
21489 glyph->padding_p = 1;
21490 }
21491 glyph->ascent = it->ascent;
21492 glyph->descent = it->descent;
21493 glyph->voffset = it->voffset;
21494 glyph->type = CHAR_GLYPH;
21495 glyph->avoid_cursor_p = it->avoid_cursor_p;
21496 glyph->multibyte_p = it->multibyte_p;
21497 glyph->left_box_line_p = it->start_of_box_run_p;
21498 glyph->right_box_line_p = it->end_of_box_run_p;
21499 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21500 || it->phys_descent > it->descent);
21501 glyph->glyph_not_available_p = it->glyph_not_available_p;
21502 glyph->face_id = it->face_id;
21503 glyph->u.ch = it->char_to_display;
21504 glyph->slice = null_glyph_slice;
21505 glyph->font_type = FONT_TYPE_UNKNOWN;
21506 if (it->bidi_p)
21507 {
21508 glyph->resolved_level = it->bidi_it.resolved_level;
21509 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21510 abort ();
21511 glyph->bidi_type = it->bidi_it.type;
21512 }
21513 else
21514 {
21515 glyph->resolved_level = 0;
21516 glyph->bidi_type = UNKNOWN_BT;
21517 }
21518 ++it->glyph_row->used[area];
21519 }
21520 else
21521 IT_EXPAND_MATRIX_WIDTH (it, area);
21522 }
21523
21524 /* Store one glyph for the composition IT->cmp_it.id in
21525 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21526 non-null. */
21527
21528 static INLINE void
21529 append_composite_glyph (struct it *it)
21530 {
21531 struct glyph *glyph;
21532 enum glyph_row_area area = it->area;
21533
21534 xassert (it->glyph_row);
21535
21536 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21537 if (glyph < it->glyph_row->glyphs[area + 1])
21538 {
21539 /* If the glyph row is reversed, we need to prepend the glyph
21540 rather than append it. */
21541 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21542 {
21543 struct glyph *g;
21544
21545 /* Make room for the new glyph. */
21546 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21547 g[1] = *g;
21548 glyph = it->glyph_row->glyphs[it->area];
21549 }
21550 glyph->charpos = it->cmp_it.charpos;
21551 glyph->object = it->object;
21552 glyph->pixel_width = it->pixel_width;
21553 glyph->ascent = it->ascent;
21554 glyph->descent = it->descent;
21555 glyph->voffset = it->voffset;
21556 glyph->type = COMPOSITE_GLYPH;
21557 if (it->cmp_it.ch < 0)
21558 {
21559 glyph->u.cmp.automatic = 0;
21560 glyph->u.cmp.id = it->cmp_it.id;
21561 }
21562 else
21563 {
21564 glyph->u.cmp.automatic = 1;
21565 glyph->u.cmp.id = it->cmp_it.id;
21566 glyph->u.cmp.from = it->cmp_it.from;
21567 glyph->u.cmp.to = it->cmp_it.to - 1;
21568 }
21569 glyph->avoid_cursor_p = it->avoid_cursor_p;
21570 glyph->multibyte_p = it->multibyte_p;
21571 glyph->left_box_line_p = it->start_of_box_run_p;
21572 glyph->right_box_line_p = it->end_of_box_run_p;
21573 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21574 || it->phys_descent > it->descent);
21575 glyph->padding_p = 0;
21576 glyph->glyph_not_available_p = 0;
21577 glyph->face_id = it->face_id;
21578 glyph->slice = null_glyph_slice;
21579 glyph->font_type = FONT_TYPE_UNKNOWN;
21580 if (it->bidi_p)
21581 {
21582 glyph->resolved_level = it->bidi_it.resolved_level;
21583 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21584 abort ();
21585 glyph->bidi_type = it->bidi_it.type;
21586 }
21587 ++it->glyph_row->used[area];
21588 }
21589 else
21590 IT_EXPAND_MATRIX_WIDTH (it, area);
21591 }
21592
21593
21594 /* Change IT->ascent and IT->height according to the setting of
21595 IT->voffset. */
21596
21597 static INLINE void
21598 take_vertical_position_into_account (struct it *it)
21599 {
21600 if (it->voffset)
21601 {
21602 if (it->voffset < 0)
21603 /* Increase the ascent so that we can display the text higher
21604 in the line. */
21605 it->ascent -= it->voffset;
21606 else
21607 /* Increase the descent so that we can display the text lower
21608 in the line. */
21609 it->descent += it->voffset;
21610 }
21611 }
21612
21613
21614 /* Produce glyphs/get display metrics for the image IT is loaded with.
21615 See the description of struct display_iterator in dispextern.h for
21616 an overview of struct display_iterator. */
21617
21618 static void
21619 produce_image_glyph (struct it *it)
21620 {
21621 struct image *img;
21622 struct face *face;
21623 int glyph_ascent, crop;
21624 struct glyph_slice slice;
21625
21626 xassert (it->what == IT_IMAGE);
21627
21628 face = FACE_FROM_ID (it->f, it->face_id);
21629 xassert (face);
21630 /* Make sure X resources of the face is loaded. */
21631 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21632
21633 if (it->image_id < 0)
21634 {
21635 /* Fringe bitmap. */
21636 it->ascent = it->phys_ascent = 0;
21637 it->descent = it->phys_descent = 0;
21638 it->pixel_width = 0;
21639 it->nglyphs = 0;
21640 return;
21641 }
21642
21643 img = IMAGE_FROM_ID (it->f, it->image_id);
21644 xassert (img);
21645 /* Make sure X resources of the image is loaded. */
21646 prepare_image_for_display (it->f, img);
21647
21648 slice.x = slice.y = 0;
21649 slice.width = img->width;
21650 slice.height = img->height;
21651
21652 if (INTEGERP (it->slice.x))
21653 slice.x = XINT (it->slice.x);
21654 else if (FLOATP (it->slice.x))
21655 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21656
21657 if (INTEGERP (it->slice.y))
21658 slice.y = XINT (it->slice.y);
21659 else if (FLOATP (it->slice.y))
21660 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21661
21662 if (INTEGERP (it->slice.width))
21663 slice.width = XINT (it->slice.width);
21664 else if (FLOATP (it->slice.width))
21665 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21666
21667 if (INTEGERP (it->slice.height))
21668 slice.height = XINT (it->slice.height);
21669 else if (FLOATP (it->slice.height))
21670 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21671
21672 if (slice.x >= img->width)
21673 slice.x = img->width;
21674 if (slice.y >= img->height)
21675 slice.y = img->height;
21676 if (slice.x + slice.width >= img->width)
21677 slice.width = img->width - slice.x;
21678 if (slice.y + slice.height > img->height)
21679 slice.height = img->height - slice.y;
21680
21681 if (slice.width == 0 || slice.height == 0)
21682 return;
21683
21684 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21685
21686 it->descent = slice.height - glyph_ascent;
21687 if (slice.y == 0)
21688 it->descent += img->vmargin;
21689 if (slice.y + slice.height == img->height)
21690 it->descent += img->vmargin;
21691 it->phys_descent = it->descent;
21692
21693 it->pixel_width = slice.width;
21694 if (slice.x == 0)
21695 it->pixel_width += img->hmargin;
21696 if (slice.x + slice.width == img->width)
21697 it->pixel_width += img->hmargin;
21698
21699 /* It's quite possible for images to have an ascent greater than
21700 their height, so don't get confused in that case. */
21701 if (it->descent < 0)
21702 it->descent = 0;
21703
21704 it->nglyphs = 1;
21705
21706 if (face->box != FACE_NO_BOX)
21707 {
21708 if (face->box_line_width > 0)
21709 {
21710 if (slice.y == 0)
21711 it->ascent += face->box_line_width;
21712 if (slice.y + slice.height == img->height)
21713 it->descent += face->box_line_width;
21714 }
21715
21716 if (it->start_of_box_run_p && slice.x == 0)
21717 it->pixel_width += eabs (face->box_line_width);
21718 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21719 it->pixel_width += eabs (face->box_line_width);
21720 }
21721
21722 take_vertical_position_into_account (it);
21723
21724 /* Automatically crop wide image glyphs at right edge so we can
21725 draw the cursor on same display row. */
21726 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21727 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21728 {
21729 it->pixel_width -= crop;
21730 slice.width -= crop;
21731 }
21732
21733 if (it->glyph_row)
21734 {
21735 struct glyph *glyph;
21736 enum glyph_row_area area = it->area;
21737
21738 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21739 if (glyph < it->glyph_row->glyphs[area + 1])
21740 {
21741 glyph->charpos = CHARPOS (it->position);
21742 glyph->object = it->object;
21743 glyph->pixel_width = it->pixel_width;
21744 glyph->ascent = glyph_ascent;
21745 glyph->descent = it->descent;
21746 glyph->voffset = it->voffset;
21747 glyph->type = IMAGE_GLYPH;
21748 glyph->avoid_cursor_p = it->avoid_cursor_p;
21749 glyph->multibyte_p = it->multibyte_p;
21750 glyph->left_box_line_p = it->start_of_box_run_p;
21751 glyph->right_box_line_p = it->end_of_box_run_p;
21752 glyph->overlaps_vertically_p = 0;
21753 glyph->padding_p = 0;
21754 glyph->glyph_not_available_p = 0;
21755 glyph->face_id = it->face_id;
21756 glyph->u.img_id = img->id;
21757 glyph->slice = slice;
21758 glyph->font_type = FONT_TYPE_UNKNOWN;
21759 if (it->bidi_p)
21760 {
21761 glyph->resolved_level = it->bidi_it.resolved_level;
21762 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21763 abort ();
21764 glyph->bidi_type = it->bidi_it.type;
21765 }
21766 ++it->glyph_row->used[area];
21767 }
21768 else
21769 IT_EXPAND_MATRIX_WIDTH (it, area);
21770 }
21771 }
21772
21773
21774 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21775 of the glyph, WIDTH and HEIGHT are the width and height of the
21776 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21777
21778 static void
21779 append_stretch_glyph (struct it *it, Lisp_Object object,
21780 int width, int height, int ascent)
21781 {
21782 struct glyph *glyph;
21783 enum glyph_row_area area = it->area;
21784
21785 xassert (ascent >= 0 && ascent <= height);
21786
21787 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21788 if (glyph < it->glyph_row->glyphs[area + 1])
21789 {
21790 /* If the glyph row is reversed, we need to prepend the glyph
21791 rather than append it. */
21792 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21793 {
21794 struct glyph *g;
21795
21796 /* Make room for the additional glyph. */
21797 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21798 g[1] = *g;
21799 glyph = it->glyph_row->glyphs[area];
21800 }
21801 glyph->charpos = CHARPOS (it->position);
21802 glyph->object = object;
21803 glyph->pixel_width = width;
21804 glyph->ascent = ascent;
21805 glyph->descent = height - ascent;
21806 glyph->voffset = it->voffset;
21807 glyph->type = STRETCH_GLYPH;
21808 glyph->avoid_cursor_p = it->avoid_cursor_p;
21809 glyph->multibyte_p = it->multibyte_p;
21810 glyph->left_box_line_p = it->start_of_box_run_p;
21811 glyph->right_box_line_p = it->end_of_box_run_p;
21812 glyph->overlaps_vertically_p = 0;
21813 glyph->padding_p = 0;
21814 glyph->glyph_not_available_p = 0;
21815 glyph->face_id = it->face_id;
21816 glyph->u.stretch.ascent = ascent;
21817 glyph->u.stretch.height = height;
21818 glyph->slice = null_glyph_slice;
21819 glyph->font_type = FONT_TYPE_UNKNOWN;
21820 if (it->bidi_p)
21821 {
21822 glyph->resolved_level = it->bidi_it.resolved_level;
21823 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21824 abort ();
21825 glyph->bidi_type = it->bidi_it.type;
21826 }
21827 else
21828 {
21829 glyph->resolved_level = 0;
21830 glyph->bidi_type = UNKNOWN_BT;
21831 }
21832 ++it->glyph_row->used[area];
21833 }
21834 else
21835 IT_EXPAND_MATRIX_WIDTH (it, area);
21836 }
21837
21838
21839 /* Produce a stretch glyph for iterator IT. IT->object is the value
21840 of the glyph property displayed. The value must be a list
21841 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21842 being recognized:
21843
21844 1. `:width WIDTH' specifies that the space should be WIDTH *
21845 canonical char width wide. WIDTH may be an integer or floating
21846 point number.
21847
21848 2. `:relative-width FACTOR' specifies that the width of the stretch
21849 should be computed from the width of the first character having the
21850 `glyph' property, and should be FACTOR times that width.
21851
21852 3. `:align-to HPOS' specifies that the space should be wide enough
21853 to reach HPOS, a value in canonical character units.
21854
21855 Exactly one of the above pairs must be present.
21856
21857 4. `:height HEIGHT' specifies that the height of the stretch produced
21858 should be HEIGHT, measured in canonical character units.
21859
21860 5. `:relative-height FACTOR' specifies that the height of the
21861 stretch should be FACTOR times the height of the characters having
21862 the glyph property.
21863
21864 Either none or exactly one of 4 or 5 must be present.
21865
21866 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21867 of the stretch should be used for the ascent of the stretch.
21868 ASCENT must be in the range 0 <= ASCENT <= 100. */
21869
21870 static void
21871 produce_stretch_glyph (struct it *it)
21872 {
21873 /* (space :width WIDTH :height HEIGHT ...) */
21874 Lisp_Object prop, plist;
21875 int width = 0, height = 0, align_to = -1;
21876 int zero_width_ok_p = 0, zero_height_ok_p = 0;
21877 int ascent = 0;
21878 double tem;
21879 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21880 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
21881
21882 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21883
21884 /* List should start with `space'. */
21885 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
21886 plist = XCDR (it->object);
21887
21888 /* Compute the width of the stretch. */
21889 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
21890 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
21891 {
21892 /* Absolute width `:width WIDTH' specified and valid. */
21893 zero_width_ok_p = 1;
21894 width = (int)tem;
21895 }
21896 else if (prop = Fplist_get (plist, QCrelative_width),
21897 NUMVAL (prop) > 0)
21898 {
21899 /* Relative width `:relative-width FACTOR' specified and valid.
21900 Compute the width of the characters having the `glyph'
21901 property. */
21902 struct it it2;
21903 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
21904
21905 it2 = *it;
21906 if (it->multibyte_p)
21907 {
21908 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
21909 - IT_BYTEPOS (*it));
21910 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
21911 }
21912 else
21913 it2.c = *p, it2.len = 1;
21914
21915 it2.glyph_row = NULL;
21916 it2.what = IT_CHARACTER;
21917 x_produce_glyphs (&it2);
21918 width = NUMVAL (prop) * it2.pixel_width;
21919 }
21920 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
21921 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
21922 {
21923 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
21924 align_to = (align_to < 0
21925 ? 0
21926 : align_to - window_box_left_offset (it->w, TEXT_AREA));
21927 else if (align_to < 0)
21928 align_to = window_box_left_offset (it->w, TEXT_AREA);
21929 width = max (0, (int)tem + align_to - it->current_x);
21930 zero_width_ok_p = 1;
21931 }
21932 else
21933 /* Nothing specified -> width defaults to canonical char width. */
21934 width = FRAME_COLUMN_WIDTH (it->f);
21935
21936 if (width <= 0 && (width < 0 || !zero_width_ok_p))
21937 width = 1;
21938
21939 /* Compute height. */
21940 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
21941 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21942 {
21943 height = (int)tem;
21944 zero_height_ok_p = 1;
21945 }
21946 else if (prop = Fplist_get (plist, QCrelative_height),
21947 NUMVAL (prop) > 0)
21948 height = FONT_HEIGHT (font) * NUMVAL (prop);
21949 else
21950 height = FONT_HEIGHT (font);
21951
21952 if (height <= 0 && (height < 0 || !zero_height_ok_p))
21953 height = 1;
21954
21955 /* Compute percentage of height used for ascent. If
21956 `:ascent ASCENT' is present and valid, use that. Otherwise,
21957 derive the ascent from the font in use. */
21958 if (prop = Fplist_get (plist, QCascent),
21959 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
21960 ascent = height * NUMVAL (prop) / 100.0;
21961 else if (!NILP (prop)
21962 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21963 ascent = min (max (0, (int)tem), height);
21964 else
21965 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
21966
21967 if (width > 0 && it->line_wrap != TRUNCATE
21968 && it->current_x + width > it->last_visible_x)
21969 width = it->last_visible_x - it->current_x - 1;
21970
21971 if (width > 0 && height > 0 && it->glyph_row)
21972 {
21973 Lisp_Object object = it->stack[it->sp - 1].string;
21974 if (!STRINGP (object))
21975 object = it->w->buffer;
21976 append_stretch_glyph (it, object, width, height, ascent);
21977 }
21978
21979 it->pixel_width = width;
21980 it->ascent = it->phys_ascent = ascent;
21981 it->descent = it->phys_descent = height - it->ascent;
21982 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
21983
21984 take_vertical_position_into_account (it);
21985 }
21986
21987 /* Calculate line-height and line-spacing properties.
21988 An integer value specifies explicit pixel value.
21989 A float value specifies relative value to current face height.
21990 A cons (float . face-name) specifies relative value to
21991 height of specified face font.
21992
21993 Returns height in pixels, or nil. */
21994
21995
21996 static Lisp_Object
21997 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
21998 int boff, int override)
21999 {
22000 Lisp_Object face_name = Qnil;
22001 int ascent, descent, height;
22002
22003 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22004 return val;
22005
22006 if (CONSP (val))
22007 {
22008 face_name = XCAR (val);
22009 val = XCDR (val);
22010 if (!NUMBERP (val))
22011 val = make_number (1);
22012 if (NILP (face_name))
22013 {
22014 height = it->ascent + it->descent;
22015 goto scale;
22016 }
22017 }
22018
22019 if (NILP (face_name))
22020 {
22021 font = FRAME_FONT (it->f);
22022 boff = FRAME_BASELINE_OFFSET (it->f);
22023 }
22024 else if (EQ (face_name, Qt))
22025 {
22026 override = 0;
22027 }
22028 else
22029 {
22030 int face_id;
22031 struct face *face;
22032
22033 face_id = lookup_named_face (it->f, face_name, 0);
22034 if (face_id < 0)
22035 return make_number (-1);
22036
22037 face = FACE_FROM_ID (it->f, face_id);
22038 font = face->font;
22039 if (font == NULL)
22040 return make_number (-1);
22041 boff = font->baseline_offset;
22042 if (font->vertical_centering)
22043 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22044 }
22045
22046 ascent = FONT_BASE (font) + boff;
22047 descent = FONT_DESCENT (font) - boff;
22048
22049 if (override)
22050 {
22051 it->override_ascent = ascent;
22052 it->override_descent = descent;
22053 it->override_boff = boff;
22054 }
22055
22056 height = ascent + descent;
22057
22058 scale:
22059 if (FLOATP (val))
22060 height = (int)(XFLOAT_DATA (val) * height);
22061 else if (INTEGERP (val))
22062 height *= XINT (val);
22063
22064 return make_number (height);
22065 }
22066
22067
22068 /* RIF:
22069 Produce glyphs/get display metrics for the display element IT is
22070 loaded with. See the description of struct it in dispextern.h
22071 for an overview of struct it. */
22072
22073 void
22074 x_produce_glyphs (struct it *it)
22075 {
22076 int extra_line_spacing = it->extra_line_spacing;
22077
22078 it->glyph_not_available_p = 0;
22079
22080 if (it->what == IT_CHARACTER)
22081 {
22082 XChar2b char2b;
22083 struct font *font;
22084 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22085 struct font_metrics *pcm;
22086 int font_not_found_p;
22087 int boff; /* baseline offset */
22088 /* We may change it->multibyte_p upon unibyte<->multibyte
22089 conversion. So, save the current value now and restore it
22090 later.
22091
22092 Note: It seems that we don't have to record multibyte_p in
22093 struct glyph because the character code itself tells whether
22094 or not the character is multibyte. Thus, in the future, we
22095 must consider eliminating the field `multibyte_p' in the
22096 struct glyph. */
22097 int saved_multibyte_p = it->multibyte_p;
22098
22099 /* Maybe translate single-byte characters to multibyte, or the
22100 other way. */
22101 it->char_to_display = it->c;
22102 if (!ASCII_BYTE_P (it->c)
22103 && ! it->multibyte_p)
22104 {
22105 if (SINGLE_BYTE_CHAR_P (it->c)
22106 && unibyte_display_via_language_environment)
22107 {
22108 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
22109
22110 /* get_next_display_element assures that this decoding
22111 never fails. */
22112 it->char_to_display = DECODE_CHAR (unibyte, it->c);
22113 it->multibyte_p = 1;
22114 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
22115 -1, Qnil);
22116 face = FACE_FROM_ID (it->f, it->face_id);
22117 }
22118 }
22119
22120 /* Get font to use. Encode IT->char_to_display. */
22121 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
22122 &char2b, it->multibyte_p, 0);
22123 font = face->font;
22124
22125 font_not_found_p = font == NULL;
22126 if (font_not_found_p)
22127 {
22128 /* When no suitable font found, display an empty box based
22129 on the metrics of the font of the default face (or what
22130 remapped). */
22131 struct face *no_font_face
22132 = FACE_FROM_ID (it->f,
22133 NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
22134 : lookup_basic_face (it->f, DEFAULT_FACE_ID));
22135 font = no_font_face->font;
22136 boff = font->baseline_offset;
22137 }
22138 else
22139 {
22140 boff = font->baseline_offset;
22141 if (font->vertical_centering)
22142 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22143 }
22144
22145 if (it->char_to_display >= ' '
22146 && (!it->multibyte_p || it->char_to_display < 128))
22147 {
22148 /* Either unibyte or ASCII. */
22149 int stretched_p;
22150
22151 it->nglyphs = 1;
22152
22153 pcm = get_per_char_metric (it->f, font, &char2b);
22154
22155 if (it->override_ascent >= 0)
22156 {
22157 it->ascent = it->override_ascent;
22158 it->descent = it->override_descent;
22159 boff = it->override_boff;
22160 }
22161 else
22162 {
22163 it->ascent = FONT_BASE (font) + boff;
22164 it->descent = FONT_DESCENT (font) - boff;
22165 }
22166
22167 if (pcm)
22168 {
22169 it->phys_ascent = pcm->ascent + boff;
22170 it->phys_descent = pcm->descent - boff;
22171 it->pixel_width = pcm->width;
22172 }
22173 else
22174 {
22175 it->glyph_not_available_p = 1;
22176 it->phys_ascent = it->ascent;
22177 it->phys_descent = it->descent;
22178 it->pixel_width = FONT_WIDTH (font);
22179 }
22180
22181 if (it->constrain_row_ascent_descent_p)
22182 {
22183 if (it->descent > it->max_descent)
22184 {
22185 it->ascent += it->descent - it->max_descent;
22186 it->descent = it->max_descent;
22187 }
22188 if (it->ascent > it->max_ascent)
22189 {
22190 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22191 it->ascent = it->max_ascent;
22192 }
22193 it->phys_ascent = min (it->phys_ascent, it->ascent);
22194 it->phys_descent = min (it->phys_descent, it->descent);
22195 extra_line_spacing = 0;
22196 }
22197
22198 /* If this is a space inside a region of text with
22199 `space-width' property, change its width. */
22200 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22201 if (stretched_p)
22202 it->pixel_width *= XFLOATINT (it->space_width);
22203
22204 /* If face has a box, add the box thickness to the character
22205 height. If character has a box line to the left and/or
22206 right, add the box line width to the character's width. */
22207 if (face->box != FACE_NO_BOX)
22208 {
22209 int thick = face->box_line_width;
22210
22211 if (thick > 0)
22212 {
22213 it->ascent += thick;
22214 it->descent += thick;
22215 }
22216 else
22217 thick = -thick;
22218
22219 if (it->start_of_box_run_p)
22220 it->pixel_width += thick;
22221 if (it->end_of_box_run_p)
22222 it->pixel_width += thick;
22223 }
22224
22225 /* If face has an overline, add the height of the overline
22226 (1 pixel) and a 1 pixel margin to the character height. */
22227 if (face->overline_p)
22228 it->ascent += overline_margin;
22229
22230 if (it->constrain_row_ascent_descent_p)
22231 {
22232 if (it->ascent > it->max_ascent)
22233 it->ascent = it->max_ascent;
22234 if (it->descent > it->max_descent)
22235 it->descent = it->max_descent;
22236 }
22237
22238 take_vertical_position_into_account (it);
22239
22240 /* If we have to actually produce glyphs, do it. */
22241 if (it->glyph_row)
22242 {
22243 if (stretched_p)
22244 {
22245 /* Translate a space with a `space-width' property
22246 into a stretch glyph. */
22247 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22248 / FONT_HEIGHT (font));
22249 append_stretch_glyph (it, it->object, it->pixel_width,
22250 it->ascent + it->descent, ascent);
22251 }
22252 else
22253 append_glyph (it);
22254
22255 /* If characters with lbearing or rbearing are displayed
22256 in this line, record that fact in a flag of the
22257 glyph row. This is used to optimize X output code. */
22258 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22259 it->glyph_row->contains_overlapping_glyphs_p = 1;
22260 }
22261 if (! stretched_p && it->pixel_width == 0)
22262 /* We assure that all visible glyphs have at least 1-pixel
22263 width. */
22264 it->pixel_width = 1;
22265 }
22266 else if (it->char_to_display == '\n')
22267 {
22268 /* A newline has no width, but we need the height of the
22269 line. But if previous part of the line sets a height,
22270 don't increase that height */
22271
22272 Lisp_Object height;
22273 Lisp_Object total_height = Qnil;
22274
22275 it->override_ascent = -1;
22276 it->pixel_width = 0;
22277 it->nglyphs = 0;
22278
22279 height = get_it_property (it, Qline_height);
22280 /* Split (line-height total-height) list */
22281 if (CONSP (height)
22282 && CONSP (XCDR (height))
22283 && NILP (XCDR (XCDR (height))))
22284 {
22285 total_height = XCAR (XCDR (height));
22286 height = XCAR (height);
22287 }
22288 height = calc_line_height_property (it, height, font, boff, 1);
22289
22290 if (it->override_ascent >= 0)
22291 {
22292 it->ascent = it->override_ascent;
22293 it->descent = it->override_descent;
22294 boff = it->override_boff;
22295 }
22296 else
22297 {
22298 it->ascent = FONT_BASE (font) + boff;
22299 it->descent = FONT_DESCENT (font) - boff;
22300 }
22301
22302 if (EQ (height, Qt))
22303 {
22304 if (it->descent > it->max_descent)
22305 {
22306 it->ascent += it->descent - it->max_descent;
22307 it->descent = it->max_descent;
22308 }
22309 if (it->ascent > it->max_ascent)
22310 {
22311 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22312 it->ascent = it->max_ascent;
22313 }
22314 it->phys_ascent = min (it->phys_ascent, it->ascent);
22315 it->phys_descent = min (it->phys_descent, it->descent);
22316 it->constrain_row_ascent_descent_p = 1;
22317 extra_line_spacing = 0;
22318 }
22319 else
22320 {
22321 Lisp_Object spacing;
22322
22323 it->phys_ascent = it->ascent;
22324 it->phys_descent = it->descent;
22325
22326 if ((it->max_ascent > 0 || it->max_descent > 0)
22327 && face->box != FACE_NO_BOX
22328 && face->box_line_width > 0)
22329 {
22330 it->ascent += face->box_line_width;
22331 it->descent += face->box_line_width;
22332 }
22333 if (!NILP (height)
22334 && XINT (height) > it->ascent + it->descent)
22335 it->ascent = XINT (height) - it->descent;
22336
22337 if (!NILP (total_height))
22338 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22339 else
22340 {
22341 spacing = get_it_property (it, Qline_spacing);
22342 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22343 }
22344 if (INTEGERP (spacing))
22345 {
22346 extra_line_spacing = XINT (spacing);
22347 if (!NILP (total_height))
22348 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22349 }
22350 }
22351 }
22352 else if (it->char_to_display == '\t')
22353 {
22354 if (font->space_width > 0)
22355 {
22356 int tab_width = it->tab_width * font->space_width;
22357 int x = it->current_x + it->continuation_lines_width;
22358 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22359
22360 /* If the distance from the current position to the next tab
22361 stop is less than a space character width, use the
22362 tab stop after that. */
22363 if (next_tab_x - x < font->space_width)
22364 next_tab_x += tab_width;
22365
22366 it->pixel_width = next_tab_x - x;
22367 it->nglyphs = 1;
22368 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22369 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22370
22371 if (it->glyph_row)
22372 {
22373 append_stretch_glyph (it, it->object, it->pixel_width,
22374 it->ascent + it->descent, it->ascent);
22375 }
22376 }
22377 else
22378 {
22379 it->pixel_width = 0;
22380 it->nglyphs = 1;
22381 }
22382 }
22383 else
22384 {
22385 /* A multi-byte character. Assume that the display width of the
22386 character is the width of the character multiplied by the
22387 width of the font. */
22388
22389 /* If we found a font, this font should give us the right
22390 metrics. If we didn't find a font, use the frame's
22391 default font and calculate the width of the character by
22392 multiplying the width of font by the width of the
22393 character. */
22394
22395 pcm = get_per_char_metric (it->f, font, &char2b);
22396
22397 if (font_not_found_p || !pcm)
22398 {
22399 int char_width = CHAR_WIDTH (it->char_to_display);
22400
22401 if (char_width == 0)
22402 /* This is a non spacing character. But, as we are
22403 going to display an empty box, the box must occupy
22404 at least one column. */
22405 char_width = 1;
22406 it->glyph_not_available_p = 1;
22407 it->pixel_width = font->space_width * char_width;
22408 it->phys_ascent = FONT_BASE (font) + boff;
22409 it->phys_descent = FONT_DESCENT (font) - boff;
22410 }
22411 else
22412 {
22413 it->pixel_width = pcm->width;
22414 it->phys_ascent = pcm->ascent + boff;
22415 it->phys_descent = pcm->descent - boff;
22416 if (it->glyph_row
22417 && (pcm->lbearing < 0
22418 || pcm->rbearing > pcm->width))
22419 it->glyph_row->contains_overlapping_glyphs_p = 1;
22420 }
22421 it->nglyphs = 1;
22422 it->ascent = FONT_BASE (font) + boff;
22423 it->descent = FONT_DESCENT (font) - boff;
22424 if (face->box != FACE_NO_BOX)
22425 {
22426 int thick = face->box_line_width;
22427
22428 if (thick > 0)
22429 {
22430 it->ascent += thick;
22431 it->descent += thick;
22432 }
22433 else
22434 thick = - thick;
22435
22436 if (it->start_of_box_run_p)
22437 it->pixel_width += thick;
22438 if (it->end_of_box_run_p)
22439 it->pixel_width += thick;
22440 }
22441
22442 /* If face has an overline, add the height of the overline
22443 (1 pixel) and a 1 pixel margin to the character height. */
22444 if (face->overline_p)
22445 it->ascent += overline_margin;
22446
22447 take_vertical_position_into_account (it);
22448
22449 if (it->ascent < 0)
22450 it->ascent = 0;
22451 if (it->descent < 0)
22452 it->descent = 0;
22453
22454 if (it->glyph_row)
22455 append_glyph (it);
22456 if (it->pixel_width == 0)
22457 /* We assure that all visible glyphs have at least 1-pixel
22458 width. */
22459 it->pixel_width = 1;
22460 }
22461 it->multibyte_p = saved_multibyte_p;
22462 }
22463 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22464 {
22465 /* A static composition.
22466
22467 Note: A composition is represented as one glyph in the
22468 glyph matrix. There are no padding glyphs.
22469
22470 Important note: pixel_width, ascent, and descent are the
22471 values of what is drawn by draw_glyphs (i.e. the values of
22472 the overall glyphs composed). */
22473 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22474 int boff; /* baseline offset */
22475 struct composition *cmp = composition_table[it->cmp_it.id];
22476 int glyph_len = cmp->glyph_len;
22477 struct font *font = face->font;
22478
22479 it->nglyphs = 1;
22480
22481 /* If we have not yet calculated pixel size data of glyphs of
22482 the composition for the current face font, calculate them
22483 now. Theoretically, we have to check all fonts for the
22484 glyphs, but that requires much time and memory space. So,
22485 here we check only the font of the first glyph. This may
22486 lead to incorrect display, but it's very rare, and C-l
22487 (recenter-top-bottom) can correct the display anyway. */
22488 if (! cmp->font || cmp->font != font)
22489 {
22490 /* Ascent and descent of the font of the first character
22491 of this composition (adjusted by baseline offset).
22492 Ascent and descent of overall glyphs should not be less
22493 than these, respectively. */
22494 int font_ascent, font_descent, font_height;
22495 /* Bounding box of the overall glyphs. */
22496 int leftmost, rightmost, lowest, highest;
22497 int lbearing, rbearing;
22498 int i, width, ascent, descent;
22499 int left_padded = 0, right_padded = 0;
22500 int c;
22501 XChar2b char2b;
22502 struct font_metrics *pcm;
22503 int font_not_found_p;
22504 int pos;
22505
22506 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22507 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22508 break;
22509 if (glyph_len < cmp->glyph_len)
22510 right_padded = 1;
22511 for (i = 0; i < glyph_len; i++)
22512 {
22513 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22514 break;
22515 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22516 }
22517 if (i > 0)
22518 left_padded = 1;
22519
22520 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22521 : IT_CHARPOS (*it));
22522 /* If no suitable font is found, use the default font. */
22523 font_not_found_p = font == NULL;
22524 if (font_not_found_p)
22525 {
22526 face = face->ascii_face;
22527 font = face->font;
22528 }
22529 boff = font->baseline_offset;
22530 if (font->vertical_centering)
22531 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22532 font_ascent = FONT_BASE (font) + boff;
22533 font_descent = FONT_DESCENT (font) - boff;
22534 font_height = FONT_HEIGHT (font);
22535
22536 cmp->font = (void *) font;
22537
22538 pcm = NULL;
22539 if (! font_not_found_p)
22540 {
22541 get_char_face_and_encoding (it->f, c, it->face_id,
22542 &char2b, it->multibyte_p, 0);
22543 pcm = get_per_char_metric (it->f, font, &char2b);
22544 }
22545
22546 /* Initialize the bounding box. */
22547 if (pcm)
22548 {
22549 width = pcm->width;
22550 ascent = pcm->ascent;
22551 descent = pcm->descent;
22552 lbearing = pcm->lbearing;
22553 rbearing = pcm->rbearing;
22554 }
22555 else
22556 {
22557 width = FONT_WIDTH (font);
22558 ascent = FONT_BASE (font);
22559 descent = FONT_DESCENT (font);
22560 lbearing = 0;
22561 rbearing = width;
22562 }
22563
22564 rightmost = width;
22565 leftmost = 0;
22566 lowest = - descent + boff;
22567 highest = ascent + boff;
22568
22569 if (! font_not_found_p
22570 && font->default_ascent
22571 && CHAR_TABLE_P (Vuse_default_ascent)
22572 && !NILP (Faref (Vuse_default_ascent,
22573 make_number (it->char_to_display))))
22574 highest = font->default_ascent + boff;
22575
22576 /* Draw the first glyph at the normal position. It may be
22577 shifted to right later if some other glyphs are drawn
22578 at the left. */
22579 cmp->offsets[i * 2] = 0;
22580 cmp->offsets[i * 2 + 1] = boff;
22581 cmp->lbearing = lbearing;
22582 cmp->rbearing = rbearing;
22583
22584 /* Set cmp->offsets for the remaining glyphs. */
22585 for (i++; i < glyph_len; i++)
22586 {
22587 int left, right, btm, top;
22588 int ch = COMPOSITION_GLYPH (cmp, i);
22589 int face_id;
22590 struct face *this_face;
22591 int this_boff;
22592
22593 if (ch == '\t')
22594 ch = ' ';
22595 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22596 this_face = FACE_FROM_ID (it->f, face_id);
22597 font = this_face->font;
22598
22599 if (font == NULL)
22600 pcm = NULL;
22601 else
22602 {
22603 this_boff = font->baseline_offset;
22604 if (font->vertical_centering)
22605 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22606 get_char_face_and_encoding (it->f, ch, face_id,
22607 &char2b, it->multibyte_p, 0);
22608 pcm = get_per_char_metric (it->f, font, &char2b);
22609 }
22610 if (! pcm)
22611 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22612 else
22613 {
22614 width = pcm->width;
22615 ascent = pcm->ascent;
22616 descent = pcm->descent;
22617 lbearing = pcm->lbearing;
22618 rbearing = pcm->rbearing;
22619 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22620 {
22621 /* Relative composition with or without
22622 alternate chars. */
22623 left = (leftmost + rightmost - width) / 2;
22624 btm = - descent + boff;
22625 if (font->relative_compose
22626 && (! CHAR_TABLE_P (Vignore_relative_composition)
22627 || NILP (Faref (Vignore_relative_composition,
22628 make_number (ch)))))
22629 {
22630
22631 if (- descent >= font->relative_compose)
22632 /* One extra pixel between two glyphs. */
22633 btm = highest + 1;
22634 else if (ascent <= 0)
22635 /* One extra pixel between two glyphs. */
22636 btm = lowest - 1 - ascent - descent;
22637 }
22638 }
22639 else
22640 {
22641 /* A composition rule is specified by an integer
22642 value that encodes global and new reference
22643 points (GREF and NREF). GREF and NREF are
22644 specified by numbers as below:
22645
22646 0---1---2 -- ascent
22647 | |
22648 | |
22649 | |
22650 9--10--11 -- center
22651 | |
22652 ---3---4---5--- baseline
22653 | |
22654 6---7---8 -- descent
22655 */
22656 int rule = COMPOSITION_RULE (cmp, i);
22657 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22658
22659 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22660 grefx = gref % 3, nrefx = nref % 3;
22661 grefy = gref / 3, nrefy = nref / 3;
22662 if (xoff)
22663 xoff = font_height * (xoff - 128) / 256;
22664 if (yoff)
22665 yoff = font_height * (yoff - 128) / 256;
22666
22667 left = (leftmost
22668 + grefx * (rightmost - leftmost) / 2
22669 - nrefx * width / 2
22670 + xoff);
22671
22672 btm = ((grefy == 0 ? highest
22673 : grefy == 1 ? 0
22674 : grefy == 2 ? lowest
22675 : (highest + lowest) / 2)
22676 - (nrefy == 0 ? ascent + descent
22677 : nrefy == 1 ? descent - boff
22678 : nrefy == 2 ? 0
22679 : (ascent + descent) / 2)
22680 + yoff);
22681 }
22682
22683 cmp->offsets[i * 2] = left;
22684 cmp->offsets[i * 2 + 1] = btm + descent;
22685
22686 /* Update the bounding box of the overall glyphs. */
22687 if (width > 0)
22688 {
22689 right = left + width;
22690 if (left < leftmost)
22691 leftmost = left;
22692 if (right > rightmost)
22693 rightmost = right;
22694 }
22695 top = btm + descent + ascent;
22696 if (top > highest)
22697 highest = top;
22698 if (btm < lowest)
22699 lowest = btm;
22700
22701 if (cmp->lbearing > left + lbearing)
22702 cmp->lbearing = left + lbearing;
22703 if (cmp->rbearing < left + rbearing)
22704 cmp->rbearing = left + rbearing;
22705 }
22706 }
22707
22708 /* If there are glyphs whose x-offsets are negative,
22709 shift all glyphs to the right and make all x-offsets
22710 non-negative. */
22711 if (leftmost < 0)
22712 {
22713 for (i = 0; i < cmp->glyph_len; i++)
22714 cmp->offsets[i * 2] -= leftmost;
22715 rightmost -= leftmost;
22716 cmp->lbearing -= leftmost;
22717 cmp->rbearing -= leftmost;
22718 }
22719
22720 if (left_padded && cmp->lbearing < 0)
22721 {
22722 for (i = 0; i < cmp->glyph_len; i++)
22723 cmp->offsets[i * 2] -= cmp->lbearing;
22724 rightmost -= cmp->lbearing;
22725 cmp->rbearing -= cmp->lbearing;
22726 cmp->lbearing = 0;
22727 }
22728 if (right_padded && rightmost < cmp->rbearing)
22729 {
22730 rightmost = cmp->rbearing;
22731 }
22732
22733 cmp->pixel_width = rightmost;
22734 cmp->ascent = highest;
22735 cmp->descent = - lowest;
22736 if (cmp->ascent < font_ascent)
22737 cmp->ascent = font_ascent;
22738 if (cmp->descent < font_descent)
22739 cmp->descent = font_descent;
22740 }
22741
22742 if (it->glyph_row
22743 && (cmp->lbearing < 0
22744 || cmp->rbearing > cmp->pixel_width))
22745 it->glyph_row->contains_overlapping_glyphs_p = 1;
22746
22747 it->pixel_width = cmp->pixel_width;
22748 it->ascent = it->phys_ascent = cmp->ascent;
22749 it->descent = it->phys_descent = cmp->descent;
22750 if (face->box != FACE_NO_BOX)
22751 {
22752 int thick = face->box_line_width;
22753
22754 if (thick > 0)
22755 {
22756 it->ascent += thick;
22757 it->descent += thick;
22758 }
22759 else
22760 thick = - thick;
22761
22762 if (it->start_of_box_run_p)
22763 it->pixel_width += thick;
22764 if (it->end_of_box_run_p)
22765 it->pixel_width += thick;
22766 }
22767
22768 /* If face has an overline, add the height of the overline
22769 (1 pixel) and a 1 pixel margin to the character height. */
22770 if (face->overline_p)
22771 it->ascent += overline_margin;
22772
22773 take_vertical_position_into_account (it);
22774 if (it->ascent < 0)
22775 it->ascent = 0;
22776 if (it->descent < 0)
22777 it->descent = 0;
22778
22779 if (it->glyph_row)
22780 append_composite_glyph (it);
22781 }
22782 else if (it->what == IT_COMPOSITION)
22783 {
22784 /* A dynamic (automatic) composition. */
22785 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22786 Lisp_Object gstring;
22787 struct font_metrics metrics;
22788
22789 gstring = composition_gstring_from_id (it->cmp_it.id);
22790 it->pixel_width
22791 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
22792 &metrics);
22793 if (it->glyph_row
22794 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
22795 it->glyph_row->contains_overlapping_glyphs_p = 1;
22796 it->ascent = it->phys_ascent = metrics.ascent;
22797 it->descent = it->phys_descent = metrics.descent;
22798 if (face->box != FACE_NO_BOX)
22799 {
22800 int thick = face->box_line_width;
22801
22802 if (thick > 0)
22803 {
22804 it->ascent += thick;
22805 it->descent += thick;
22806 }
22807 else
22808 thick = - thick;
22809
22810 if (it->start_of_box_run_p)
22811 it->pixel_width += thick;
22812 if (it->end_of_box_run_p)
22813 it->pixel_width += thick;
22814 }
22815 /* If face has an overline, add the height of the overline
22816 (1 pixel) and a 1 pixel margin to the character height. */
22817 if (face->overline_p)
22818 it->ascent += overline_margin;
22819 take_vertical_position_into_account (it);
22820 if (it->ascent < 0)
22821 it->ascent = 0;
22822 if (it->descent < 0)
22823 it->descent = 0;
22824
22825 if (it->glyph_row)
22826 append_composite_glyph (it);
22827 }
22828 else if (it->what == IT_IMAGE)
22829 produce_image_glyph (it);
22830 else if (it->what == IT_STRETCH)
22831 produce_stretch_glyph (it);
22832
22833 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22834 because this isn't true for images with `:ascent 100'. */
22835 xassert (it->ascent >= 0 && it->descent >= 0);
22836 if (it->area == TEXT_AREA)
22837 it->current_x += it->pixel_width;
22838
22839 if (extra_line_spacing > 0)
22840 {
22841 it->descent += extra_line_spacing;
22842 if (extra_line_spacing > it->max_extra_line_spacing)
22843 it->max_extra_line_spacing = extra_line_spacing;
22844 }
22845
22846 it->max_ascent = max (it->max_ascent, it->ascent);
22847 it->max_descent = max (it->max_descent, it->descent);
22848 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
22849 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
22850 }
22851
22852 /* EXPORT for RIF:
22853 Output LEN glyphs starting at START at the nominal cursor position.
22854 Advance the nominal cursor over the text. The global variable
22855 updated_window contains the window being updated, updated_row is
22856 the glyph row being updated, and updated_area is the area of that
22857 row being updated. */
22858
22859 void
22860 x_write_glyphs (struct glyph *start, int len)
22861 {
22862 int x, hpos;
22863
22864 xassert (updated_window && updated_row);
22865 BLOCK_INPUT;
22866
22867 /* Write glyphs. */
22868
22869 hpos = start - updated_row->glyphs[updated_area];
22870 x = draw_glyphs (updated_window, output_cursor.x,
22871 updated_row, updated_area,
22872 hpos, hpos + len,
22873 DRAW_NORMAL_TEXT, 0);
22874
22875 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22876 if (updated_area == TEXT_AREA
22877 && updated_window->phys_cursor_on_p
22878 && updated_window->phys_cursor.vpos == output_cursor.vpos
22879 && updated_window->phys_cursor.hpos >= hpos
22880 && updated_window->phys_cursor.hpos < hpos + len)
22881 updated_window->phys_cursor_on_p = 0;
22882
22883 UNBLOCK_INPUT;
22884
22885 /* Advance the output cursor. */
22886 output_cursor.hpos += len;
22887 output_cursor.x = x;
22888 }
22889
22890
22891 /* EXPORT for RIF:
22892 Insert LEN glyphs from START at the nominal cursor position. */
22893
22894 void
22895 x_insert_glyphs (struct glyph *start, int len)
22896 {
22897 struct frame *f;
22898 struct window *w;
22899 int line_height, shift_by_width, shifted_region_width;
22900 struct glyph_row *row;
22901 struct glyph *glyph;
22902 int frame_x, frame_y;
22903 EMACS_INT hpos;
22904
22905 xassert (updated_window && updated_row);
22906 BLOCK_INPUT;
22907 w = updated_window;
22908 f = XFRAME (WINDOW_FRAME (w));
22909
22910 /* Get the height of the line we are in. */
22911 row = updated_row;
22912 line_height = row->height;
22913
22914 /* Get the width of the glyphs to insert. */
22915 shift_by_width = 0;
22916 for (glyph = start; glyph < start + len; ++glyph)
22917 shift_by_width += glyph->pixel_width;
22918
22919 /* Get the width of the region to shift right. */
22920 shifted_region_width = (window_box_width (w, updated_area)
22921 - output_cursor.x
22922 - shift_by_width);
22923
22924 /* Shift right. */
22925 frame_x = window_box_left (w, updated_area) + output_cursor.x;
22926 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
22927
22928 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
22929 line_height, shift_by_width);
22930
22931 /* Write the glyphs. */
22932 hpos = start - row->glyphs[updated_area];
22933 draw_glyphs (w, output_cursor.x, row, updated_area,
22934 hpos, hpos + len,
22935 DRAW_NORMAL_TEXT, 0);
22936
22937 /* Advance the output cursor. */
22938 output_cursor.hpos += len;
22939 output_cursor.x += shift_by_width;
22940 UNBLOCK_INPUT;
22941 }
22942
22943
22944 /* EXPORT for RIF:
22945 Erase the current text line from the nominal cursor position
22946 (inclusive) to pixel column TO_X (exclusive). The idea is that
22947 everything from TO_X onward is already erased.
22948
22949 TO_X is a pixel position relative to updated_area of
22950 updated_window. TO_X == -1 means clear to the end of this area. */
22951
22952 void
22953 x_clear_end_of_line (int to_x)
22954 {
22955 struct frame *f;
22956 struct window *w = updated_window;
22957 int max_x, min_y, max_y;
22958 int from_x, from_y, to_y;
22959
22960 xassert (updated_window && updated_row);
22961 f = XFRAME (w->frame);
22962
22963 if (updated_row->full_width_p)
22964 max_x = WINDOW_TOTAL_WIDTH (w);
22965 else
22966 max_x = window_box_width (w, updated_area);
22967 max_y = window_text_bottom_y (w);
22968
22969 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
22970 of window. For TO_X > 0, truncate to end of drawing area. */
22971 if (to_x == 0)
22972 return;
22973 else if (to_x < 0)
22974 to_x = max_x;
22975 else
22976 to_x = min (to_x, max_x);
22977
22978 to_y = min (max_y, output_cursor.y + updated_row->height);
22979
22980 /* Notice if the cursor will be cleared by this operation. */
22981 if (!updated_row->full_width_p)
22982 notice_overwritten_cursor (w, updated_area,
22983 output_cursor.x, -1,
22984 updated_row->y,
22985 MATRIX_ROW_BOTTOM_Y (updated_row));
22986
22987 from_x = output_cursor.x;
22988
22989 /* Translate to frame coordinates. */
22990 if (updated_row->full_width_p)
22991 {
22992 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
22993 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
22994 }
22995 else
22996 {
22997 int area_left = window_box_left (w, updated_area);
22998 from_x += area_left;
22999 to_x += area_left;
23000 }
23001
23002 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23003 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23004 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23005
23006 /* Prevent inadvertently clearing to end of the X window. */
23007 if (to_x > from_x && to_y > from_y)
23008 {
23009 BLOCK_INPUT;
23010 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23011 to_x - from_x, to_y - from_y);
23012 UNBLOCK_INPUT;
23013 }
23014 }
23015
23016 #endif /* HAVE_WINDOW_SYSTEM */
23017
23018
23019 \f
23020 /***********************************************************************
23021 Cursor types
23022 ***********************************************************************/
23023
23024 /* Value is the internal representation of the specified cursor type
23025 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23026 of the bar cursor. */
23027
23028 static enum text_cursor_kinds
23029 get_specified_cursor_type (Lisp_Object arg, int *width)
23030 {
23031 enum text_cursor_kinds type;
23032
23033 if (NILP (arg))
23034 return NO_CURSOR;
23035
23036 if (EQ (arg, Qbox))
23037 return FILLED_BOX_CURSOR;
23038
23039 if (EQ (arg, Qhollow))
23040 return HOLLOW_BOX_CURSOR;
23041
23042 if (EQ (arg, Qbar))
23043 {
23044 *width = 2;
23045 return BAR_CURSOR;
23046 }
23047
23048 if (CONSP (arg)
23049 && EQ (XCAR (arg), Qbar)
23050 && INTEGERP (XCDR (arg))
23051 && XINT (XCDR (arg)) >= 0)
23052 {
23053 *width = XINT (XCDR (arg));
23054 return BAR_CURSOR;
23055 }
23056
23057 if (EQ (arg, Qhbar))
23058 {
23059 *width = 2;
23060 return HBAR_CURSOR;
23061 }
23062
23063 if (CONSP (arg)
23064 && EQ (XCAR (arg), Qhbar)
23065 && INTEGERP (XCDR (arg))
23066 && XINT (XCDR (arg)) >= 0)
23067 {
23068 *width = XINT (XCDR (arg));
23069 return HBAR_CURSOR;
23070 }
23071
23072 /* Treat anything unknown as "hollow box cursor".
23073 It was bad to signal an error; people have trouble fixing
23074 .Xdefaults with Emacs, when it has something bad in it. */
23075 type = HOLLOW_BOX_CURSOR;
23076
23077 return type;
23078 }
23079
23080 /* Set the default cursor types for specified frame. */
23081 void
23082 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23083 {
23084 int width;
23085 Lisp_Object tem;
23086
23087 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23088 FRAME_CURSOR_WIDTH (f) = width;
23089
23090 /* By default, set up the blink-off state depending on the on-state. */
23091
23092 tem = Fassoc (arg, Vblink_cursor_alist);
23093 if (!NILP (tem))
23094 {
23095 FRAME_BLINK_OFF_CURSOR (f)
23096 = get_specified_cursor_type (XCDR (tem), &width);
23097 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23098 }
23099 else
23100 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23101 }
23102
23103
23104 /* Return the cursor we want to be displayed in window W. Return
23105 width of bar/hbar cursor through WIDTH arg. Return with
23106 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23107 (i.e. if the `system caret' should track this cursor).
23108
23109 In a mini-buffer window, we want the cursor only to appear if we
23110 are reading input from this window. For the selected window, we
23111 want the cursor type given by the frame parameter or buffer local
23112 setting of cursor-type. If explicitly marked off, draw no cursor.
23113 In all other cases, we want a hollow box cursor. */
23114
23115 static enum text_cursor_kinds
23116 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23117 int *active_cursor)
23118 {
23119 struct frame *f = XFRAME (w->frame);
23120 struct buffer *b = XBUFFER (w->buffer);
23121 int cursor_type = DEFAULT_CURSOR;
23122 Lisp_Object alt_cursor;
23123 int non_selected = 0;
23124
23125 *active_cursor = 1;
23126
23127 /* Echo area */
23128 if (cursor_in_echo_area
23129 && FRAME_HAS_MINIBUF_P (f)
23130 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23131 {
23132 if (w == XWINDOW (echo_area_window))
23133 {
23134 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
23135 {
23136 *width = FRAME_CURSOR_WIDTH (f);
23137 return FRAME_DESIRED_CURSOR (f);
23138 }
23139 else
23140 return get_specified_cursor_type (b->cursor_type, width);
23141 }
23142
23143 *active_cursor = 0;
23144 non_selected = 1;
23145 }
23146
23147 /* Detect a nonselected window or nonselected frame. */
23148 else if (w != XWINDOW (f->selected_window)
23149 #ifdef HAVE_WINDOW_SYSTEM
23150 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
23151 #endif
23152 )
23153 {
23154 *active_cursor = 0;
23155
23156 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23157 return NO_CURSOR;
23158
23159 non_selected = 1;
23160 }
23161
23162 /* Never display a cursor in a window in which cursor-type is nil. */
23163 if (NILP (b->cursor_type))
23164 return NO_CURSOR;
23165
23166 /* Get the normal cursor type for this window. */
23167 if (EQ (b->cursor_type, Qt))
23168 {
23169 cursor_type = FRAME_DESIRED_CURSOR (f);
23170 *width = FRAME_CURSOR_WIDTH (f);
23171 }
23172 else
23173 cursor_type = get_specified_cursor_type (b->cursor_type, width);
23174
23175 /* Use cursor-in-non-selected-windows instead
23176 for non-selected window or frame. */
23177 if (non_selected)
23178 {
23179 alt_cursor = b->cursor_in_non_selected_windows;
23180 if (!EQ (Qt, alt_cursor))
23181 return get_specified_cursor_type (alt_cursor, width);
23182 /* t means modify the normal cursor type. */
23183 if (cursor_type == FILLED_BOX_CURSOR)
23184 cursor_type = HOLLOW_BOX_CURSOR;
23185 else if (cursor_type == BAR_CURSOR && *width > 1)
23186 --*width;
23187 return cursor_type;
23188 }
23189
23190 /* Use normal cursor if not blinked off. */
23191 if (!w->cursor_off_p)
23192 {
23193 #ifdef HAVE_WINDOW_SYSTEM
23194 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23195 {
23196 if (cursor_type == FILLED_BOX_CURSOR)
23197 {
23198 /* Using a block cursor on large images can be very annoying.
23199 So use a hollow cursor for "large" images.
23200 If image is not transparent (no mask), also use hollow cursor. */
23201 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23202 if (img != NULL && IMAGEP (img->spec))
23203 {
23204 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23205 where N = size of default frame font size.
23206 This should cover most of the "tiny" icons people may use. */
23207 if (!img->mask
23208 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23209 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23210 cursor_type = HOLLOW_BOX_CURSOR;
23211 }
23212 }
23213 else if (cursor_type != NO_CURSOR)
23214 {
23215 /* Display current only supports BOX and HOLLOW cursors for images.
23216 So for now, unconditionally use a HOLLOW cursor when cursor is
23217 not a solid box cursor. */
23218 cursor_type = HOLLOW_BOX_CURSOR;
23219 }
23220 }
23221 #endif
23222 return cursor_type;
23223 }
23224
23225 /* Cursor is blinked off, so determine how to "toggle" it. */
23226
23227 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23228 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
23229 return get_specified_cursor_type (XCDR (alt_cursor), width);
23230
23231 /* Then see if frame has specified a specific blink off cursor type. */
23232 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23233 {
23234 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23235 return FRAME_BLINK_OFF_CURSOR (f);
23236 }
23237
23238 #if 0
23239 /* Some people liked having a permanently visible blinking cursor,
23240 while others had very strong opinions against it. So it was
23241 decided to remove it. KFS 2003-09-03 */
23242
23243 /* Finally perform built-in cursor blinking:
23244 filled box <-> hollow box
23245 wide [h]bar <-> narrow [h]bar
23246 narrow [h]bar <-> no cursor
23247 other type <-> no cursor */
23248
23249 if (cursor_type == FILLED_BOX_CURSOR)
23250 return HOLLOW_BOX_CURSOR;
23251
23252 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23253 {
23254 *width = 1;
23255 return cursor_type;
23256 }
23257 #endif
23258
23259 return NO_CURSOR;
23260 }
23261
23262
23263 #ifdef HAVE_WINDOW_SYSTEM
23264
23265 /* Notice when the text cursor of window W has been completely
23266 overwritten by a drawing operation that outputs glyphs in AREA
23267 starting at X0 and ending at X1 in the line starting at Y0 and
23268 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23269 the rest of the line after X0 has been written. Y coordinates
23270 are window-relative. */
23271
23272 static void
23273 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23274 int x0, int x1, int y0, int y1)
23275 {
23276 int cx0, cx1, cy0, cy1;
23277 struct glyph_row *row;
23278
23279 if (!w->phys_cursor_on_p)
23280 return;
23281 if (area != TEXT_AREA)
23282 return;
23283
23284 if (w->phys_cursor.vpos < 0
23285 || w->phys_cursor.vpos >= w->current_matrix->nrows
23286 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23287 !(row->enabled_p && row->displays_text_p)))
23288 return;
23289
23290 if (row->cursor_in_fringe_p)
23291 {
23292 row->cursor_in_fringe_p = 0;
23293 draw_fringe_bitmap (w, row, row->reversed_p);
23294 w->phys_cursor_on_p = 0;
23295 return;
23296 }
23297
23298 cx0 = w->phys_cursor.x;
23299 cx1 = cx0 + w->phys_cursor_width;
23300 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23301 return;
23302
23303 /* The cursor image will be completely removed from the
23304 screen if the output area intersects the cursor area in
23305 y-direction. When we draw in [y0 y1[, and some part of
23306 the cursor is at y < y0, that part must have been drawn
23307 before. When scrolling, the cursor is erased before
23308 actually scrolling, so we don't come here. When not
23309 scrolling, the rows above the old cursor row must have
23310 changed, and in this case these rows must have written
23311 over the cursor image.
23312
23313 Likewise if part of the cursor is below y1, with the
23314 exception of the cursor being in the first blank row at
23315 the buffer and window end because update_text_area
23316 doesn't draw that row. (Except when it does, but
23317 that's handled in update_text_area.) */
23318
23319 cy0 = w->phys_cursor.y;
23320 cy1 = cy0 + w->phys_cursor_height;
23321 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23322 return;
23323
23324 w->phys_cursor_on_p = 0;
23325 }
23326
23327 #endif /* HAVE_WINDOW_SYSTEM */
23328
23329 \f
23330 /************************************************************************
23331 Mouse Face
23332 ************************************************************************/
23333
23334 #ifdef HAVE_WINDOW_SYSTEM
23335
23336 /* EXPORT for RIF:
23337 Fix the display of area AREA of overlapping row ROW in window W
23338 with respect to the overlapping part OVERLAPS. */
23339
23340 void
23341 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23342 enum glyph_row_area area, int overlaps)
23343 {
23344 int i, x;
23345
23346 BLOCK_INPUT;
23347
23348 x = 0;
23349 for (i = 0; i < row->used[area];)
23350 {
23351 if (row->glyphs[area][i].overlaps_vertically_p)
23352 {
23353 int start = i, start_x = x;
23354
23355 do
23356 {
23357 x += row->glyphs[area][i].pixel_width;
23358 ++i;
23359 }
23360 while (i < row->used[area]
23361 && row->glyphs[area][i].overlaps_vertically_p);
23362
23363 draw_glyphs (w, start_x, row, area,
23364 start, i,
23365 DRAW_NORMAL_TEXT, overlaps);
23366 }
23367 else
23368 {
23369 x += row->glyphs[area][i].pixel_width;
23370 ++i;
23371 }
23372 }
23373
23374 UNBLOCK_INPUT;
23375 }
23376
23377
23378 /* EXPORT:
23379 Draw the cursor glyph of window W in glyph row ROW. See the
23380 comment of draw_glyphs for the meaning of HL. */
23381
23382 void
23383 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23384 enum draw_glyphs_face hl)
23385 {
23386 /* If cursor hpos is out of bounds, don't draw garbage. This can
23387 happen in mini-buffer windows when switching between echo area
23388 glyphs and mini-buffer. */
23389 if ((row->reversed_p
23390 ? (w->phys_cursor.hpos >= 0)
23391 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23392 {
23393 int on_p = w->phys_cursor_on_p;
23394 int x1;
23395 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23396 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23397 hl, 0);
23398 w->phys_cursor_on_p = on_p;
23399
23400 if (hl == DRAW_CURSOR)
23401 w->phys_cursor_width = x1 - w->phys_cursor.x;
23402 /* When we erase the cursor, and ROW is overlapped by other
23403 rows, make sure that these overlapping parts of other rows
23404 are redrawn. */
23405 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23406 {
23407 w->phys_cursor_width = x1 - w->phys_cursor.x;
23408
23409 if (row > w->current_matrix->rows
23410 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23411 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23412 OVERLAPS_ERASED_CURSOR);
23413
23414 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23415 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23416 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23417 OVERLAPS_ERASED_CURSOR);
23418 }
23419 }
23420 }
23421
23422
23423 /* EXPORT:
23424 Erase the image of a cursor of window W from the screen. */
23425
23426 void
23427 erase_phys_cursor (struct window *w)
23428 {
23429 struct frame *f = XFRAME (w->frame);
23430 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23431 int hpos = w->phys_cursor.hpos;
23432 int vpos = w->phys_cursor.vpos;
23433 int mouse_face_here_p = 0;
23434 struct glyph_matrix *active_glyphs = w->current_matrix;
23435 struct glyph_row *cursor_row;
23436 struct glyph *cursor_glyph;
23437 enum draw_glyphs_face hl;
23438
23439 /* No cursor displayed or row invalidated => nothing to do on the
23440 screen. */
23441 if (w->phys_cursor_type == NO_CURSOR)
23442 goto mark_cursor_off;
23443
23444 /* VPOS >= active_glyphs->nrows means that window has been resized.
23445 Don't bother to erase the cursor. */
23446 if (vpos >= active_glyphs->nrows)
23447 goto mark_cursor_off;
23448
23449 /* If row containing cursor is marked invalid, there is nothing we
23450 can do. */
23451 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23452 if (!cursor_row->enabled_p)
23453 goto mark_cursor_off;
23454
23455 /* If line spacing is > 0, old cursor may only be partially visible in
23456 window after split-window. So adjust visible height. */
23457 cursor_row->visible_height = min (cursor_row->visible_height,
23458 window_text_bottom_y (w) - cursor_row->y);
23459
23460 /* If row is completely invisible, don't attempt to delete a cursor which
23461 isn't there. This can happen if cursor is at top of a window, and
23462 we switch to a buffer with a header line in that window. */
23463 if (cursor_row->visible_height <= 0)
23464 goto mark_cursor_off;
23465
23466 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23467 if (cursor_row->cursor_in_fringe_p)
23468 {
23469 cursor_row->cursor_in_fringe_p = 0;
23470 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23471 goto mark_cursor_off;
23472 }
23473
23474 /* This can happen when the new row is shorter than the old one.
23475 In this case, either draw_glyphs or clear_end_of_line
23476 should have cleared the cursor. Note that we wouldn't be
23477 able to erase the cursor in this case because we don't have a
23478 cursor glyph at hand. */
23479 if ((cursor_row->reversed_p
23480 ? (w->phys_cursor.hpos < 0)
23481 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23482 goto mark_cursor_off;
23483
23484 /* If the cursor is in the mouse face area, redisplay that when
23485 we clear the cursor. */
23486 if (! NILP (dpyinfo->mouse_face_window)
23487 && w == XWINDOW (dpyinfo->mouse_face_window)
23488 && (vpos > dpyinfo->mouse_face_beg_row
23489 || (vpos == dpyinfo->mouse_face_beg_row
23490 && hpos >= dpyinfo->mouse_face_beg_col))
23491 && (vpos < dpyinfo->mouse_face_end_row
23492 || (vpos == dpyinfo->mouse_face_end_row
23493 && hpos < dpyinfo->mouse_face_end_col))
23494 /* Don't redraw the cursor's spot in mouse face if it is at the
23495 end of a line (on a newline). The cursor appears there, but
23496 mouse highlighting does not. */
23497 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23498 mouse_face_here_p = 1;
23499
23500 /* Maybe clear the display under the cursor. */
23501 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23502 {
23503 int x, y, left_x;
23504 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23505 int width;
23506
23507 cursor_glyph = get_phys_cursor_glyph (w);
23508 if (cursor_glyph == NULL)
23509 goto mark_cursor_off;
23510
23511 width = cursor_glyph->pixel_width;
23512 left_x = window_box_left_offset (w, TEXT_AREA);
23513 x = w->phys_cursor.x;
23514 if (x < left_x)
23515 width -= left_x - x;
23516 width = min (width, window_box_width (w, TEXT_AREA) - x);
23517 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23518 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23519
23520 if (width > 0)
23521 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23522 }
23523
23524 /* Erase the cursor by redrawing the character underneath it. */
23525 if (mouse_face_here_p)
23526 hl = DRAW_MOUSE_FACE;
23527 else
23528 hl = DRAW_NORMAL_TEXT;
23529 draw_phys_cursor_glyph (w, cursor_row, hl);
23530
23531 mark_cursor_off:
23532 w->phys_cursor_on_p = 0;
23533 w->phys_cursor_type = NO_CURSOR;
23534 }
23535
23536
23537 /* EXPORT:
23538 Display or clear cursor of window W. If ON is zero, clear the
23539 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23540 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23541
23542 void
23543 display_and_set_cursor (struct window *w, int on,
23544 int hpos, int vpos, int x, int y)
23545 {
23546 struct frame *f = XFRAME (w->frame);
23547 int new_cursor_type;
23548 int new_cursor_width;
23549 int active_cursor;
23550 struct glyph_row *glyph_row;
23551 struct glyph *glyph;
23552
23553 /* This is pointless on invisible frames, and dangerous on garbaged
23554 windows and frames; in the latter case, the frame or window may
23555 be in the midst of changing its size, and x and y may be off the
23556 window. */
23557 if (! FRAME_VISIBLE_P (f)
23558 || FRAME_GARBAGED_P (f)
23559 || vpos >= w->current_matrix->nrows
23560 || hpos >= w->current_matrix->matrix_w)
23561 return;
23562
23563 /* If cursor is off and we want it off, return quickly. */
23564 if (!on && !w->phys_cursor_on_p)
23565 return;
23566
23567 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23568 /* If cursor row is not enabled, we don't really know where to
23569 display the cursor. */
23570 if (!glyph_row->enabled_p)
23571 {
23572 w->phys_cursor_on_p = 0;
23573 return;
23574 }
23575
23576 glyph = NULL;
23577 if (!glyph_row->exact_window_width_line_p
23578 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23579 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23580
23581 xassert (interrupt_input_blocked);
23582
23583 /* Set new_cursor_type to the cursor we want to be displayed. */
23584 new_cursor_type = get_window_cursor_type (w, glyph,
23585 &new_cursor_width, &active_cursor);
23586
23587 /* If cursor is currently being shown and we don't want it to be or
23588 it is in the wrong place, or the cursor type is not what we want,
23589 erase it. */
23590 if (w->phys_cursor_on_p
23591 && (!on
23592 || w->phys_cursor.x != x
23593 || w->phys_cursor.y != y
23594 || new_cursor_type != w->phys_cursor_type
23595 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23596 && new_cursor_width != w->phys_cursor_width)))
23597 erase_phys_cursor (w);
23598
23599 /* Don't check phys_cursor_on_p here because that flag is only set
23600 to zero in some cases where we know that the cursor has been
23601 completely erased, to avoid the extra work of erasing the cursor
23602 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23603 still not be visible, or it has only been partly erased. */
23604 if (on)
23605 {
23606 w->phys_cursor_ascent = glyph_row->ascent;
23607 w->phys_cursor_height = glyph_row->height;
23608
23609 /* Set phys_cursor_.* before x_draw_.* is called because some
23610 of them may need the information. */
23611 w->phys_cursor.x = x;
23612 w->phys_cursor.y = glyph_row->y;
23613 w->phys_cursor.hpos = hpos;
23614 w->phys_cursor.vpos = vpos;
23615 }
23616
23617 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23618 new_cursor_type, new_cursor_width,
23619 on, active_cursor);
23620 }
23621
23622
23623 /* Switch the display of W's cursor on or off, according to the value
23624 of ON. */
23625
23626 void
23627 update_window_cursor (struct window *w, int on)
23628 {
23629 /* Don't update cursor in windows whose frame is in the process
23630 of being deleted. */
23631 if (w->current_matrix)
23632 {
23633 BLOCK_INPUT;
23634 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23635 w->phys_cursor.x, w->phys_cursor.y);
23636 UNBLOCK_INPUT;
23637 }
23638 }
23639
23640
23641 /* Call update_window_cursor with parameter ON_P on all leaf windows
23642 in the window tree rooted at W. */
23643
23644 static void
23645 update_cursor_in_window_tree (struct window *w, int on_p)
23646 {
23647 while (w)
23648 {
23649 if (!NILP (w->hchild))
23650 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23651 else if (!NILP (w->vchild))
23652 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23653 else
23654 update_window_cursor (w, on_p);
23655
23656 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23657 }
23658 }
23659
23660
23661 /* EXPORT:
23662 Display the cursor on window W, or clear it, according to ON_P.
23663 Don't change the cursor's position. */
23664
23665 void
23666 x_update_cursor (struct frame *f, int on_p)
23667 {
23668 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23669 }
23670
23671
23672 /* EXPORT:
23673 Clear the cursor of window W to background color, and mark the
23674 cursor as not shown. This is used when the text where the cursor
23675 is about to be rewritten. */
23676
23677 void
23678 x_clear_cursor (struct window *w)
23679 {
23680 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
23681 update_window_cursor (w, 0);
23682 }
23683
23684
23685 /* EXPORT:
23686 Display the active region described by mouse_face_* according to DRAW. */
23687
23688 void
23689 show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23690 {
23691 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
23692 struct frame *f = XFRAME (WINDOW_FRAME (w));
23693
23694 if (/* If window is in the process of being destroyed, don't bother
23695 to do anything. */
23696 w->current_matrix != NULL
23697 /* Don't update mouse highlight if hidden */
23698 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
23699 /* Recognize when we are called to operate on rows that don't exist
23700 anymore. This can happen when a window is split. */
23701 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
23702 {
23703 int phys_cursor_on_p = w->phys_cursor_on_p;
23704 struct glyph_row *row, *first, *last;
23705
23706 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
23707 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
23708
23709 for (row = first; row <= last && row->enabled_p; ++row)
23710 {
23711 int start_hpos, end_hpos, start_x;
23712
23713 /* For all but the first row, the highlight starts at column 0. */
23714 if (row == first)
23715 {
23716 start_hpos = dpyinfo->mouse_face_beg_col;
23717 start_x = dpyinfo->mouse_face_beg_x;
23718 }
23719 else
23720 {
23721 start_hpos = 0;
23722 start_x = 0;
23723 }
23724
23725 if (row == last)
23726 end_hpos = dpyinfo->mouse_face_end_col;
23727 else
23728 {
23729 end_hpos = row->used[TEXT_AREA];
23730 if (draw == DRAW_NORMAL_TEXT)
23731 row->fill_line_p = 1; /* Clear to end of line */
23732 }
23733
23734 if (end_hpos > start_hpos)
23735 {
23736 draw_glyphs (w, start_x, row, TEXT_AREA,
23737 start_hpos, end_hpos,
23738 draw, 0);
23739
23740 row->mouse_face_p
23741 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
23742 }
23743 }
23744
23745 /* When we've written over the cursor, arrange for it to
23746 be displayed again. */
23747 if (phys_cursor_on_p && !w->phys_cursor_on_p)
23748 {
23749 BLOCK_INPUT;
23750 display_and_set_cursor (w, 1,
23751 w->phys_cursor.hpos, w->phys_cursor.vpos,
23752 w->phys_cursor.x, w->phys_cursor.y);
23753 UNBLOCK_INPUT;
23754 }
23755 }
23756
23757 /* Change the mouse cursor. */
23758 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
23759 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
23760 else if (draw == DRAW_MOUSE_FACE)
23761 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
23762 else
23763 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
23764 }
23765
23766 /* EXPORT:
23767 Clear out the mouse-highlighted active region.
23768 Redraw it un-highlighted first. Value is non-zero if mouse
23769 face was actually drawn unhighlighted. */
23770
23771 int
23772 clear_mouse_face (Display_Info *dpyinfo)
23773 {
23774 int cleared = 0;
23775
23776 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
23777 {
23778 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
23779 cleared = 1;
23780 }
23781
23782 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23783 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23784 dpyinfo->mouse_face_window = Qnil;
23785 dpyinfo->mouse_face_overlay = Qnil;
23786 return cleared;
23787 }
23788
23789
23790 /* EXPORT:
23791 Non-zero if physical cursor of window W is within mouse face. */
23792
23793 int
23794 cursor_in_mouse_face_p (struct window *w)
23795 {
23796 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23797 int in_mouse_face = 0;
23798
23799 if (WINDOWP (dpyinfo->mouse_face_window)
23800 && XWINDOW (dpyinfo->mouse_face_window) == w)
23801 {
23802 int hpos = w->phys_cursor.hpos;
23803 int vpos = w->phys_cursor.vpos;
23804
23805 if (vpos >= dpyinfo->mouse_face_beg_row
23806 && vpos <= dpyinfo->mouse_face_end_row
23807 && (vpos > dpyinfo->mouse_face_beg_row
23808 || hpos >= dpyinfo->mouse_face_beg_col)
23809 && (vpos < dpyinfo->mouse_face_end_row
23810 || hpos < dpyinfo->mouse_face_end_col
23811 || dpyinfo->mouse_face_past_end))
23812 in_mouse_face = 1;
23813 }
23814
23815 return in_mouse_face;
23816 }
23817
23818
23819
23820 \f
23821 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23822 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23823 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23824 for the overlay or run of text properties specifying the mouse
23825 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23826 before-string and after-string that must also be highlighted.
23827 DISPLAY_STRING, if non-nil, is a display string that may cover some
23828 or all of the highlighted text. */
23829
23830 static void
23831 mouse_face_from_buffer_pos (Lisp_Object window,
23832 Display_Info *dpyinfo,
23833 EMACS_INT mouse_charpos,
23834 EMACS_INT start_charpos,
23835 EMACS_INT end_charpos,
23836 Lisp_Object before_string,
23837 Lisp_Object after_string,
23838 Lisp_Object display_string)
23839 {
23840 struct window *w = XWINDOW (window);
23841 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23842 struct glyph_row *row;
23843 struct glyph *glyph, *end;
23844 EMACS_INT ignore;
23845 int x;
23846
23847 xassert (NILP (display_string) || STRINGP (display_string));
23848 xassert (NILP (before_string) || STRINGP (before_string));
23849 xassert (NILP (after_string) || STRINGP (after_string));
23850
23851 /* Find the first highlighted glyph. */
23852 if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
23853 {
23854 dpyinfo->mouse_face_beg_col = 0;
23855 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
23856 dpyinfo->mouse_face_beg_x = first->x;
23857 dpyinfo->mouse_face_beg_y = first->y;
23858 }
23859 else
23860 {
23861 row = row_containing_pos (w, start_charpos, first, NULL, 0);
23862 if (row == NULL)
23863 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23864
23865 /* If the before-string or display-string contains newlines,
23866 row_containing_pos skips to its last row. Move back. */
23867 if (!NILP (before_string) || !NILP (display_string))
23868 {
23869 struct glyph_row *prev;
23870 while ((prev = row - 1, prev >= first)
23871 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23872 && prev->used[TEXT_AREA] > 0)
23873 {
23874 struct glyph *beg = prev->glyphs[TEXT_AREA];
23875 glyph = beg + prev->used[TEXT_AREA];
23876 while (--glyph >= beg && INTEGERP (glyph->object));
23877 if (glyph < beg
23878 || !(EQ (glyph->object, before_string)
23879 || EQ (glyph->object, display_string)))
23880 break;
23881 row = prev;
23882 }
23883 }
23884
23885 glyph = row->glyphs[TEXT_AREA];
23886 end = glyph + row->used[TEXT_AREA];
23887 x = row->x;
23888 dpyinfo->mouse_face_beg_y = row->y;
23889 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
23890
23891 /* Skip truncation glyphs at the start of the glyph row. */
23892 if (row->displays_text_p)
23893 for (; glyph < end
23894 && INTEGERP (glyph->object)
23895 && glyph->charpos < 0;
23896 ++glyph)
23897 x += glyph->pixel_width;
23898
23899 /* Scan the glyph row, stopping before BEFORE_STRING or
23900 DISPLAY_STRING or START_CHARPOS. */
23901 for (; glyph < end
23902 && !INTEGERP (glyph->object)
23903 && !EQ (glyph->object, before_string)
23904 && !EQ (glyph->object, display_string)
23905 && !(BUFFERP (glyph->object)
23906 && glyph->charpos >= start_charpos);
23907 ++glyph)
23908 x += glyph->pixel_width;
23909
23910 dpyinfo->mouse_face_beg_x = x;
23911 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
23912 }
23913
23914 /* Find the last highlighted glyph. */
23915 row = row_containing_pos (w, end_charpos, first, NULL, 0);
23916 if (row == NULL)
23917 {
23918 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23919 dpyinfo->mouse_face_past_end = 1;
23920 }
23921 else if (!NILP (after_string))
23922 {
23923 /* If the after-string has newlines, advance to its last row. */
23924 struct glyph_row *next;
23925 struct glyph_row *last
23926 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23927
23928 for (next = row + 1;
23929 next <= last
23930 && next->used[TEXT_AREA] > 0
23931 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
23932 ++next)
23933 row = next;
23934 }
23935
23936 glyph = row->glyphs[TEXT_AREA];
23937 end = glyph + row->used[TEXT_AREA];
23938 x = row->x;
23939 dpyinfo->mouse_face_end_y = row->y;
23940 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
23941
23942 /* Skip truncation glyphs at the start of the row. */
23943 if (row->displays_text_p)
23944 for (; glyph < end
23945 && INTEGERP (glyph->object)
23946 && glyph->charpos < 0;
23947 ++glyph)
23948 x += glyph->pixel_width;
23949
23950 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
23951 AFTER_STRING. */
23952 for (; glyph < end
23953 && !INTEGERP (glyph->object)
23954 && !EQ (glyph->object, after_string)
23955 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
23956 ++glyph)
23957 x += glyph->pixel_width;
23958
23959 /* If we found AFTER_STRING, consume it and stop. */
23960 if (EQ (glyph->object, after_string))
23961 {
23962 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
23963 x += glyph->pixel_width;
23964 }
23965 else
23966 {
23967 /* If there's no after-string, we must check if we overshot,
23968 which might be the case if we stopped after a string glyph.
23969 That glyph may belong to a before-string or display-string
23970 associated with the end position, which must not be
23971 highlighted. */
23972 Lisp_Object prev_object;
23973 EMACS_INT pos;
23974
23975 while (glyph > row->glyphs[TEXT_AREA])
23976 {
23977 prev_object = (glyph - 1)->object;
23978 if (!STRINGP (prev_object) || EQ (prev_object, display_string))
23979 break;
23980
23981 pos = string_buffer_position (w, prev_object, end_charpos);
23982 if (pos && pos < end_charpos)
23983 break;
23984
23985 for (; glyph > row->glyphs[TEXT_AREA]
23986 && EQ ((glyph - 1)->object, prev_object);
23987 --glyph)
23988 x -= (glyph - 1)->pixel_width;
23989 }
23990 }
23991
23992 dpyinfo->mouse_face_end_x = x;
23993 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
23994 dpyinfo->mouse_face_window = window;
23995 dpyinfo->mouse_face_face_id
23996 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
23997 mouse_charpos + 1,
23998 !dpyinfo->mouse_face_hidden, -1);
23999 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24000 }
24001
24002
24003 /* Find the position of the glyph for position POS in OBJECT in
24004 window W's current matrix, and return in *X, *Y the pixel
24005 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24006
24007 RIGHT_P non-zero means return the position of the right edge of the
24008 glyph, RIGHT_P zero means return the left edge position.
24009
24010 If no glyph for POS exists in the matrix, return the position of
24011 the glyph with the next smaller position that is in the matrix, if
24012 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24013 exists in the matrix, return the position of the glyph with the
24014 next larger position in OBJECT.
24015
24016 Value is non-zero if a glyph was found. */
24017
24018 static int
24019 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24020 int *hpos, int *vpos, int *x, int *y, int right_p)
24021 {
24022 int yb = window_text_bottom_y (w);
24023 struct glyph_row *r;
24024 struct glyph *best_glyph = NULL;
24025 struct glyph_row *best_row = NULL;
24026 int best_x = 0;
24027
24028 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24029 r->enabled_p && r->y < yb;
24030 ++r)
24031 {
24032 struct glyph *g = r->glyphs[TEXT_AREA];
24033 struct glyph *e = g + r->used[TEXT_AREA];
24034 int gx;
24035
24036 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24037 if (EQ (g->object, object))
24038 {
24039 if (g->charpos == pos)
24040 {
24041 best_glyph = g;
24042 best_x = gx;
24043 best_row = r;
24044 goto found;
24045 }
24046 else if (best_glyph == NULL
24047 || ((eabs (g->charpos - pos)
24048 < eabs (best_glyph->charpos - pos))
24049 && (right_p
24050 ? g->charpos < pos
24051 : g->charpos > pos)))
24052 {
24053 best_glyph = g;
24054 best_x = gx;
24055 best_row = r;
24056 }
24057 }
24058 }
24059
24060 found:
24061
24062 if (best_glyph)
24063 {
24064 *x = best_x;
24065 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24066
24067 if (right_p)
24068 {
24069 *x += best_glyph->pixel_width;
24070 ++*hpos;
24071 }
24072
24073 *y = best_row->y;
24074 *vpos = best_row - w->current_matrix->rows;
24075 }
24076
24077 return best_glyph != NULL;
24078 }
24079
24080
24081 /* See if position X, Y is within a hot-spot of an image. */
24082
24083 static int
24084 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24085 {
24086 if (!CONSP (hot_spot))
24087 return 0;
24088
24089 if (EQ (XCAR (hot_spot), Qrect))
24090 {
24091 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24092 Lisp_Object rect = XCDR (hot_spot);
24093 Lisp_Object tem;
24094 if (!CONSP (rect))
24095 return 0;
24096 if (!CONSP (XCAR (rect)))
24097 return 0;
24098 if (!CONSP (XCDR (rect)))
24099 return 0;
24100 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24101 return 0;
24102 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24103 return 0;
24104 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24105 return 0;
24106 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24107 return 0;
24108 return 1;
24109 }
24110 else if (EQ (XCAR (hot_spot), Qcircle))
24111 {
24112 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24113 Lisp_Object circ = XCDR (hot_spot);
24114 Lisp_Object lr, lx0, ly0;
24115 if (CONSP (circ)
24116 && CONSP (XCAR (circ))
24117 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24118 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24119 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24120 {
24121 double r = XFLOATINT (lr);
24122 double dx = XINT (lx0) - x;
24123 double dy = XINT (ly0) - y;
24124 return (dx * dx + dy * dy <= r * r);
24125 }
24126 }
24127 else if (EQ (XCAR (hot_spot), Qpoly))
24128 {
24129 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24130 if (VECTORP (XCDR (hot_spot)))
24131 {
24132 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24133 Lisp_Object *poly = v->contents;
24134 int n = v->size;
24135 int i;
24136 int inside = 0;
24137 Lisp_Object lx, ly;
24138 int x0, y0;
24139
24140 /* Need an even number of coordinates, and at least 3 edges. */
24141 if (n < 6 || n & 1)
24142 return 0;
24143
24144 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24145 If count is odd, we are inside polygon. Pixels on edges
24146 may or may not be included depending on actual geometry of the
24147 polygon. */
24148 if ((lx = poly[n-2], !INTEGERP (lx))
24149 || (ly = poly[n-1], !INTEGERP (lx)))
24150 return 0;
24151 x0 = XINT (lx), y0 = XINT (ly);
24152 for (i = 0; i < n; i += 2)
24153 {
24154 int x1 = x0, y1 = y0;
24155 if ((lx = poly[i], !INTEGERP (lx))
24156 || (ly = poly[i+1], !INTEGERP (ly)))
24157 return 0;
24158 x0 = XINT (lx), y0 = XINT (ly);
24159
24160 /* Does this segment cross the X line? */
24161 if (x0 >= x)
24162 {
24163 if (x1 >= x)
24164 continue;
24165 }
24166 else if (x1 < x)
24167 continue;
24168 if (y > y0 && y > y1)
24169 continue;
24170 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24171 inside = !inside;
24172 }
24173 return inside;
24174 }
24175 }
24176 return 0;
24177 }
24178
24179 Lisp_Object
24180 find_hot_spot (Lisp_Object map, int x, int y)
24181 {
24182 while (CONSP (map))
24183 {
24184 if (CONSP (XCAR (map))
24185 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24186 return XCAR (map);
24187 map = XCDR (map);
24188 }
24189
24190 return Qnil;
24191 }
24192
24193 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
24194 3, 3, 0,
24195 doc: /* Lookup in image map MAP coordinates X and Y.
24196 An image map is an alist where each element has the format (AREA ID PLIST).
24197 An AREA is specified as either a rectangle, a circle, or a polygon:
24198 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24199 pixel coordinates of the upper left and bottom right corners.
24200 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24201 and the radius of the circle; r may be a float or integer.
24202 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24203 vector describes one corner in the polygon.
24204 Returns the alist element for the first matching AREA in MAP. */)
24205 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
24206 {
24207 if (NILP (map))
24208 return Qnil;
24209
24210 CHECK_NUMBER (x);
24211 CHECK_NUMBER (y);
24212
24213 return find_hot_spot (map, XINT (x), XINT (y));
24214 }
24215
24216
24217 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24218 static void
24219 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
24220 {
24221 /* Do not change cursor shape while dragging mouse. */
24222 if (!NILP (do_mouse_tracking))
24223 return;
24224
24225 if (!NILP (pointer))
24226 {
24227 if (EQ (pointer, Qarrow))
24228 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24229 else if (EQ (pointer, Qhand))
24230 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
24231 else if (EQ (pointer, Qtext))
24232 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24233 else if (EQ (pointer, intern ("hdrag")))
24234 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24235 #ifdef HAVE_X_WINDOWS
24236 else if (EQ (pointer, intern ("vdrag")))
24237 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
24238 #endif
24239 else if (EQ (pointer, intern ("hourglass")))
24240 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
24241 else if (EQ (pointer, Qmodeline))
24242 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
24243 else
24244 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24245 }
24246
24247 if (cursor != No_Cursor)
24248 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24249 }
24250
24251 /* Take proper action when mouse has moved to the mode or header line
24252 or marginal area AREA of window W, x-position X and y-position Y.
24253 X is relative to the start of the text display area of W, so the
24254 width of bitmap areas and scroll bars must be subtracted to get a
24255 position relative to the start of the mode line. */
24256
24257 static void
24258 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24259 enum window_part area)
24260 {
24261 struct window *w = XWINDOW (window);
24262 struct frame *f = XFRAME (w->frame);
24263 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24264 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24265 Lisp_Object pointer = Qnil;
24266 int charpos, dx, dy, width, height;
24267 Lisp_Object string, object = Qnil;
24268 Lisp_Object pos, help;
24269
24270 Lisp_Object mouse_face;
24271 int original_x_pixel = x;
24272 struct glyph * glyph = NULL, * row_start_glyph = NULL;
24273 struct glyph_row *row;
24274
24275 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
24276 {
24277 int x0;
24278 struct glyph *end;
24279
24280 string = mode_line_string (w, area, &x, &y, &charpos,
24281 &object, &dx, &dy, &width, &height);
24282
24283 row = (area == ON_MODE_LINE
24284 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
24285 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
24286
24287 /* Find glyph */
24288 if (row->mode_line_p && row->enabled_p)
24289 {
24290 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
24291 end = glyph + row->used[TEXT_AREA];
24292
24293 for (x0 = original_x_pixel;
24294 glyph < end && x0 >= glyph->pixel_width;
24295 ++glyph)
24296 x0 -= glyph->pixel_width;
24297
24298 if (glyph >= end)
24299 glyph = NULL;
24300 }
24301 }
24302 else
24303 {
24304 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
24305 string = marginal_area_string (w, area, &x, &y, &charpos,
24306 &object, &dx, &dy, &width, &height);
24307 }
24308
24309 help = Qnil;
24310
24311 if (IMAGEP (object))
24312 {
24313 Lisp_Object image_map, hotspot;
24314 if ((image_map = Fplist_get (XCDR (object), QCmap),
24315 !NILP (image_map))
24316 && (hotspot = find_hot_spot (image_map, dx, dy),
24317 CONSP (hotspot))
24318 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24319 {
24320 Lisp_Object area_id, plist;
24321
24322 area_id = XCAR (hotspot);
24323 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24324 If so, we could look for mouse-enter, mouse-leave
24325 properties in PLIST (and do something...). */
24326 hotspot = XCDR (hotspot);
24327 if (CONSP (hotspot)
24328 && (plist = XCAR (hotspot), CONSP (plist)))
24329 {
24330 pointer = Fplist_get (plist, Qpointer);
24331 if (NILP (pointer))
24332 pointer = Qhand;
24333 help = Fplist_get (plist, Qhelp_echo);
24334 if (!NILP (help))
24335 {
24336 help_echo_string = help;
24337 /* Is this correct? ++kfs */
24338 XSETWINDOW (help_echo_window, w);
24339 help_echo_object = w->buffer;
24340 help_echo_pos = charpos;
24341 }
24342 }
24343 }
24344 if (NILP (pointer))
24345 pointer = Fplist_get (XCDR (object), QCpointer);
24346 }
24347
24348 if (STRINGP (string))
24349 {
24350 pos = make_number (charpos);
24351 /* If we're on a string with `help-echo' text property, arrange
24352 for the help to be displayed. This is done by setting the
24353 global variable help_echo_string to the help string. */
24354 if (NILP (help))
24355 {
24356 help = Fget_text_property (pos, Qhelp_echo, string);
24357 if (!NILP (help))
24358 {
24359 help_echo_string = help;
24360 XSETWINDOW (help_echo_window, w);
24361 help_echo_object = string;
24362 help_echo_pos = charpos;
24363 }
24364 }
24365
24366 if (NILP (pointer))
24367 pointer = Fget_text_property (pos, Qpointer, string);
24368
24369 /* Change the mouse pointer according to what is under X/Y. */
24370 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
24371 {
24372 Lisp_Object map;
24373 map = Fget_text_property (pos, Qlocal_map, string);
24374 if (!KEYMAPP (map))
24375 map = Fget_text_property (pos, Qkeymap, string);
24376 if (!KEYMAPP (map))
24377 cursor = dpyinfo->vertical_scroll_bar_cursor;
24378 }
24379
24380 /* Change the mouse face according to what is under X/Y. */
24381 mouse_face = Fget_text_property (pos, Qmouse_face, string);
24382 if (!NILP (mouse_face)
24383 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24384 && glyph)
24385 {
24386 Lisp_Object b, e;
24387
24388 struct glyph * tmp_glyph;
24389
24390 int gpos;
24391 int gseq_length;
24392 int total_pixel_width;
24393 EMACS_INT ignore;
24394
24395 int vpos, hpos;
24396
24397 b = Fprevious_single_property_change (make_number (charpos + 1),
24398 Qmouse_face, string, Qnil);
24399 if (NILP (b))
24400 b = make_number (0);
24401
24402 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24403 if (NILP (e))
24404 e = make_number (SCHARS (string));
24405
24406 /* Calculate the position(glyph position: GPOS) of GLYPH in
24407 displayed string. GPOS is different from CHARPOS.
24408
24409 CHARPOS is the position of glyph in internal string
24410 object. A mode line string format has structures which
24411 is converted to a flatten by emacs lisp interpreter.
24412 The internal string is an element of the structures.
24413 The displayed string is the flatten string. */
24414 gpos = 0;
24415 if (glyph > row_start_glyph)
24416 {
24417 tmp_glyph = glyph - 1;
24418 while (tmp_glyph >= row_start_glyph
24419 && tmp_glyph->charpos >= XINT (b)
24420 && EQ (tmp_glyph->object, glyph->object))
24421 {
24422 tmp_glyph--;
24423 gpos++;
24424 }
24425 }
24426
24427 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24428 displayed string holding GLYPH.
24429
24430 GSEQ_LENGTH is different from SCHARS (STRING).
24431 SCHARS (STRING) returns the length of the internal string. */
24432 for (tmp_glyph = glyph, gseq_length = gpos;
24433 tmp_glyph->charpos < XINT (e);
24434 tmp_glyph++, gseq_length++)
24435 {
24436 if (!EQ (tmp_glyph->object, glyph->object))
24437 break;
24438 }
24439
24440 total_pixel_width = 0;
24441 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24442 total_pixel_width += tmp_glyph->pixel_width;
24443
24444 /* Pre calculation of re-rendering position */
24445 vpos = (x - gpos);
24446 hpos = (area == ON_MODE_LINE
24447 ? (w->current_matrix)->nrows - 1
24448 : 0);
24449
24450 /* If the re-rendering position is included in the last
24451 re-rendering area, we should do nothing. */
24452 if ( EQ (window, dpyinfo->mouse_face_window)
24453 && dpyinfo->mouse_face_beg_col <= vpos
24454 && vpos < dpyinfo->mouse_face_end_col
24455 && dpyinfo->mouse_face_beg_row == hpos )
24456 return;
24457
24458 if (clear_mouse_face (dpyinfo))
24459 cursor = No_Cursor;
24460
24461 dpyinfo->mouse_face_beg_col = vpos;
24462 dpyinfo->mouse_face_beg_row = hpos;
24463
24464 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
24465 dpyinfo->mouse_face_beg_y = 0;
24466
24467 dpyinfo->mouse_face_end_col = vpos + gseq_length;
24468 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
24469
24470 dpyinfo->mouse_face_end_x = 0;
24471 dpyinfo->mouse_face_end_y = 0;
24472
24473 dpyinfo->mouse_face_past_end = 0;
24474 dpyinfo->mouse_face_window = window;
24475
24476 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
24477 charpos,
24478 0, 0, 0, &ignore,
24479 glyph->face_id, 1);
24480 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24481
24482 if (NILP (pointer))
24483 pointer = Qhand;
24484 }
24485 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24486 clear_mouse_face (dpyinfo);
24487 }
24488 define_frame_cursor1 (f, cursor, pointer);
24489 }
24490
24491
24492 /* EXPORT:
24493 Take proper action when the mouse has moved to position X, Y on
24494 frame F as regards highlighting characters that have mouse-face
24495 properties. Also de-highlighting chars where the mouse was before.
24496 X and Y can be negative or out of range. */
24497
24498 void
24499 note_mouse_highlight (struct frame *f, int x, int y)
24500 {
24501 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24502 enum window_part part;
24503 Lisp_Object window;
24504 struct window *w;
24505 Cursor cursor = No_Cursor;
24506 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
24507 struct buffer *b;
24508
24509 /* When a menu is active, don't highlight because this looks odd. */
24510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24511 if (popup_activated ())
24512 return;
24513 #endif
24514
24515 if (NILP (Vmouse_highlight)
24516 || !f->glyphs_initialized_p
24517 || f->pointer_invisible)
24518 return;
24519
24520 dpyinfo->mouse_face_mouse_x = x;
24521 dpyinfo->mouse_face_mouse_y = y;
24522 dpyinfo->mouse_face_mouse_frame = f;
24523
24524 if (dpyinfo->mouse_face_defer)
24525 return;
24526
24527 if (gc_in_progress)
24528 {
24529 dpyinfo->mouse_face_deferred_gc = 1;
24530 return;
24531 }
24532
24533 /* Which window is that in? */
24534 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
24535
24536 /* If we were displaying active text in another window, clear that.
24537 Also clear if we move out of text area in same window. */
24538 if (! EQ (window, dpyinfo->mouse_face_window)
24539 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
24540 && !NILP (dpyinfo->mouse_face_window)))
24541 clear_mouse_face (dpyinfo);
24542
24543 /* Not on a window -> return. */
24544 if (!WINDOWP (window))
24545 return;
24546
24547 /* Reset help_echo_string. It will get recomputed below. */
24548 help_echo_string = Qnil;
24549
24550 /* Convert to window-relative pixel coordinates. */
24551 w = XWINDOW (window);
24552 frame_to_window_pixel_xy (w, &x, &y);
24553
24554 /* Handle tool-bar window differently since it doesn't display a
24555 buffer. */
24556 if (EQ (window, f->tool_bar_window))
24557 {
24558 note_tool_bar_highlight (f, x, y);
24559 return;
24560 }
24561
24562 /* Mouse is on the mode, header line or margin? */
24563 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
24564 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
24565 {
24566 note_mode_line_or_margin_highlight (window, x, y, part);
24567 return;
24568 }
24569
24570 if (part == ON_VERTICAL_BORDER)
24571 {
24572 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24573 help_echo_string = build_string ("drag-mouse-1: resize");
24574 }
24575 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
24576 || part == ON_SCROLL_BAR)
24577 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24578 else
24579 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24580
24581 /* Are we in a window whose display is up to date?
24582 And verify the buffer's text has not changed. */
24583 b = XBUFFER (w->buffer);
24584 if (part == ON_TEXT
24585 && EQ (w->window_end_valid, w->buffer)
24586 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
24587 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
24588 {
24589 int hpos, vpos, i, dx, dy, area;
24590 EMACS_INT pos;
24591 struct glyph *glyph;
24592 Lisp_Object object;
24593 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
24594 Lisp_Object *overlay_vec = NULL;
24595 int noverlays;
24596 struct buffer *obuf;
24597 int obegv, ozv, same_region;
24598
24599 /* Find the glyph under X/Y. */
24600 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
24601
24602 /* Look for :pointer property on image. */
24603 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24604 {
24605 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24606 if (img != NULL && IMAGEP (img->spec))
24607 {
24608 Lisp_Object image_map, hotspot;
24609 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
24610 !NILP (image_map))
24611 && (hotspot = find_hot_spot (image_map,
24612 glyph->slice.x + dx,
24613 glyph->slice.y + dy),
24614 CONSP (hotspot))
24615 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24616 {
24617 Lisp_Object area_id, plist;
24618
24619 area_id = XCAR (hotspot);
24620 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24621 If so, we could look for mouse-enter, mouse-leave
24622 properties in PLIST (and do something...). */
24623 hotspot = XCDR (hotspot);
24624 if (CONSP (hotspot)
24625 && (plist = XCAR (hotspot), CONSP (plist)))
24626 {
24627 pointer = Fplist_get (plist, Qpointer);
24628 if (NILP (pointer))
24629 pointer = Qhand;
24630 help_echo_string = Fplist_get (plist, Qhelp_echo);
24631 if (!NILP (help_echo_string))
24632 {
24633 help_echo_window = window;
24634 help_echo_object = glyph->object;
24635 help_echo_pos = glyph->charpos;
24636 }
24637 }
24638 }
24639 if (NILP (pointer))
24640 pointer = Fplist_get (XCDR (img->spec), QCpointer);
24641 }
24642 }
24643
24644 /* Clear mouse face if X/Y not over text. */
24645 if (glyph == NULL
24646 || area != TEXT_AREA
24647 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
24648 {
24649 if (clear_mouse_face (dpyinfo))
24650 cursor = No_Cursor;
24651 if (NILP (pointer))
24652 {
24653 if (area != TEXT_AREA)
24654 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24655 else
24656 pointer = Vvoid_text_area_pointer;
24657 }
24658 goto set_cursor;
24659 }
24660
24661 pos = glyph->charpos;
24662 object = glyph->object;
24663 if (!STRINGP (object) && !BUFFERP (object))
24664 goto set_cursor;
24665
24666 /* If we get an out-of-range value, return now; avoid an error. */
24667 if (BUFFERP (object) && pos > BUF_Z (b))
24668 goto set_cursor;
24669
24670 /* Make the window's buffer temporarily current for
24671 overlays_at and compute_char_face. */
24672 obuf = current_buffer;
24673 current_buffer = b;
24674 obegv = BEGV;
24675 ozv = ZV;
24676 BEGV = BEG;
24677 ZV = Z;
24678
24679 /* Is this char mouse-active or does it have help-echo? */
24680 position = make_number (pos);
24681
24682 if (BUFFERP (object))
24683 {
24684 /* Put all the overlays we want in a vector in overlay_vec. */
24685 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
24686 /* Sort overlays into increasing priority order. */
24687 noverlays = sort_overlays (overlay_vec, noverlays, w);
24688 }
24689 else
24690 noverlays = 0;
24691
24692 same_region = (EQ (window, dpyinfo->mouse_face_window)
24693 && vpos >= dpyinfo->mouse_face_beg_row
24694 && vpos <= dpyinfo->mouse_face_end_row
24695 && (vpos > dpyinfo->mouse_face_beg_row
24696 || hpos >= dpyinfo->mouse_face_beg_col)
24697 && (vpos < dpyinfo->mouse_face_end_row
24698 || hpos < dpyinfo->mouse_face_end_col
24699 || dpyinfo->mouse_face_past_end));
24700
24701 if (same_region)
24702 cursor = No_Cursor;
24703
24704 /* Check mouse-face highlighting. */
24705 if (! same_region
24706 /* If there exists an overlay with mouse-face overlapping
24707 the one we are currently highlighting, we have to
24708 check if we enter the overlapping overlay, and then
24709 highlight only that. */
24710 || (OVERLAYP (dpyinfo->mouse_face_overlay)
24711 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
24712 {
24713 /* Find the highest priority overlay with a mouse-face. */
24714 overlay = Qnil;
24715 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
24716 {
24717 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
24718 if (!NILP (mouse_face))
24719 overlay = overlay_vec[i];
24720 }
24721
24722 /* If we're highlighting the same overlay as before, there's
24723 no need to do that again. */
24724 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
24725 goto check_help_echo;
24726 dpyinfo->mouse_face_overlay = overlay;
24727
24728 /* Clear the display of the old active region, if any. */
24729 if (clear_mouse_face (dpyinfo))
24730 cursor = No_Cursor;
24731
24732 /* If no overlay applies, get a text property. */
24733 if (NILP (overlay))
24734 mouse_face = Fget_text_property (position, Qmouse_face, object);
24735
24736 /* Next, compute the bounds of the mouse highlighting and
24737 display it. */
24738 if (!NILP (mouse_face) && STRINGP (object))
24739 {
24740 /* The mouse-highlighting comes from a display string
24741 with a mouse-face. */
24742 Lisp_Object b, e;
24743 EMACS_INT ignore;
24744
24745 b = Fprevious_single_property_change
24746 (make_number (pos + 1), Qmouse_face, object, Qnil);
24747 e = Fnext_single_property_change
24748 (position, Qmouse_face, object, Qnil);
24749 if (NILP (b))
24750 b = make_number (0);
24751 if (NILP (e))
24752 e = make_number (SCHARS (object) - 1);
24753
24754 fast_find_string_pos (w, XINT (b), object,
24755 &dpyinfo->mouse_face_beg_col,
24756 &dpyinfo->mouse_face_beg_row,
24757 &dpyinfo->mouse_face_beg_x,
24758 &dpyinfo->mouse_face_beg_y, 0);
24759 fast_find_string_pos (w, XINT (e), object,
24760 &dpyinfo->mouse_face_end_col,
24761 &dpyinfo->mouse_face_end_row,
24762 &dpyinfo->mouse_face_end_x,
24763 &dpyinfo->mouse_face_end_y, 1);
24764 dpyinfo->mouse_face_past_end = 0;
24765 dpyinfo->mouse_face_window = window;
24766 dpyinfo->mouse_face_face_id
24767 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
24768 glyph->face_id, 1);
24769 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24770 cursor = No_Cursor;
24771 }
24772 else
24773 {
24774 /* The mouse-highlighting, if any, comes from an overlay
24775 or text property in the buffer. */
24776 Lisp_Object buffer, display_string;
24777
24778 if (STRINGP (object))
24779 {
24780 /* If we are on a display string with no mouse-face,
24781 check if the text under it has one. */
24782 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
24783 int start = MATRIX_ROW_START_CHARPOS (r);
24784 pos = string_buffer_position (w, object, start);
24785 if (pos > 0)
24786 {
24787 mouse_face = get_char_property_and_overlay
24788 (make_number (pos), Qmouse_face, w->buffer, &overlay);
24789 buffer = w->buffer;
24790 display_string = object;
24791 }
24792 }
24793 else
24794 {
24795 buffer = object;
24796 display_string = Qnil;
24797 }
24798
24799 if (!NILP (mouse_face))
24800 {
24801 Lisp_Object before, after;
24802 Lisp_Object before_string, after_string;
24803
24804 if (NILP (overlay))
24805 {
24806 /* Handle the text property case. */
24807 before = Fprevious_single_property_change
24808 (make_number (pos + 1), Qmouse_face, buffer,
24809 Fmarker_position (w->start));
24810 after = Fnext_single_property_change
24811 (make_number (pos), Qmouse_face, buffer,
24812 make_number (BUF_Z (XBUFFER (buffer))
24813 - XFASTINT (w->window_end_pos)));
24814 before_string = after_string = Qnil;
24815 }
24816 else
24817 {
24818 /* Handle the overlay case. */
24819 before = Foverlay_start (overlay);
24820 after = Foverlay_end (overlay);
24821 before_string = Foverlay_get (overlay, Qbefore_string);
24822 after_string = Foverlay_get (overlay, Qafter_string);
24823
24824 if (!STRINGP (before_string)) before_string = Qnil;
24825 if (!STRINGP (after_string)) after_string = Qnil;
24826 }
24827
24828 mouse_face_from_buffer_pos (window, dpyinfo, pos,
24829 XFASTINT (before),
24830 XFASTINT (after),
24831 before_string, after_string,
24832 display_string);
24833 cursor = No_Cursor;
24834 }
24835 }
24836 }
24837
24838 check_help_echo:
24839
24840 /* Look for a `help-echo' property. */
24841 if (NILP (help_echo_string)) {
24842 Lisp_Object help, overlay;
24843
24844 /* Check overlays first. */
24845 help = overlay = Qnil;
24846 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
24847 {
24848 overlay = overlay_vec[i];
24849 help = Foverlay_get (overlay, Qhelp_echo);
24850 }
24851
24852 if (!NILP (help))
24853 {
24854 help_echo_string = help;
24855 help_echo_window = window;
24856 help_echo_object = overlay;
24857 help_echo_pos = pos;
24858 }
24859 else
24860 {
24861 Lisp_Object object = glyph->object;
24862 int charpos = glyph->charpos;
24863
24864 /* Try text properties. */
24865 if (STRINGP (object)
24866 && charpos >= 0
24867 && charpos < SCHARS (object))
24868 {
24869 help = Fget_text_property (make_number (charpos),
24870 Qhelp_echo, object);
24871 if (NILP (help))
24872 {
24873 /* If the string itself doesn't specify a help-echo,
24874 see if the buffer text ``under'' it does. */
24875 struct glyph_row *r
24876 = MATRIX_ROW (w->current_matrix, vpos);
24877 int start = MATRIX_ROW_START_CHARPOS (r);
24878 EMACS_INT pos = string_buffer_position (w, object, start);
24879 if (pos > 0)
24880 {
24881 help = Fget_char_property (make_number (pos),
24882 Qhelp_echo, w->buffer);
24883 if (!NILP (help))
24884 {
24885 charpos = pos;
24886 object = w->buffer;
24887 }
24888 }
24889 }
24890 }
24891 else if (BUFFERP (object)
24892 && charpos >= BEGV
24893 && charpos < ZV)
24894 help = Fget_text_property (make_number (charpos), Qhelp_echo,
24895 object);
24896
24897 if (!NILP (help))
24898 {
24899 help_echo_string = help;
24900 help_echo_window = window;
24901 help_echo_object = object;
24902 help_echo_pos = charpos;
24903 }
24904 }
24905 }
24906
24907 /* Look for a `pointer' property. */
24908 if (NILP (pointer))
24909 {
24910 /* Check overlays first. */
24911 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
24912 pointer = Foverlay_get (overlay_vec[i], Qpointer);
24913
24914 if (NILP (pointer))
24915 {
24916 Lisp_Object object = glyph->object;
24917 int charpos = glyph->charpos;
24918
24919 /* Try text properties. */
24920 if (STRINGP (object)
24921 && charpos >= 0
24922 && charpos < SCHARS (object))
24923 {
24924 pointer = Fget_text_property (make_number (charpos),
24925 Qpointer, object);
24926 if (NILP (pointer))
24927 {
24928 /* If the string itself doesn't specify a pointer,
24929 see if the buffer text ``under'' it does. */
24930 struct glyph_row *r
24931 = MATRIX_ROW (w->current_matrix, vpos);
24932 int start = MATRIX_ROW_START_CHARPOS (r);
24933 EMACS_INT pos = string_buffer_position (w, object,
24934 start);
24935 if (pos > 0)
24936 pointer = Fget_char_property (make_number (pos),
24937 Qpointer, w->buffer);
24938 }
24939 }
24940 else if (BUFFERP (object)
24941 && charpos >= BEGV
24942 && charpos < ZV)
24943 pointer = Fget_text_property (make_number (charpos),
24944 Qpointer, object);
24945 }
24946 }
24947
24948 BEGV = obegv;
24949 ZV = ozv;
24950 current_buffer = obuf;
24951 }
24952
24953 set_cursor:
24954
24955 define_frame_cursor1 (f, cursor, pointer);
24956 }
24957
24958
24959 /* EXPORT for RIF:
24960 Clear any mouse-face on window W. This function is part of the
24961 redisplay interface, and is called from try_window_id and similar
24962 functions to ensure the mouse-highlight is off. */
24963
24964 void
24965 x_clear_window_mouse_face (struct window *w)
24966 {
24967 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
24968 Lisp_Object window;
24969
24970 BLOCK_INPUT;
24971 XSETWINDOW (window, w);
24972 if (EQ (window, dpyinfo->mouse_face_window))
24973 clear_mouse_face (dpyinfo);
24974 UNBLOCK_INPUT;
24975 }
24976
24977
24978 /* EXPORT:
24979 Just discard the mouse face information for frame F, if any.
24980 This is used when the size of F is changed. */
24981
24982 void
24983 cancel_mouse_face (struct frame *f)
24984 {
24985 Lisp_Object window;
24986 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24987
24988 window = dpyinfo->mouse_face_window;
24989 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
24990 {
24991 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
24992 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
24993 dpyinfo->mouse_face_window = Qnil;
24994 }
24995 }
24996
24997
24998 #endif /* HAVE_WINDOW_SYSTEM */
24999
25000 \f
25001 /***********************************************************************
25002 Exposure Events
25003 ***********************************************************************/
25004
25005 #ifdef HAVE_WINDOW_SYSTEM
25006
25007 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25008 which intersects rectangle R. R is in window-relative coordinates. */
25009
25010 static void
25011 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25012 enum glyph_row_area area)
25013 {
25014 struct glyph *first = row->glyphs[area];
25015 struct glyph *end = row->glyphs[area] + row->used[area];
25016 struct glyph *last;
25017 int first_x, start_x, x;
25018
25019 if (area == TEXT_AREA && row->fill_line_p)
25020 /* If row extends face to end of line write the whole line. */
25021 draw_glyphs (w, 0, row, area,
25022 0, row->used[area],
25023 DRAW_NORMAL_TEXT, 0);
25024 else
25025 {
25026 /* Set START_X to the window-relative start position for drawing glyphs of
25027 AREA. The first glyph of the text area can be partially visible.
25028 The first glyphs of other areas cannot. */
25029 start_x = window_box_left_offset (w, area);
25030 x = start_x;
25031 if (area == TEXT_AREA)
25032 x += row->x;
25033
25034 /* Find the first glyph that must be redrawn. */
25035 while (first < end
25036 && x + first->pixel_width < r->x)
25037 {
25038 x += first->pixel_width;
25039 ++first;
25040 }
25041
25042 /* Find the last one. */
25043 last = first;
25044 first_x = x;
25045 while (last < end
25046 && x < r->x + r->width)
25047 {
25048 x += last->pixel_width;
25049 ++last;
25050 }
25051
25052 /* Repaint. */
25053 if (last > first)
25054 draw_glyphs (w, first_x - start_x, row, area,
25055 first - row->glyphs[area], last - row->glyphs[area],
25056 DRAW_NORMAL_TEXT, 0);
25057 }
25058 }
25059
25060
25061 /* Redraw the parts of the glyph row ROW on window W intersecting
25062 rectangle R. R is in window-relative coordinates. Value is
25063 non-zero if mouse-face was overwritten. */
25064
25065 static int
25066 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25067 {
25068 xassert (row->enabled_p);
25069
25070 if (row->mode_line_p || w->pseudo_window_p)
25071 draw_glyphs (w, 0, row, TEXT_AREA,
25072 0, row->used[TEXT_AREA],
25073 DRAW_NORMAL_TEXT, 0);
25074 else
25075 {
25076 if (row->used[LEFT_MARGIN_AREA])
25077 expose_area (w, row, r, LEFT_MARGIN_AREA);
25078 if (row->used[TEXT_AREA])
25079 expose_area (w, row, r, TEXT_AREA);
25080 if (row->used[RIGHT_MARGIN_AREA])
25081 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25082 draw_row_fringe_bitmaps (w, row);
25083 }
25084
25085 return row->mouse_face_p;
25086 }
25087
25088
25089 /* Redraw those parts of glyphs rows during expose event handling that
25090 overlap other rows. Redrawing of an exposed line writes over parts
25091 of lines overlapping that exposed line; this function fixes that.
25092
25093 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25094 row in W's current matrix that is exposed and overlaps other rows.
25095 LAST_OVERLAPPING_ROW is the last such row. */
25096
25097 static void
25098 expose_overlaps (struct window *w,
25099 struct glyph_row *first_overlapping_row,
25100 struct glyph_row *last_overlapping_row,
25101 XRectangle *r)
25102 {
25103 struct glyph_row *row;
25104
25105 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25106 if (row->overlapping_p)
25107 {
25108 xassert (row->enabled_p && !row->mode_line_p);
25109
25110 row->clip = r;
25111 if (row->used[LEFT_MARGIN_AREA])
25112 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
25113
25114 if (row->used[TEXT_AREA])
25115 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
25116
25117 if (row->used[RIGHT_MARGIN_AREA])
25118 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
25119 row->clip = NULL;
25120 }
25121 }
25122
25123
25124 /* Return non-zero if W's cursor intersects rectangle R. */
25125
25126 static int
25127 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
25128 {
25129 XRectangle cr, result;
25130 struct glyph *cursor_glyph;
25131 struct glyph_row *row;
25132
25133 if (w->phys_cursor.vpos >= 0
25134 && w->phys_cursor.vpos < w->current_matrix->nrows
25135 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
25136 row->enabled_p)
25137 && row->cursor_in_fringe_p)
25138 {
25139 /* Cursor is in the fringe. */
25140 cr.x = window_box_right_offset (w,
25141 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
25142 ? RIGHT_MARGIN_AREA
25143 : TEXT_AREA));
25144 cr.y = row->y;
25145 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
25146 cr.height = row->height;
25147 return x_intersect_rectangles (&cr, r, &result);
25148 }
25149
25150 cursor_glyph = get_phys_cursor_glyph (w);
25151 if (cursor_glyph)
25152 {
25153 /* r is relative to W's box, but w->phys_cursor.x is relative
25154 to left edge of W's TEXT area. Adjust it. */
25155 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
25156 cr.y = w->phys_cursor.y;
25157 cr.width = cursor_glyph->pixel_width;
25158 cr.height = w->phys_cursor_height;
25159 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25160 I assume the effect is the same -- and this is portable. */
25161 return x_intersect_rectangles (&cr, r, &result);
25162 }
25163 /* If we don't understand the format, pretend we're not in the hot-spot. */
25164 return 0;
25165 }
25166
25167
25168 /* EXPORT:
25169 Draw a vertical window border to the right of window W if W doesn't
25170 have vertical scroll bars. */
25171
25172 void
25173 x_draw_vertical_border (struct window *w)
25174 {
25175 struct frame *f = XFRAME (WINDOW_FRAME (w));
25176
25177 /* We could do better, if we knew what type of scroll-bar the adjacent
25178 windows (on either side) have... But we don't :-(
25179 However, I think this works ok. ++KFS 2003-04-25 */
25180
25181 /* Redraw borders between horizontally adjacent windows. Don't
25182 do it for frames with vertical scroll bars because either the
25183 right scroll bar of a window, or the left scroll bar of its
25184 neighbor will suffice as a border. */
25185 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
25186 return;
25187
25188 if (!WINDOW_RIGHTMOST_P (w)
25189 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
25190 {
25191 int x0, x1, y0, y1;
25192
25193 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25194 y1 -= 1;
25195
25196 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25197 x1 -= 1;
25198
25199 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
25200 }
25201 else if (!WINDOW_LEFTMOST_P (w)
25202 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
25203 {
25204 int x0, x1, y0, y1;
25205
25206 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25207 y1 -= 1;
25208
25209 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25210 x0 -= 1;
25211
25212 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
25213 }
25214 }
25215
25216
25217 /* Redraw the part of window W intersection rectangle FR. Pixel
25218 coordinates in FR are frame-relative. Call this function with
25219 input blocked. Value is non-zero if the exposure overwrites
25220 mouse-face. */
25221
25222 static int
25223 expose_window (struct window *w, XRectangle *fr)
25224 {
25225 struct frame *f = XFRAME (w->frame);
25226 XRectangle wr, r;
25227 int mouse_face_overwritten_p = 0;
25228
25229 /* If window is not yet fully initialized, do nothing. This can
25230 happen when toolkit scroll bars are used and a window is split.
25231 Reconfiguring the scroll bar will generate an expose for a newly
25232 created window. */
25233 if (w->current_matrix == NULL)
25234 return 0;
25235
25236 /* When we're currently updating the window, display and current
25237 matrix usually don't agree. Arrange for a thorough display
25238 later. */
25239 if (w == updated_window)
25240 {
25241 SET_FRAME_GARBAGED (f);
25242 return 0;
25243 }
25244
25245 /* Frame-relative pixel rectangle of W. */
25246 wr.x = WINDOW_LEFT_EDGE_X (w);
25247 wr.y = WINDOW_TOP_EDGE_Y (w);
25248 wr.width = WINDOW_TOTAL_WIDTH (w);
25249 wr.height = WINDOW_TOTAL_HEIGHT (w);
25250
25251 if (x_intersect_rectangles (fr, &wr, &r))
25252 {
25253 int yb = window_text_bottom_y (w);
25254 struct glyph_row *row;
25255 int cursor_cleared_p;
25256 struct glyph_row *first_overlapping_row, *last_overlapping_row;
25257
25258 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
25259 r.x, r.y, r.width, r.height));
25260
25261 /* Convert to window coordinates. */
25262 r.x -= WINDOW_LEFT_EDGE_X (w);
25263 r.y -= WINDOW_TOP_EDGE_Y (w);
25264
25265 /* Turn off the cursor. */
25266 if (!w->pseudo_window_p
25267 && phys_cursor_in_rect_p (w, &r))
25268 {
25269 x_clear_cursor (w);
25270 cursor_cleared_p = 1;
25271 }
25272 else
25273 cursor_cleared_p = 0;
25274
25275 /* Update lines intersecting rectangle R. */
25276 first_overlapping_row = last_overlapping_row = NULL;
25277 for (row = w->current_matrix->rows;
25278 row->enabled_p;
25279 ++row)
25280 {
25281 int y0 = row->y;
25282 int y1 = MATRIX_ROW_BOTTOM_Y (row);
25283
25284 if ((y0 >= r.y && y0 < r.y + r.height)
25285 || (y1 > r.y && y1 < r.y + r.height)
25286 || (r.y >= y0 && r.y < y1)
25287 || (r.y + r.height > y0 && r.y + r.height < y1))
25288 {
25289 /* A header line may be overlapping, but there is no need
25290 to fix overlapping areas for them. KFS 2005-02-12 */
25291 if (row->overlapping_p && !row->mode_line_p)
25292 {
25293 if (first_overlapping_row == NULL)
25294 first_overlapping_row = row;
25295 last_overlapping_row = row;
25296 }
25297
25298 row->clip = fr;
25299 if (expose_line (w, row, &r))
25300 mouse_face_overwritten_p = 1;
25301 row->clip = NULL;
25302 }
25303 else if (row->overlapping_p)
25304 {
25305 /* We must redraw a row overlapping the exposed area. */
25306 if (y0 < r.y
25307 ? y0 + row->phys_height > r.y
25308 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
25309 {
25310 if (first_overlapping_row == NULL)
25311 first_overlapping_row = row;
25312 last_overlapping_row = row;
25313 }
25314 }
25315
25316 if (y1 >= yb)
25317 break;
25318 }
25319
25320 /* Display the mode line if there is one. */
25321 if (WINDOW_WANTS_MODELINE_P (w)
25322 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
25323 row->enabled_p)
25324 && row->y < r.y + r.height)
25325 {
25326 if (expose_line (w, row, &r))
25327 mouse_face_overwritten_p = 1;
25328 }
25329
25330 if (!w->pseudo_window_p)
25331 {
25332 /* Fix the display of overlapping rows. */
25333 if (first_overlapping_row)
25334 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
25335 fr);
25336
25337 /* Draw border between windows. */
25338 x_draw_vertical_border (w);
25339
25340 /* Turn the cursor on again. */
25341 if (cursor_cleared_p)
25342 update_window_cursor (w, 1);
25343 }
25344 }
25345
25346 return mouse_face_overwritten_p;
25347 }
25348
25349
25350
25351 /* Redraw (parts) of all windows in the window tree rooted at W that
25352 intersect R. R contains frame pixel coordinates. Value is
25353 non-zero if the exposure overwrites mouse-face. */
25354
25355 static int
25356 expose_window_tree (struct window *w, XRectangle *r)
25357 {
25358 struct frame *f = XFRAME (w->frame);
25359 int mouse_face_overwritten_p = 0;
25360
25361 while (w && !FRAME_GARBAGED_P (f))
25362 {
25363 if (!NILP (w->hchild))
25364 mouse_face_overwritten_p
25365 |= expose_window_tree (XWINDOW (w->hchild), r);
25366 else if (!NILP (w->vchild))
25367 mouse_face_overwritten_p
25368 |= expose_window_tree (XWINDOW (w->vchild), r);
25369 else
25370 mouse_face_overwritten_p |= expose_window (w, r);
25371
25372 w = NILP (w->next) ? NULL : XWINDOW (w->next);
25373 }
25374
25375 return mouse_face_overwritten_p;
25376 }
25377
25378
25379 /* EXPORT:
25380 Redisplay an exposed area of frame F. X and Y are the upper-left
25381 corner of the exposed rectangle. W and H are width and height of
25382 the exposed area. All are pixel values. W or H zero means redraw
25383 the entire frame. */
25384
25385 void
25386 expose_frame (struct frame *f, int x, int y, int w, int h)
25387 {
25388 XRectangle r;
25389 int mouse_face_overwritten_p = 0;
25390
25391 TRACE ((stderr, "expose_frame "));
25392
25393 /* No need to redraw if frame will be redrawn soon. */
25394 if (FRAME_GARBAGED_P (f))
25395 {
25396 TRACE ((stderr, " garbaged\n"));
25397 return;
25398 }
25399
25400 /* If basic faces haven't been realized yet, there is no point in
25401 trying to redraw anything. This can happen when we get an expose
25402 event while Emacs is starting, e.g. by moving another window. */
25403 if (FRAME_FACE_CACHE (f) == NULL
25404 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
25405 {
25406 TRACE ((stderr, " no faces\n"));
25407 return;
25408 }
25409
25410 if (w == 0 || h == 0)
25411 {
25412 r.x = r.y = 0;
25413 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
25414 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
25415 }
25416 else
25417 {
25418 r.x = x;
25419 r.y = y;
25420 r.width = w;
25421 r.height = h;
25422 }
25423
25424 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
25425 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
25426
25427 if (WINDOWP (f->tool_bar_window))
25428 mouse_face_overwritten_p
25429 |= expose_window (XWINDOW (f->tool_bar_window), &r);
25430
25431 #ifdef HAVE_X_WINDOWS
25432 #ifndef MSDOS
25433 #ifndef USE_X_TOOLKIT
25434 if (WINDOWP (f->menu_bar_window))
25435 mouse_face_overwritten_p
25436 |= expose_window (XWINDOW (f->menu_bar_window), &r);
25437 #endif /* not USE_X_TOOLKIT */
25438 #endif
25439 #endif
25440
25441 /* Some window managers support a focus-follows-mouse style with
25442 delayed raising of frames. Imagine a partially obscured frame,
25443 and moving the mouse into partially obscured mouse-face on that
25444 frame. The visible part of the mouse-face will be highlighted,
25445 then the WM raises the obscured frame. With at least one WM, KDE
25446 2.1, Emacs is not getting any event for the raising of the frame
25447 (even tried with SubstructureRedirectMask), only Expose events.
25448 These expose events will draw text normally, i.e. not
25449 highlighted. Which means we must redo the highlight here.
25450 Subsume it under ``we love X''. --gerd 2001-08-15 */
25451 /* Included in Windows version because Windows most likely does not
25452 do the right thing if any third party tool offers
25453 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25454 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
25455 {
25456 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25457 if (f == dpyinfo->mouse_face_mouse_frame)
25458 {
25459 int x = dpyinfo->mouse_face_mouse_x;
25460 int y = dpyinfo->mouse_face_mouse_y;
25461 clear_mouse_face (dpyinfo);
25462 note_mouse_highlight (f, x, y);
25463 }
25464 }
25465 }
25466
25467
25468 /* EXPORT:
25469 Determine the intersection of two rectangles R1 and R2. Return
25470 the intersection in *RESULT. Value is non-zero if RESULT is not
25471 empty. */
25472
25473 int
25474 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
25475 {
25476 XRectangle *left, *right;
25477 XRectangle *upper, *lower;
25478 int intersection_p = 0;
25479
25480 /* Rearrange so that R1 is the left-most rectangle. */
25481 if (r1->x < r2->x)
25482 left = r1, right = r2;
25483 else
25484 left = r2, right = r1;
25485
25486 /* X0 of the intersection is right.x0, if this is inside R1,
25487 otherwise there is no intersection. */
25488 if (right->x <= left->x + left->width)
25489 {
25490 result->x = right->x;
25491
25492 /* The right end of the intersection is the minimum of the
25493 the right ends of left and right. */
25494 result->width = (min (left->x + left->width, right->x + right->width)
25495 - result->x);
25496
25497 /* Same game for Y. */
25498 if (r1->y < r2->y)
25499 upper = r1, lower = r2;
25500 else
25501 upper = r2, lower = r1;
25502
25503 /* The upper end of the intersection is lower.y0, if this is inside
25504 of upper. Otherwise, there is no intersection. */
25505 if (lower->y <= upper->y + upper->height)
25506 {
25507 result->y = lower->y;
25508
25509 /* The lower end of the intersection is the minimum of the lower
25510 ends of upper and lower. */
25511 result->height = (min (lower->y + lower->height,
25512 upper->y + upper->height)
25513 - result->y);
25514 intersection_p = 1;
25515 }
25516 }
25517
25518 return intersection_p;
25519 }
25520
25521 #endif /* HAVE_WINDOW_SYSTEM */
25522
25523 \f
25524 /***********************************************************************
25525 Initialization
25526 ***********************************************************************/
25527
25528 void
25529 syms_of_xdisp (void)
25530 {
25531 Vwith_echo_area_save_vector = Qnil;
25532 staticpro (&Vwith_echo_area_save_vector);
25533
25534 Vmessage_stack = Qnil;
25535 staticpro (&Vmessage_stack);
25536
25537 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
25538 staticpro (&Qinhibit_redisplay);
25539
25540 message_dolog_marker1 = Fmake_marker ();
25541 staticpro (&message_dolog_marker1);
25542 message_dolog_marker2 = Fmake_marker ();
25543 staticpro (&message_dolog_marker2);
25544 message_dolog_marker3 = Fmake_marker ();
25545 staticpro (&message_dolog_marker3);
25546
25547 #if GLYPH_DEBUG
25548 defsubr (&Sdump_frame_glyph_matrix);
25549 defsubr (&Sdump_glyph_matrix);
25550 defsubr (&Sdump_glyph_row);
25551 defsubr (&Sdump_tool_bar_row);
25552 defsubr (&Strace_redisplay);
25553 defsubr (&Strace_to_stderr);
25554 #endif
25555 #ifdef HAVE_WINDOW_SYSTEM
25556 defsubr (&Stool_bar_lines_needed);
25557 defsubr (&Slookup_image_map);
25558 #endif
25559 defsubr (&Sformat_mode_line);
25560 defsubr (&Sinvisible_p);
25561 defsubr (&Scurrent_bidi_paragraph_direction);
25562
25563 staticpro (&Qmenu_bar_update_hook);
25564 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
25565
25566 staticpro (&Qoverriding_terminal_local_map);
25567 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
25568
25569 staticpro (&Qoverriding_local_map);
25570 Qoverriding_local_map = intern_c_string ("overriding-local-map");
25571
25572 staticpro (&Qwindow_scroll_functions);
25573 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
25574
25575 staticpro (&Qwindow_text_change_functions);
25576 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
25577
25578 staticpro (&Qredisplay_end_trigger_functions);
25579 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
25580
25581 staticpro (&Qinhibit_point_motion_hooks);
25582 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
25583
25584 Qeval = intern_c_string ("eval");
25585 staticpro (&Qeval);
25586
25587 QCdata = intern_c_string (":data");
25588 staticpro (&QCdata);
25589 Qdisplay = intern_c_string ("display");
25590 staticpro (&Qdisplay);
25591 Qspace_width = intern_c_string ("space-width");
25592 staticpro (&Qspace_width);
25593 Qraise = intern_c_string ("raise");
25594 staticpro (&Qraise);
25595 Qslice = intern_c_string ("slice");
25596 staticpro (&Qslice);
25597 Qspace = intern_c_string ("space");
25598 staticpro (&Qspace);
25599 Qmargin = intern_c_string ("margin");
25600 staticpro (&Qmargin);
25601 Qpointer = intern_c_string ("pointer");
25602 staticpro (&Qpointer);
25603 Qleft_margin = intern_c_string ("left-margin");
25604 staticpro (&Qleft_margin);
25605 Qright_margin = intern_c_string ("right-margin");
25606 staticpro (&Qright_margin);
25607 Qcenter = intern_c_string ("center");
25608 staticpro (&Qcenter);
25609 Qline_height = intern_c_string ("line-height");
25610 staticpro (&Qline_height);
25611 QCalign_to = intern_c_string (":align-to");
25612 staticpro (&QCalign_to);
25613 QCrelative_width = intern_c_string (":relative-width");
25614 staticpro (&QCrelative_width);
25615 QCrelative_height = intern_c_string (":relative-height");
25616 staticpro (&QCrelative_height);
25617 QCeval = intern_c_string (":eval");
25618 staticpro (&QCeval);
25619 QCpropertize = intern_c_string (":propertize");
25620 staticpro (&QCpropertize);
25621 QCfile = intern_c_string (":file");
25622 staticpro (&QCfile);
25623 Qfontified = intern_c_string ("fontified");
25624 staticpro (&Qfontified);
25625 Qfontification_functions = intern_c_string ("fontification-functions");
25626 staticpro (&Qfontification_functions);
25627 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
25628 staticpro (&Qtrailing_whitespace);
25629 Qescape_glyph = intern_c_string ("escape-glyph");
25630 staticpro (&Qescape_glyph);
25631 Qnobreak_space = intern_c_string ("nobreak-space");
25632 staticpro (&Qnobreak_space);
25633 Qimage = intern_c_string ("image");
25634 staticpro (&Qimage);
25635 Qtext = intern_c_string ("text");
25636 staticpro (&Qtext);
25637 Qboth = intern_c_string ("both");
25638 staticpro (&Qboth);
25639 Qboth_horiz = intern_c_string ("both-horiz");
25640 staticpro (&Qboth_horiz);
25641 QCmap = intern_c_string (":map");
25642 staticpro (&QCmap);
25643 QCpointer = intern_c_string (":pointer");
25644 staticpro (&QCpointer);
25645 Qrect = intern_c_string ("rect");
25646 staticpro (&Qrect);
25647 Qcircle = intern_c_string ("circle");
25648 staticpro (&Qcircle);
25649 Qpoly = intern_c_string ("poly");
25650 staticpro (&Qpoly);
25651 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
25652 staticpro (&Qmessage_truncate_lines);
25653 Qgrow_only = intern_c_string ("grow-only");
25654 staticpro (&Qgrow_only);
25655 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
25656 staticpro (&Qinhibit_menubar_update);
25657 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
25658 staticpro (&Qinhibit_eval_during_redisplay);
25659 Qposition = intern_c_string ("position");
25660 staticpro (&Qposition);
25661 Qbuffer_position = intern_c_string ("buffer-position");
25662 staticpro (&Qbuffer_position);
25663 Qobject = intern_c_string ("object");
25664 staticpro (&Qobject);
25665 Qbar = intern_c_string ("bar");
25666 staticpro (&Qbar);
25667 Qhbar = intern_c_string ("hbar");
25668 staticpro (&Qhbar);
25669 Qbox = intern_c_string ("box");
25670 staticpro (&Qbox);
25671 Qhollow = intern_c_string ("hollow");
25672 staticpro (&Qhollow);
25673 Qhand = intern_c_string ("hand");
25674 staticpro (&Qhand);
25675 Qarrow = intern_c_string ("arrow");
25676 staticpro (&Qarrow);
25677 Qtext = intern_c_string ("text");
25678 staticpro (&Qtext);
25679 Qrisky_local_variable = intern_c_string ("risky-local-variable");
25680 staticpro (&Qrisky_local_variable);
25681 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
25682 staticpro (&Qinhibit_free_realized_faces);
25683
25684 list_of_error = Fcons (Fcons (intern_c_string ("error"),
25685 Fcons (intern_c_string ("void-variable"), Qnil)),
25686 Qnil);
25687 staticpro (&list_of_error);
25688
25689 Qlast_arrow_position = intern_c_string ("last-arrow-position");
25690 staticpro (&Qlast_arrow_position);
25691 Qlast_arrow_string = intern_c_string ("last-arrow-string");
25692 staticpro (&Qlast_arrow_string);
25693
25694 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
25695 staticpro (&Qoverlay_arrow_string);
25696 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
25697 staticpro (&Qoverlay_arrow_bitmap);
25698
25699 echo_buffer[0] = echo_buffer[1] = Qnil;
25700 staticpro (&echo_buffer[0]);
25701 staticpro (&echo_buffer[1]);
25702
25703 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
25704 staticpro (&echo_area_buffer[0]);
25705 staticpro (&echo_area_buffer[1]);
25706
25707 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
25708 staticpro (&Vmessages_buffer_name);
25709
25710 mode_line_proptrans_alist = Qnil;
25711 staticpro (&mode_line_proptrans_alist);
25712 mode_line_string_list = Qnil;
25713 staticpro (&mode_line_string_list);
25714 mode_line_string_face = Qnil;
25715 staticpro (&mode_line_string_face);
25716 mode_line_string_face_prop = Qnil;
25717 staticpro (&mode_line_string_face_prop);
25718 Vmode_line_unwind_vector = Qnil;
25719 staticpro (&Vmode_line_unwind_vector);
25720
25721 help_echo_string = Qnil;
25722 staticpro (&help_echo_string);
25723 help_echo_object = Qnil;
25724 staticpro (&help_echo_object);
25725 help_echo_window = Qnil;
25726 staticpro (&help_echo_window);
25727 previous_help_echo_string = Qnil;
25728 staticpro (&previous_help_echo_string);
25729 help_echo_pos = -1;
25730
25731 Qright_to_left = intern_c_string ("right-to-left");
25732 staticpro (&Qright_to_left);
25733 Qleft_to_right = intern_c_string ("left-to-right");
25734 staticpro (&Qleft_to_right);
25735
25736 #ifdef HAVE_WINDOW_SYSTEM
25737 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
25738 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
25739 For example, if a block cursor is over a tab, it will be drawn as
25740 wide as that tab on the display. */);
25741 x_stretch_cursor_p = 0;
25742 #endif
25743
25744 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
25745 doc: /* *Non-nil means highlight trailing whitespace.
25746 The face used for trailing whitespace is `trailing-whitespace'. */);
25747 Vshow_trailing_whitespace = Qnil;
25748
25749 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
25750 doc: /* *Control highlighting of nobreak space and soft hyphen.
25751 A value of t means highlight the character itself (for nobreak space,
25752 use face `nobreak-space').
25753 A value of nil means no highlighting.
25754 Other values mean display the escape glyph followed by an ordinary
25755 space or ordinary hyphen. */);
25756 Vnobreak_char_display = Qt;
25757
25758 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
25759 doc: /* *The pointer shape to show in void text areas.
25760 A value of nil means to show the text pointer. Other options are `arrow',
25761 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25762 Vvoid_text_area_pointer = Qarrow;
25763
25764 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
25765 doc: /* Non-nil means don't actually do any redisplay.
25766 This is used for internal purposes. */);
25767 Vinhibit_redisplay = Qnil;
25768
25769 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
25770 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
25771 Vglobal_mode_string = Qnil;
25772
25773 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
25774 doc: /* Marker for where to display an arrow on top of the buffer text.
25775 This must be the beginning of a line in order to work.
25776 See also `overlay-arrow-string'. */);
25777 Voverlay_arrow_position = Qnil;
25778
25779 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
25780 doc: /* String to display as an arrow in non-window frames.
25781 See also `overlay-arrow-position'. */);
25782 Voverlay_arrow_string = make_pure_c_string ("=>");
25783
25784 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
25785 doc: /* List of variables (symbols) which hold markers for overlay arrows.
25786 The symbols on this list are examined during redisplay to determine
25787 where to display overlay arrows. */);
25788 Voverlay_arrow_variable_list
25789 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
25790
25791 DEFVAR_INT ("scroll-step", &scroll_step,
25792 doc: /* *The number of lines to try scrolling a window by when point moves out.
25793 If that fails to bring point back on frame, point is centered instead.
25794 If this is zero, point is always centered after it moves off frame.
25795 If you want scrolling to always be a line at a time, you should set
25796 `scroll-conservatively' to a large value rather than set this to 1. */);
25797
25798 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
25799 doc: /* *Scroll up to this many lines, to bring point back on screen.
25800 If point moves off-screen, redisplay will scroll by up to
25801 `scroll-conservatively' lines in order to bring point just barely
25802 onto the screen again. If that cannot be done, then redisplay
25803 recenters point as usual.
25804
25805 A value of zero means always recenter point if it moves off screen. */);
25806 scroll_conservatively = 0;
25807
25808 DEFVAR_INT ("scroll-margin", &scroll_margin,
25809 doc: /* *Number of lines of margin at the top and bottom of a window.
25810 Recenter the window whenever point gets within this many lines
25811 of the top or bottom of the window. */);
25812 scroll_margin = 0;
25813
25814 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
25815 doc: /* Pixels per inch value for non-window system displays.
25816 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
25817 Vdisplay_pixels_per_inch = make_float (72.0);
25818
25819 #if GLYPH_DEBUG
25820 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
25821 #endif
25822
25823 DEFVAR_LISP ("truncate-partial-width-windows",
25824 &Vtruncate_partial_width_windows,
25825 doc: /* Non-nil means truncate lines in windows narrower than the frame.
25826 For an integer value, truncate lines in each window narrower than the
25827 full frame width, provided the window width is less than that integer;
25828 otherwise, respect the value of `truncate-lines'.
25829
25830 For any other non-nil value, truncate lines in all windows that do
25831 not span the full frame width.
25832
25833 A value of nil means to respect the value of `truncate-lines'.
25834
25835 If `word-wrap' is enabled, you might want to reduce this. */);
25836 Vtruncate_partial_width_windows = make_number (50);
25837
25838 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
25839 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
25840 Any other value means to use the appropriate face, `mode-line',
25841 `header-line', or `menu' respectively. */);
25842 mode_line_inverse_video = 1;
25843
25844 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
25845 doc: /* *Maximum buffer size for which line number should be displayed.
25846 If the buffer is bigger than this, the line number does not appear
25847 in the mode line. A value of nil means no limit. */);
25848 Vline_number_display_limit = Qnil;
25849
25850 DEFVAR_INT ("line-number-display-limit-width",
25851 &line_number_display_limit_width,
25852 doc: /* *Maximum line width (in characters) for line number display.
25853 If the average length of the lines near point is bigger than this, then the
25854 line number may be omitted from the mode line. */);
25855 line_number_display_limit_width = 200;
25856
25857 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
25858 doc: /* *Non-nil means highlight region even in nonselected windows. */);
25859 highlight_nonselected_windows = 0;
25860
25861 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
25862 doc: /* Non-nil if more than one frame is visible on this display.
25863 Minibuffer-only frames don't count, but iconified frames do.
25864 This variable is not guaranteed to be accurate except while processing
25865 `frame-title-format' and `icon-title-format'. */);
25866
25867 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
25868 doc: /* Template for displaying the title bar of visible frames.
25869 \(Assuming the window manager supports this feature.)
25870
25871 This variable has the same structure as `mode-line-format', except that
25872 the %c and %l constructs are ignored. It is used only on frames for
25873 which no explicit name has been set \(see `modify-frame-parameters'). */);
25874
25875 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
25876 doc: /* Template for displaying the title bar of an iconified frame.
25877 \(Assuming the window manager supports this feature.)
25878 This variable has the same structure as `mode-line-format' (which see),
25879 and is used only on frames for which no explicit name has been set
25880 \(see `modify-frame-parameters'). */);
25881 Vicon_title_format
25882 = Vframe_title_format
25883 = pure_cons (intern_c_string ("multiple-frames"),
25884 pure_cons (make_pure_c_string ("%b"),
25885 pure_cons (pure_cons (empty_unibyte_string,
25886 pure_cons (intern_c_string ("invocation-name"),
25887 pure_cons (make_pure_c_string ("@"),
25888 pure_cons (intern_c_string ("system-name"),
25889 Qnil)))),
25890 Qnil)));
25891
25892 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
25893 doc: /* Maximum number of lines to keep in the message log buffer.
25894 If nil, disable message logging. If t, log messages but don't truncate
25895 the buffer when it becomes large. */);
25896 Vmessage_log_max = make_number (100);
25897
25898 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
25899 doc: /* Functions called before redisplay, if window sizes have changed.
25900 The value should be a list of functions that take one argument.
25901 Just before redisplay, for each frame, if any of its windows have changed
25902 size since the last redisplay, or have been split or deleted,
25903 all the functions in the list are called, with the frame as argument. */);
25904 Vwindow_size_change_functions = Qnil;
25905
25906 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
25907 doc: /* List of functions to call before redisplaying a window with scrolling.
25908 Each function is called with two arguments, the window and its new
25909 display-start position. Note that these functions are also called by
25910 `set-window-buffer'. Also note that the value of `window-end' is not
25911 valid when these functions are called. */);
25912 Vwindow_scroll_functions = Qnil;
25913
25914 DEFVAR_LISP ("window-text-change-functions",
25915 &Vwindow_text_change_functions,
25916 doc: /* Functions to call in redisplay when text in the window might change. */);
25917 Vwindow_text_change_functions = Qnil;
25918
25919 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
25920 doc: /* Functions called when redisplay of a window reaches the end trigger.
25921 Each function is called with two arguments, the window and the end trigger value.
25922 See `set-window-redisplay-end-trigger'. */);
25923 Vredisplay_end_trigger_functions = Qnil;
25924
25925 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
25926 doc: /* *Non-nil means autoselect window with mouse pointer.
25927 If nil, do not autoselect windows.
25928 A positive number means delay autoselection by that many seconds: a
25929 window is autoselected only after the mouse has remained in that
25930 window for the duration of the delay.
25931 A negative number has a similar effect, but causes windows to be
25932 autoselected only after the mouse has stopped moving. \(Because of
25933 the way Emacs compares mouse events, you will occasionally wait twice
25934 that time before the window gets selected.\)
25935 Any other value means to autoselect window instantaneously when the
25936 mouse pointer enters it.
25937
25938 Autoselection selects the minibuffer only if it is active, and never
25939 unselects the minibuffer if it is active.
25940
25941 When customizing this variable make sure that the actual value of
25942 `focus-follows-mouse' matches the behavior of your window manager. */);
25943 Vmouse_autoselect_window = Qnil;
25944
25945 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
25946 doc: /* *Non-nil means automatically resize tool-bars.
25947 This dynamically changes the tool-bar's height to the minimum height
25948 that is needed to make all tool-bar items visible.
25949 If value is `grow-only', the tool-bar's height is only increased
25950 automatically; to decrease the tool-bar height, use \\[recenter]. */);
25951 Vauto_resize_tool_bars = Qt;
25952
25953 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
25954 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
25955 auto_raise_tool_bar_buttons_p = 1;
25956
25957 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
25958 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
25959 make_cursor_line_fully_visible_p = 1;
25960
25961 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
25962 doc: /* *Border below tool-bar in pixels.
25963 If an integer, use it as the height of the border.
25964 If it is one of `internal-border-width' or `border-width', use the
25965 value of the corresponding frame parameter.
25966 Otherwise, no border is added below the tool-bar. */);
25967 Vtool_bar_border = Qinternal_border_width;
25968
25969 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
25970 doc: /* *Margin around tool-bar buttons in pixels.
25971 If an integer, use that for both horizontal and vertical margins.
25972 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
25973 HORZ specifying the horizontal margin, and VERT specifying the
25974 vertical margin. */);
25975 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
25976
25977 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
25978 doc: /* *Relief thickness of tool-bar buttons. */);
25979 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
25980
25981 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
25982 doc: /* *Tool bar style to use.
25983 It can be one of
25984 image - show images only
25985 text - show text only
25986 both - show both, text under image
25987 both-horiz - show text to the right of the image
25988 any other - use system default or image if no system default. */);
25989 Vtool_bar_style = Qnil;
25990
25991 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
25992 doc: /* *Maximum number of characters a label can have to be shown.
25993 The tool bar style must also show labels for this to have any effect, see
25994 `tool-bar-style'. */);
25995 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
25996
25997 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
25998 doc: /* List of functions to call to fontify regions of text.
25999 Each function is called with one argument POS. Functions must
26000 fontify a region starting at POS in the current buffer, and give
26001 fontified regions the property `fontified'. */);
26002 Vfontification_functions = Qnil;
26003 Fmake_variable_buffer_local (Qfontification_functions);
26004
26005 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26006 &unibyte_display_via_language_environment,
26007 doc: /* *Non-nil means display unibyte text according to language environment.
26008 Specifically, this means that raw bytes in the range 160-255 decimal
26009 are displayed by converting them to the equivalent multibyte characters
26010 according to the current language environment. As a result, they are
26011 displayed according to the current fontset.
26012
26013 Note that this variable affects only how these bytes are displayed,
26014 but does not change the fact they are interpreted as raw bytes. */);
26015 unibyte_display_via_language_environment = 0;
26016
26017 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
26018 doc: /* *Maximum height for resizing mini-windows.
26019 If a float, it specifies a fraction of the mini-window frame's height.
26020 If an integer, it specifies a number of lines. */);
26021 Vmax_mini_window_height = make_float (0.25);
26022
26023 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
26024 doc: /* *How to resize mini-windows.
26025 A value of nil means don't automatically resize mini-windows.
26026 A value of t means resize them to fit the text displayed in them.
26027 A value of `grow-only', the default, means let mini-windows grow
26028 only, until their display becomes empty, at which point the windows
26029 go back to their normal size. */);
26030 Vresize_mini_windows = Qgrow_only;
26031
26032 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
26033 doc: /* Alist specifying how to blink the cursor off.
26034 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26035 `cursor-type' frame-parameter or variable equals ON-STATE,
26036 comparing using `equal', Emacs uses OFF-STATE to specify
26037 how to blink it off. ON-STATE and OFF-STATE are values for
26038 the `cursor-type' frame parameter.
26039
26040 If a frame's ON-STATE has no entry in this list,
26041 the frame's other specifications determine how to blink the cursor off. */);
26042 Vblink_cursor_alist = Qnil;
26043
26044 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
26045 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
26046 automatic_hscrolling_p = 1;
26047 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26048 staticpro (&Qauto_hscroll_mode);
26049
26050 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
26051 doc: /* *How many columns away from the window edge point is allowed to get
26052 before automatic hscrolling will horizontally scroll the window. */);
26053 hscroll_margin = 5;
26054
26055 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
26056 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26057 When point is less than `hscroll-margin' columns from the window
26058 edge, automatic hscrolling will scroll the window by the amount of columns
26059 determined by this variable. If its value is a positive integer, scroll that
26060 many columns. If it's a positive floating-point number, it specifies the
26061 fraction of the window's width to scroll. If it's nil or zero, point will be
26062 centered horizontally after the scroll. Any other value, including negative
26063 numbers, are treated as if the value were zero.
26064
26065 Automatic hscrolling always moves point outside the scroll margin, so if
26066 point was more than scroll step columns inside the margin, the window will
26067 scroll more than the value given by the scroll step.
26068
26069 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26070 and `scroll-right' overrides this variable's effect. */);
26071 Vhscroll_step = make_number (0);
26072
26073 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
26074 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26075 Bind this around calls to `message' to let it take effect. */);
26076 message_truncate_lines = 0;
26077
26078 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
26079 doc: /* Normal hook run to update the menu bar definitions.
26080 Redisplay runs this hook before it redisplays the menu bar.
26081 This is used to update submenus such as Buffers,
26082 whose contents depend on various data. */);
26083 Vmenu_bar_update_hook = Qnil;
26084
26085 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
26086 doc: /* Frame for which we are updating a menu.
26087 The enable predicate for a menu binding should check this variable. */);
26088 Vmenu_updating_frame = Qnil;
26089
26090 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
26091 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26092 inhibit_menubar_update = 0;
26093
26094 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
26095 doc: /* Prefix prepended to all continuation lines at display time.
26096 The value may be a string, an image, or a stretch-glyph; it is
26097 interpreted in the same way as the value of a `display' text property.
26098
26099 This variable is overridden by any `wrap-prefix' text or overlay
26100 property.
26101
26102 To add a prefix to non-continuation lines, use `line-prefix'. */);
26103 Vwrap_prefix = Qnil;
26104 staticpro (&Qwrap_prefix);
26105 Qwrap_prefix = intern_c_string ("wrap-prefix");
26106 Fmake_variable_buffer_local (Qwrap_prefix);
26107
26108 DEFVAR_LISP ("line-prefix", &Vline_prefix,
26109 doc: /* Prefix prepended to all non-continuation lines at display time.
26110 The value may be a string, an image, or a stretch-glyph; it is
26111 interpreted in the same way as the value of a `display' text property.
26112
26113 This variable is overridden by any `line-prefix' text or overlay
26114 property.
26115
26116 To add a prefix to continuation lines, use `wrap-prefix'. */);
26117 Vline_prefix = Qnil;
26118 staticpro (&Qline_prefix);
26119 Qline_prefix = intern_c_string ("line-prefix");
26120 Fmake_variable_buffer_local (Qline_prefix);
26121
26122 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
26123 doc: /* Non-nil means don't eval Lisp during redisplay. */);
26124 inhibit_eval_during_redisplay = 0;
26125
26126 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
26127 doc: /* Non-nil means don't free realized faces. Internal use only. */);
26128 inhibit_free_realized_faces = 0;
26129
26130 #if GLYPH_DEBUG
26131 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
26132 doc: /* Inhibit try_window_id display optimization. */);
26133 inhibit_try_window_id = 0;
26134
26135 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
26136 doc: /* Inhibit try_window_reusing display optimization. */);
26137 inhibit_try_window_reusing = 0;
26138
26139 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
26140 doc: /* Inhibit try_cursor_movement display optimization. */);
26141 inhibit_try_cursor_movement = 0;
26142 #endif /* GLYPH_DEBUG */
26143
26144 DEFVAR_INT ("overline-margin", &overline_margin,
26145 doc: /* *Space between overline and text, in pixels.
26146 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26147 margin to the caracter height. */);
26148 overline_margin = 2;
26149
26150 DEFVAR_INT ("underline-minimum-offset",
26151 &underline_minimum_offset,
26152 doc: /* Minimum distance between baseline and underline.
26153 This can improve legibility of underlined text at small font sizes,
26154 particularly when using variable `x-use-underline-position-properties'
26155 with fonts that specify an UNDERLINE_POSITION relatively close to the
26156 baseline. The default value is 1. */);
26157 underline_minimum_offset = 1;
26158
26159 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
26160 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26161 display_hourglass_p = 1;
26162
26163 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
26164 doc: /* *Seconds to wait before displaying an hourglass pointer.
26165 Value must be an integer or float. */);
26166 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26167
26168 hourglass_atimer = NULL;
26169 hourglass_shown_p = 0;
26170 }
26171
26172
26173 /* Initialize this module when Emacs starts. */
26174
26175 void
26176 init_xdisp (void)
26177 {
26178 Lisp_Object root_window;
26179 struct window *mini_w;
26180
26181 current_header_line_height = current_mode_line_height = -1;
26182
26183 CHARPOS (this_line_start_pos) = 0;
26184
26185 mini_w = XWINDOW (minibuf_window);
26186 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
26187
26188 if (!noninteractive)
26189 {
26190 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
26191 int i;
26192
26193 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
26194 set_window_height (root_window,
26195 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
26196 0);
26197 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
26198 set_window_height (minibuf_window, 1, 0);
26199
26200 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
26201 mini_w->total_cols = make_number (FRAME_COLS (f));
26202
26203 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
26204 scratch_glyph_row.glyphs[TEXT_AREA + 1]
26205 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
26206
26207 /* The default ellipsis glyphs `...'. */
26208 for (i = 0; i < 3; ++i)
26209 default_invis_vector[i] = make_number ('.');
26210 }
26211
26212 {
26213 /* Allocate the buffer for frame titles.
26214 Also used for `format-mode-line'. */
26215 int size = 100;
26216 mode_line_noprop_buf = (char *) xmalloc (size);
26217 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
26218 mode_line_noprop_ptr = mode_line_noprop_buf;
26219 mode_line_target = MODE_LINE_DISPLAY;
26220 }
26221
26222 help_echo_showing_p = 0;
26223 }
26224
26225 /* Since w32 does not support atimers, it defines its own implementation of
26226 the following three functions in w32fns.c. */
26227 #ifndef WINDOWSNT
26228
26229 /* Platform-independent portion of hourglass implementation. */
26230
26231 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26232 int
26233 hourglass_started (void)
26234 {
26235 return hourglass_shown_p || hourglass_atimer != NULL;
26236 }
26237
26238 /* Cancel a currently active hourglass timer, and start a new one. */
26239 void
26240 start_hourglass (void)
26241 {
26242 #if defined (HAVE_WINDOW_SYSTEM)
26243 EMACS_TIME delay;
26244 int secs, usecs = 0;
26245
26246 cancel_hourglass ();
26247
26248 if (INTEGERP (Vhourglass_delay)
26249 && XINT (Vhourglass_delay) > 0)
26250 secs = XFASTINT (Vhourglass_delay);
26251 else if (FLOATP (Vhourglass_delay)
26252 && XFLOAT_DATA (Vhourglass_delay) > 0)
26253 {
26254 Lisp_Object tem;
26255 tem = Ftruncate (Vhourglass_delay, Qnil);
26256 secs = XFASTINT (tem);
26257 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
26258 }
26259 else
26260 secs = DEFAULT_HOURGLASS_DELAY;
26261
26262 EMACS_SET_SECS_USECS (delay, secs, usecs);
26263 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
26264 show_hourglass, NULL);
26265 #endif
26266 }
26267
26268
26269 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26270 shown. */
26271 void
26272 cancel_hourglass (void)
26273 {
26274 #if defined (HAVE_WINDOW_SYSTEM)
26275 if (hourglass_atimer)
26276 {
26277 cancel_atimer (hourglass_atimer);
26278 hourglass_atimer = NULL;
26279 }
26280
26281 if (hourglass_shown_p)
26282 hide_hourglass ();
26283 #endif
26284 }
26285 #endif /* ! WINDOWSNT */
26286
26287 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26288 (do not change this comment) */