* alloc.c: Do not define struct catchtag.
[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 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code. (Or,
35 let's say almost---see the description of direct update
36 operations, below.)
37
38 The following diagram shows how redisplay code is invoked. As you
39 can see, Lisp calls redisplay and vice versa. Under window systems
40 like X, some portions of the redisplay code are also called
41 asynchronously during mouse movement or expose events. It is very
42 important that these code parts do NOT use the C library (malloc,
43 free) because many C libraries under Unix are not reentrant. They
44 may also NOT call functions of the Lisp interpreter which could
45 change the interpreter's state. If you don't follow these rules,
46 you will encounter bugs which are very hard to explain.
47
48 (Direct functions, see below)
49 direct_output_for_insert,
50 direct_forward_char (dispnew.c)
51 +---------------------------------+
52 | |
53 | V
54 +--------------+ redisplay +----------------+
55 | Lisp machine |---------------->| Redisplay code |<--+
56 +--------------+ (xdisp.c) +----------------+ |
57 ^ | |
58 +----------------------------------+ |
59 Don't use this path when called |
60 asynchronously! |
61 |
62 expose_window (asynchronous) |
63 |
64 X expose events -----+
65
66 What does redisplay do? Obviously, it has to figure out somehow what
67 has been changed since the last time the display has been updated,
68 and to make these changes visible. Preferably it would do that in
69 a moderately intelligent way, i.e. fast.
70
71 Changes in buffer text can be deduced from window and buffer
72 structures, and from some global variables like `beg_unchanged' and
73 `end_unchanged'. The contents of the display are additionally
74 recorded in a `glyph matrix', a two-dimensional matrix of glyph
75 structures. Each row in such a matrix corresponds to a line on the
76 display, and each glyph in a row corresponds to a column displaying
77 a character, an image, or what else. This matrix is called the
78 `current glyph matrix' or `current matrix' in redisplay
79 terminology.
80
81 For buffer parts that have been changed since the last update, a
82 second glyph matrix is constructed, the so called `desired glyph
83 matrix' or short `desired matrix'. Current and desired matrix are
84 then compared to find a cheap way to update the display, e.g. by
85 reusing part of the display by scrolling lines.
86
87
88 Direct operations.
89
90 You will find a lot of redisplay optimizations when you start
91 looking at the innards of redisplay. The overall goal of all these
92 optimizations is to make redisplay fast because it is done
93 frequently.
94
95 Two optimizations are not found in xdisp.c. These are the direct
96 operations mentioned above. As the name suggests they follow a
97 different principle than the rest of redisplay. Instead of
98 building a desired matrix and then comparing it with the current
99 display, they perform their actions directly on the display and on
100 the current matrix.
101
102 One direct operation updates the display after one character has
103 been entered. The other one moves the cursor by one position
104 forward or backward. You find these functions under the names
105 `direct_output_for_insert' and `direct_output_forward_char' in
106 dispnew.c.
107
108
109 Desired matrices.
110
111 Desired matrices are always built per Emacs window. The function
112 `display_line' is the central function to look at if you are
113 interested. It constructs one row in a desired matrix given an
114 iterator structure containing both a buffer position and a
115 description of the environment in which the text is to be
116 displayed. But this is too early, read on.
117
118 Characters and pixmaps displayed for a range of buffer text depend
119 on various settings of buffers and windows, on overlays and text
120 properties, on display tables, on selective display. The good news
121 is that all this hairy stuff is hidden behind a small set of
122 interface functions taking an iterator structure (struct it)
123 argument.
124
125 Iteration over things to be displayed is then simple. It is
126 started by initializing an iterator with a call to init_iterator.
127 Calls to get_next_display_element fill the iterator structure with
128 relevant information about the next thing to display. Calls to
129 set_iterator_to_next move the iterator to the next thing.
130
131 Besides this, an iterator also contains information about the
132 display environment in which glyphs for display elements are to be
133 produced. It has fields for the width and height of the display,
134 the information whether long lines are truncated or continued, a
135 current X and Y position, and lots of other stuff you can better
136 see in dispextern.h.
137
138 Glyphs in a desired matrix are normally constructed in a loop
139 calling get_next_display_element and then produce_glyphs. The call
140 to produce_glyphs will fill the iterator structure with pixel
141 information about the element being displayed and at the same time
142 produce glyphs for it. If the display element fits on the line
143 being displayed, set_iterator_to_next is called next, otherwise the
144 glyphs produced are discarded.
145
146
147 Frame matrices.
148
149 That just couldn't be all, could it? What about terminal types not
150 supporting operations on sub-windows of the screen? To update the
151 display on such a terminal, window-based glyph matrices are not
152 well suited. To be able to reuse part of the display (scrolling
153 lines up and down), we must instead have a view of the whole
154 screen. This is what `frame matrices' are for. They are a trick.
155
156 Frames on terminals like above have a glyph pool. Windows on such
157 a frame sub-allocate their glyph memory from their frame's glyph
158 pool. The frame itself is given its own glyph matrices. By
159 coincidence---or maybe something else---rows in window glyph
160 matrices are slices of corresponding rows in frame matrices. Thus
161 writing to window matrices implicitly updates a frame matrix which
162 provides us with the view of the whole screen that we originally
163 wanted to have without having to move many bytes around. To be
164 honest, there is a little bit more done, but not much more. If you
165 plan to extend that code, take a look at dispnew.c. The function
166 build_frame_matrix is a good starting point. */
167
168 #include <config.h>
169 #include <stdio.h>
170 #include <limits.h>
171 #include <setjmp.h>
172
173 #include "lisp.h"
174 #include "keyboard.h"
175 #include "frame.h"
176 #include "window.h"
177 #include "termchar.h"
178 #include "dispextern.h"
179 #include "buffer.h"
180 #include "character.h"
181 #include "charset.h"
182 #include "indent.h"
183 #include "commands.h"
184 #include "keymap.h"
185 #include "macros.h"
186 #include "disptab.h"
187 #include "termhooks.h"
188 #include "intervals.h"
189 #include "coding.h"
190 #include "process.h"
191 #include "region-cache.h"
192 #include "font.h"
193 #include "fontset.h"
194 #include "blockinput.h"
195
196 #ifdef HAVE_X_WINDOWS
197 #include "xterm.h"
198 #endif
199 #ifdef WINDOWSNT
200 #include "w32term.h"
201 #endif
202 #ifdef HAVE_NS
203 #include "nsterm.h"
204 #endif
205 #ifdef USE_GTK
206 #include "gtkutil.h"
207 #endif
208
209 #include "font.h"
210
211 #ifndef FRAME_X_OUTPUT
212 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
213 #endif
214
215 #define INFINITY 10000000
216
217 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
218 || defined(HAVE_NS) || defined (USE_GTK)
219 extern void set_frame_menubar P_ ((struct frame *f, int, int));
220 extern int pending_menu_activation;
221 #endif
222
223 extern int interrupt_input;
224 extern int command_loop_level;
225
226 extern Lisp_Object do_mouse_tracking;
227
228 extern int minibuffer_auto_raise;
229 extern Lisp_Object Vminibuffer_list;
230
231 extern Lisp_Object Qface;
232 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
233
234 extern Lisp_Object Voverriding_local_map;
235 extern Lisp_Object Voverriding_local_map_menu_flag;
236 extern Lisp_Object Qmenu_item;
237 extern Lisp_Object Qwhen;
238 extern Lisp_Object Qhelp_echo;
239 extern Lisp_Object Qbefore_string, Qafter_string;
240
241 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
242 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
243 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
244 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
245 Lisp_Object Qinhibit_point_motion_hooks;
246 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
247 Lisp_Object Qfontified;
248 Lisp_Object Qgrow_only;
249 Lisp_Object Qinhibit_eval_during_redisplay;
250 Lisp_Object Qbuffer_position, Qposition, Qobject;
251
252 /* Cursor shapes */
253 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
254
255 /* Pointer shapes */
256 Lisp_Object Qarrow, Qhand, Qtext;
257
258 Lisp_Object Qrisky_local_variable;
259
260 /* Holds the list (error). */
261 Lisp_Object list_of_error;
262
263 /* Functions called to fontify regions of text. */
264
265 Lisp_Object Vfontification_functions;
266 Lisp_Object Qfontification_functions;
267
268 /* Non-nil means automatically select any window when the mouse
269 cursor moves into it. */
270 Lisp_Object Vmouse_autoselect_window;
271
272 Lisp_Object Vwrap_prefix, Qwrap_prefix;
273 Lisp_Object Vline_prefix, Qline_prefix;
274
275 /* Non-zero means draw tool bar buttons raised when the mouse moves
276 over them. */
277
278 int auto_raise_tool_bar_buttons_p;
279
280 /* Non-zero means to reposition window if cursor line is only partially visible. */
281
282 int make_cursor_line_fully_visible_p;
283
284 /* Margin below tool bar in pixels. 0 or nil means no margin.
285 If value is `internal-border-width' or `border-width',
286 the corresponding frame parameter is used. */
287
288 Lisp_Object Vtool_bar_border;
289
290 /* Margin around tool bar buttons in pixels. */
291
292 Lisp_Object Vtool_bar_button_margin;
293
294 /* Thickness of shadow to draw around tool bar buttons. */
295
296 EMACS_INT tool_bar_button_relief;
297
298 /* Non-nil means automatically resize tool-bars so that all tool-bar
299 items are visible, and no blank lines remain.
300
301 If value is `grow-only', only make tool-bar bigger. */
302
303 Lisp_Object Vauto_resize_tool_bars;
304
305 /* Non-zero means draw block and hollow cursor as wide as the glyph
306 under it. For example, if a block cursor is over a tab, it will be
307 drawn as wide as that tab on the display. */
308
309 int x_stretch_cursor_p;
310
311 /* Non-nil means don't actually do any redisplay. */
312
313 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
314
315 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
316
317 int inhibit_eval_during_redisplay;
318
319 /* Names of text properties relevant for redisplay. */
320
321 Lisp_Object Qdisplay;
322 extern Lisp_Object Qface, Qinvisible, Qwidth;
323
324 /* Symbols used in text property values. */
325
326 Lisp_Object Vdisplay_pixels_per_inch;
327 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
328 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
329 Lisp_Object Qslice;
330 Lisp_Object Qcenter;
331 Lisp_Object Qmargin, Qpointer;
332 Lisp_Object Qline_height;
333 extern Lisp_Object Qheight;
334 extern Lisp_Object QCwidth, QCheight, QCascent;
335 extern Lisp_Object Qscroll_bar;
336 extern Lisp_Object Qcursor;
337
338 /* Non-nil means highlight trailing whitespace. */
339
340 Lisp_Object Vshow_trailing_whitespace;
341
342 /* Non-nil means escape non-break space and hyphens. */
343
344 Lisp_Object Vnobreak_char_display;
345
346 #ifdef HAVE_WINDOW_SYSTEM
347 extern Lisp_Object Voverflow_newline_into_fringe;
348
349 /* Test if overflow newline into fringe. Called with iterator IT
350 at or past right window margin, and with IT->current_x set. */
351
352 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
353 (!NILP (Voverflow_newline_into_fringe) \
354 && FRAME_WINDOW_P (it->f) \
355 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
356 && it->current_x == it->last_visible_x \
357 && it->line_wrap != WORD_WRAP)
358
359 #else /* !HAVE_WINDOW_SYSTEM */
360 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
361 #endif /* HAVE_WINDOW_SYSTEM */
362
363 /* Test if the display element loaded in IT is a space or tab
364 character. This is used to determine word wrapping. */
365
366 #define IT_DISPLAYING_WHITESPACE(it) \
367 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
368
369 /* Non-nil means show the text cursor in void text areas
370 i.e. in blank areas after eol and eob. This used to be
371 the default in 21.3. */
372
373 Lisp_Object Vvoid_text_area_pointer;
374
375 /* Name of the face used to highlight trailing whitespace. */
376
377 Lisp_Object Qtrailing_whitespace;
378
379 /* Name and number of the face used to highlight escape glyphs. */
380
381 Lisp_Object Qescape_glyph;
382
383 /* Name and number of the face used to highlight non-breaking spaces. */
384
385 Lisp_Object Qnobreak_space;
386
387 /* The symbol `image' which is the car of the lists used to represent
388 images in Lisp. */
389
390 Lisp_Object Qimage;
391
392 /* The image map types. */
393 Lisp_Object QCmap, QCpointer;
394 Lisp_Object Qrect, Qcircle, Qpoly;
395
396 /* Non-zero means print newline to stdout before next mini-buffer
397 message. */
398
399 int noninteractive_need_newline;
400
401 /* Non-zero means print newline to message log before next message. */
402
403 static int message_log_need_newline;
404
405 /* Three markers that message_dolog uses.
406 It could allocate them itself, but that causes trouble
407 in handling memory-full errors. */
408 static Lisp_Object message_dolog_marker1;
409 static Lisp_Object message_dolog_marker2;
410 static Lisp_Object message_dolog_marker3;
411 \f
412 /* The buffer position of the first character appearing entirely or
413 partially on the line of the selected window which contains the
414 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
415 redisplay optimization in redisplay_internal. */
416
417 static struct text_pos this_line_start_pos;
418
419 /* Number of characters past the end of the line above, including the
420 terminating newline. */
421
422 static struct text_pos this_line_end_pos;
423
424 /* The vertical positions and the height of this line. */
425
426 static int this_line_vpos;
427 static int this_line_y;
428 static int this_line_pixel_height;
429
430 /* X position at which this display line starts. Usually zero;
431 negative if first character is partially visible. */
432
433 static int this_line_start_x;
434
435 /* Buffer that this_line_.* variables are referring to. */
436
437 static struct buffer *this_line_buffer;
438
439 /* Nonzero means truncate lines in all windows less wide than the
440 frame. */
441
442 Lisp_Object Vtruncate_partial_width_windows;
443
444 /* A flag to control how to display unibyte 8-bit character. */
445
446 int unibyte_display_via_language_environment;
447
448 /* Nonzero means we have more than one non-mini-buffer-only frame.
449 Not guaranteed to be accurate except while parsing
450 frame-title-format. */
451
452 int multiple_frames;
453
454 Lisp_Object Vglobal_mode_string;
455
456
457 /* List of variables (symbols) which hold markers for overlay arrows.
458 The symbols on this list are examined during redisplay to determine
459 where to display overlay arrows. */
460
461 Lisp_Object Voverlay_arrow_variable_list;
462
463 /* Marker for where to display an arrow on top of the buffer text. */
464
465 Lisp_Object Voverlay_arrow_position;
466
467 /* String to display for the arrow. Only used on terminal frames. */
468
469 Lisp_Object Voverlay_arrow_string;
470
471 /* Values of those variables at last redisplay are stored as
472 properties on `overlay-arrow-position' symbol. However, if
473 Voverlay_arrow_position is a marker, last-arrow-position is its
474 numerical position. */
475
476 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
477
478 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
479 properties on a symbol in overlay-arrow-variable-list. */
480
481 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
482
483 /* Like mode-line-format, but for the title bar on a visible frame. */
484
485 Lisp_Object Vframe_title_format;
486
487 /* Like mode-line-format, but for the title bar on an iconified frame. */
488
489 Lisp_Object Vicon_title_format;
490
491 /* List of functions to call when a window's size changes. These
492 functions get one arg, a frame on which one or more windows' sizes
493 have changed. */
494
495 static Lisp_Object Vwindow_size_change_functions;
496
497 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
498
499 /* Nonzero if an overlay arrow has been displayed in this window. */
500
501 static int overlay_arrow_seen;
502
503 /* Nonzero means highlight the region even in nonselected windows. */
504
505 int highlight_nonselected_windows;
506
507 /* If cursor motion alone moves point off frame, try scrolling this
508 many lines up or down if that will bring it back. */
509
510 static EMACS_INT scroll_step;
511
512 /* Nonzero means scroll just far enough to bring point back on the
513 screen, when appropriate. */
514
515 static EMACS_INT scroll_conservatively;
516
517 /* Recenter the window whenever point gets within this many lines of
518 the top or bottom of the window. This value is translated into a
519 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
520 that there is really a fixed pixel height scroll margin. */
521
522 EMACS_INT scroll_margin;
523
524 /* Number of windows showing the buffer of the selected window (or
525 another buffer with the same base buffer). keyboard.c refers to
526 this. */
527
528 int buffer_shared;
529
530 /* Vector containing glyphs for an ellipsis `...'. */
531
532 static Lisp_Object default_invis_vector[3];
533
534 /* Zero means display the mode-line/header-line/menu-bar in the default face
535 (this slightly odd definition is for compatibility with previous versions
536 of emacs), non-zero means display them using their respective faces.
537
538 This variable is deprecated. */
539
540 int mode_line_inverse_video;
541
542 /* Prompt to display in front of the mini-buffer contents. */
543
544 Lisp_Object minibuf_prompt;
545
546 /* Width of current mini-buffer prompt. Only set after display_line
547 of the line that contains the prompt. */
548
549 int minibuf_prompt_width;
550
551 /* This is the window where the echo area message was displayed. It
552 is always a mini-buffer window, but it may not be the same window
553 currently active as a mini-buffer. */
554
555 Lisp_Object echo_area_window;
556
557 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
558 pushes the current message and the value of
559 message_enable_multibyte on the stack, the function restore_message
560 pops the stack and displays MESSAGE again. */
561
562 Lisp_Object Vmessage_stack;
563
564 /* Nonzero means multibyte characters were enabled when the echo area
565 message was specified. */
566
567 int message_enable_multibyte;
568
569 /* Nonzero if we should redraw the mode lines on the next redisplay. */
570
571 int update_mode_lines;
572
573 /* Nonzero if window sizes or contents have changed since last
574 redisplay that finished. */
575
576 int windows_or_buffers_changed;
577
578 /* Nonzero means a frame's cursor type has been changed. */
579
580 int cursor_type_changed;
581
582 /* Nonzero after display_mode_line if %l was used and it displayed a
583 line number. */
584
585 int line_number_displayed;
586
587 /* Maximum buffer size for which to display line numbers. */
588
589 Lisp_Object Vline_number_display_limit;
590
591 /* Line width to consider when repositioning for line number display. */
592
593 static EMACS_INT line_number_display_limit_width;
594
595 /* Number of lines to keep in the message log buffer. t means
596 infinite. nil means don't log at all. */
597
598 Lisp_Object Vmessage_log_max;
599
600 /* The name of the *Messages* buffer, a string. */
601
602 static Lisp_Object Vmessages_buffer_name;
603
604 /* Current, index 0, and last displayed echo area message. Either
605 buffers from echo_buffers, or nil to indicate no message. */
606
607 Lisp_Object echo_area_buffer[2];
608
609 /* The buffers referenced from echo_area_buffer. */
610
611 static Lisp_Object echo_buffer[2];
612
613 /* A vector saved used in with_area_buffer to reduce consing. */
614
615 static Lisp_Object Vwith_echo_area_save_vector;
616
617 /* Non-zero means display_echo_area should display the last echo area
618 message again. Set by redisplay_preserve_echo_area. */
619
620 static int display_last_displayed_message_p;
621
622 /* Nonzero if echo area is being used by print; zero if being used by
623 message. */
624
625 int message_buf_print;
626
627 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
628
629 Lisp_Object Qinhibit_menubar_update;
630 int inhibit_menubar_update;
631
632 /* When evaluating expressions from menu bar items (enable conditions,
633 for instance), this is the frame they are being processed for. */
634
635 Lisp_Object Vmenu_updating_frame;
636
637 /* Maximum height for resizing mini-windows. Either a float
638 specifying a fraction of the available height, or an integer
639 specifying a number of lines. */
640
641 Lisp_Object Vmax_mini_window_height;
642
643 /* Non-zero means messages should be displayed with truncated
644 lines instead of being continued. */
645
646 int message_truncate_lines;
647 Lisp_Object Qmessage_truncate_lines;
648
649 /* Set to 1 in clear_message to make redisplay_internal aware
650 of an emptied echo area. */
651
652 static int message_cleared_p;
653
654 /* How to blink the default frame cursor off. */
655 Lisp_Object Vblink_cursor_alist;
656
657 /* A scratch glyph row with contents used for generating truncation
658 glyphs. Also used in direct_output_for_insert. */
659
660 #define MAX_SCRATCH_GLYPHS 100
661 struct glyph_row scratch_glyph_row;
662 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
663
664 /* Ascent and height of the last line processed by move_it_to. */
665
666 static int last_max_ascent, last_height;
667
668 /* Non-zero if there's a help-echo in the echo area. */
669
670 int help_echo_showing_p;
671
672 /* If >= 0, computed, exact values of mode-line and header-line height
673 to use in the macros CURRENT_MODE_LINE_HEIGHT and
674 CURRENT_HEADER_LINE_HEIGHT. */
675
676 int current_mode_line_height, current_header_line_height;
677
678 /* The maximum distance to look ahead for text properties. Values
679 that are too small let us call compute_char_face and similar
680 functions too often which is expensive. Values that are too large
681 let us call compute_char_face and alike too often because we
682 might not be interested in text properties that far away. */
683
684 #define TEXT_PROP_DISTANCE_LIMIT 100
685
686 #if GLYPH_DEBUG
687
688 /* Variables to turn off display optimizations from Lisp. */
689
690 int inhibit_try_window_id, inhibit_try_window_reusing;
691 int inhibit_try_cursor_movement;
692
693 /* Non-zero means print traces of redisplay if compiled with
694 GLYPH_DEBUG != 0. */
695
696 int trace_redisplay_p;
697
698 #endif /* GLYPH_DEBUG */
699
700 #ifdef DEBUG_TRACE_MOVE
701 /* Non-zero means trace with TRACE_MOVE to stderr. */
702 int trace_move;
703
704 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
705 #else
706 #define TRACE_MOVE(x) (void) 0
707 #endif
708
709 /* Non-zero means automatically scroll windows horizontally to make
710 point visible. */
711
712 int automatic_hscrolling_p;
713 Lisp_Object Qauto_hscroll_mode;
714
715 /* How close to the margin can point get before the window is scrolled
716 horizontally. */
717 EMACS_INT hscroll_margin;
718
719 /* How much to scroll horizontally when point is inside the above margin. */
720 Lisp_Object Vhscroll_step;
721
722 /* The variable `resize-mini-windows'. If nil, don't resize
723 mini-windows. If t, always resize them to fit the text they
724 display. If `grow-only', let mini-windows grow only until they
725 become empty. */
726
727 Lisp_Object Vresize_mini_windows;
728
729 /* Buffer being redisplayed -- for redisplay_window_error. */
730
731 struct buffer *displayed_buffer;
732
733 /* Space between overline and text. */
734
735 EMACS_INT overline_margin;
736
737 /* Require underline to be at least this many screen pixels below baseline
738 This to avoid underline "merging" with the base of letters at small
739 font sizes, particularly when x_use_underline_position_properties is on. */
740
741 EMACS_INT underline_minimum_offset;
742
743 /* Value returned from text property handlers (see below). */
744
745 enum prop_handled
746 {
747 HANDLED_NORMALLY,
748 HANDLED_RECOMPUTE_PROPS,
749 HANDLED_OVERLAY_STRING_CONSUMED,
750 HANDLED_RETURN
751 };
752
753 /* A description of text properties that redisplay is interested
754 in. */
755
756 struct props
757 {
758 /* The name of the property. */
759 Lisp_Object *name;
760
761 /* A unique index for the property. */
762 enum prop_idx idx;
763
764 /* A handler function called to set up iterator IT from the property
765 at IT's current position. Value is used to steer handle_stop. */
766 enum prop_handled (*handler) P_ ((struct it *it));
767 };
768
769 static enum prop_handled handle_face_prop P_ ((struct it *));
770 static enum prop_handled handle_invisible_prop P_ ((struct it *));
771 static enum prop_handled handle_display_prop P_ ((struct it *));
772 static enum prop_handled handle_composition_prop P_ ((struct it *));
773 static enum prop_handled handle_overlay_change P_ ((struct it *));
774 static enum prop_handled handle_fontified_prop P_ ((struct it *));
775
776 /* Properties handled by iterators. */
777
778 static struct props it_props[] =
779 {
780 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
781 /* Handle `face' before `display' because some sub-properties of
782 `display' need to know the face. */
783 {&Qface, FACE_PROP_IDX, handle_face_prop},
784 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
785 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
786 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
787 {NULL, 0, NULL}
788 };
789
790 /* Value is the position described by X. If X is a marker, value is
791 the marker_position of X. Otherwise, value is X. */
792
793 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
794
795 /* Enumeration returned by some move_it_.* functions internally. */
796
797 enum move_it_result
798 {
799 /* Not used. Undefined value. */
800 MOVE_UNDEFINED,
801
802 /* Move ended at the requested buffer position or ZV. */
803 MOVE_POS_MATCH_OR_ZV,
804
805 /* Move ended at the requested X pixel position. */
806 MOVE_X_REACHED,
807
808 /* Move within a line ended at the end of a line that must be
809 continued. */
810 MOVE_LINE_CONTINUED,
811
812 /* Move within a line ended at the end of a line that would
813 be displayed truncated. */
814 MOVE_LINE_TRUNCATED,
815
816 /* Move within a line ended at a line end. */
817 MOVE_NEWLINE_OR_CR
818 };
819
820 /* This counter is used to clear the face cache every once in a while
821 in redisplay_internal. It is incremented for each redisplay.
822 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
823 cleared. */
824
825 #define CLEAR_FACE_CACHE_COUNT 500
826 static int clear_face_cache_count;
827
828 /* Similarly for the image cache. */
829
830 #ifdef HAVE_WINDOW_SYSTEM
831 #define CLEAR_IMAGE_CACHE_COUNT 101
832 static int clear_image_cache_count;
833 #endif
834
835 /* Non-zero while redisplay_internal is in progress. */
836
837 int redisplaying_p;
838
839 /* Non-zero means don't free realized faces. Bound while freeing
840 realized faces is dangerous because glyph matrices might still
841 reference them. */
842
843 int inhibit_free_realized_faces;
844 Lisp_Object Qinhibit_free_realized_faces;
845
846 /* If a string, XTread_socket generates an event to display that string.
847 (The display is done in read_char.) */
848
849 Lisp_Object help_echo_string;
850 Lisp_Object help_echo_window;
851 Lisp_Object help_echo_object;
852 int help_echo_pos;
853
854 /* Temporary variable for XTread_socket. */
855
856 Lisp_Object previous_help_echo_string;
857
858 /* Null glyph slice */
859
860 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
861
862 /* Platform-independent portion of hourglass implementation. */
863
864 /* Non-zero means we're allowed to display a hourglass pointer. */
865 int display_hourglass_p;
866
867 /* Non-zero means an hourglass cursor is currently shown. */
868 int hourglass_shown_p;
869
870 /* If non-null, an asynchronous timer that, when it expires, displays
871 an hourglass cursor on all frames. */
872 struct atimer *hourglass_atimer;
873
874 /* Number of seconds to wait before displaying an hourglass cursor. */
875 Lisp_Object Vhourglass_delay;
876
877 /* Default number of seconds to wait before displaying an hourglass
878 cursor. */
879 #define DEFAULT_HOURGLASS_DELAY 1
880
881 \f
882 /* Function prototypes. */
883
884 static void setup_for_ellipsis P_ ((struct it *, int));
885 static void mark_window_display_accurate_1 P_ ((struct window *, int));
886 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
887 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
888 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
889 static int redisplay_mode_lines P_ ((Lisp_Object, int));
890 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
891
892 static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
893
894 static void handle_line_prefix P_ ((struct it *));
895
896 static void pint2str P_ ((char *, int, int));
897 static void pint2hrstr P_ ((char *, int, int));
898 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
899 struct text_pos));
900 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
901 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
902 static void store_mode_line_noprop_char P_ ((char));
903 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
904 static void x_consider_frame_title P_ ((Lisp_Object));
905 static void handle_stop P_ ((struct it *));
906 static int tool_bar_lines_needed P_ ((struct frame *, int *));
907 static int single_display_spec_intangible_p P_ ((Lisp_Object));
908 static void ensure_echo_area_buffers P_ ((void));
909 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
910 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
911 static int with_echo_area_buffer P_ ((struct window *, int,
912 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
913 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
914 static void clear_garbaged_frames P_ ((void));
915 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
916 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
917 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
918 static int display_echo_area P_ ((struct window *));
919 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
920 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
921 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
922 static int string_char_and_length P_ ((const unsigned char *, int, int *));
923 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
924 struct text_pos));
925 static int compute_window_start_on_continuation_line P_ ((struct window *));
926 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
927 static void insert_left_trunc_glyphs P_ ((struct it *));
928 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
929 Lisp_Object));
930 static void extend_face_to_end_of_line P_ ((struct it *));
931 static int append_space_for_newline P_ ((struct it *, int));
932 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
933 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
934 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
935 static int trailing_whitespace_p P_ ((int));
936 static int message_log_check_duplicate P_ ((int, int, int, int));
937 static void push_it P_ ((struct it *));
938 static void pop_it P_ ((struct it *));
939 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
940 static void select_frame_for_redisplay P_ ((Lisp_Object));
941 static void redisplay_internal P_ ((int));
942 static int echo_area_display P_ ((int));
943 static void redisplay_windows P_ ((Lisp_Object));
944 static void redisplay_window P_ ((Lisp_Object, int));
945 static Lisp_Object redisplay_window_error ();
946 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
947 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
948 static int update_menu_bar P_ ((struct frame *, int, int));
949 static int try_window_reusing_current_matrix P_ ((struct window *));
950 static int try_window_id P_ ((struct window *));
951 static int display_line P_ ((struct it *));
952 static int display_mode_lines P_ ((struct window *));
953 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
954 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
955 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
956 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
957 static void display_menu_bar P_ ((struct window *));
958 static int display_count_lines P_ ((int, int, int, int, int *));
959 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
960 EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
961 static void compute_line_metrics P_ ((struct it *));
962 static void run_redisplay_end_trigger_hook P_ ((struct it *));
963 static int get_overlay_strings P_ ((struct it *, int));
964 static int get_overlay_strings_1 P_ ((struct it *, int, int));
965 static void next_overlay_string P_ ((struct it *));
966 static void reseat P_ ((struct it *, struct text_pos, int));
967 static void reseat_1 P_ ((struct it *, struct text_pos, int));
968 static void back_to_previous_visible_line_start P_ ((struct it *));
969 void reseat_at_previous_visible_line_start P_ ((struct it *));
970 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
971 static int next_element_from_ellipsis P_ ((struct it *));
972 static int next_element_from_display_vector P_ ((struct it *));
973 static int next_element_from_string P_ ((struct it *));
974 static int next_element_from_c_string P_ ((struct it *));
975 static int next_element_from_buffer P_ ((struct it *));
976 static int next_element_from_composition P_ ((struct it *));
977 static int next_element_from_image P_ ((struct it *));
978 static int next_element_from_stretch P_ ((struct it *));
979 static void load_overlay_strings P_ ((struct it *, int));
980 static int init_from_display_pos P_ ((struct it *, struct window *,
981 struct display_pos *));
982 static void reseat_to_string P_ ((struct it *, unsigned char *,
983 Lisp_Object, int, int, int, int));
984 static enum move_it_result
985 move_it_in_display_line_to (struct it *, EMACS_INT, int,
986 enum move_operation_enum);
987 void move_it_vertically_backward P_ ((struct it *, int));
988 static void init_to_row_start P_ ((struct it *, struct window *,
989 struct glyph_row *));
990 static int init_to_row_end P_ ((struct it *, struct window *,
991 struct glyph_row *));
992 static void back_to_previous_line_start P_ ((struct it *));
993 static int forward_to_next_line_start P_ ((struct it *, int *));
994 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
995 Lisp_Object, int));
996 static struct text_pos string_pos P_ ((int, Lisp_Object));
997 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
998 static int number_of_chars P_ ((unsigned char *, int));
999 static void compute_stop_pos P_ ((struct it *));
1000 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
1001 Lisp_Object));
1002 static int face_before_or_after_it_pos P_ ((struct it *, int));
1003 static EMACS_INT next_overlay_change P_ ((EMACS_INT));
1004 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
1005 Lisp_Object, Lisp_Object,
1006 struct text_pos *, int));
1007 static int underlying_face_id P_ ((struct it *));
1008 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
1009 struct window *));
1010
1011 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1012 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1013
1014 #ifdef HAVE_WINDOW_SYSTEM
1015
1016 static void update_tool_bar P_ ((struct frame *, int));
1017 static void build_desired_tool_bar_string P_ ((struct frame *f));
1018 static int redisplay_tool_bar P_ ((struct frame *));
1019 static void display_tool_bar_line P_ ((struct it *, int));
1020 static void notice_overwritten_cursor P_ ((struct window *,
1021 enum glyph_row_area,
1022 int, int, int, int));
1023
1024
1025
1026 #endif /* HAVE_WINDOW_SYSTEM */
1027
1028 \f
1029 /***********************************************************************
1030 Window display dimensions
1031 ***********************************************************************/
1032
1033 /* Return the bottom boundary y-position for text lines in window W.
1034 This is the first y position at which a line cannot start.
1035 It is relative to the top of the window.
1036
1037 This is the height of W minus the height of a mode line, if any. */
1038
1039 INLINE int
1040 window_text_bottom_y (w)
1041 struct window *w;
1042 {
1043 int height = WINDOW_TOTAL_HEIGHT (w);
1044
1045 if (WINDOW_WANTS_MODELINE_P (w))
1046 height -= CURRENT_MODE_LINE_HEIGHT (w);
1047 return height;
1048 }
1049
1050 /* Return the pixel width of display area AREA of window W. AREA < 0
1051 means return the total width of W, not including fringes to
1052 the left and right of the window. */
1053
1054 INLINE int
1055 window_box_width (w, area)
1056 struct window *w;
1057 int area;
1058 {
1059 int cols = XFASTINT (w->total_cols);
1060 int pixels = 0;
1061
1062 if (!w->pseudo_window_p)
1063 {
1064 cols -= WINDOW_SCROLL_BAR_COLS (w);
1065
1066 if (area == TEXT_AREA)
1067 {
1068 if (INTEGERP (w->left_margin_cols))
1069 cols -= XFASTINT (w->left_margin_cols);
1070 if (INTEGERP (w->right_margin_cols))
1071 cols -= XFASTINT (w->right_margin_cols);
1072 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1073 }
1074 else if (area == LEFT_MARGIN_AREA)
1075 {
1076 cols = (INTEGERP (w->left_margin_cols)
1077 ? XFASTINT (w->left_margin_cols) : 0);
1078 pixels = 0;
1079 }
1080 else if (area == RIGHT_MARGIN_AREA)
1081 {
1082 cols = (INTEGERP (w->right_margin_cols)
1083 ? XFASTINT (w->right_margin_cols) : 0);
1084 pixels = 0;
1085 }
1086 }
1087
1088 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1089 }
1090
1091
1092 /* Return the pixel height of the display area of window W, not
1093 including mode lines of W, if any. */
1094
1095 INLINE int
1096 window_box_height (w)
1097 struct window *w;
1098 {
1099 struct frame *f = XFRAME (w->frame);
1100 int height = WINDOW_TOTAL_HEIGHT (w);
1101
1102 xassert (height >= 0);
1103
1104 /* Note: the code below that determines the mode-line/header-line
1105 height is essentially the same as that contained in the macro
1106 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1107 the appropriate glyph row has its `mode_line_p' flag set,
1108 and if it doesn't, uses estimate_mode_line_height instead. */
1109
1110 if (WINDOW_WANTS_MODELINE_P (w))
1111 {
1112 struct glyph_row *ml_row
1113 = (w->current_matrix && w->current_matrix->rows
1114 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1115 : 0);
1116 if (ml_row && ml_row->mode_line_p)
1117 height -= ml_row->height;
1118 else
1119 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1120 }
1121
1122 if (WINDOW_WANTS_HEADER_LINE_P (w))
1123 {
1124 struct glyph_row *hl_row
1125 = (w->current_matrix && w->current_matrix->rows
1126 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1127 : 0);
1128 if (hl_row && hl_row->mode_line_p)
1129 height -= hl_row->height;
1130 else
1131 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1132 }
1133
1134 /* With a very small font and a mode-line that's taller than
1135 default, we might end up with a negative height. */
1136 return max (0, height);
1137 }
1138
1139 /* Return the window-relative coordinate of the left edge of display
1140 area AREA of window W. AREA < 0 means return the left edge of the
1141 whole window, to the right of the left fringe of W. */
1142
1143 INLINE int
1144 window_box_left_offset (w, area)
1145 struct window *w;
1146 int area;
1147 {
1148 int x;
1149
1150 if (w->pseudo_window_p)
1151 return 0;
1152
1153 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1154
1155 if (area == TEXT_AREA)
1156 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1157 + window_box_width (w, LEFT_MARGIN_AREA));
1158 else if (area == RIGHT_MARGIN_AREA)
1159 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1160 + window_box_width (w, LEFT_MARGIN_AREA)
1161 + window_box_width (w, TEXT_AREA)
1162 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1163 ? 0
1164 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1165 else if (area == LEFT_MARGIN_AREA
1166 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1167 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1168
1169 return x;
1170 }
1171
1172
1173 /* Return the window-relative coordinate of the right edge of display
1174 area AREA of window W. AREA < 0 means return the left edge of the
1175 whole window, to the left of the right fringe of W. */
1176
1177 INLINE int
1178 window_box_right_offset (w, area)
1179 struct window *w;
1180 int area;
1181 {
1182 return window_box_left_offset (w, area) + window_box_width (w, area);
1183 }
1184
1185 /* Return the frame-relative coordinate of the left edge of display
1186 area AREA of window W. AREA < 0 means return the left edge of the
1187 whole window, to the right of the left fringe of W. */
1188
1189 INLINE int
1190 window_box_left (w, area)
1191 struct window *w;
1192 int area;
1193 {
1194 struct frame *f = XFRAME (w->frame);
1195 int x;
1196
1197 if (w->pseudo_window_p)
1198 return FRAME_INTERNAL_BORDER_WIDTH (f);
1199
1200 x = (WINDOW_LEFT_EDGE_X (w)
1201 + window_box_left_offset (w, area));
1202
1203 return x;
1204 }
1205
1206
1207 /* Return the frame-relative coordinate of the right edge of display
1208 area AREA of window W. AREA < 0 means return the left edge of the
1209 whole window, to the left of the right fringe of W. */
1210
1211 INLINE int
1212 window_box_right (w, area)
1213 struct window *w;
1214 int area;
1215 {
1216 return window_box_left (w, area) + window_box_width (w, area);
1217 }
1218
1219 /* Get the bounding box of the display area AREA of window W, without
1220 mode lines, in frame-relative coordinates. AREA < 0 means the
1221 whole window, not including the left and right fringes of
1222 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1223 coordinates of the upper-left corner of the box. Return in
1224 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1225
1226 INLINE void
1227 window_box (w, area, box_x, box_y, box_width, box_height)
1228 struct window *w;
1229 int area;
1230 int *box_x, *box_y, *box_width, *box_height;
1231 {
1232 if (box_width)
1233 *box_width = window_box_width (w, area);
1234 if (box_height)
1235 *box_height = window_box_height (w);
1236 if (box_x)
1237 *box_x = window_box_left (w, area);
1238 if (box_y)
1239 {
1240 *box_y = WINDOW_TOP_EDGE_Y (w);
1241 if (WINDOW_WANTS_HEADER_LINE_P (w))
1242 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1243 }
1244 }
1245
1246
1247 /* Get the bounding box of the display area AREA of window W, without
1248 mode lines. AREA < 0 means the whole window, not including the
1249 left and right fringe of the window. Return in *TOP_LEFT_X
1250 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1251 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1252 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1253 box. */
1254
1255 INLINE void
1256 window_box_edges (w, area, top_left_x, top_left_y,
1257 bottom_right_x, bottom_right_y)
1258 struct window *w;
1259 int area;
1260 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1261 {
1262 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1263 bottom_right_y);
1264 *bottom_right_x += *top_left_x;
1265 *bottom_right_y += *top_left_y;
1266 }
1267
1268
1269 \f
1270 /***********************************************************************
1271 Utilities
1272 ***********************************************************************/
1273
1274 /* Return the bottom y-position of the line the iterator IT is in.
1275 This can modify IT's settings. */
1276
1277 int
1278 line_bottom_y (it)
1279 struct it *it;
1280 {
1281 int line_height = it->max_ascent + it->max_descent;
1282 int line_top_y = it->current_y;
1283
1284 if (line_height == 0)
1285 {
1286 if (last_height)
1287 line_height = last_height;
1288 else if (IT_CHARPOS (*it) < ZV)
1289 {
1290 move_it_by_lines (it, 1, 1);
1291 line_height = (it->max_ascent || it->max_descent
1292 ? it->max_ascent + it->max_descent
1293 : last_height);
1294 }
1295 else
1296 {
1297 struct glyph_row *row = it->glyph_row;
1298
1299 /* Use the default character height. */
1300 it->glyph_row = NULL;
1301 it->what = IT_CHARACTER;
1302 it->c = ' ';
1303 it->len = 1;
1304 PRODUCE_GLYPHS (it);
1305 line_height = it->ascent + it->descent;
1306 it->glyph_row = row;
1307 }
1308 }
1309
1310 return line_top_y + line_height;
1311 }
1312
1313
1314 /* Return 1 if position CHARPOS is visible in window W.
1315 CHARPOS < 0 means return info about WINDOW_END position.
1316 If visible, set *X and *Y to pixel coordinates of top left corner.
1317 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1318 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1319
1320 int
1321 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1322 struct window *w;
1323 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1324 {
1325 struct it it;
1326 struct text_pos top;
1327 int visible_p = 0;
1328 struct buffer *old_buffer = NULL;
1329
1330 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1331 return visible_p;
1332
1333 if (XBUFFER (w->buffer) != current_buffer)
1334 {
1335 old_buffer = current_buffer;
1336 set_buffer_internal_1 (XBUFFER (w->buffer));
1337 }
1338
1339 SET_TEXT_POS_FROM_MARKER (top, w->start);
1340
1341 /* Compute exact mode line heights. */
1342 if (WINDOW_WANTS_MODELINE_P (w))
1343 current_mode_line_height
1344 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1345 current_buffer->mode_line_format);
1346
1347 if (WINDOW_WANTS_HEADER_LINE_P (w))
1348 current_header_line_height
1349 = display_mode_line (w, HEADER_LINE_FACE_ID,
1350 current_buffer->header_line_format);
1351
1352 start_display (&it, w, top);
1353 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1354 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1355
1356 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1357 {
1358 /* We have reached CHARPOS, or passed it. How the call to
1359 move_it_to can overshoot: (i) If CHARPOS is on invisible
1360 text, move_it_to stops at the end of the invisible text,
1361 after CHARPOS. (ii) If CHARPOS is in a display vector,
1362 move_it_to stops on its last glyph. */
1363 int top_x = it.current_x;
1364 int top_y = it.current_y;
1365 enum it_method it_method = it.method;
1366 /* Calling line_bottom_y may change it.method. */
1367 int bottom_y = (last_height = 0, line_bottom_y (&it));
1368 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1369
1370 if (top_y < window_top_y)
1371 visible_p = bottom_y > window_top_y;
1372 else if (top_y < it.last_visible_y)
1373 visible_p = 1;
1374 if (visible_p)
1375 {
1376 if (it_method == GET_FROM_BUFFER)
1377 {
1378 Lisp_Object window, prop;
1379
1380 XSETWINDOW (window, w);
1381 prop = Fget_char_property (make_number (it.position.charpos),
1382 Qinvisible, window);
1383
1384 /* If charpos coincides with invisible text covered with an
1385 ellipsis, use the first glyph of the ellipsis to compute
1386 the pixel positions. */
1387 if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
1388 {
1389 struct glyph_row *row = it.glyph_row;
1390 struct glyph *glyph = row->glyphs[TEXT_AREA];
1391 struct glyph *end = glyph + row->used[TEXT_AREA];
1392 int x = row->x;
1393
1394 for (; glyph < end
1395 && (!BUFFERP (glyph->object)
1396 || glyph->charpos < charpos);
1397 glyph++)
1398 x += glyph->pixel_width;
1399 top_x = x;
1400 }
1401 }
1402 else if (it_method == GET_FROM_DISPLAY_VECTOR)
1403 {
1404 /* We stopped on the last glyph of a display vector.
1405 Try and recompute. Hack alert! */
1406 if (charpos < 2 || top.charpos >= charpos)
1407 top_x = it.glyph_row->x;
1408 else
1409 {
1410 struct it it2;
1411 start_display (&it2, w, top);
1412 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1413 get_next_display_element (&it2);
1414 PRODUCE_GLYPHS (&it2);
1415 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1416 || it2.current_x > it2.last_visible_x)
1417 top_x = it.glyph_row->x;
1418 else
1419 {
1420 top_x = it2.current_x;
1421 top_y = it2.current_y;
1422 }
1423 }
1424 }
1425
1426 *x = top_x;
1427 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1428 *rtop = max (0, window_top_y - top_y);
1429 *rbot = max (0, bottom_y - it.last_visible_y);
1430 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1431 - max (top_y, window_top_y)));
1432 *vpos = it.vpos;
1433 }
1434 }
1435 else
1436 {
1437 struct it it2;
1438
1439 it2 = it;
1440 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1441 move_it_by_lines (&it, 1, 0);
1442 if (charpos < IT_CHARPOS (it)
1443 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1444 {
1445 visible_p = 1;
1446 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1447 *x = it2.current_x;
1448 *y = it2.current_y + it2.max_ascent - it2.ascent;
1449 *rtop = max (0, -it2.current_y);
1450 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1451 - it.last_visible_y));
1452 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1453 it.last_visible_y)
1454 - max (it2.current_y,
1455 WINDOW_HEADER_LINE_HEIGHT (w))));
1456 *vpos = it2.vpos;
1457 }
1458 }
1459
1460 if (old_buffer)
1461 set_buffer_internal_1 (old_buffer);
1462
1463 current_header_line_height = current_mode_line_height = -1;
1464
1465 if (visible_p && XFASTINT (w->hscroll) > 0)
1466 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1467
1468 #if 0
1469 /* Debugging code. */
1470 if (visible_p)
1471 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1472 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1473 else
1474 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1475 #endif
1476
1477 return visible_p;
1478 }
1479
1480
1481 /* Return the next character from STR which is MAXLEN bytes long.
1482 Return in *LEN the length of the character. This is like
1483 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1484 we find one, we return a `?', but with the length of the invalid
1485 character. */
1486
1487 static INLINE int
1488 string_char_and_length (str, maxlen, len)
1489 const unsigned char *str;
1490 int maxlen, *len;
1491 {
1492 int c;
1493
1494 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1495 if (!CHAR_VALID_P (c, 1))
1496 /* We may not change the length here because other places in Emacs
1497 don't use this function, i.e. they silently accept invalid
1498 characters. */
1499 c = '?';
1500
1501 return c;
1502 }
1503
1504
1505
1506 /* Given a position POS containing a valid character and byte position
1507 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1508
1509 static struct text_pos
1510 string_pos_nchars_ahead (pos, string, nchars)
1511 struct text_pos pos;
1512 Lisp_Object string;
1513 int nchars;
1514 {
1515 xassert (STRINGP (string) && nchars >= 0);
1516
1517 if (STRING_MULTIBYTE (string))
1518 {
1519 int rest = SBYTES (string) - BYTEPOS (pos);
1520 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1521 int len;
1522
1523 while (nchars--)
1524 {
1525 string_char_and_length (p, rest, &len);
1526 p += len, rest -= len;
1527 xassert (rest >= 0);
1528 CHARPOS (pos) += 1;
1529 BYTEPOS (pos) += len;
1530 }
1531 }
1532 else
1533 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1534
1535 return pos;
1536 }
1537
1538
1539 /* Value is the text position, i.e. character and byte position,
1540 for character position CHARPOS in STRING. */
1541
1542 static INLINE struct text_pos
1543 string_pos (charpos, string)
1544 int charpos;
1545 Lisp_Object string;
1546 {
1547 struct text_pos pos;
1548 xassert (STRINGP (string));
1549 xassert (charpos >= 0);
1550 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1551 return pos;
1552 }
1553
1554
1555 /* Value is a text position, i.e. character and byte position, for
1556 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1557 means recognize multibyte characters. */
1558
1559 static struct text_pos
1560 c_string_pos (charpos, s, multibyte_p)
1561 int charpos;
1562 unsigned char *s;
1563 int multibyte_p;
1564 {
1565 struct text_pos pos;
1566
1567 xassert (s != NULL);
1568 xassert (charpos >= 0);
1569
1570 if (multibyte_p)
1571 {
1572 int rest = strlen (s), len;
1573
1574 SET_TEXT_POS (pos, 0, 0);
1575 while (charpos--)
1576 {
1577 string_char_and_length (s, rest, &len);
1578 s += len, rest -= len;
1579 xassert (rest >= 0);
1580 CHARPOS (pos) += 1;
1581 BYTEPOS (pos) += len;
1582 }
1583 }
1584 else
1585 SET_TEXT_POS (pos, charpos, charpos);
1586
1587 return pos;
1588 }
1589
1590
1591 /* Value is the number of characters in C string S. MULTIBYTE_P
1592 non-zero means recognize multibyte characters. */
1593
1594 static int
1595 number_of_chars (s, multibyte_p)
1596 unsigned char *s;
1597 int multibyte_p;
1598 {
1599 int nchars;
1600
1601 if (multibyte_p)
1602 {
1603 int rest = strlen (s), len;
1604 unsigned char *p = (unsigned char *) s;
1605
1606 for (nchars = 0; rest > 0; ++nchars)
1607 {
1608 string_char_and_length (p, rest, &len);
1609 rest -= len, p += len;
1610 }
1611 }
1612 else
1613 nchars = strlen (s);
1614
1615 return nchars;
1616 }
1617
1618
1619 /* Compute byte position NEWPOS->bytepos corresponding to
1620 NEWPOS->charpos. POS is a known position in string STRING.
1621 NEWPOS->charpos must be >= POS.charpos. */
1622
1623 static void
1624 compute_string_pos (newpos, pos, string)
1625 struct text_pos *newpos, pos;
1626 Lisp_Object string;
1627 {
1628 xassert (STRINGP (string));
1629 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1630
1631 if (STRING_MULTIBYTE (string))
1632 *newpos = string_pos_nchars_ahead (pos, string,
1633 CHARPOS (*newpos) - CHARPOS (pos));
1634 else
1635 BYTEPOS (*newpos) = CHARPOS (*newpos);
1636 }
1637
1638 /* EXPORT:
1639 Return an estimation of the pixel height of mode or header lines on
1640 frame F. FACE_ID specifies what line's height to estimate. */
1641
1642 int
1643 estimate_mode_line_height (f, face_id)
1644 struct frame *f;
1645 enum face_id face_id;
1646 {
1647 #ifdef HAVE_WINDOW_SYSTEM
1648 if (FRAME_WINDOW_P (f))
1649 {
1650 int height = FONT_HEIGHT (FRAME_FONT (f));
1651
1652 /* This function is called so early when Emacs starts that the face
1653 cache and mode line face are not yet initialized. */
1654 if (FRAME_FACE_CACHE (f))
1655 {
1656 struct face *face = FACE_FROM_ID (f, face_id);
1657 if (face)
1658 {
1659 if (face->font)
1660 height = FONT_HEIGHT (face->font);
1661 if (face->box_line_width > 0)
1662 height += 2 * face->box_line_width;
1663 }
1664 }
1665
1666 return height;
1667 }
1668 #endif
1669
1670 return 1;
1671 }
1672
1673 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1674 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1675 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1676 not force the value into range. */
1677
1678 void
1679 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1680 FRAME_PTR f;
1681 register int pix_x, pix_y;
1682 int *x, *y;
1683 NativeRectangle *bounds;
1684 int noclip;
1685 {
1686
1687 #ifdef HAVE_WINDOW_SYSTEM
1688 if (FRAME_WINDOW_P (f))
1689 {
1690 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1691 even for negative values. */
1692 if (pix_x < 0)
1693 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1694 if (pix_y < 0)
1695 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1696
1697 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1698 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1699
1700 if (bounds)
1701 STORE_NATIVE_RECT (*bounds,
1702 FRAME_COL_TO_PIXEL_X (f, pix_x),
1703 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1704 FRAME_COLUMN_WIDTH (f) - 1,
1705 FRAME_LINE_HEIGHT (f) - 1);
1706
1707 if (!noclip)
1708 {
1709 if (pix_x < 0)
1710 pix_x = 0;
1711 else if (pix_x > FRAME_TOTAL_COLS (f))
1712 pix_x = FRAME_TOTAL_COLS (f);
1713
1714 if (pix_y < 0)
1715 pix_y = 0;
1716 else if (pix_y > FRAME_LINES (f))
1717 pix_y = FRAME_LINES (f);
1718 }
1719 }
1720 #endif
1721
1722 *x = pix_x;
1723 *y = pix_y;
1724 }
1725
1726
1727 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1728 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1729 can't tell the positions because W's display is not up to date,
1730 return 0. */
1731
1732 int
1733 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1734 struct window *w;
1735 int hpos, vpos;
1736 int *frame_x, *frame_y;
1737 {
1738 #ifdef HAVE_WINDOW_SYSTEM
1739 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1740 {
1741 int success_p;
1742
1743 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1744 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1745
1746 if (display_completed)
1747 {
1748 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1749 struct glyph *glyph = row->glyphs[TEXT_AREA];
1750 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1751
1752 hpos = row->x;
1753 vpos = row->y;
1754 while (glyph < end)
1755 {
1756 hpos += glyph->pixel_width;
1757 ++glyph;
1758 }
1759
1760 /* If first glyph is partially visible, its first visible position is still 0. */
1761 if (hpos < 0)
1762 hpos = 0;
1763
1764 success_p = 1;
1765 }
1766 else
1767 {
1768 hpos = vpos = 0;
1769 success_p = 0;
1770 }
1771
1772 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1773 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1774 return success_p;
1775 }
1776 #endif
1777
1778 *frame_x = hpos;
1779 *frame_y = vpos;
1780 return 1;
1781 }
1782
1783
1784 #ifdef HAVE_WINDOW_SYSTEM
1785
1786 /* Find the glyph under window-relative coordinates X/Y in window W.
1787 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1788 strings. Return in *HPOS and *VPOS the row and column number of
1789 the glyph found. Return in *AREA the glyph area containing X.
1790 Value is a pointer to the glyph found or null if X/Y is not on
1791 text, or we can't tell because W's current matrix is not up to
1792 date. */
1793
1794 static
1795 struct glyph *
1796 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1797 struct window *w;
1798 int x, y;
1799 int *hpos, *vpos, *dx, *dy, *area;
1800 {
1801 struct glyph *glyph, *end;
1802 struct glyph_row *row = NULL;
1803 int x0, i;
1804
1805 /* Find row containing Y. Give up if some row is not enabled. */
1806 for (i = 0; i < w->current_matrix->nrows; ++i)
1807 {
1808 row = MATRIX_ROW (w->current_matrix, i);
1809 if (!row->enabled_p)
1810 return NULL;
1811 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1812 break;
1813 }
1814
1815 *vpos = i;
1816 *hpos = 0;
1817
1818 /* Give up if Y is not in the window. */
1819 if (i == w->current_matrix->nrows)
1820 return NULL;
1821
1822 /* Get the glyph area containing X. */
1823 if (w->pseudo_window_p)
1824 {
1825 *area = TEXT_AREA;
1826 x0 = 0;
1827 }
1828 else
1829 {
1830 if (x < window_box_left_offset (w, TEXT_AREA))
1831 {
1832 *area = LEFT_MARGIN_AREA;
1833 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1834 }
1835 else if (x < window_box_right_offset (w, TEXT_AREA))
1836 {
1837 *area = TEXT_AREA;
1838 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1839 }
1840 else
1841 {
1842 *area = RIGHT_MARGIN_AREA;
1843 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1844 }
1845 }
1846
1847 /* Find glyph containing X. */
1848 glyph = row->glyphs[*area];
1849 end = glyph + row->used[*area];
1850 x -= x0;
1851 while (glyph < end && x >= glyph->pixel_width)
1852 {
1853 x -= glyph->pixel_width;
1854 ++glyph;
1855 }
1856
1857 if (glyph == end)
1858 return NULL;
1859
1860 if (dx)
1861 {
1862 *dx = x;
1863 *dy = y - (row->y + row->ascent - glyph->ascent);
1864 }
1865
1866 *hpos = glyph - row->glyphs[*area];
1867 return glyph;
1868 }
1869
1870
1871 /* EXPORT:
1872 Convert frame-relative x/y to coordinates relative to window W.
1873 Takes pseudo-windows into account. */
1874
1875 void
1876 frame_to_window_pixel_xy (w, x, y)
1877 struct window *w;
1878 int *x, *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 (s, rects, n)
1901 struct glyph_string *s;
1902 NativeRectangle *rects;
1903 int n;
1904 {
1905 XRectangle r;
1906
1907 if (n <= 0)
1908 return 0;
1909
1910 if (s->row->full_width_p)
1911 {
1912 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1913 r.x = WINDOW_LEFT_EDGE_X (s->w);
1914 r.width = WINDOW_TOTAL_WIDTH (s->w);
1915
1916 /* Unless displaying a mode or menu bar line, which are always
1917 fully visible, clip to the visible part of the row. */
1918 if (s->w->pseudo_window_p)
1919 r.height = s->row->visible_height;
1920 else
1921 r.height = s->height;
1922 }
1923 else
1924 {
1925 /* This is a text line that may be partially visible. */
1926 r.x = window_box_left (s->w, s->area);
1927 r.width = window_box_width (s->w, s->area);
1928 r.height = s->row->visible_height;
1929 }
1930
1931 if (s->clip_head)
1932 if (r.x < s->clip_head->x)
1933 {
1934 if (r.width >= s->clip_head->x - r.x)
1935 r.width -= s->clip_head->x - r.x;
1936 else
1937 r.width = 0;
1938 r.x = s->clip_head->x;
1939 }
1940 if (s->clip_tail)
1941 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1942 {
1943 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1944 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1945 else
1946 r.width = 0;
1947 }
1948
1949 /* If S draws overlapping rows, it's sufficient to use the top and
1950 bottom of the window for clipping because this glyph string
1951 intentionally draws over other lines. */
1952 if (s->for_overlaps)
1953 {
1954 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1955 r.height = window_text_bottom_y (s->w) - r.y;
1956
1957 /* Alas, the above simple strategy does not work for the
1958 environments with anti-aliased text: if the same text is
1959 drawn onto the same place multiple times, it gets thicker.
1960 If the overlap we are processing is for the erased cursor, we
1961 take the intersection with the rectagle of the cursor. */
1962 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1963 {
1964 XRectangle rc, r_save = r;
1965
1966 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1967 rc.y = s->w->phys_cursor.y;
1968 rc.width = s->w->phys_cursor_width;
1969 rc.height = s->w->phys_cursor_height;
1970
1971 x_intersect_rectangles (&r_save, &rc, &r);
1972 }
1973 }
1974 else
1975 {
1976 /* Don't use S->y for clipping because it doesn't take partially
1977 visible lines into account. For example, it can be negative for
1978 partially visible lines at the top of a window. */
1979 if (!s->row->full_width_p
1980 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1981 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1982 else
1983 r.y = max (0, s->row->y);
1984
1985 /* If drawing a tool-bar window, draw it over the internal border
1986 at the top of the window. */
1987 if (WINDOWP (s->f->tool_bar_window)
1988 && s->w == XWINDOW (s->f->tool_bar_window))
1989 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1990 }
1991
1992 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1993
1994 /* If drawing the cursor, don't let glyph draw outside its
1995 advertised boundaries. Cleartype does this under some circumstances. */
1996 if (s->hl == DRAW_CURSOR)
1997 {
1998 struct glyph *glyph = s->first_glyph;
1999 int height, max_y;
2000
2001 if (s->x > r.x)
2002 {
2003 r.width -= s->x - r.x;
2004 r.x = s->x;
2005 }
2006 r.width = min (r.width, glyph->pixel_width);
2007
2008 /* If r.y is below window bottom, ensure that we still see a cursor. */
2009 height = min (glyph->ascent + glyph->descent,
2010 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2011 max_y = window_text_bottom_y (s->w) - height;
2012 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2013 if (s->ybase - glyph->ascent > max_y)
2014 {
2015 r.y = max_y;
2016 r.height = height;
2017 }
2018 else
2019 {
2020 /* Don't draw cursor glyph taller than our actual glyph. */
2021 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2022 if (height < r.height)
2023 {
2024 max_y = r.y + r.height;
2025 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2026 r.height = min (max_y - r.y, height);
2027 }
2028 }
2029 }
2030
2031 if (s->row->clip)
2032 {
2033 XRectangle r_save = r;
2034
2035 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2036 r.width = 0;
2037 }
2038
2039 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2040 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2041 {
2042 #ifdef CONVERT_FROM_XRECT
2043 CONVERT_FROM_XRECT (r, *rects);
2044 #else
2045 *rects = r;
2046 #endif
2047 return 1;
2048 }
2049 else
2050 {
2051 /* If we are processing overlapping and allowed to return
2052 multiple clipping rectangles, we exclude the row of the glyph
2053 string from the clipping rectangle. This is to avoid drawing
2054 the same text on the environment with anti-aliasing. */
2055 #ifdef CONVERT_FROM_XRECT
2056 XRectangle rs[2];
2057 #else
2058 XRectangle *rs = rects;
2059 #endif
2060 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2061
2062 if (s->for_overlaps & OVERLAPS_PRED)
2063 {
2064 rs[i] = r;
2065 if (r.y + r.height > row_y)
2066 {
2067 if (r.y < row_y)
2068 rs[i].height = row_y - r.y;
2069 else
2070 rs[i].height = 0;
2071 }
2072 i++;
2073 }
2074 if (s->for_overlaps & OVERLAPS_SUCC)
2075 {
2076 rs[i] = r;
2077 if (r.y < row_y + s->row->visible_height)
2078 {
2079 if (r.y + r.height > row_y + s->row->visible_height)
2080 {
2081 rs[i].y = row_y + s->row->visible_height;
2082 rs[i].height = r.y + r.height - rs[i].y;
2083 }
2084 else
2085 rs[i].height = 0;
2086 }
2087 i++;
2088 }
2089
2090 n = i;
2091 #ifdef CONVERT_FROM_XRECT
2092 for (i = 0; i < n; i++)
2093 CONVERT_FROM_XRECT (rs[i], rects[i]);
2094 #endif
2095 return n;
2096 }
2097 }
2098
2099 /* EXPORT:
2100 Return in *NR the clipping rectangle for glyph string S. */
2101
2102 void
2103 get_glyph_string_clip_rect (s, nr)
2104 struct glyph_string *s;
2105 NativeRectangle *nr;
2106 {
2107 get_glyph_string_clip_rects (s, nr, 1);
2108 }
2109
2110
2111 /* EXPORT:
2112 Return the position and height of the phys cursor in window W.
2113 Set w->phys_cursor_width to width of phys cursor.
2114 */
2115
2116 void
2117 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2118 struct window *w;
2119 struct glyph_row *row;
2120 struct glyph *glyph;
2121 int *xp, *yp, *heightp;
2122 {
2123 struct frame *f = XFRAME (WINDOW_FRAME (w));
2124 int x, y, wd, h, h0, y0;
2125
2126 /* Compute the width of the rectangle to draw. If on a stretch
2127 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2128 rectangle as wide as the glyph, but use a canonical character
2129 width instead. */
2130 wd = glyph->pixel_width - 1;
2131 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2132 wd++; /* Why? */
2133 #endif
2134
2135 x = w->phys_cursor.x;
2136 if (x < 0)
2137 {
2138 wd += x;
2139 x = 0;
2140 }
2141
2142 if (glyph->type == STRETCH_GLYPH
2143 && !x_stretch_cursor_p)
2144 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2145 w->phys_cursor_width = wd;
2146
2147 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2148
2149 /* If y is below window bottom, ensure that we still see a cursor. */
2150 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2151
2152 h = max (h0, glyph->ascent + glyph->descent);
2153 h0 = min (h0, glyph->ascent + glyph->descent);
2154
2155 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2156 if (y < y0)
2157 {
2158 h = max (h - (y0 - y) + 1, h0);
2159 y = y0 - 1;
2160 }
2161 else
2162 {
2163 y0 = window_text_bottom_y (w) - h0;
2164 if (y > y0)
2165 {
2166 h += y - y0;
2167 y = y0;
2168 }
2169 }
2170
2171 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2172 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2173 *heightp = h;
2174 }
2175
2176 /*
2177 * Remember which glyph the mouse is over.
2178 */
2179
2180 void
2181 remember_mouse_glyph (f, gx, gy, rect)
2182 struct frame *f;
2183 int gx, gy;
2184 NativeRectangle *rect;
2185 {
2186 Lisp_Object window;
2187 struct window *w;
2188 struct glyph_row *r, *gr, *end_row;
2189 enum window_part part;
2190 enum glyph_row_area area;
2191 int x, y, width, height;
2192
2193 /* Try to determine frame pixel position and size of the glyph under
2194 frame pixel coordinates X/Y on frame F. */
2195
2196 if (!f->glyphs_initialized_p
2197 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2198 NILP (window)))
2199 {
2200 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2201 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2202 goto virtual_glyph;
2203 }
2204
2205 w = XWINDOW (window);
2206 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2207 height = WINDOW_FRAME_LINE_HEIGHT (w);
2208
2209 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2210 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2211
2212 if (w->pseudo_window_p)
2213 {
2214 area = TEXT_AREA;
2215 part = ON_MODE_LINE; /* Don't adjust margin. */
2216 goto text_glyph;
2217 }
2218
2219 switch (part)
2220 {
2221 case ON_LEFT_MARGIN:
2222 area = LEFT_MARGIN_AREA;
2223 goto text_glyph;
2224
2225 case ON_RIGHT_MARGIN:
2226 area = RIGHT_MARGIN_AREA;
2227 goto text_glyph;
2228
2229 case ON_HEADER_LINE:
2230 case ON_MODE_LINE:
2231 gr = (part == ON_HEADER_LINE
2232 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2233 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2234 gy = gr->y;
2235 area = TEXT_AREA;
2236 goto text_glyph_row_found;
2237
2238 case ON_TEXT:
2239 area = TEXT_AREA;
2240
2241 text_glyph:
2242 gr = 0; gy = 0;
2243 for (; r <= end_row && r->enabled_p; ++r)
2244 if (r->y + r->height > y)
2245 {
2246 gr = r; gy = r->y;
2247 break;
2248 }
2249
2250 text_glyph_row_found:
2251 if (gr && gy <= y)
2252 {
2253 struct glyph *g = gr->glyphs[area];
2254 struct glyph *end = g + gr->used[area];
2255
2256 height = gr->height;
2257 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2258 if (gx + g->pixel_width > x)
2259 break;
2260
2261 if (g < end)
2262 {
2263 if (g->type == IMAGE_GLYPH)
2264 {
2265 /* Don't remember when mouse is over image, as
2266 image may have hot-spots. */
2267 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2268 return;
2269 }
2270 width = g->pixel_width;
2271 }
2272 else
2273 {
2274 /* Use nominal char spacing at end of line. */
2275 x -= gx;
2276 gx += (x / width) * width;
2277 }
2278
2279 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2280 gx += window_box_left_offset (w, area);
2281 }
2282 else
2283 {
2284 /* Use nominal line height at end of window. */
2285 gx = (x / width) * width;
2286 y -= gy;
2287 gy += (y / height) * height;
2288 }
2289 break;
2290
2291 case ON_LEFT_FRINGE:
2292 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2293 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2294 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2295 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2296 goto row_glyph;
2297
2298 case ON_RIGHT_FRINGE:
2299 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2300 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2301 : window_box_right_offset (w, TEXT_AREA));
2302 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2303 goto row_glyph;
2304
2305 case ON_SCROLL_BAR:
2306 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2307 ? 0
2308 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2309 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2310 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2311 : 0)));
2312 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2313
2314 row_glyph:
2315 gr = 0, gy = 0;
2316 for (; r <= end_row && r->enabled_p; ++r)
2317 if (r->y + r->height > y)
2318 {
2319 gr = r; gy = r->y;
2320 break;
2321 }
2322
2323 if (gr && gy <= y)
2324 height = gr->height;
2325 else
2326 {
2327 /* Use nominal line height at end of window. */
2328 y -= gy;
2329 gy += (y / height) * height;
2330 }
2331 break;
2332
2333 default:
2334 ;
2335 virtual_glyph:
2336 /* If there is no glyph under the mouse, then we divide the screen
2337 into a grid of the smallest glyph in the frame, and use that
2338 as our "glyph". */
2339
2340 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2341 round down even for negative values. */
2342 if (gx < 0)
2343 gx -= width - 1;
2344 if (gy < 0)
2345 gy -= height - 1;
2346
2347 gx = (gx / width) * width;
2348 gy = (gy / height) * height;
2349
2350 goto store_rect;
2351 }
2352
2353 gx += WINDOW_LEFT_EDGE_X (w);
2354 gy += WINDOW_TOP_EDGE_Y (w);
2355
2356 store_rect:
2357 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2358
2359 /* Visible feedback for debugging. */
2360 #if 0
2361 #if HAVE_X_WINDOWS
2362 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2363 f->output_data.x->normal_gc,
2364 gx, gy, width, height);
2365 #endif
2366 #endif
2367 }
2368
2369
2370 #endif /* HAVE_WINDOW_SYSTEM */
2371
2372 \f
2373 /***********************************************************************
2374 Lisp form evaluation
2375 ***********************************************************************/
2376
2377 /* Error handler for safe_eval and safe_call. */
2378
2379 static Lisp_Object
2380 safe_eval_handler (arg)
2381 Lisp_Object arg;
2382 {
2383 add_to_log ("Error during redisplay: %s", arg, Qnil);
2384 return Qnil;
2385 }
2386
2387
2388 /* Evaluate SEXPR and return the result, or nil if something went
2389 wrong. Prevent redisplay during the evaluation. */
2390
2391 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2392 Return the result, or nil if something went wrong. Prevent
2393 redisplay during the evaluation. */
2394
2395 Lisp_Object
2396 safe_call (nargs, args)
2397 int nargs;
2398 Lisp_Object *args;
2399 {
2400 Lisp_Object val;
2401
2402 if (inhibit_eval_during_redisplay)
2403 val = Qnil;
2404 else
2405 {
2406 int count = SPECPDL_INDEX ();
2407 struct gcpro gcpro1;
2408
2409 GCPRO1 (args[0]);
2410 gcpro1.nvars = nargs;
2411 specbind (Qinhibit_redisplay, Qt);
2412 /* Use Qt to ensure debugger does not run,
2413 so there is no possibility of wanting to redisplay. */
2414 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2415 safe_eval_handler);
2416 UNGCPRO;
2417 val = unbind_to (count, val);
2418 }
2419
2420 return val;
2421 }
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_call1 (fn, arg)
2429 Lisp_Object fn, arg;
2430 {
2431 Lisp_Object args[2];
2432 args[0] = fn;
2433 args[1] = arg;
2434 return safe_call (2, args);
2435 }
2436
2437 static Lisp_Object Qeval;
2438
2439 Lisp_Object
2440 safe_eval (Lisp_Object sexpr)
2441 {
2442 return safe_call1 (Qeval, sexpr);
2443 }
2444
2445 /* Call function FN with one argument ARG.
2446 Return the result, or nil if something went wrong. */
2447
2448 Lisp_Object
2449 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2450 {
2451 Lisp_Object args[3];
2452 args[0] = fn;
2453 args[1] = arg1;
2454 args[2] = arg2;
2455 return safe_call (3, args);
2456 }
2457
2458
2459 \f
2460 /***********************************************************************
2461 Debugging
2462 ***********************************************************************/
2463
2464 #if 0
2465
2466 /* Define CHECK_IT to perform sanity checks on iterators.
2467 This is for debugging. It is too slow to do unconditionally. */
2468
2469 static void
2470 check_it (it)
2471 struct it *it;
2472 {
2473 if (it->method == GET_FROM_STRING)
2474 {
2475 xassert (STRINGP (it->string));
2476 xassert (IT_STRING_CHARPOS (*it) >= 0);
2477 }
2478 else
2479 {
2480 xassert (IT_STRING_CHARPOS (*it) < 0);
2481 if (it->method == GET_FROM_BUFFER)
2482 {
2483 /* Check that character and byte positions agree. */
2484 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2485 }
2486 }
2487
2488 if (it->dpvec)
2489 xassert (it->current.dpvec_index >= 0);
2490 else
2491 xassert (it->current.dpvec_index < 0);
2492 }
2493
2494 #define CHECK_IT(IT) check_it ((IT))
2495
2496 #else /* not 0 */
2497
2498 #define CHECK_IT(IT) (void) 0
2499
2500 #endif /* not 0 */
2501
2502
2503 #if GLYPH_DEBUG
2504
2505 /* Check that the window end of window W is what we expect it
2506 to be---the last row in the current matrix displaying text. */
2507
2508 static void
2509 check_window_end (w)
2510 struct window *w;
2511 {
2512 if (!MINI_WINDOW_P (w)
2513 && !NILP (w->window_end_valid))
2514 {
2515 struct glyph_row *row;
2516 xassert ((row = MATRIX_ROW (w->current_matrix,
2517 XFASTINT (w->window_end_vpos)),
2518 !row->enabled_p
2519 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2520 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2521 }
2522 }
2523
2524 #define CHECK_WINDOW_END(W) check_window_end ((W))
2525
2526 #else /* not GLYPH_DEBUG */
2527
2528 #define CHECK_WINDOW_END(W) (void) 0
2529
2530 #endif /* not GLYPH_DEBUG */
2531
2532
2533 \f
2534 /***********************************************************************
2535 Iterator initialization
2536 ***********************************************************************/
2537
2538 /* Initialize IT for displaying current_buffer in window W, starting
2539 at character position CHARPOS. CHARPOS < 0 means that no buffer
2540 position is specified which is useful when the iterator is assigned
2541 a position later. BYTEPOS is the byte position corresponding to
2542 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2543
2544 If ROW is not null, calls to produce_glyphs with IT as parameter
2545 will produce glyphs in that row.
2546
2547 BASE_FACE_ID is the id of a base face to use. It must be one of
2548 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2549 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2550 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2551
2552 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2553 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2554 will be initialized to use the corresponding mode line glyph row of
2555 the desired matrix of W. */
2556
2557 void
2558 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2559 struct it *it;
2560 struct window *w;
2561 int charpos, bytepos;
2562 struct glyph_row *row;
2563 enum face_id base_face_id;
2564 {
2565 int highlight_region_p;
2566 enum face_id remapped_base_face_id = base_face_id;
2567
2568 /* Some precondition checks. */
2569 xassert (w != NULL && it != NULL);
2570 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2571 && charpos <= ZV));
2572
2573 /* If face attributes have been changed since the last redisplay,
2574 free realized faces now because they depend on face definitions
2575 that might have changed. Don't free faces while there might be
2576 desired matrices pending which reference these faces. */
2577 if (face_change_count && !inhibit_free_realized_faces)
2578 {
2579 face_change_count = 0;
2580 free_all_realized_faces (Qnil);
2581 }
2582
2583 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2584 if (! NILP (Vface_remapping_alist))
2585 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2586
2587 /* Use one of the mode line rows of W's desired matrix if
2588 appropriate. */
2589 if (row == NULL)
2590 {
2591 if (base_face_id == MODE_LINE_FACE_ID
2592 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2593 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2594 else if (base_face_id == HEADER_LINE_FACE_ID)
2595 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2596 }
2597
2598 /* Clear IT. */
2599 bzero (it, sizeof *it);
2600 it->current.overlay_string_index = -1;
2601 it->current.dpvec_index = -1;
2602 it->base_face_id = remapped_base_face_id;
2603 it->string = Qnil;
2604 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2605
2606 /* The window in which we iterate over current_buffer: */
2607 XSETWINDOW (it->window, w);
2608 it->w = w;
2609 it->f = XFRAME (w->frame);
2610
2611 it->cmp_it.id = -1;
2612
2613 /* Extra space between lines (on window systems only). */
2614 if (base_face_id == DEFAULT_FACE_ID
2615 && FRAME_WINDOW_P (it->f))
2616 {
2617 if (NATNUMP (current_buffer->extra_line_spacing))
2618 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2619 else if (FLOATP (current_buffer->extra_line_spacing))
2620 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2621 * FRAME_LINE_HEIGHT (it->f));
2622 else if (it->f->extra_line_spacing > 0)
2623 it->extra_line_spacing = it->f->extra_line_spacing;
2624 it->max_extra_line_spacing = 0;
2625 }
2626
2627 /* If realized faces have been removed, e.g. because of face
2628 attribute changes of named faces, recompute them. When running
2629 in batch mode, the face cache of the initial frame is null. If
2630 we happen to get called, make a dummy face cache. */
2631 if (FRAME_FACE_CACHE (it->f) == NULL)
2632 init_frame_faces (it->f);
2633 if (FRAME_FACE_CACHE (it->f)->used == 0)
2634 recompute_basic_faces (it->f);
2635
2636 /* Current value of the `slice', `space-width', and 'height' properties. */
2637 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2638 it->space_width = Qnil;
2639 it->font_height = Qnil;
2640 it->override_ascent = -1;
2641
2642 /* Are control characters displayed as `^C'? */
2643 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2644
2645 /* -1 means everything between a CR and the following line end
2646 is invisible. >0 means lines indented more than this value are
2647 invisible. */
2648 it->selective = (INTEGERP (current_buffer->selective_display)
2649 ? XFASTINT (current_buffer->selective_display)
2650 : (!NILP (current_buffer->selective_display)
2651 ? -1 : 0));
2652 it->selective_display_ellipsis_p
2653 = !NILP (current_buffer->selective_display_ellipses);
2654
2655 /* Display table to use. */
2656 it->dp = window_display_table (w);
2657
2658 /* Are multibyte characters enabled in current_buffer? */
2659 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2660
2661 /* Non-zero if we should highlight the region. */
2662 highlight_region_p
2663 = (!NILP (Vtransient_mark_mode)
2664 && !NILP (current_buffer->mark_active)
2665 && XMARKER (current_buffer->mark)->buffer != 0);
2666
2667 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2668 start and end of a visible region in window IT->w. Set both to
2669 -1 to indicate no region. */
2670 if (highlight_region_p
2671 /* Maybe highlight only in selected window. */
2672 && (/* Either show region everywhere. */
2673 highlight_nonselected_windows
2674 /* Or show region in the selected window. */
2675 || w == XWINDOW (selected_window)
2676 /* Or show the region if we are in the mini-buffer and W is
2677 the window the mini-buffer refers to. */
2678 || (MINI_WINDOW_P (XWINDOW (selected_window))
2679 && WINDOWP (minibuf_selected_window)
2680 && w == XWINDOW (minibuf_selected_window))))
2681 {
2682 int charpos = marker_position (current_buffer->mark);
2683 it->region_beg_charpos = min (PT, charpos);
2684 it->region_end_charpos = max (PT, charpos);
2685 }
2686 else
2687 it->region_beg_charpos = it->region_end_charpos = -1;
2688
2689 /* Get the position at which the redisplay_end_trigger hook should
2690 be run, if it is to be run at all. */
2691 if (MARKERP (w->redisplay_end_trigger)
2692 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2693 it->redisplay_end_trigger_charpos
2694 = marker_position (w->redisplay_end_trigger);
2695 else if (INTEGERP (w->redisplay_end_trigger))
2696 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2697
2698 /* Correct bogus values of tab_width. */
2699 it->tab_width = XINT (current_buffer->tab_width);
2700 if (it->tab_width <= 0 || it->tab_width > 1000)
2701 it->tab_width = 8;
2702
2703 /* Are lines in the display truncated? */
2704 if (base_face_id != DEFAULT_FACE_ID
2705 || XINT (it->w->hscroll)
2706 || (! WINDOW_FULL_WIDTH_P (it->w)
2707 && ((!NILP (Vtruncate_partial_width_windows)
2708 && !INTEGERP (Vtruncate_partial_width_windows))
2709 || (INTEGERP (Vtruncate_partial_width_windows)
2710 && (WINDOW_TOTAL_COLS (it->w)
2711 < XINT (Vtruncate_partial_width_windows))))))
2712 it->line_wrap = TRUNCATE;
2713 else if (NILP (current_buffer->truncate_lines))
2714 it->line_wrap = NILP (current_buffer->word_wrap)
2715 ? WINDOW_WRAP : WORD_WRAP;
2716 else
2717 it->line_wrap = TRUNCATE;
2718
2719 /* Get dimensions of truncation and continuation glyphs. These are
2720 displayed as fringe bitmaps under X, so we don't need them for such
2721 frames. */
2722 if (!FRAME_WINDOW_P (it->f))
2723 {
2724 if (it->line_wrap == TRUNCATE)
2725 {
2726 /* We will need the truncation glyph. */
2727 xassert (it->glyph_row == NULL);
2728 produce_special_glyphs (it, IT_TRUNCATION);
2729 it->truncation_pixel_width = it->pixel_width;
2730 }
2731 else
2732 {
2733 /* We will need the continuation glyph. */
2734 xassert (it->glyph_row == NULL);
2735 produce_special_glyphs (it, IT_CONTINUATION);
2736 it->continuation_pixel_width = it->pixel_width;
2737 }
2738
2739 /* Reset these values to zero because the produce_special_glyphs
2740 above has changed them. */
2741 it->pixel_width = it->ascent = it->descent = 0;
2742 it->phys_ascent = it->phys_descent = 0;
2743 }
2744
2745 /* Set this after getting the dimensions of truncation and
2746 continuation glyphs, so that we don't produce glyphs when calling
2747 produce_special_glyphs, above. */
2748 it->glyph_row = row;
2749 it->area = TEXT_AREA;
2750
2751 /* Get the dimensions of the display area. The display area
2752 consists of the visible window area plus a horizontally scrolled
2753 part to the left of the window. All x-values are relative to the
2754 start of this total display area. */
2755 if (base_face_id != DEFAULT_FACE_ID)
2756 {
2757 /* Mode lines, menu bar in terminal frames. */
2758 it->first_visible_x = 0;
2759 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2760 }
2761 else
2762 {
2763 it->first_visible_x
2764 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2765 it->last_visible_x = (it->first_visible_x
2766 + window_box_width (w, TEXT_AREA));
2767
2768 /* If we truncate lines, leave room for the truncator glyph(s) at
2769 the right margin. Otherwise, leave room for the continuation
2770 glyph(s). Truncation and continuation glyphs are not inserted
2771 for window-based redisplay. */
2772 if (!FRAME_WINDOW_P (it->f))
2773 {
2774 if (it->line_wrap == TRUNCATE)
2775 it->last_visible_x -= it->truncation_pixel_width;
2776 else
2777 it->last_visible_x -= it->continuation_pixel_width;
2778 }
2779
2780 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2781 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2782 }
2783
2784 /* Leave room for a border glyph. */
2785 if (!FRAME_WINDOW_P (it->f)
2786 && !WINDOW_RIGHTMOST_P (it->w))
2787 it->last_visible_x -= 1;
2788
2789 it->last_visible_y = window_text_bottom_y (w);
2790
2791 /* For mode lines and alike, arrange for the first glyph having a
2792 left box line if the face specifies a box. */
2793 if (base_face_id != DEFAULT_FACE_ID)
2794 {
2795 struct face *face;
2796
2797 it->face_id = remapped_base_face_id;
2798
2799 /* If we have a boxed mode line, make the first character appear
2800 with a left box line. */
2801 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2802 if (face->box != FACE_NO_BOX)
2803 it->start_of_box_run_p = 1;
2804 }
2805
2806 /* If a buffer position was specified, set the iterator there,
2807 getting overlays and face properties from that position. */
2808 if (charpos >= BUF_BEG (current_buffer))
2809 {
2810 it->end_charpos = ZV;
2811 it->face_id = -1;
2812 IT_CHARPOS (*it) = charpos;
2813
2814 /* Compute byte position if not specified. */
2815 if (bytepos < charpos)
2816 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2817 else
2818 IT_BYTEPOS (*it) = bytepos;
2819
2820 it->start = it->current;
2821
2822 /* Compute faces etc. */
2823 reseat (it, it->current.pos, 1);
2824 }
2825
2826 CHECK_IT (it);
2827 }
2828
2829
2830 /* Initialize IT for the display of window W with window start POS. */
2831
2832 void
2833 start_display (it, w, pos)
2834 struct it *it;
2835 struct window *w;
2836 struct text_pos pos;
2837 {
2838 struct glyph_row *row;
2839 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2840
2841 row = w->desired_matrix->rows + first_vpos;
2842 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2843 it->first_vpos = first_vpos;
2844
2845 /* Don't reseat to previous visible line start if current start
2846 position is in a string or image. */
2847 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2848 {
2849 int start_at_line_beg_p;
2850 int first_y = it->current_y;
2851
2852 /* If window start is not at a line start, skip forward to POS to
2853 get the correct continuation lines width. */
2854 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2855 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2856 if (!start_at_line_beg_p)
2857 {
2858 int new_x;
2859
2860 reseat_at_previous_visible_line_start (it);
2861 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2862
2863 new_x = it->current_x + it->pixel_width;
2864
2865 /* If lines are continued, this line may end in the middle
2866 of a multi-glyph character (e.g. a control character
2867 displayed as \003, or in the middle of an overlay
2868 string). In this case move_it_to above will not have
2869 taken us to the start of the continuation line but to the
2870 end of the continued line. */
2871 if (it->current_x > 0
2872 && it->line_wrap != TRUNCATE /* Lines are continued. */
2873 && (/* And glyph doesn't fit on the line. */
2874 new_x > it->last_visible_x
2875 /* Or it fits exactly and we're on a window
2876 system frame. */
2877 || (new_x == it->last_visible_x
2878 && FRAME_WINDOW_P (it->f))))
2879 {
2880 if (it->current.dpvec_index >= 0
2881 || it->current.overlay_string_index >= 0)
2882 {
2883 set_iterator_to_next (it, 1);
2884 move_it_in_display_line_to (it, -1, -1, 0);
2885 }
2886
2887 it->continuation_lines_width += it->current_x;
2888 }
2889
2890 /* We're starting a new display line, not affected by the
2891 height of the continued line, so clear the appropriate
2892 fields in the iterator structure. */
2893 it->max_ascent = it->max_descent = 0;
2894 it->max_phys_ascent = it->max_phys_descent = 0;
2895
2896 it->current_y = first_y;
2897 it->vpos = 0;
2898 it->current_x = it->hpos = 0;
2899 }
2900 }
2901 }
2902
2903
2904 /* Return 1 if POS is a position in ellipses displayed for invisible
2905 text. W is the window we display, for text property lookup. */
2906
2907 static int
2908 in_ellipses_for_invisible_text_p (pos, w)
2909 struct display_pos *pos;
2910 struct window *w;
2911 {
2912 Lisp_Object prop, window;
2913 int ellipses_p = 0;
2914 int charpos = CHARPOS (pos->pos);
2915
2916 /* If POS specifies a position in a display vector, this might
2917 be for an ellipsis displayed for invisible text. We won't
2918 get the iterator set up for delivering that ellipsis unless
2919 we make sure that it gets aware of the invisible text. */
2920 if (pos->dpvec_index >= 0
2921 && pos->overlay_string_index < 0
2922 && CHARPOS (pos->string_pos) < 0
2923 && charpos > BEGV
2924 && (XSETWINDOW (window, w),
2925 prop = Fget_char_property (make_number (charpos),
2926 Qinvisible, window),
2927 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2928 {
2929 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2930 window);
2931 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2932 }
2933
2934 return ellipses_p;
2935 }
2936
2937
2938 /* Initialize IT for stepping through current_buffer in window W,
2939 starting at position POS that includes overlay string and display
2940 vector/ control character translation position information. Value
2941 is zero if there are overlay strings with newlines at POS. */
2942
2943 static int
2944 init_from_display_pos (it, w, pos)
2945 struct it *it;
2946 struct window *w;
2947 struct display_pos *pos;
2948 {
2949 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2950 int i, overlay_strings_with_newlines = 0;
2951
2952 /* If POS specifies a position in a display vector, this might
2953 be for an ellipsis displayed for invisible text. We won't
2954 get the iterator set up for delivering that ellipsis unless
2955 we make sure that it gets aware of the invisible text. */
2956 if (in_ellipses_for_invisible_text_p (pos, w))
2957 {
2958 --charpos;
2959 bytepos = 0;
2960 }
2961
2962 /* Keep in mind: the call to reseat in init_iterator skips invisible
2963 text, so we might end up at a position different from POS. This
2964 is only a problem when POS is a row start after a newline and an
2965 overlay starts there with an after-string, and the overlay has an
2966 invisible property. Since we don't skip invisible text in
2967 display_line and elsewhere immediately after consuming the
2968 newline before the row start, such a POS will not be in a string,
2969 but the call to init_iterator below will move us to the
2970 after-string. */
2971 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2972
2973 /* This only scans the current chunk -- it should scan all chunks.
2974 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2975 to 16 in 22.1 to make this a lesser problem. */
2976 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2977 {
2978 const char *s = SDATA (it->overlay_strings[i]);
2979 const char *e = s + SBYTES (it->overlay_strings[i]);
2980
2981 while (s < e && *s != '\n')
2982 ++s;
2983
2984 if (s < e)
2985 {
2986 overlay_strings_with_newlines = 1;
2987 break;
2988 }
2989 }
2990
2991 /* If position is within an overlay string, set up IT to the right
2992 overlay string. */
2993 if (pos->overlay_string_index >= 0)
2994 {
2995 int relative_index;
2996
2997 /* If the first overlay string happens to have a `display'
2998 property for an image, the iterator will be set up for that
2999 image, and we have to undo that setup first before we can
3000 correct the overlay string index. */
3001 if (it->method == GET_FROM_IMAGE)
3002 pop_it (it);
3003
3004 /* We already have the first chunk of overlay strings in
3005 IT->overlay_strings. Load more until the one for
3006 pos->overlay_string_index is in IT->overlay_strings. */
3007 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3008 {
3009 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3010 it->current.overlay_string_index = 0;
3011 while (n--)
3012 {
3013 load_overlay_strings (it, 0);
3014 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3015 }
3016 }
3017
3018 it->current.overlay_string_index = pos->overlay_string_index;
3019 relative_index = (it->current.overlay_string_index
3020 % OVERLAY_STRING_CHUNK_SIZE);
3021 it->string = it->overlay_strings[relative_index];
3022 xassert (STRINGP (it->string));
3023 it->current.string_pos = pos->string_pos;
3024 it->method = GET_FROM_STRING;
3025 }
3026
3027 if (CHARPOS (pos->string_pos) >= 0)
3028 {
3029 /* Recorded position is not in an overlay string, but in another
3030 string. This can only be a string from a `display' property.
3031 IT should already be filled with that string. */
3032 it->current.string_pos = pos->string_pos;
3033 xassert (STRINGP (it->string));
3034 }
3035
3036 /* Restore position in display vector translations, control
3037 character translations or ellipses. */
3038 if (pos->dpvec_index >= 0)
3039 {
3040 if (it->dpvec == NULL)
3041 get_next_display_element (it);
3042 xassert (it->dpvec && it->current.dpvec_index == 0);
3043 it->current.dpvec_index = pos->dpvec_index;
3044 }
3045
3046 CHECK_IT (it);
3047 return !overlay_strings_with_newlines;
3048 }
3049
3050
3051 /* Initialize IT for stepping through current_buffer in window W
3052 starting at ROW->start. */
3053
3054 static void
3055 init_to_row_start (it, w, row)
3056 struct it *it;
3057 struct window *w;
3058 struct glyph_row *row;
3059 {
3060 init_from_display_pos (it, w, &row->start);
3061 it->start = row->start;
3062 it->continuation_lines_width = row->continuation_lines_width;
3063 CHECK_IT (it);
3064 }
3065
3066
3067 /* Initialize IT for stepping through current_buffer in window W
3068 starting in the line following ROW, i.e. starting at ROW->end.
3069 Value is zero if there are overlay strings with newlines at ROW's
3070 end position. */
3071
3072 static int
3073 init_to_row_end (it, w, row)
3074 struct it *it;
3075 struct window *w;
3076 struct glyph_row *row;
3077 {
3078 int success = 0;
3079
3080 if (init_from_display_pos (it, w, &row->end))
3081 {
3082 if (row->continued_p)
3083 it->continuation_lines_width
3084 = row->continuation_lines_width + row->pixel_width;
3085 CHECK_IT (it);
3086 success = 1;
3087 }
3088
3089 return success;
3090 }
3091
3092
3093
3094 \f
3095 /***********************************************************************
3096 Text properties
3097 ***********************************************************************/
3098
3099 /* Called when IT reaches IT->stop_charpos. Handle text property and
3100 overlay changes. Set IT->stop_charpos to the next position where
3101 to stop. */
3102
3103 static void
3104 handle_stop (it)
3105 struct it *it;
3106 {
3107 enum prop_handled handled;
3108 int handle_overlay_change_p;
3109 struct props *p;
3110
3111 it->dpvec = NULL;
3112 it->current.dpvec_index = -1;
3113 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3114 it->ignore_overlay_strings_at_pos_p = 0;
3115 it->ellipsis_p = 0;
3116
3117 /* Use face of preceding text for ellipsis (if invisible) */
3118 if (it->selective_display_ellipsis_p)
3119 it->saved_face_id = it->face_id;
3120
3121 do
3122 {
3123 handled = HANDLED_NORMALLY;
3124
3125 /* Call text property handlers. */
3126 for (p = it_props; p->handler; ++p)
3127 {
3128 handled = p->handler (it);
3129
3130 if (handled == HANDLED_RECOMPUTE_PROPS)
3131 break;
3132 else if (handled == HANDLED_RETURN)
3133 {
3134 /* We still want to show before and after strings from
3135 overlays even if the actual buffer text is replaced. */
3136 if (!handle_overlay_change_p
3137 || it->sp > 1
3138 || !get_overlay_strings_1 (it, 0, 0))
3139 {
3140 if (it->ellipsis_p)
3141 setup_for_ellipsis (it, 0);
3142 /* When handling a display spec, we might load an
3143 empty string. In that case, discard it here. We
3144 used to discard it in handle_single_display_spec,
3145 but that causes get_overlay_strings_1, above, to
3146 ignore overlay strings that we must check. */
3147 if (STRINGP (it->string) && !SCHARS (it->string))
3148 pop_it (it);
3149 return;
3150 }
3151 else if (STRINGP (it->string) && !SCHARS (it->string))
3152 pop_it (it);
3153 else
3154 {
3155 it->ignore_overlay_strings_at_pos_p = 1;
3156 it->string_from_display_prop_p = 0;
3157 handle_overlay_change_p = 0;
3158 }
3159 handled = HANDLED_RECOMPUTE_PROPS;
3160 break;
3161 }
3162 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3163 handle_overlay_change_p = 0;
3164 }
3165
3166 if (handled != HANDLED_RECOMPUTE_PROPS)
3167 {
3168 /* Don't check for overlay strings below when set to deliver
3169 characters from a display vector. */
3170 if (it->method == GET_FROM_DISPLAY_VECTOR)
3171 handle_overlay_change_p = 0;
3172
3173 /* Handle overlay changes.
3174 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3175 if it finds overlays. */
3176 if (handle_overlay_change_p)
3177 handled = handle_overlay_change (it);
3178 }
3179
3180 if (it->ellipsis_p)
3181 {
3182 setup_for_ellipsis (it, 0);
3183 break;
3184 }
3185 }
3186 while (handled == HANDLED_RECOMPUTE_PROPS);
3187
3188 /* Determine where to stop next. */
3189 if (handled == HANDLED_NORMALLY)
3190 compute_stop_pos (it);
3191 }
3192
3193
3194 /* Compute IT->stop_charpos from text property and overlay change
3195 information for IT's current position. */
3196
3197 static void
3198 compute_stop_pos (it)
3199 struct it *it;
3200 {
3201 register INTERVAL iv, next_iv;
3202 Lisp_Object object, limit, position;
3203 EMACS_INT charpos, bytepos;
3204
3205 /* If nowhere else, stop at the end. */
3206 it->stop_charpos = it->end_charpos;
3207
3208 if (STRINGP (it->string))
3209 {
3210 /* Strings are usually short, so don't limit the search for
3211 properties. */
3212 object = it->string;
3213 limit = Qnil;
3214 charpos = IT_STRING_CHARPOS (*it);
3215 bytepos = IT_STRING_BYTEPOS (*it);
3216 }
3217 else
3218 {
3219 EMACS_INT pos;
3220
3221 /* If next overlay change is in front of the current stop pos
3222 (which is IT->end_charpos), stop there. Note: value of
3223 next_overlay_change is point-max if no overlay change
3224 follows. */
3225 charpos = IT_CHARPOS (*it);
3226 bytepos = IT_BYTEPOS (*it);
3227 pos = next_overlay_change (charpos);
3228 if (pos < it->stop_charpos)
3229 it->stop_charpos = pos;
3230
3231 /* If showing the region, we have to stop at the region
3232 start or end because the face might change there. */
3233 if (it->region_beg_charpos > 0)
3234 {
3235 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3236 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3237 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3238 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3239 }
3240
3241 /* Set up variables for computing the stop position from text
3242 property changes. */
3243 XSETBUFFER (object, current_buffer);
3244 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3245 }
3246
3247 /* Get the interval containing IT's position. Value is a null
3248 interval if there isn't such an interval. */
3249 position = make_number (charpos);
3250 iv = validate_interval_range (object, &position, &position, 0);
3251 if (!NULL_INTERVAL_P (iv))
3252 {
3253 Lisp_Object values_here[LAST_PROP_IDX];
3254 struct props *p;
3255
3256 /* Get properties here. */
3257 for (p = it_props; p->handler; ++p)
3258 values_here[p->idx] = textget (iv->plist, *p->name);
3259
3260 /* Look for an interval following iv that has different
3261 properties. */
3262 for (next_iv = next_interval (iv);
3263 (!NULL_INTERVAL_P (next_iv)
3264 && (NILP (limit)
3265 || XFASTINT (limit) > next_iv->position));
3266 next_iv = next_interval (next_iv))
3267 {
3268 for (p = it_props; p->handler; ++p)
3269 {
3270 Lisp_Object new_value;
3271
3272 new_value = textget (next_iv->plist, *p->name);
3273 if (!EQ (values_here[p->idx], new_value))
3274 break;
3275 }
3276
3277 if (p->handler)
3278 break;
3279 }
3280
3281 if (!NULL_INTERVAL_P (next_iv))
3282 {
3283 if (INTEGERP (limit)
3284 && next_iv->position >= XFASTINT (limit))
3285 /* No text property change up to limit. */
3286 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3287 else
3288 /* Text properties change in next_iv. */
3289 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3290 }
3291 }
3292
3293 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3294 it->stop_charpos, it->string);
3295
3296 xassert (STRINGP (it->string)
3297 || (it->stop_charpos >= BEGV
3298 && it->stop_charpos >= IT_CHARPOS (*it)));
3299 }
3300
3301
3302 /* Return the position of the next overlay change after POS in
3303 current_buffer. Value is point-max if no overlay change
3304 follows. This is like `next-overlay-change' but doesn't use
3305 xmalloc. */
3306
3307 static EMACS_INT
3308 next_overlay_change (pos)
3309 EMACS_INT pos;
3310 {
3311 int noverlays;
3312 EMACS_INT endpos;
3313 Lisp_Object *overlays;
3314 int i;
3315
3316 /* Get all overlays at the given position. */
3317 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3318
3319 /* If any of these overlays ends before endpos,
3320 use its ending point instead. */
3321 for (i = 0; i < noverlays; ++i)
3322 {
3323 Lisp_Object oend;
3324 EMACS_INT oendpos;
3325
3326 oend = OVERLAY_END (overlays[i]);
3327 oendpos = OVERLAY_POSITION (oend);
3328 endpos = min (endpos, oendpos);
3329 }
3330
3331 return endpos;
3332 }
3333
3334
3335 \f
3336 /***********************************************************************
3337 Fontification
3338 ***********************************************************************/
3339
3340 /* Handle changes in the `fontified' property of the current buffer by
3341 calling hook functions from Qfontification_functions to fontify
3342 regions of text. */
3343
3344 static enum prop_handled
3345 handle_fontified_prop (it)
3346 struct it *it;
3347 {
3348 Lisp_Object prop, pos;
3349 enum prop_handled handled = HANDLED_NORMALLY;
3350
3351 if (!NILP (Vmemory_full))
3352 return handled;
3353
3354 /* Get the value of the `fontified' property at IT's current buffer
3355 position. (The `fontified' property doesn't have a special
3356 meaning in strings.) If the value is nil, call functions from
3357 Qfontification_functions. */
3358 if (!STRINGP (it->string)
3359 && it->s == NULL
3360 && !NILP (Vfontification_functions)
3361 && !NILP (Vrun_hooks)
3362 && (pos = make_number (IT_CHARPOS (*it)),
3363 prop = Fget_char_property (pos, Qfontified, Qnil),
3364 /* Ignore the special cased nil value always present at EOB since
3365 no amount of fontifying will be able to change it. */
3366 NILP (prop) && IT_CHARPOS (*it) < Z))
3367 {
3368 int count = SPECPDL_INDEX ();
3369 Lisp_Object val;
3370
3371 val = Vfontification_functions;
3372 specbind (Qfontification_functions, Qnil);
3373
3374 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3375 safe_call1 (val, pos);
3376 else
3377 {
3378 Lisp_Object globals, fn;
3379 struct gcpro gcpro1, gcpro2;
3380
3381 globals = Qnil;
3382 GCPRO2 (val, globals);
3383
3384 for (; CONSP (val); val = XCDR (val))
3385 {
3386 fn = XCAR (val);
3387
3388 if (EQ (fn, Qt))
3389 {
3390 /* A value of t indicates this hook has a local
3391 binding; it means to run the global binding too.
3392 In a global value, t should not occur. If it
3393 does, we must ignore it to avoid an endless
3394 loop. */
3395 for (globals = Fdefault_value (Qfontification_functions);
3396 CONSP (globals);
3397 globals = XCDR (globals))
3398 {
3399 fn = XCAR (globals);
3400 if (!EQ (fn, Qt))
3401 safe_call1 (fn, pos);
3402 }
3403 }
3404 else
3405 safe_call1 (fn, pos);
3406 }
3407
3408 UNGCPRO;
3409 }
3410
3411 unbind_to (count, Qnil);
3412
3413 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3414 something. This avoids an endless loop if they failed to
3415 fontify the text for which reason ever. */
3416 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3417 handled = HANDLED_RECOMPUTE_PROPS;
3418 }
3419
3420 return handled;
3421 }
3422
3423
3424 \f
3425 /***********************************************************************
3426 Faces
3427 ***********************************************************************/
3428
3429 /* Set up iterator IT from face properties at its current position.
3430 Called from handle_stop. */
3431
3432 static enum prop_handled
3433 handle_face_prop (it)
3434 struct it *it;
3435 {
3436 int new_face_id;
3437 EMACS_INT next_stop;
3438
3439 if (!STRINGP (it->string))
3440 {
3441 new_face_id
3442 = face_at_buffer_position (it->w,
3443 IT_CHARPOS (*it),
3444 it->region_beg_charpos,
3445 it->region_end_charpos,
3446 &next_stop,
3447 (IT_CHARPOS (*it)
3448 + TEXT_PROP_DISTANCE_LIMIT),
3449 0, it->base_face_id);
3450
3451 /* Is this a start of a run of characters with box face?
3452 Caveat: this can be called for a freshly initialized
3453 iterator; face_id is -1 in this case. We know that the new
3454 face will not change until limit, i.e. if the new face has a
3455 box, all characters up to limit will have one. But, as
3456 usual, we don't know whether limit is really the end. */
3457 if (new_face_id != it->face_id)
3458 {
3459 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3460
3461 /* If new face has a box but old face has not, this is
3462 the start of a run of characters with box, i.e. it has
3463 a shadow on the left side. The value of face_id of the
3464 iterator will be -1 if this is the initial call that gets
3465 the face. In this case, we have to look in front of IT's
3466 position and see whether there is a face != new_face_id. */
3467 it->start_of_box_run_p
3468 = (new_face->box != FACE_NO_BOX
3469 && (it->face_id >= 0
3470 || IT_CHARPOS (*it) == BEG
3471 || new_face_id != face_before_it_pos (it)));
3472 it->face_box_p = new_face->box != FACE_NO_BOX;
3473 }
3474 }
3475 else
3476 {
3477 int base_face_id, bufpos;
3478 int i;
3479 Lisp_Object from_overlay
3480 = (it->current.overlay_string_index >= 0
3481 ? it->string_overlays[it->current.overlay_string_index]
3482 : Qnil);
3483
3484 /* See if we got to this string directly or indirectly from
3485 an overlay property. That includes the before-string or
3486 after-string of an overlay, strings in display properties
3487 provided by an overlay, their text properties, etc.
3488
3489 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3490 if (! NILP (from_overlay))
3491 for (i = it->sp - 1; i >= 0; i--)
3492 {
3493 if (it->stack[i].current.overlay_string_index >= 0)
3494 from_overlay
3495 = it->string_overlays[it->stack[i].current.overlay_string_index];
3496 else if (! NILP (it->stack[i].from_overlay))
3497 from_overlay = it->stack[i].from_overlay;
3498
3499 if (!NILP (from_overlay))
3500 break;
3501 }
3502
3503 if (! NILP (from_overlay))
3504 {
3505 bufpos = IT_CHARPOS (*it);
3506 /* For a string from an overlay, the base face depends
3507 only on text properties and ignores overlays. */
3508 base_face_id
3509 = face_for_overlay_string (it->w,
3510 IT_CHARPOS (*it),
3511 it->region_beg_charpos,
3512 it->region_end_charpos,
3513 &next_stop,
3514 (IT_CHARPOS (*it)
3515 + TEXT_PROP_DISTANCE_LIMIT),
3516 0,
3517 from_overlay);
3518 }
3519 else
3520 {
3521 bufpos = 0;
3522
3523 /* For strings from a `display' property, use the face at
3524 IT's current buffer position as the base face to merge
3525 with, so that overlay strings appear in the same face as
3526 surrounding text, unless they specify their own
3527 faces. */
3528 base_face_id = underlying_face_id (it);
3529 }
3530
3531 new_face_id = face_at_string_position (it->w,
3532 it->string,
3533 IT_STRING_CHARPOS (*it),
3534 bufpos,
3535 it->region_beg_charpos,
3536 it->region_end_charpos,
3537 &next_stop,
3538 base_face_id, 0);
3539
3540 /* Is this a start of a run of characters with box? Caveat:
3541 this can be called for a freshly allocated iterator; face_id
3542 is -1 is this case. We know that the new face will not
3543 change until the next check pos, i.e. if the new face has a
3544 box, all characters up to that position will have a
3545 box. But, as usual, we don't know whether that position
3546 is really the end. */
3547 if (new_face_id != it->face_id)
3548 {
3549 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3550 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3551
3552 /* If new face has a box but old face hasn't, this is the
3553 start of a run of characters with box, i.e. it has a
3554 shadow on the left side. */
3555 it->start_of_box_run_p
3556 = new_face->box && (old_face == NULL || !old_face->box);
3557 it->face_box_p = new_face->box != FACE_NO_BOX;
3558 }
3559 }
3560
3561 it->face_id = new_face_id;
3562 return HANDLED_NORMALLY;
3563 }
3564
3565
3566 /* Return the ID of the face ``underlying'' IT's current position,
3567 which is in a string. If the iterator is associated with a
3568 buffer, return the face at IT's current buffer position.
3569 Otherwise, use the iterator's base_face_id. */
3570
3571 static int
3572 underlying_face_id (it)
3573 struct it *it;
3574 {
3575 int face_id = it->base_face_id, i;
3576
3577 xassert (STRINGP (it->string));
3578
3579 for (i = it->sp - 1; i >= 0; --i)
3580 if (NILP (it->stack[i].string))
3581 face_id = it->stack[i].face_id;
3582
3583 return face_id;
3584 }
3585
3586
3587 /* Compute the face one character before or after the current position
3588 of IT. BEFORE_P non-zero means get the face in front of IT's
3589 position. Value is the id of the face. */
3590
3591 static int
3592 face_before_or_after_it_pos (it, before_p)
3593 struct it *it;
3594 int before_p;
3595 {
3596 int face_id, limit;
3597 EMACS_INT next_check_charpos;
3598 struct text_pos pos;
3599
3600 xassert (it->s == NULL);
3601
3602 if (STRINGP (it->string))
3603 {
3604 int bufpos, base_face_id;
3605
3606 /* No face change past the end of the string (for the case
3607 we are padding with spaces). No face change before the
3608 string start. */
3609 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3610 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3611 return it->face_id;
3612
3613 /* Set pos to the position before or after IT's current position. */
3614 if (before_p)
3615 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3616 else
3617 /* For composition, we must check the character after the
3618 composition. */
3619 pos = (it->what == IT_COMPOSITION
3620 ? string_pos (IT_STRING_CHARPOS (*it)
3621 + it->cmp_it.nchars, it->string)
3622 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3623
3624 if (it->current.overlay_string_index >= 0)
3625 bufpos = IT_CHARPOS (*it);
3626 else
3627 bufpos = 0;
3628
3629 base_face_id = underlying_face_id (it);
3630
3631 /* Get the face for ASCII, or unibyte. */
3632 face_id = face_at_string_position (it->w,
3633 it->string,
3634 CHARPOS (pos),
3635 bufpos,
3636 it->region_beg_charpos,
3637 it->region_end_charpos,
3638 &next_check_charpos,
3639 base_face_id, 0);
3640
3641 /* Correct the face for charsets different from ASCII. Do it
3642 for the multibyte case only. The face returned above is
3643 suitable for unibyte text if IT->string is unibyte. */
3644 if (STRING_MULTIBYTE (it->string))
3645 {
3646 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3647 int rest = SBYTES (it->string) - BYTEPOS (pos);
3648 int c, len;
3649 struct face *face = FACE_FROM_ID (it->f, face_id);
3650
3651 c = string_char_and_length (p, rest, &len);
3652 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3653 }
3654 }
3655 else
3656 {
3657 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3658 || (IT_CHARPOS (*it) <= BEGV && before_p))
3659 return it->face_id;
3660
3661 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3662 pos = it->current.pos;
3663
3664 if (before_p)
3665 DEC_TEXT_POS (pos, it->multibyte_p);
3666 else
3667 {
3668 if (it->what == IT_COMPOSITION)
3669 /* For composition, we must check the position after the
3670 composition. */
3671 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3672 else
3673 INC_TEXT_POS (pos, it->multibyte_p);
3674 }
3675
3676 /* Determine face for CHARSET_ASCII, or unibyte. */
3677 face_id = face_at_buffer_position (it->w,
3678 CHARPOS (pos),
3679 it->region_beg_charpos,
3680 it->region_end_charpos,
3681 &next_check_charpos,
3682 limit, 0, -1);
3683
3684 /* Correct the face for charsets different from ASCII. Do it
3685 for the multibyte case only. The face returned above is
3686 suitable for unibyte text if current_buffer is unibyte. */
3687 if (it->multibyte_p)
3688 {
3689 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3690 struct face *face = FACE_FROM_ID (it->f, face_id);
3691 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3692 }
3693 }
3694
3695 return face_id;
3696 }
3697
3698
3699 \f
3700 /***********************************************************************
3701 Invisible text
3702 ***********************************************************************/
3703
3704 /* Set up iterator IT from invisible properties at its current
3705 position. Called from handle_stop. */
3706
3707 static enum prop_handled
3708 handle_invisible_prop (it)
3709 struct it *it;
3710 {
3711 enum prop_handled handled = HANDLED_NORMALLY;
3712
3713 if (STRINGP (it->string))
3714 {
3715 extern Lisp_Object Qinvisible;
3716 Lisp_Object prop, end_charpos, limit, charpos;
3717
3718 /* Get the value of the invisible text property at the
3719 current position. Value will be nil if there is no such
3720 property. */
3721 charpos = make_number (IT_STRING_CHARPOS (*it));
3722 prop = Fget_text_property (charpos, Qinvisible, it->string);
3723
3724 if (!NILP (prop)
3725 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3726 {
3727 handled = HANDLED_RECOMPUTE_PROPS;
3728
3729 /* Get the position at which the next change of the
3730 invisible text property can be found in IT->string.
3731 Value will be nil if the property value is the same for
3732 all the rest of IT->string. */
3733 XSETINT (limit, SCHARS (it->string));
3734 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3735 it->string, limit);
3736
3737 /* Text at current position is invisible. The next
3738 change in the property is at position end_charpos.
3739 Move IT's current position to that position. */
3740 if (INTEGERP (end_charpos)
3741 && XFASTINT (end_charpos) < XFASTINT (limit))
3742 {
3743 struct text_pos old;
3744 old = it->current.string_pos;
3745 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3746 compute_string_pos (&it->current.string_pos, old, it->string);
3747 }
3748 else
3749 {
3750 /* The rest of the string is invisible. If this is an
3751 overlay string, proceed with the next overlay string
3752 or whatever comes and return a character from there. */
3753 if (it->current.overlay_string_index >= 0)
3754 {
3755 next_overlay_string (it);
3756 /* Don't check for overlay strings when we just
3757 finished processing them. */
3758 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3759 }
3760 else
3761 {
3762 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3763 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3764 }
3765 }
3766 }
3767 }
3768 else
3769 {
3770 int invis_p;
3771 EMACS_INT newpos, next_stop, start_charpos;
3772 Lisp_Object pos, prop, overlay;
3773
3774 /* First of all, is there invisible text at this position? */
3775 start_charpos = IT_CHARPOS (*it);
3776 pos = make_number (IT_CHARPOS (*it));
3777 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3778 &overlay);
3779 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3780
3781 /* If we are on invisible text, skip over it. */
3782 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3783 {
3784 /* Record whether we have to display an ellipsis for the
3785 invisible text. */
3786 int display_ellipsis_p = invis_p == 2;
3787
3788 handled = HANDLED_RECOMPUTE_PROPS;
3789
3790 /* Loop skipping over invisible text. The loop is left at
3791 ZV or with IT on the first char being visible again. */
3792 do
3793 {
3794 /* Try to skip some invisible text. Return value is the
3795 position reached which can be equal to IT's position
3796 if there is nothing invisible here. This skips both
3797 over invisible text properties and overlays with
3798 invisible property. */
3799 newpos = skip_invisible (IT_CHARPOS (*it),
3800 &next_stop, ZV, it->window);
3801
3802 /* If we skipped nothing at all we weren't at invisible
3803 text in the first place. If everything to the end of
3804 the buffer was skipped, end the loop. */
3805 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3806 invis_p = 0;
3807 else
3808 {
3809 /* We skipped some characters but not necessarily
3810 all there are. Check if we ended up on visible
3811 text. Fget_char_property returns the property of
3812 the char before the given position, i.e. if we
3813 get invis_p = 0, this means that the char at
3814 newpos is visible. */
3815 pos = make_number (newpos);
3816 prop = Fget_char_property (pos, Qinvisible, it->window);
3817 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3818 }
3819
3820 /* If we ended up on invisible text, proceed to
3821 skip starting with next_stop. */
3822 if (invis_p)
3823 IT_CHARPOS (*it) = next_stop;
3824
3825 /* If there are adjacent invisible texts, don't lose the
3826 second one's ellipsis. */
3827 if (invis_p == 2)
3828 display_ellipsis_p = 1;
3829 }
3830 while (invis_p);
3831
3832 /* The position newpos is now either ZV or on visible text. */
3833 IT_CHARPOS (*it) = newpos;
3834 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3835
3836 /* If there are before-strings at the start of invisible
3837 text, and the text is invisible because of a text
3838 property, arrange to show before-strings because 20.x did
3839 it that way. (If the text is invisible because of an
3840 overlay property instead of a text property, this is
3841 already handled in the overlay code.) */
3842 if (NILP (overlay)
3843 && get_overlay_strings (it, start_charpos))
3844 {
3845 handled = HANDLED_RECOMPUTE_PROPS;
3846 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3847 }
3848 else if (display_ellipsis_p)
3849 {
3850 /* Make sure that the glyphs of the ellipsis will get
3851 correct `charpos' values. If we would not update
3852 it->position here, the glyphs would belong to the
3853 last visible character _before_ the invisible
3854 text, which confuses `set_cursor_from_row'.
3855
3856 We use the last invisible position instead of the
3857 first because this way the cursor is always drawn on
3858 the first "." of the ellipsis, whenever PT is inside
3859 the invisible text. Otherwise the cursor would be
3860 placed _after_ the ellipsis when the point is after the
3861 first invisible character. */
3862 if (!STRINGP (it->object))
3863 {
3864 it->position.charpos = IT_CHARPOS (*it) - 1;
3865 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3866 }
3867 it->ellipsis_p = 1;
3868 /* Let the ellipsis display before
3869 considering any properties of the following char.
3870 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3871 handled = HANDLED_RETURN;
3872 }
3873 }
3874 }
3875
3876 return handled;
3877 }
3878
3879
3880 /* Make iterator IT return `...' next.
3881 Replaces LEN characters from buffer. */
3882
3883 static void
3884 setup_for_ellipsis (it, len)
3885 struct it *it;
3886 int len;
3887 {
3888 /* Use the display table definition for `...'. Invalid glyphs
3889 will be handled by the method returning elements from dpvec. */
3890 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3891 {
3892 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3893 it->dpvec = v->contents;
3894 it->dpend = v->contents + v->size;
3895 }
3896 else
3897 {
3898 /* Default `...'. */
3899 it->dpvec = default_invis_vector;
3900 it->dpend = default_invis_vector + 3;
3901 }
3902
3903 it->dpvec_char_len = len;
3904 it->current.dpvec_index = 0;
3905 it->dpvec_face_id = -1;
3906
3907 /* Remember the current face id in case glyphs specify faces.
3908 IT's face is restored in set_iterator_to_next.
3909 saved_face_id was set to preceding char's face in handle_stop. */
3910 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3911 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3912
3913 it->method = GET_FROM_DISPLAY_VECTOR;
3914 it->ellipsis_p = 1;
3915 }
3916
3917
3918 \f
3919 /***********************************************************************
3920 'display' property
3921 ***********************************************************************/
3922
3923 /* Set up iterator IT from `display' property at its current position.
3924 Called from handle_stop.
3925 We return HANDLED_RETURN if some part of the display property
3926 overrides the display of the buffer text itself.
3927 Otherwise we return HANDLED_NORMALLY. */
3928
3929 static enum prop_handled
3930 handle_display_prop (it)
3931 struct it *it;
3932 {
3933 Lisp_Object prop, object, overlay;
3934 struct text_pos *position;
3935 /* Nonzero if some property replaces the display of the text itself. */
3936 int display_replaced_p = 0;
3937
3938 if (STRINGP (it->string))
3939 {
3940 object = it->string;
3941 position = &it->current.string_pos;
3942 }
3943 else
3944 {
3945 XSETWINDOW (object, it->w);
3946 position = &it->current.pos;
3947 }
3948
3949 /* Reset those iterator values set from display property values. */
3950 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3951 it->space_width = Qnil;
3952 it->font_height = Qnil;
3953 it->voffset = 0;
3954
3955 /* We don't support recursive `display' properties, i.e. string
3956 values that have a string `display' property, that have a string
3957 `display' property etc. */
3958 if (!it->string_from_display_prop_p)
3959 it->area = TEXT_AREA;
3960
3961 prop = get_char_property_and_overlay (make_number (position->charpos),
3962 Qdisplay, object, &overlay);
3963 if (NILP (prop))
3964 return HANDLED_NORMALLY;
3965 /* Now OVERLAY is the overlay that gave us this property, or nil
3966 if it was a text property. */
3967
3968 if (!STRINGP (it->string))
3969 object = it->w->buffer;
3970
3971 if (CONSP (prop)
3972 /* Simple properties. */
3973 && !EQ (XCAR (prop), Qimage)
3974 && !EQ (XCAR (prop), Qspace)
3975 && !EQ (XCAR (prop), Qwhen)
3976 && !EQ (XCAR (prop), Qslice)
3977 && !EQ (XCAR (prop), Qspace_width)
3978 && !EQ (XCAR (prop), Qheight)
3979 && !EQ (XCAR (prop), Qraise)
3980 /* Marginal area specifications. */
3981 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3982 && !EQ (XCAR (prop), Qleft_fringe)
3983 && !EQ (XCAR (prop), Qright_fringe)
3984 && !NILP (XCAR (prop)))
3985 {
3986 for (; CONSP (prop); prop = XCDR (prop))
3987 {
3988 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3989 position, display_replaced_p))
3990 {
3991 display_replaced_p = 1;
3992 /* If some text in a string is replaced, `position' no
3993 longer points to the position of `object'. */
3994 if (STRINGP (object))
3995 break;
3996 }
3997 }
3998 }
3999 else if (VECTORP (prop))
4000 {
4001 int i;
4002 for (i = 0; i < ASIZE (prop); ++i)
4003 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4004 position, display_replaced_p))
4005 {
4006 display_replaced_p = 1;
4007 /* If some text in a string is replaced, `position' no
4008 longer points to the position of `object'. */
4009 if (STRINGP (object))
4010 break;
4011 }
4012 }
4013 else
4014 {
4015 if (handle_single_display_spec (it, prop, object, overlay,
4016 position, 0))
4017 display_replaced_p = 1;
4018 }
4019
4020 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4021 }
4022
4023
4024 /* Value is the position of the end of the `display' property starting
4025 at START_POS in OBJECT. */
4026
4027 static struct text_pos
4028 display_prop_end (it, object, start_pos)
4029 struct it *it;
4030 Lisp_Object object;
4031 struct text_pos start_pos;
4032 {
4033 Lisp_Object end;
4034 struct text_pos end_pos;
4035
4036 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4037 Qdisplay, object, Qnil);
4038 CHARPOS (end_pos) = XFASTINT (end);
4039 if (STRINGP (object))
4040 compute_string_pos (&end_pos, start_pos, it->string);
4041 else
4042 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4043
4044 return end_pos;
4045 }
4046
4047
4048 /* Set up IT from a single `display' specification PROP. OBJECT
4049 is the object in which the `display' property was found. *POSITION
4050 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4051 means that we previously saw a display specification which already
4052 replaced text display with something else, for example an image;
4053 we ignore such properties after the first one has been processed.
4054
4055 OVERLAY is the overlay this `display' property came from,
4056 or nil if it was a text property.
4057
4058 If PROP is a `space' or `image' specification, and in some other
4059 cases too, set *POSITION to the position where the `display'
4060 property ends.
4061
4062 Value is non-zero if something was found which replaces the display
4063 of buffer or string text. */
4064
4065 static int
4066 handle_single_display_spec (it, spec, object, overlay, position,
4067 display_replaced_before_p)
4068 struct it *it;
4069 Lisp_Object spec;
4070 Lisp_Object object;
4071 Lisp_Object overlay;
4072 struct text_pos *position;
4073 int display_replaced_before_p;
4074 {
4075 Lisp_Object form;
4076 Lisp_Object location, value;
4077 struct text_pos start_pos, save_pos;
4078 int valid_p;
4079
4080 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4081 If the result is non-nil, use VALUE instead of SPEC. */
4082 form = Qt;
4083 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4084 {
4085 spec = XCDR (spec);
4086 if (!CONSP (spec))
4087 return 0;
4088 form = XCAR (spec);
4089 spec = XCDR (spec);
4090 }
4091
4092 if (!NILP (form) && !EQ (form, Qt))
4093 {
4094 int count = SPECPDL_INDEX ();
4095 struct gcpro gcpro1;
4096
4097 /* Bind `object' to the object having the `display' property, a
4098 buffer or string. Bind `position' to the position in the
4099 object where the property was found, and `buffer-position'
4100 to the current position in the buffer. */
4101 specbind (Qobject, object);
4102 specbind (Qposition, make_number (CHARPOS (*position)));
4103 specbind (Qbuffer_position,
4104 make_number (STRINGP (object)
4105 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4106 GCPRO1 (form);
4107 form = safe_eval (form);
4108 UNGCPRO;
4109 unbind_to (count, Qnil);
4110 }
4111
4112 if (NILP (form))
4113 return 0;
4114
4115 /* Handle `(height HEIGHT)' specifications. */
4116 if (CONSP (spec)
4117 && EQ (XCAR (spec), Qheight)
4118 && CONSP (XCDR (spec)))
4119 {
4120 if (!FRAME_WINDOW_P (it->f))
4121 return 0;
4122
4123 it->font_height = XCAR (XCDR (spec));
4124 if (!NILP (it->font_height))
4125 {
4126 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4127 int new_height = -1;
4128
4129 if (CONSP (it->font_height)
4130 && (EQ (XCAR (it->font_height), Qplus)
4131 || EQ (XCAR (it->font_height), Qminus))
4132 && CONSP (XCDR (it->font_height))
4133 && INTEGERP (XCAR (XCDR (it->font_height))))
4134 {
4135 /* `(+ N)' or `(- N)' where N is an integer. */
4136 int steps = XINT (XCAR (XCDR (it->font_height)));
4137 if (EQ (XCAR (it->font_height), Qplus))
4138 steps = - steps;
4139 it->face_id = smaller_face (it->f, it->face_id, steps);
4140 }
4141 else if (FUNCTIONP (it->font_height))
4142 {
4143 /* Call function with current height as argument.
4144 Value is the new height. */
4145 Lisp_Object height;
4146 height = safe_call1 (it->font_height,
4147 face->lface[LFACE_HEIGHT_INDEX]);
4148 if (NUMBERP (height))
4149 new_height = XFLOATINT (height);
4150 }
4151 else if (NUMBERP (it->font_height))
4152 {
4153 /* Value is a multiple of the canonical char height. */
4154 struct face *face;
4155
4156 face = FACE_FROM_ID (it->f,
4157 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4158 new_height = (XFLOATINT (it->font_height)
4159 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4160 }
4161 else
4162 {
4163 /* Evaluate IT->font_height with `height' bound to the
4164 current specified height to get the new height. */
4165 int count = SPECPDL_INDEX ();
4166
4167 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4168 value = safe_eval (it->font_height);
4169 unbind_to (count, Qnil);
4170
4171 if (NUMBERP (value))
4172 new_height = XFLOATINT (value);
4173 }
4174
4175 if (new_height > 0)
4176 it->face_id = face_with_height (it->f, it->face_id, new_height);
4177 }
4178
4179 return 0;
4180 }
4181
4182 /* Handle `(space-width WIDTH)'. */
4183 if (CONSP (spec)
4184 && EQ (XCAR (spec), Qspace_width)
4185 && CONSP (XCDR (spec)))
4186 {
4187 if (!FRAME_WINDOW_P (it->f))
4188 return 0;
4189
4190 value = XCAR (XCDR (spec));
4191 if (NUMBERP (value) && XFLOATINT (value) > 0)
4192 it->space_width = value;
4193
4194 return 0;
4195 }
4196
4197 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4198 if (CONSP (spec)
4199 && EQ (XCAR (spec), Qslice))
4200 {
4201 Lisp_Object tem;
4202
4203 if (!FRAME_WINDOW_P (it->f))
4204 return 0;
4205
4206 if (tem = XCDR (spec), CONSP (tem))
4207 {
4208 it->slice.x = XCAR (tem);
4209 if (tem = XCDR (tem), CONSP (tem))
4210 {
4211 it->slice.y = XCAR (tem);
4212 if (tem = XCDR (tem), CONSP (tem))
4213 {
4214 it->slice.width = XCAR (tem);
4215 if (tem = XCDR (tem), CONSP (tem))
4216 it->slice.height = XCAR (tem);
4217 }
4218 }
4219 }
4220
4221 return 0;
4222 }
4223
4224 /* Handle `(raise FACTOR)'. */
4225 if (CONSP (spec)
4226 && EQ (XCAR (spec), Qraise)
4227 && CONSP (XCDR (spec)))
4228 {
4229 if (!FRAME_WINDOW_P (it->f))
4230 return 0;
4231
4232 #ifdef HAVE_WINDOW_SYSTEM
4233 value = XCAR (XCDR (spec));
4234 if (NUMBERP (value))
4235 {
4236 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4237 it->voffset = - (XFLOATINT (value)
4238 * (FONT_HEIGHT (face->font)));
4239 }
4240 #endif /* HAVE_WINDOW_SYSTEM */
4241
4242 return 0;
4243 }
4244
4245 /* Don't handle the other kinds of display specifications
4246 inside a string that we got from a `display' property. */
4247 if (it->string_from_display_prop_p)
4248 return 0;
4249
4250 /* Characters having this form of property are not displayed, so
4251 we have to find the end of the property. */
4252 start_pos = *position;
4253 *position = display_prop_end (it, object, start_pos);
4254 value = Qnil;
4255
4256 /* Stop the scan at that end position--we assume that all
4257 text properties change there. */
4258 it->stop_charpos = position->charpos;
4259
4260 /* Handle `(left-fringe BITMAP [FACE])'
4261 and `(right-fringe BITMAP [FACE])'. */
4262 if (CONSP (spec)
4263 && (EQ (XCAR (spec), Qleft_fringe)
4264 || EQ (XCAR (spec), Qright_fringe))
4265 && CONSP (XCDR (spec)))
4266 {
4267 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4268 int fringe_bitmap;
4269
4270 if (!FRAME_WINDOW_P (it->f))
4271 /* If we return here, POSITION has been advanced
4272 across the text with this property. */
4273 return 0;
4274
4275 #ifdef HAVE_WINDOW_SYSTEM
4276 value = XCAR (XCDR (spec));
4277 if (!SYMBOLP (value)
4278 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4279 /* If we return here, POSITION has been advanced
4280 across the text with this property. */
4281 return 0;
4282
4283 if (CONSP (XCDR (XCDR (spec))))
4284 {
4285 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4286 int face_id2 = lookup_derived_face (it->f, face_name,
4287 FRINGE_FACE_ID, 0);
4288 if (face_id2 >= 0)
4289 face_id = face_id2;
4290 }
4291
4292 /* Save current settings of IT so that we can restore them
4293 when we are finished with the glyph property value. */
4294
4295 save_pos = it->position;
4296 it->position = *position;
4297 push_it (it);
4298 it->position = save_pos;
4299
4300 it->area = TEXT_AREA;
4301 it->what = IT_IMAGE;
4302 it->image_id = -1; /* no image */
4303 it->position = start_pos;
4304 it->object = NILP (object) ? it->w->buffer : object;
4305 it->method = GET_FROM_IMAGE;
4306 it->from_overlay = Qnil;
4307 it->face_id = face_id;
4308
4309 /* Say that we haven't consumed the characters with
4310 `display' property yet. The call to pop_it in
4311 set_iterator_to_next will clean this up. */
4312 *position = start_pos;
4313
4314 if (EQ (XCAR (spec), Qleft_fringe))
4315 {
4316 it->left_user_fringe_bitmap = fringe_bitmap;
4317 it->left_user_fringe_face_id = face_id;
4318 }
4319 else
4320 {
4321 it->right_user_fringe_bitmap = fringe_bitmap;
4322 it->right_user_fringe_face_id = face_id;
4323 }
4324 #endif /* HAVE_WINDOW_SYSTEM */
4325 return 1;
4326 }
4327
4328 /* Prepare to handle `((margin left-margin) ...)',
4329 `((margin right-margin) ...)' and `((margin nil) ...)'
4330 prefixes for display specifications. */
4331 location = Qunbound;
4332 if (CONSP (spec) && CONSP (XCAR (spec)))
4333 {
4334 Lisp_Object tem;
4335
4336 value = XCDR (spec);
4337 if (CONSP (value))
4338 value = XCAR (value);
4339
4340 tem = XCAR (spec);
4341 if (EQ (XCAR (tem), Qmargin)
4342 && (tem = XCDR (tem),
4343 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4344 (NILP (tem)
4345 || EQ (tem, Qleft_margin)
4346 || EQ (tem, Qright_margin))))
4347 location = tem;
4348 }
4349
4350 if (EQ (location, Qunbound))
4351 {
4352 location = Qnil;
4353 value = spec;
4354 }
4355
4356 /* After this point, VALUE is the property after any
4357 margin prefix has been stripped. It must be a string,
4358 an image specification, or `(space ...)'.
4359
4360 LOCATION specifies where to display: `left-margin',
4361 `right-margin' or nil. */
4362
4363 valid_p = (STRINGP (value)
4364 #ifdef HAVE_WINDOW_SYSTEM
4365 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4366 #endif /* not HAVE_WINDOW_SYSTEM */
4367 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4368
4369 if (valid_p && !display_replaced_before_p)
4370 {
4371 /* Save current settings of IT so that we can restore them
4372 when we are finished with the glyph property value. */
4373 save_pos = it->position;
4374 it->position = *position;
4375 push_it (it);
4376 it->position = save_pos;
4377 it->from_overlay = overlay;
4378
4379 if (NILP (location))
4380 it->area = TEXT_AREA;
4381 else if (EQ (location, Qleft_margin))
4382 it->area = LEFT_MARGIN_AREA;
4383 else
4384 it->area = RIGHT_MARGIN_AREA;
4385
4386 if (STRINGP (value))
4387 {
4388 it->string = value;
4389 it->multibyte_p = STRING_MULTIBYTE (it->string);
4390 it->current.overlay_string_index = -1;
4391 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4392 it->end_charpos = it->string_nchars = SCHARS (it->string);
4393 it->method = GET_FROM_STRING;
4394 it->stop_charpos = 0;
4395 it->string_from_display_prop_p = 1;
4396 /* Say that we haven't consumed the characters with
4397 `display' property yet. The call to pop_it in
4398 set_iterator_to_next will clean this up. */
4399 if (BUFFERP (object))
4400 *position = start_pos;
4401 }
4402 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4403 {
4404 it->method = GET_FROM_STRETCH;
4405 it->object = value;
4406 *position = it->position = start_pos;
4407 }
4408 #ifdef HAVE_WINDOW_SYSTEM
4409 else
4410 {
4411 it->what = IT_IMAGE;
4412 it->image_id = lookup_image (it->f, value);
4413 it->position = start_pos;
4414 it->object = NILP (object) ? it->w->buffer : object;
4415 it->method = GET_FROM_IMAGE;
4416
4417 /* Say that we haven't consumed the characters with
4418 `display' property yet. The call to pop_it in
4419 set_iterator_to_next will clean this up. */
4420 *position = start_pos;
4421 }
4422 #endif /* HAVE_WINDOW_SYSTEM */
4423
4424 return 1;
4425 }
4426
4427 /* Invalid property or property not supported. Restore
4428 POSITION to what it was before. */
4429 *position = start_pos;
4430 return 0;
4431 }
4432
4433
4434 /* Check if SPEC is a display sub-property value whose text should be
4435 treated as intangible. */
4436
4437 static int
4438 single_display_spec_intangible_p (prop)
4439 Lisp_Object prop;
4440 {
4441 /* Skip over `when FORM'. */
4442 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4443 {
4444 prop = XCDR (prop);
4445 if (!CONSP (prop))
4446 return 0;
4447 prop = XCDR (prop);
4448 }
4449
4450 if (STRINGP (prop))
4451 return 1;
4452
4453 if (!CONSP (prop))
4454 return 0;
4455
4456 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4457 we don't need to treat text as intangible. */
4458 if (EQ (XCAR (prop), Qmargin))
4459 {
4460 prop = XCDR (prop);
4461 if (!CONSP (prop))
4462 return 0;
4463
4464 prop = XCDR (prop);
4465 if (!CONSP (prop)
4466 || EQ (XCAR (prop), Qleft_margin)
4467 || EQ (XCAR (prop), Qright_margin))
4468 return 0;
4469 }
4470
4471 return (CONSP (prop)
4472 && (EQ (XCAR (prop), Qimage)
4473 || EQ (XCAR (prop), Qspace)));
4474 }
4475
4476
4477 /* Check if PROP is a display property value whose text should be
4478 treated as intangible. */
4479
4480 int
4481 display_prop_intangible_p (prop)
4482 Lisp_Object prop;
4483 {
4484 if (CONSP (prop)
4485 && CONSP (XCAR (prop))
4486 && !EQ (Qmargin, XCAR (XCAR (prop))))
4487 {
4488 /* A list of sub-properties. */
4489 while (CONSP (prop))
4490 {
4491 if (single_display_spec_intangible_p (XCAR (prop)))
4492 return 1;
4493 prop = XCDR (prop);
4494 }
4495 }
4496 else if (VECTORP (prop))
4497 {
4498 /* A vector of sub-properties. */
4499 int i;
4500 for (i = 0; i < ASIZE (prop); ++i)
4501 if (single_display_spec_intangible_p (AREF (prop, i)))
4502 return 1;
4503 }
4504 else
4505 return single_display_spec_intangible_p (prop);
4506
4507 return 0;
4508 }
4509
4510
4511 /* Return 1 if PROP is a display sub-property value containing STRING. */
4512
4513 static int
4514 single_display_spec_string_p (prop, string)
4515 Lisp_Object prop, string;
4516 {
4517 if (EQ (string, prop))
4518 return 1;
4519
4520 /* Skip over `when FORM'. */
4521 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4522 {
4523 prop = XCDR (prop);
4524 if (!CONSP (prop))
4525 return 0;
4526 prop = XCDR (prop);
4527 }
4528
4529 if (CONSP (prop))
4530 /* Skip over `margin LOCATION'. */
4531 if (EQ (XCAR (prop), Qmargin))
4532 {
4533 prop = XCDR (prop);
4534 if (!CONSP (prop))
4535 return 0;
4536
4537 prop = XCDR (prop);
4538 if (!CONSP (prop))
4539 return 0;
4540 }
4541
4542 return CONSP (prop) && EQ (XCAR (prop), string);
4543 }
4544
4545
4546 /* Return 1 if STRING appears in the `display' property PROP. */
4547
4548 static int
4549 display_prop_string_p (prop, string)
4550 Lisp_Object prop, string;
4551 {
4552 if (CONSP (prop)
4553 && CONSP (XCAR (prop))
4554 && !EQ (Qmargin, XCAR (XCAR (prop))))
4555 {
4556 /* A list of sub-properties. */
4557 while (CONSP (prop))
4558 {
4559 if (single_display_spec_string_p (XCAR (prop), string))
4560 return 1;
4561 prop = XCDR (prop);
4562 }
4563 }
4564 else if (VECTORP (prop))
4565 {
4566 /* A vector of sub-properties. */
4567 int i;
4568 for (i = 0; i < ASIZE (prop); ++i)
4569 if (single_display_spec_string_p (AREF (prop, i), string))
4570 return 1;
4571 }
4572 else
4573 return single_display_spec_string_p (prop, string);
4574
4575 return 0;
4576 }
4577
4578
4579 /* Determine which buffer position in W's buffer STRING comes from.
4580 AROUND_CHARPOS is an approximate position where it could come from.
4581 Value is the buffer position or 0 if it couldn't be determined.
4582
4583 W's buffer must be current.
4584
4585 This function is necessary because we don't record buffer positions
4586 in glyphs generated from strings (to keep struct glyph small).
4587 This function may only use code that doesn't eval because it is
4588 called asynchronously from note_mouse_highlight. */
4589
4590 int
4591 string_buffer_position (w, string, around_charpos)
4592 struct window *w;
4593 Lisp_Object string;
4594 int around_charpos;
4595 {
4596 Lisp_Object limit, prop, pos;
4597 const int MAX_DISTANCE = 1000;
4598 int found = 0;
4599
4600 pos = make_number (around_charpos);
4601 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4602 while (!found && !EQ (pos, limit))
4603 {
4604 prop = Fget_char_property (pos, Qdisplay, Qnil);
4605 if (!NILP (prop) && display_prop_string_p (prop, string))
4606 found = 1;
4607 else
4608 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4609 }
4610
4611 if (!found)
4612 {
4613 pos = make_number (around_charpos);
4614 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4615 while (!found && !EQ (pos, limit))
4616 {
4617 prop = Fget_char_property (pos, Qdisplay, Qnil);
4618 if (!NILP (prop) && display_prop_string_p (prop, string))
4619 found = 1;
4620 else
4621 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4622 limit);
4623 }
4624 }
4625
4626 return found ? XINT (pos) : 0;
4627 }
4628
4629
4630 \f
4631 /***********************************************************************
4632 `composition' property
4633 ***********************************************************************/
4634
4635 /* Set up iterator IT from `composition' property at its current
4636 position. Called from handle_stop. */
4637
4638 static enum prop_handled
4639 handle_composition_prop (it)
4640 struct it *it;
4641 {
4642 Lisp_Object prop, string;
4643 EMACS_INT pos, pos_byte, start, end;
4644
4645 if (STRINGP (it->string))
4646 {
4647 unsigned char *s;
4648
4649 pos = IT_STRING_CHARPOS (*it);
4650 pos_byte = IT_STRING_BYTEPOS (*it);
4651 string = it->string;
4652 s = SDATA (string) + pos_byte;
4653 it->c = STRING_CHAR (s, 0);
4654 }
4655 else
4656 {
4657 pos = IT_CHARPOS (*it);
4658 pos_byte = IT_BYTEPOS (*it);
4659 string = Qnil;
4660 it->c = FETCH_CHAR (pos_byte);
4661 }
4662
4663 /* If there's a valid composition and point is not inside of the
4664 composition (in the case that the composition is from the current
4665 buffer), draw a glyph composed from the composition components. */
4666 if (find_composition (pos, -1, &start, &end, &prop, string)
4667 && COMPOSITION_VALID_P (start, end, prop)
4668 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4669 {
4670 if (start != pos)
4671 {
4672 if (STRINGP (it->string))
4673 pos_byte = string_char_to_byte (it->string, start);
4674 else
4675 pos_byte = CHAR_TO_BYTE (start);
4676 }
4677 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4678 prop, string);
4679
4680 if (it->cmp_it.id >= 0)
4681 {
4682 it->cmp_it.ch = -1;
4683 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4684 it->cmp_it.nglyphs = -1;
4685 }
4686 }
4687
4688 return HANDLED_NORMALLY;
4689 }
4690
4691
4692 \f
4693 /***********************************************************************
4694 Overlay strings
4695 ***********************************************************************/
4696
4697 /* The following structure is used to record overlay strings for
4698 later sorting in load_overlay_strings. */
4699
4700 struct overlay_entry
4701 {
4702 Lisp_Object overlay;
4703 Lisp_Object string;
4704 int priority;
4705 int after_string_p;
4706 };
4707
4708
4709 /* Set up iterator IT from overlay strings at its current position.
4710 Called from handle_stop. */
4711
4712 static enum prop_handled
4713 handle_overlay_change (it)
4714 struct it *it;
4715 {
4716 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4717 return HANDLED_RECOMPUTE_PROPS;
4718 else
4719 return HANDLED_NORMALLY;
4720 }
4721
4722
4723 /* Set up the next overlay string for delivery by IT, if there is an
4724 overlay string to deliver. Called by set_iterator_to_next when the
4725 end of the current overlay string is reached. If there are more
4726 overlay strings to display, IT->string and
4727 IT->current.overlay_string_index are set appropriately here.
4728 Otherwise IT->string is set to nil. */
4729
4730 static void
4731 next_overlay_string (it)
4732 struct it *it;
4733 {
4734 ++it->current.overlay_string_index;
4735 if (it->current.overlay_string_index == it->n_overlay_strings)
4736 {
4737 /* No more overlay strings. Restore IT's settings to what
4738 they were before overlay strings were processed, and
4739 continue to deliver from current_buffer. */
4740
4741 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4742 pop_it (it);
4743 xassert (it->sp > 0
4744 || (NILP (it->string)
4745 && it->method == GET_FROM_BUFFER
4746 && it->stop_charpos >= BEGV
4747 && it->stop_charpos <= it->end_charpos));
4748 it->current.overlay_string_index = -1;
4749 it->n_overlay_strings = 0;
4750
4751 /* If we're at the end of the buffer, record that we have
4752 processed the overlay strings there already, so that
4753 next_element_from_buffer doesn't try it again. */
4754 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4755 it->overlay_strings_at_end_processed_p = 1;
4756 }
4757 else
4758 {
4759 /* There are more overlay strings to process. If
4760 IT->current.overlay_string_index has advanced to a position
4761 where we must load IT->overlay_strings with more strings, do
4762 it. */
4763 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4764
4765 if (it->current.overlay_string_index && i == 0)
4766 load_overlay_strings (it, 0);
4767
4768 /* Initialize IT to deliver display elements from the overlay
4769 string. */
4770 it->string = it->overlay_strings[i];
4771 it->multibyte_p = STRING_MULTIBYTE (it->string);
4772 SET_TEXT_POS (it->current.string_pos, 0, 0);
4773 it->method = GET_FROM_STRING;
4774 it->stop_charpos = 0;
4775 if (it->cmp_it.stop_pos >= 0)
4776 it->cmp_it.stop_pos = 0;
4777 }
4778
4779 CHECK_IT (it);
4780 }
4781
4782
4783 /* Compare two overlay_entry structures E1 and E2. Used as a
4784 comparison function for qsort in load_overlay_strings. Overlay
4785 strings for the same position are sorted so that
4786
4787 1. All after-strings come in front of before-strings, except
4788 when they come from the same overlay.
4789
4790 2. Within after-strings, strings are sorted so that overlay strings
4791 from overlays with higher priorities come first.
4792
4793 2. Within before-strings, strings are sorted so that overlay
4794 strings from overlays with higher priorities come last.
4795
4796 Value is analogous to strcmp. */
4797
4798
4799 static int
4800 compare_overlay_entries (e1, e2)
4801 void *e1, *e2;
4802 {
4803 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4804 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4805 int result;
4806
4807 if (entry1->after_string_p != entry2->after_string_p)
4808 {
4809 /* Let after-strings appear in front of before-strings if
4810 they come from different overlays. */
4811 if (EQ (entry1->overlay, entry2->overlay))
4812 result = entry1->after_string_p ? 1 : -1;
4813 else
4814 result = entry1->after_string_p ? -1 : 1;
4815 }
4816 else if (entry1->after_string_p)
4817 /* After-strings sorted in order of decreasing priority. */
4818 result = entry2->priority - entry1->priority;
4819 else
4820 /* Before-strings sorted in order of increasing priority. */
4821 result = entry1->priority - entry2->priority;
4822
4823 return result;
4824 }
4825
4826
4827 /* Load the vector IT->overlay_strings with overlay strings from IT's
4828 current buffer position, or from CHARPOS if that is > 0. Set
4829 IT->n_overlays to the total number of overlay strings found.
4830
4831 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4832 a time. On entry into load_overlay_strings,
4833 IT->current.overlay_string_index gives the number of overlay
4834 strings that have already been loaded by previous calls to this
4835 function.
4836
4837 IT->add_overlay_start contains an additional overlay start
4838 position to consider for taking overlay strings from, if non-zero.
4839 This position comes into play when the overlay has an `invisible'
4840 property, and both before and after-strings. When we've skipped to
4841 the end of the overlay, because of its `invisible' property, we
4842 nevertheless want its before-string to appear.
4843 IT->add_overlay_start will contain the overlay start position
4844 in this case.
4845
4846 Overlay strings are sorted so that after-string strings come in
4847 front of before-string strings. Within before and after-strings,
4848 strings are sorted by overlay priority. See also function
4849 compare_overlay_entries. */
4850
4851 static void
4852 load_overlay_strings (it, charpos)
4853 struct it *it;
4854 int charpos;
4855 {
4856 extern Lisp_Object Qwindow, Qpriority;
4857 Lisp_Object overlay, window, str, invisible;
4858 struct Lisp_Overlay *ov;
4859 int start, end;
4860 int size = 20;
4861 int n = 0, i, j, invis_p;
4862 struct overlay_entry *entries
4863 = (struct overlay_entry *) alloca (size * sizeof *entries);
4864
4865 if (charpos <= 0)
4866 charpos = IT_CHARPOS (*it);
4867
4868 /* Append the overlay string STRING of overlay OVERLAY to vector
4869 `entries' which has size `size' and currently contains `n'
4870 elements. AFTER_P non-zero means STRING is an after-string of
4871 OVERLAY. */
4872 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4873 do \
4874 { \
4875 Lisp_Object priority; \
4876 \
4877 if (n == size) \
4878 { \
4879 int new_size = 2 * size; \
4880 struct overlay_entry *old = entries; \
4881 entries = \
4882 (struct overlay_entry *) alloca (new_size \
4883 * sizeof *entries); \
4884 bcopy (old, entries, size * sizeof *entries); \
4885 size = new_size; \
4886 } \
4887 \
4888 entries[n].string = (STRING); \
4889 entries[n].overlay = (OVERLAY); \
4890 priority = Foverlay_get ((OVERLAY), Qpriority); \
4891 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4892 entries[n].after_string_p = (AFTER_P); \
4893 ++n; \
4894 } \
4895 while (0)
4896
4897 /* Process overlay before the overlay center. */
4898 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4899 {
4900 XSETMISC (overlay, ov);
4901 xassert (OVERLAYP (overlay));
4902 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4903 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4904
4905 if (end < charpos)
4906 break;
4907
4908 /* Skip this overlay if it doesn't start or end at IT's current
4909 position. */
4910 if (end != charpos && start != charpos)
4911 continue;
4912
4913 /* Skip this overlay if it doesn't apply to IT->w. */
4914 window = Foverlay_get (overlay, Qwindow);
4915 if (WINDOWP (window) && XWINDOW (window) != it->w)
4916 continue;
4917
4918 /* If the text ``under'' the overlay is invisible, both before-
4919 and after-strings from this overlay are visible; start and
4920 end position are indistinguishable. */
4921 invisible = Foverlay_get (overlay, Qinvisible);
4922 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4923
4924 /* If overlay has a non-empty before-string, record it. */
4925 if ((start == charpos || (end == charpos && invis_p))
4926 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4927 && SCHARS (str))
4928 RECORD_OVERLAY_STRING (overlay, str, 0);
4929
4930 /* If overlay has a non-empty after-string, record it. */
4931 if ((end == charpos || (start == charpos && invis_p))
4932 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4933 && SCHARS (str))
4934 RECORD_OVERLAY_STRING (overlay, str, 1);
4935 }
4936
4937 /* Process overlays after the overlay center. */
4938 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4939 {
4940 XSETMISC (overlay, ov);
4941 xassert (OVERLAYP (overlay));
4942 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4943 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4944
4945 if (start > charpos)
4946 break;
4947
4948 /* Skip this overlay if it doesn't start or end at IT's current
4949 position. */
4950 if (end != charpos && start != charpos)
4951 continue;
4952
4953 /* Skip this overlay if it doesn't apply to IT->w. */
4954 window = Foverlay_get (overlay, Qwindow);
4955 if (WINDOWP (window) && XWINDOW (window) != it->w)
4956 continue;
4957
4958 /* If the text ``under'' the overlay is invisible, it has a zero
4959 dimension, and both before- and after-strings apply. */
4960 invisible = Foverlay_get (overlay, Qinvisible);
4961 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4962
4963 /* If overlay has a non-empty before-string, record it. */
4964 if ((start == charpos || (end == charpos && invis_p))
4965 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4966 && SCHARS (str))
4967 RECORD_OVERLAY_STRING (overlay, str, 0);
4968
4969 /* If overlay has a non-empty after-string, record it. */
4970 if ((end == charpos || (start == charpos && invis_p))
4971 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4972 && SCHARS (str))
4973 RECORD_OVERLAY_STRING (overlay, str, 1);
4974 }
4975
4976 #undef RECORD_OVERLAY_STRING
4977
4978 /* Sort entries. */
4979 if (n > 1)
4980 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4981
4982 /* Record the total number of strings to process. */
4983 it->n_overlay_strings = n;
4984
4985 /* IT->current.overlay_string_index is the number of overlay strings
4986 that have already been consumed by IT. Copy some of the
4987 remaining overlay strings to IT->overlay_strings. */
4988 i = 0;
4989 j = it->current.overlay_string_index;
4990 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4991 {
4992 it->overlay_strings[i] = entries[j].string;
4993 it->string_overlays[i++] = entries[j++].overlay;
4994 }
4995
4996 CHECK_IT (it);
4997 }
4998
4999
5000 /* Get the first chunk of overlay strings at IT's current buffer
5001 position, or at CHARPOS if that is > 0. Value is non-zero if at
5002 least one overlay string was found. */
5003
5004 static int
5005 get_overlay_strings_1 (it, charpos, compute_stop_p)
5006 struct it *it;
5007 int charpos;
5008 int compute_stop_p;
5009 {
5010 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5011 process. This fills IT->overlay_strings with strings, and sets
5012 IT->n_overlay_strings to the total number of strings to process.
5013 IT->pos.overlay_string_index has to be set temporarily to zero
5014 because load_overlay_strings needs this; it must be set to -1
5015 when no overlay strings are found because a zero value would
5016 indicate a position in the first overlay string. */
5017 it->current.overlay_string_index = 0;
5018 load_overlay_strings (it, charpos);
5019
5020 /* If we found overlay strings, set up IT to deliver display
5021 elements from the first one. Otherwise set up IT to deliver
5022 from current_buffer. */
5023 if (it->n_overlay_strings)
5024 {
5025 /* Make sure we know settings in current_buffer, so that we can
5026 restore meaningful values when we're done with the overlay
5027 strings. */
5028 if (compute_stop_p)
5029 compute_stop_pos (it);
5030 xassert (it->face_id >= 0);
5031
5032 /* Save IT's settings. They are restored after all overlay
5033 strings have been processed. */
5034 xassert (!compute_stop_p || it->sp == 0);
5035
5036 /* When called from handle_stop, there might be an empty display
5037 string loaded. In that case, don't bother saving it. */
5038 if (!STRINGP (it->string) || SCHARS (it->string))
5039 push_it (it);
5040
5041 /* Set up IT to deliver display elements from the first overlay
5042 string. */
5043 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5044 it->string = it->overlay_strings[0];
5045 it->from_overlay = Qnil;
5046 it->stop_charpos = 0;
5047 xassert (STRINGP (it->string));
5048 it->end_charpos = SCHARS (it->string);
5049 it->multibyte_p = STRING_MULTIBYTE (it->string);
5050 it->method = GET_FROM_STRING;
5051 return 1;
5052 }
5053
5054 it->current.overlay_string_index = -1;
5055 return 0;
5056 }
5057
5058 static int
5059 get_overlay_strings (it, charpos)
5060 struct it *it;
5061 int charpos;
5062 {
5063 it->string = Qnil;
5064 it->method = GET_FROM_BUFFER;
5065
5066 (void) get_overlay_strings_1 (it, charpos, 1);
5067
5068 CHECK_IT (it);
5069
5070 /* Value is non-zero if we found at least one overlay string. */
5071 return STRINGP (it->string);
5072 }
5073
5074
5075 \f
5076 /***********************************************************************
5077 Saving and restoring state
5078 ***********************************************************************/
5079
5080 /* Save current settings of IT on IT->stack. Called, for example,
5081 before setting up IT for an overlay string, to be able to restore
5082 IT's settings to what they were after the overlay string has been
5083 processed. */
5084
5085 static void
5086 push_it (it)
5087 struct it *it;
5088 {
5089 struct iterator_stack_entry *p;
5090
5091 xassert (it->sp < IT_STACK_SIZE);
5092 p = it->stack + it->sp;
5093
5094 p->stop_charpos = it->stop_charpos;
5095 p->cmp_it = it->cmp_it;
5096 xassert (it->face_id >= 0);
5097 p->face_id = it->face_id;
5098 p->string = it->string;
5099 p->method = it->method;
5100 p->from_overlay = it->from_overlay;
5101 switch (p->method)
5102 {
5103 case GET_FROM_IMAGE:
5104 p->u.image.object = it->object;
5105 p->u.image.image_id = it->image_id;
5106 p->u.image.slice = it->slice;
5107 break;
5108 case GET_FROM_STRETCH:
5109 p->u.stretch.object = it->object;
5110 break;
5111 }
5112 p->position = it->position;
5113 p->current = it->current;
5114 p->end_charpos = it->end_charpos;
5115 p->string_nchars = it->string_nchars;
5116 p->area = it->area;
5117 p->multibyte_p = it->multibyte_p;
5118 p->avoid_cursor_p = it->avoid_cursor_p;
5119 p->space_width = it->space_width;
5120 p->font_height = it->font_height;
5121 p->voffset = it->voffset;
5122 p->string_from_display_prop_p = it->string_from_display_prop_p;
5123 p->display_ellipsis_p = 0;
5124 p->line_wrap = it->line_wrap;
5125 ++it->sp;
5126 }
5127
5128
5129 /* Restore IT's settings from IT->stack. Called, for example, when no
5130 more overlay strings must be processed, and we return to delivering
5131 display elements from a buffer, or when the end of a string from a
5132 `display' property is reached and we return to delivering display
5133 elements from an overlay string, or from a buffer. */
5134
5135 static void
5136 pop_it (it)
5137 struct it *it;
5138 {
5139 struct iterator_stack_entry *p;
5140
5141 xassert (it->sp > 0);
5142 --it->sp;
5143 p = it->stack + it->sp;
5144 it->stop_charpos = p->stop_charpos;
5145 it->cmp_it = p->cmp_it;
5146 it->face_id = p->face_id;
5147 it->current = p->current;
5148 it->position = p->position;
5149 it->string = p->string;
5150 it->from_overlay = p->from_overlay;
5151 if (NILP (it->string))
5152 SET_TEXT_POS (it->current.string_pos, -1, -1);
5153 it->method = p->method;
5154 switch (it->method)
5155 {
5156 case GET_FROM_IMAGE:
5157 it->image_id = p->u.image.image_id;
5158 it->object = p->u.image.object;
5159 it->slice = p->u.image.slice;
5160 break;
5161 case GET_FROM_STRETCH:
5162 it->object = p->u.comp.object;
5163 break;
5164 case GET_FROM_BUFFER:
5165 it->object = it->w->buffer;
5166 break;
5167 case GET_FROM_STRING:
5168 it->object = it->string;
5169 break;
5170 case GET_FROM_DISPLAY_VECTOR:
5171 if (it->s)
5172 it->method = GET_FROM_C_STRING;
5173 else if (STRINGP (it->string))
5174 it->method = GET_FROM_STRING;
5175 else
5176 {
5177 it->method = GET_FROM_BUFFER;
5178 it->object = it->w->buffer;
5179 }
5180 }
5181 it->end_charpos = p->end_charpos;
5182 it->string_nchars = p->string_nchars;
5183 it->area = p->area;
5184 it->multibyte_p = p->multibyte_p;
5185 it->avoid_cursor_p = p->avoid_cursor_p;
5186 it->space_width = p->space_width;
5187 it->font_height = p->font_height;
5188 it->voffset = p->voffset;
5189 it->string_from_display_prop_p = p->string_from_display_prop_p;
5190 it->line_wrap = p->line_wrap;
5191 }
5192
5193
5194 \f
5195 /***********************************************************************
5196 Moving over lines
5197 ***********************************************************************/
5198
5199 /* Set IT's current position to the previous line start. */
5200
5201 static void
5202 back_to_previous_line_start (it)
5203 struct it *it;
5204 {
5205 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5206 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5207 }
5208
5209
5210 /* Move IT to the next line start.
5211
5212 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5213 we skipped over part of the text (as opposed to moving the iterator
5214 continuously over the text). Otherwise, don't change the value
5215 of *SKIPPED_P.
5216
5217 Newlines may come from buffer text, overlay strings, or strings
5218 displayed via the `display' property. That's the reason we can't
5219 simply use find_next_newline_no_quit.
5220
5221 Note that this function may not skip over invisible text that is so
5222 because of text properties and immediately follows a newline. If
5223 it would, function reseat_at_next_visible_line_start, when called
5224 from set_iterator_to_next, would effectively make invisible
5225 characters following a newline part of the wrong glyph row, which
5226 leads to wrong cursor motion. */
5227
5228 static int
5229 forward_to_next_line_start (it, skipped_p)
5230 struct it *it;
5231 int *skipped_p;
5232 {
5233 int old_selective, newline_found_p, n;
5234 const int MAX_NEWLINE_DISTANCE = 500;
5235
5236 /* If already on a newline, just consume it to avoid unintended
5237 skipping over invisible text below. */
5238 if (it->what == IT_CHARACTER
5239 && it->c == '\n'
5240 && CHARPOS (it->position) == IT_CHARPOS (*it))
5241 {
5242 set_iterator_to_next (it, 0);
5243 it->c = 0;
5244 return 1;
5245 }
5246
5247 /* Don't handle selective display in the following. It's (a)
5248 unnecessary because it's done by the caller, and (b) leads to an
5249 infinite recursion because next_element_from_ellipsis indirectly
5250 calls this function. */
5251 old_selective = it->selective;
5252 it->selective = 0;
5253
5254 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5255 from buffer text. */
5256 for (n = newline_found_p = 0;
5257 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5258 n += STRINGP (it->string) ? 0 : 1)
5259 {
5260 if (!get_next_display_element (it))
5261 return 0;
5262 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5263 set_iterator_to_next (it, 0);
5264 }
5265
5266 /* If we didn't find a newline near enough, see if we can use a
5267 short-cut. */
5268 if (!newline_found_p)
5269 {
5270 int start = IT_CHARPOS (*it);
5271 int limit = find_next_newline_no_quit (start, 1);
5272 Lisp_Object pos;
5273
5274 xassert (!STRINGP (it->string));
5275
5276 /* If there isn't any `display' property in sight, and no
5277 overlays, we can just use the position of the newline in
5278 buffer text. */
5279 if (it->stop_charpos >= limit
5280 || ((pos = Fnext_single_property_change (make_number (start),
5281 Qdisplay,
5282 Qnil, make_number (limit)),
5283 NILP (pos))
5284 && next_overlay_change (start) == ZV))
5285 {
5286 IT_CHARPOS (*it) = limit;
5287 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5288 *skipped_p = newline_found_p = 1;
5289 }
5290 else
5291 {
5292 while (get_next_display_element (it)
5293 && !newline_found_p)
5294 {
5295 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5296 set_iterator_to_next (it, 0);
5297 }
5298 }
5299 }
5300
5301 it->selective = old_selective;
5302 return newline_found_p;
5303 }
5304
5305
5306 /* Set IT's current position to the previous visible line start. Skip
5307 invisible text that is so either due to text properties or due to
5308 selective display. Caution: this does not change IT->current_x and
5309 IT->hpos. */
5310
5311 static void
5312 back_to_previous_visible_line_start (it)
5313 struct it *it;
5314 {
5315 while (IT_CHARPOS (*it) > BEGV)
5316 {
5317 back_to_previous_line_start (it);
5318
5319 if (IT_CHARPOS (*it) <= BEGV)
5320 break;
5321
5322 /* If selective > 0, then lines indented more than that values
5323 are invisible. */
5324 if (it->selective > 0
5325 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5326 (double) it->selective)) /* iftc */
5327 continue;
5328
5329 /* Check the newline before point for invisibility. */
5330 {
5331 Lisp_Object prop;
5332 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5333 Qinvisible, it->window);
5334 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5335 continue;
5336 }
5337
5338 if (IT_CHARPOS (*it) <= BEGV)
5339 break;
5340
5341 {
5342 struct it it2;
5343 int pos;
5344 EMACS_INT beg, end;
5345 Lisp_Object val, overlay;
5346
5347 /* If newline is part of a composition, continue from start of composition */
5348 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5349 && beg < IT_CHARPOS (*it))
5350 goto replaced;
5351
5352 /* If newline is replaced by a display property, find start of overlay
5353 or interval and continue search from that point. */
5354 it2 = *it;
5355 pos = --IT_CHARPOS (it2);
5356 --IT_BYTEPOS (it2);
5357 it2.sp = 0;
5358 it2.string_from_display_prop_p = 0;
5359 if (handle_display_prop (&it2) == HANDLED_RETURN
5360 && !NILP (val = get_char_property_and_overlay
5361 (make_number (pos), Qdisplay, Qnil, &overlay))
5362 && (OVERLAYP (overlay)
5363 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5364 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5365 goto replaced;
5366
5367 /* Newline is not replaced by anything -- so we are done. */
5368 break;
5369
5370 replaced:
5371 if (beg < BEGV)
5372 beg = BEGV;
5373 IT_CHARPOS (*it) = beg;
5374 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5375 }
5376 }
5377
5378 it->continuation_lines_width = 0;
5379
5380 xassert (IT_CHARPOS (*it) >= BEGV);
5381 xassert (IT_CHARPOS (*it) == BEGV
5382 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5383 CHECK_IT (it);
5384 }
5385
5386
5387 /* Reseat iterator IT at the previous visible line start. Skip
5388 invisible text that is so either due to text properties or due to
5389 selective display. At the end, update IT's overlay information,
5390 face information etc. */
5391
5392 void
5393 reseat_at_previous_visible_line_start (it)
5394 struct it *it;
5395 {
5396 back_to_previous_visible_line_start (it);
5397 reseat (it, it->current.pos, 1);
5398 CHECK_IT (it);
5399 }
5400
5401
5402 /* Reseat iterator IT on the next visible line start in the current
5403 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5404 preceding the line start. Skip over invisible text that is so
5405 because of selective display. Compute faces, overlays etc at the
5406 new position. Note that this function does not skip over text that
5407 is invisible because of text properties. */
5408
5409 static void
5410 reseat_at_next_visible_line_start (it, on_newline_p)
5411 struct it *it;
5412 int on_newline_p;
5413 {
5414 int newline_found_p, skipped_p = 0;
5415
5416 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5417
5418 /* Skip over lines that are invisible because they are indented
5419 more than the value of IT->selective. */
5420 if (it->selective > 0)
5421 while (IT_CHARPOS (*it) < ZV
5422 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5423 (double) it->selective)) /* iftc */
5424 {
5425 xassert (IT_BYTEPOS (*it) == BEGV
5426 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5427 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5428 }
5429
5430 /* Position on the newline if that's what's requested. */
5431 if (on_newline_p && newline_found_p)
5432 {
5433 if (STRINGP (it->string))
5434 {
5435 if (IT_STRING_CHARPOS (*it) > 0)
5436 {
5437 --IT_STRING_CHARPOS (*it);
5438 --IT_STRING_BYTEPOS (*it);
5439 }
5440 }
5441 else if (IT_CHARPOS (*it) > BEGV)
5442 {
5443 --IT_CHARPOS (*it);
5444 --IT_BYTEPOS (*it);
5445 reseat (it, it->current.pos, 0);
5446 }
5447 }
5448 else if (skipped_p)
5449 reseat (it, it->current.pos, 0);
5450
5451 CHECK_IT (it);
5452 }
5453
5454
5455 \f
5456 /***********************************************************************
5457 Changing an iterator's position
5458 ***********************************************************************/
5459
5460 /* Change IT's current position to POS in current_buffer. If FORCE_P
5461 is non-zero, always check for text properties at the new position.
5462 Otherwise, text properties are only looked up if POS >=
5463 IT->check_charpos of a property. */
5464
5465 static void
5466 reseat (it, pos, force_p)
5467 struct it *it;
5468 struct text_pos pos;
5469 int force_p;
5470 {
5471 int original_pos = IT_CHARPOS (*it);
5472
5473 reseat_1 (it, pos, 0);
5474
5475 /* Determine where to check text properties. Avoid doing it
5476 where possible because text property lookup is very expensive. */
5477 if (force_p
5478 || CHARPOS (pos) > it->stop_charpos
5479 || CHARPOS (pos) < original_pos)
5480 handle_stop (it);
5481
5482 CHECK_IT (it);
5483 }
5484
5485
5486 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5487 IT->stop_pos to POS, also. */
5488
5489 static void
5490 reseat_1 (it, pos, set_stop_p)
5491 struct it *it;
5492 struct text_pos pos;
5493 int set_stop_p;
5494 {
5495 /* Don't call this function when scanning a C string. */
5496 xassert (it->s == NULL);
5497
5498 /* POS must be a reasonable value. */
5499 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5500
5501 it->current.pos = it->position = pos;
5502 it->end_charpos = ZV;
5503 it->dpvec = NULL;
5504 it->current.dpvec_index = -1;
5505 it->current.overlay_string_index = -1;
5506 IT_STRING_CHARPOS (*it) = -1;
5507 IT_STRING_BYTEPOS (*it) = -1;
5508 it->string = Qnil;
5509 it->string_from_display_prop_p = 0;
5510 it->method = GET_FROM_BUFFER;
5511 it->object = it->w->buffer;
5512 it->area = TEXT_AREA;
5513 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5514 it->sp = 0;
5515 it->string_from_display_prop_p = 0;
5516 it->face_before_selective_p = 0;
5517
5518 if (set_stop_p)
5519 it->stop_charpos = CHARPOS (pos);
5520 }
5521
5522
5523 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5524 If S is non-null, it is a C string to iterate over. Otherwise,
5525 STRING gives a Lisp string to iterate over.
5526
5527 If PRECISION > 0, don't return more then PRECISION number of
5528 characters from the string.
5529
5530 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5531 characters have been returned. FIELD_WIDTH < 0 means an infinite
5532 field width.
5533
5534 MULTIBYTE = 0 means disable processing of multibyte characters,
5535 MULTIBYTE > 0 means enable it,
5536 MULTIBYTE < 0 means use IT->multibyte_p.
5537
5538 IT must be initialized via a prior call to init_iterator before
5539 calling this function. */
5540
5541 static void
5542 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5543 struct it *it;
5544 unsigned char *s;
5545 Lisp_Object string;
5546 int charpos;
5547 int precision, field_width, multibyte;
5548 {
5549 /* No region in strings. */
5550 it->region_beg_charpos = it->region_end_charpos = -1;
5551
5552 /* No text property checks performed by default, but see below. */
5553 it->stop_charpos = -1;
5554
5555 /* Set iterator position and end position. */
5556 bzero (&it->current, sizeof it->current);
5557 it->current.overlay_string_index = -1;
5558 it->current.dpvec_index = -1;
5559 xassert (charpos >= 0);
5560
5561 /* If STRING is specified, use its multibyteness, otherwise use the
5562 setting of MULTIBYTE, if specified. */
5563 if (multibyte >= 0)
5564 it->multibyte_p = multibyte > 0;
5565
5566 if (s == NULL)
5567 {
5568 xassert (STRINGP (string));
5569 it->string = string;
5570 it->s = NULL;
5571 it->end_charpos = it->string_nchars = SCHARS (string);
5572 it->method = GET_FROM_STRING;
5573 it->current.string_pos = string_pos (charpos, string);
5574 }
5575 else
5576 {
5577 it->s = s;
5578 it->string = Qnil;
5579
5580 /* Note that we use IT->current.pos, not it->current.string_pos,
5581 for displaying C strings. */
5582 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5583 if (it->multibyte_p)
5584 {
5585 it->current.pos = c_string_pos (charpos, s, 1);
5586 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5587 }
5588 else
5589 {
5590 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5591 it->end_charpos = it->string_nchars = strlen (s);
5592 }
5593
5594 it->method = GET_FROM_C_STRING;
5595 }
5596
5597 /* PRECISION > 0 means don't return more than PRECISION characters
5598 from the string. */
5599 if (precision > 0 && it->end_charpos - charpos > precision)
5600 it->end_charpos = it->string_nchars = charpos + precision;
5601
5602 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5603 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5604 FIELD_WIDTH < 0 means infinite field width. This is useful for
5605 padding with `-' at the end of a mode line. */
5606 if (field_width < 0)
5607 field_width = INFINITY;
5608 if (field_width > it->end_charpos - charpos)
5609 it->end_charpos = charpos + field_width;
5610
5611 /* Use the standard display table for displaying strings. */
5612 if (DISP_TABLE_P (Vstandard_display_table))
5613 it->dp = XCHAR_TABLE (Vstandard_display_table);
5614
5615 it->stop_charpos = charpos;
5616 CHECK_IT (it);
5617 }
5618
5619
5620 \f
5621 /***********************************************************************
5622 Iteration
5623 ***********************************************************************/
5624
5625 /* Map enum it_method value to corresponding next_element_from_* function. */
5626
5627 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5628 {
5629 next_element_from_buffer,
5630 next_element_from_display_vector,
5631 next_element_from_string,
5632 next_element_from_c_string,
5633 next_element_from_image,
5634 next_element_from_stretch
5635 };
5636
5637 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5638
5639
5640 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5641 (possibly with the following characters). */
5642
5643 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS) \
5644 ((IT)->cmp_it.id >= 0 \
5645 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5646 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5647 (IT)->end_charpos, (IT)->w, \
5648 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5649 (IT)->string)))
5650
5651
5652 /* Load IT's display element fields with information about the next
5653 display element from the current position of IT. Value is zero if
5654 end of buffer (or C string) is reached. */
5655
5656 static struct frame *last_escape_glyph_frame = NULL;
5657 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5658 static int last_escape_glyph_merged_face_id = 0;
5659
5660 int
5661 get_next_display_element (it)
5662 struct it *it;
5663 {
5664 /* Non-zero means that we found a display element. Zero means that
5665 we hit the end of what we iterate over. Performance note: the
5666 function pointer `method' used here turns out to be faster than
5667 using a sequence of if-statements. */
5668 int success_p;
5669
5670 get_next:
5671 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5672
5673 if (it->what == IT_CHARACTER)
5674 {
5675 /* Map via display table or translate control characters.
5676 IT->c, IT->len etc. have been set to the next character by
5677 the function call above. If we have a display table, and it
5678 contains an entry for IT->c, translate it. Don't do this if
5679 IT->c itself comes from a display table, otherwise we could
5680 end up in an infinite recursion. (An alternative could be to
5681 count the recursion depth of this function and signal an
5682 error when a certain maximum depth is reached.) Is it worth
5683 it? */
5684 if (success_p && it->dpvec == NULL)
5685 {
5686 Lisp_Object dv;
5687 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5688 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5689 nbsp_or_shy = char_is_other;
5690 int decoded = it->c;
5691
5692 if (it->dp
5693 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5694 VECTORP (dv)))
5695 {
5696 struct Lisp_Vector *v = XVECTOR (dv);
5697
5698 /* Return the first character from the display table
5699 entry, if not empty. If empty, don't display the
5700 current character. */
5701 if (v->size)
5702 {
5703 it->dpvec_char_len = it->len;
5704 it->dpvec = v->contents;
5705 it->dpend = v->contents + v->size;
5706 it->current.dpvec_index = 0;
5707 it->dpvec_face_id = -1;
5708 it->saved_face_id = it->face_id;
5709 it->method = GET_FROM_DISPLAY_VECTOR;
5710 it->ellipsis_p = 0;
5711 }
5712 else
5713 {
5714 set_iterator_to_next (it, 0);
5715 }
5716 goto get_next;
5717 }
5718
5719 if (unibyte_display_via_language_environment
5720 && !ASCII_CHAR_P (it->c))
5721 decoded = DECODE_CHAR (unibyte, it->c);
5722
5723 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5724 {
5725 if (it->multibyte_p)
5726 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5727 : it->c == 0xAD ? char_is_soft_hyphen
5728 : char_is_other);
5729 else if (unibyte_display_via_language_environment)
5730 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5731 : decoded == 0xAD ? char_is_soft_hyphen
5732 : char_is_other);
5733 }
5734
5735 /* Translate control characters into `\003' or `^C' form.
5736 Control characters coming from a display table entry are
5737 currently not translated because we use IT->dpvec to hold
5738 the translation. This could easily be changed but I
5739 don't believe that it is worth doing.
5740
5741 If it->multibyte_p is nonzero, non-printable non-ASCII
5742 characters are also translated to octal form.
5743
5744 If it->multibyte_p is zero, eight-bit characters that
5745 don't have corresponding multibyte char code are also
5746 translated to octal form. */
5747 if ((it->c < ' '
5748 ? (it->area != TEXT_AREA
5749 /* In mode line, treat \n, \t like other crl chars. */
5750 || (it->c != '\t'
5751 && it->glyph_row
5752 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5753 || (it->c != '\n' && it->c != '\t'))
5754 : (nbsp_or_shy
5755 || (it->multibyte_p
5756 ? ! CHAR_PRINTABLE_P (it->c)
5757 : (! unibyte_display_via_language_environment
5758 ? it->c >= 0x80
5759 : (decoded >= 0x80 && decoded < 0xA0))))))
5760 {
5761 /* IT->c is a control character which must be displayed
5762 either as '\003' or as `^C' where the '\\' and '^'
5763 can be defined in the display table. Fill
5764 IT->ctl_chars with glyphs for what we have to
5765 display. Then, set IT->dpvec to these glyphs. */
5766 Lisp_Object gc;
5767 int ctl_len;
5768 int face_id, lface_id = 0 ;
5769 int escape_glyph;
5770
5771 /* Handle control characters with ^. */
5772
5773 if (it->c < 128 && it->ctl_arrow_p)
5774 {
5775 int g;
5776
5777 g = '^'; /* default glyph for Control */
5778 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5779 if (it->dp
5780 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5781 && GLYPH_CODE_CHAR_VALID_P (gc))
5782 {
5783 g = GLYPH_CODE_CHAR (gc);
5784 lface_id = GLYPH_CODE_FACE (gc);
5785 }
5786 if (lface_id)
5787 {
5788 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5789 }
5790 else if (it->f == last_escape_glyph_frame
5791 && it->face_id == last_escape_glyph_face_id)
5792 {
5793 face_id = last_escape_glyph_merged_face_id;
5794 }
5795 else
5796 {
5797 /* Merge the escape-glyph face into the current face. */
5798 face_id = merge_faces (it->f, Qescape_glyph, 0,
5799 it->face_id);
5800 last_escape_glyph_frame = it->f;
5801 last_escape_glyph_face_id = it->face_id;
5802 last_escape_glyph_merged_face_id = face_id;
5803 }
5804
5805 XSETINT (it->ctl_chars[0], g);
5806 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5807 ctl_len = 2;
5808 goto display_control;
5809 }
5810
5811 /* Handle non-break space in the mode where it only gets
5812 highlighting. */
5813
5814 if (EQ (Vnobreak_char_display, Qt)
5815 && nbsp_or_shy == char_is_nbsp)
5816 {
5817 /* Merge the no-break-space face into the current face. */
5818 face_id = merge_faces (it->f, Qnobreak_space, 0,
5819 it->face_id);
5820
5821 it->c = ' ';
5822 XSETINT (it->ctl_chars[0], ' ');
5823 ctl_len = 1;
5824 goto display_control;
5825 }
5826
5827 /* Handle sequences that start with the "escape glyph". */
5828
5829 /* the default escape glyph is \. */
5830 escape_glyph = '\\';
5831
5832 if (it->dp
5833 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5834 && GLYPH_CODE_CHAR_VALID_P (gc))
5835 {
5836 escape_glyph = GLYPH_CODE_CHAR (gc);
5837 lface_id = GLYPH_CODE_FACE (gc);
5838 }
5839 if (lface_id)
5840 {
5841 /* The display table specified a face.
5842 Merge it into face_id and also into escape_glyph. */
5843 face_id = merge_faces (it->f, Qt, lface_id,
5844 it->face_id);
5845 }
5846 else if (it->f == last_escape_glyph_frame
5847 && it->face_id == last_escape_glyph_face_id)
5848 {
5849 face_id = last_escape_glyph_merged_face_id;
5850 }
5851 else
5852 {
5853 /* Merge the escape-glyph face into the current face. */
5854 face_id = merge_faces (it->f, Qescape_glyph, 0,
5855 it->face_id);
5856 last_escape_glyph_frame = it->f;
5857 last_escape_glyph_face_id = it->face_id;
5858 last_escape_glyph_merged_face_id = face_id;
5859 }
5860
5861 /* Handle soft hyphens in the mode where they only get
5862 highlighting. */
5863
5864 if (EQ (Vnobreak_char_display, Qt)
5865 && nbsp_or_shy == char_is_soft_hyphen)
5866 {
5867 it->c = '-';
5868 XSETINT (it->ctl_chars[0], '-');
5869 ctl_len = 1;
5870 goto display_control;
5871 }
5872
5873 /* Handle non-break space and soft hyphen
5874 with the escape glyph. */
5875
5876 if (nbsp_or_shy)
5877 {
5878 XSETINT (it->ctl_chars[0], escape_glyph);
5879 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5880 XSETINT (it->ctl_chars[1], it->c);
5881 ctl_len = 2;
5882 goto display_control;
5883 }
5884
5885 {
5886 unsigned char str[MAX_MULTIBYTE_LENGTH];
5887 int len;
5888 int i;
5889
5890 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5891 if (CHAR_BYTE8_P (it->c))
5892 {
5893 str[0] = CHAR_TO_BYTE8 (it->c);
5894 len = 1;
5895 }
5896 else if (it->c < 256)
5897 {
5898 str[0] = it->c;
5899 len = 1;
5900 }
5901 else
5902 {
5903 /* It's an invalid character, which shouldn't
5904 happen actually, but due to bugs it may
5905 happen. Let's print the char as is, there's
5906 not much meaningful we can do with it. */
5907 str[0] = it->c;
5908 str[1] = it->c >> 8;
5909 str[2] = it->c >> 16;
5910 str[3] = it->c >> 24;
5911 len = 4;
5912 }
5913
5914 for (i = 0; i < len; i++)
5915 {
5916 int g;
5917 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5918 /* Insert three more glyphs into IT->ctl_chars for
5919 the octal display of the character. */
5920 g = ((str[i] >> 6) & 7) + '0';
5921 XSETINT (it->ctl_chars[i * 4 + 1], g);
5922 g = ((str[i] >> 3) & 7) + '0';
5923 XSETINT (it->ctl_chars[i * 4 + 2], g);
5924 g = (str[i] & 7) + '0';
5925 XSETINT (it->ctl_chars[i * 4 + 3], g);
5926 }
5927 ctl_len = len * 4;
5928 }
5929
5930 display_control:
5931 /* Set up IT->dpvec and return first character from it. */
5932 it->dpvec_char_len = it->len;
5933 it->dpvec = it->ctl_chars;
5934 it->dpend = it->dpvec + ctl_len;
5935 it->current.dpvec_index = 0;
5936 it->dpvec_face_id = face_id;
5937 it->saved_face_id = it->face_id;
5938 it->method = GET_FROM_DISPLAY_VECTOR;
5939 it->ellipsis_p = 0;
5940 goto get_next;
5941 }
5942 }
5943 }
5944
5945 #ifdef HAVE_WINDOW_SYSTEM
5946 /* Adjust face id for a multibyte character. There are no multibyte
5947 character in unibyte text. */
5948 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5949 && it->multibyte_p
5950 && success_p
5951 && FRAME_WINDOW_P (it->f))
5952 {
5953 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5954
5955 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
5956 {
5957 /* Automatic composition with glyph-string. */
5958 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
5959
5960 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
5961 }
5962 else
5963 {
5964 int pos = (it->s ? -1
5965 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5966 : IT_CHARPOS (*it));
5967
5968 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5969 }
5970 }
5971 #endif
5972
5973 /* Is this character the last one of a run of characters with
5974 box? If yes, set IT->end_of_box_run_p to 1. */
5975 if (it->face_box_p
5976 && it->s == NULL)
5977 {
5978 if (it->method == GET_FROM_STRING && it->sp)
5979 {
5980 int face_id = underlying_face_id (it);
5981 struct face *face = FACE_FROM_ID (it->f, face_id);
5982
5983 if (face)
5984 {
5985 if (face->box == FACE_NO_BOX)
5986 {
5987 /* If the box comes from face properties in a
5988 display string, check faces in that string. */
5989 int string_face_id = face_after_it_pos (it);
5990 it->end_of_box_run_p
5991 = (FACE_FROM_ID (it->f, string_face_id)->box
5992 == FACE_NO_BOX);
5993 }
5994 /* Otherwise, the box comes from the underlying face.
5995 If this is the last string character displayed, check
5996 the next buffer location. */
5997 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
5998 && (it->current.overlay_string_index
5999 == it->n_overlay_strings - 1))
6000 {
6001 EMACS_INT ignore;
6002 int next_face_id;
6003 struct text_pos pos = it->current.pos;
6004 INC_TEXT_POS (pos, it->multibyte_p);
6005
6006 next_face_id = face_at_buffer_position
6007 (it->w, CHARPOS (pos), it->region_beg_charpos,
6008 it->region_end_charpos, &ignore,
6009 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6010 -1);
6011 it->end_of_box_run_p
6012 = (FACE_FROM_ID (it->f, next_face_id)->box
6013 == FACE_NO_BOX);
6014 }
6015 }
6016 }
6017 else
6018 {
6019 int face_id = face_after_it_pos (it);
6020 it->end_of_box_run_p
6021 = (face_id != it->face_id
6022 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6023 }
6024 }
6025
6026 /* Value is 0 if end of buffer or string reached. */
6027 return success_p;
6028 }
6029
6030
6031 /* Move IT to the next display element.
6032
6033 RESEAT_P non-zero means if called on a newline in buffer text,
6034 skip to the next visible line start.
6035
6036 Functions get_next_display_element and set_iterator_to_next are
6037 separate because I find this arrangement easier to handle than a
6038 get_next_display_element function that also increments IT's
6039 position. The way it is we can first look at an iterator's current
6040 display element, decide whether it fits on a line, and if it does,
6041 increment the iterator position. The other way around we probably
6042 would either need a flag indicating whether the iterator has to be
6043 incremented the next time, or we would have to implement a
6044 decrement position function which would not be easy to write. */
6045
6046 void
6047 set_iterator_to_next (it, reseat_p)
6048 struct it *it;
6049 int reseat_p;
6050 {
6051 /* Reset flags indicating start and end of a sequence of characters
6052 with box. Reset them at the start of this function because
6053 moving the iterator to a new position might set them. */
6054 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6055
6056 switch (it->method)
6057 {
6058 case GET_FROM_BUFFER:
6059 /* The current display element of IT is a character from
6060 current_buffer. Advance in the buffer, and maybe skip over
6061 invisible lines that are so because of selective display. */
6062 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6063 reseat_at_next_visible_line_start (it, 0);
6064 else if (it->cmp_it.id >= 0)
6065 {
6066 IT_CHARPOS (*it) += it->cmp_it.nchars;
6067 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6068 if (it->cmp_it.to < it->cmp_it.nglyphs)
6069 it->cmp_it.from = it->cmp_it.to;
6070 else
6071 {
6072 it->cmp_it.id = -1;
6073 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6074 IT_BYTEPOS (*it), it->stop_charpos,
6075 Qnil);
6076 }
6077 }
6078 else
6079 {
6080 xassert (it->len != 0);
6081 IT_BYTEPOS (*it) += it->len;
6082 IT_CHARPOS (*it) += 1;
6083 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6084 }
6085 break;
6086
6087 case GET_FROM_C_STRING:
6088 /* Current display element of IT is from a C string. */
6089 IT_BYTEPOS (*it) += it->len;
6090 IT_CHARPOS (*it) += 1;
6091 break;
6092
6093 case GET_FROM_DISPLAY_VECTOR:
6094 /* Current display element of IT is from a display table entry.
6095 Advance in the display table definition. Reset it to null if
6096 end reached, and continue with characters from buffers/
6097 strings. */
6098 ++it->current.dpvec_index;
6099
6100 /* Restore face of the iterator to what they were before the
6101 display vector entry (these entries may contain faces). */
6102 it->face_id = it->saved_face_id;
6103
6104 if (it->dpvec + it->current.dpvec_index == it->dpend)
6105 {
6106 int recheck_faces = it->ellipsis_p;
6107
6108 if (it->s)
6109 it->method = GET_FROM_C_STRING;
6110 else if (STRINGP (it->string))
6111 it->method = GET_FROM_STRING;
6112 else
6113 {
6114 it->method = GET_FROM_BUFFER;
6115 it->object = it->w->buffer;
6116 }
6117
6118 it->dpvec = NULL;
6119 it->current.dpvec_index = -1;
6120
6121 /* Skip over characters which were displayed via IT->dpvec. */
6122 if (it->dpvec_char_len < 0)
6123 reseat_at_next_visible_line_start (it, 1);
6124 else if (it->dpvec_char_len > 0)
6125 {
6126 if (it->method == GET_FROM_STRING
6127 && it->n_overlay_strings > 0)
6128 it->ignore_overlay_strings_at_pos_p = 1;
6129 it->len = it->dpvec_char_len;
6130 set_iterator_to_next (it, reseat_p);
6131 }
6132
6133 /* Maybe recheck faces after display vector */
6134 if (recheck_faces)
6135 it->stop_charpos = IT_CHARPOS (*it);
6136 }
6137 break;
6138
6139 case GET_FROM_STRING:
6140 /* Current display element is a character from a Lisp string. */
6141 xassert (it->s == NULL && STRINGP (it->string));
6142 if (it->cmp_it.id >= 0)
6143 {
6144 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6145 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6146 if (it->cmp_it.to < it->cmp_it.nglyphs)
6147 it->cmp_it.from = it->cmp_it.to;
6148 else
6149 {
6150 it->cmp_it.id = -1;
6151 composition_compute_stop_pos (&it->cmp_it,
6152 IT_STRING_CHARPOS (*it),
6153 IT_STRING_BYTEPOS (*it),
6154 it->stop_charpos, it->string);
6155 }
6156 }
6157 else
6158 {
6159 IT_STRING_BYTEPOS (*it) += it->len;
6160 IT_STRING_CHARPOS (*it) += 1;
6161 }
6162
6163 consider_string_end:
6164
6165 if (it->current.overlay_string_index >= 0)
6166 {
6167 /* IT->string is an overlay string. Advance to the
6168 next, if there is one. */
6169 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6170 {
6171 it->ellipsis_p = 0;
6172 next_overlay_string (it);
6173 if (it->ellipsis_p)
6174 setup_for_ellipsis (it, 0);
6175 }
6176 }
6177 else
6178 {
6179 /* IT->string is not an overlay string. If we reached
6180 its end, and there is something on IT->stack, proceed
6181 with what is on the stack. This can be either another
6182 string, this time an overlay string, or a buffer. */
6183 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6184 && it->sp > 0)
6185 {
6186 pop_it (it);
6187 if (it->method == GET_FROM_STRING)
6188 goto consider_string_end;
6189 }
6190 }
6191 break;
6192
6193 case GET_FROM_IMAGE:
6194 case GET_FROM_STRETCH:
6195 /* The position etc with which we have to proceed are on
6196 the stack. The position may be at the end of a string,
6197 if the `display' property takes up the whole string. */
6198 xassert (it->sp > 0);
6199 pop_it (it);
6200 if (it->method == GET_FROM_STRING)
6201 goto consider_string_end;
6202 break;
6203
6204 default:
6205 /* There are no other methods defined, so this should be a bug. */
6206 abort ();
6207 }
6208
6209 xassert (it->method != GET_FROM_STRING
6210 || (STRINGP (it->string)
6211 && IT_STRING_CHARPOS (*it) >= 0));
6212 }
6213
6214 /* Load IT's display element fields with information about the next
6215 display element which comes from a display table entry or from the
6216 result of translating a control character to one of the forms `^C'
6217 or `\003'.
6218
6219 IT->dpvec holds the glyphs to return as characters.
6220 IT->saved_face_id holds the face id before the display vector--
6221 it is restored into IT->face_idin set_iterator_to_next. */
6222
6223 static int
6224 next_element_from_display_vector (it)
6225 struct it *it;
6226 {
6227 Lisp_Object gc;
6228
6229 /* Precondition. */
6230 xassert (it->dpvec && it->current.dpvec_index >= 0);
6231
6232 it->face_id = it->saved_face_id;
6233
6234 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6235 That seemed totally bogus - so I changed it... */
6236 gc = it->dpvec[it->current.dpvec_index];
6237
6238 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6239 {
6240 it->c = GLYPH_CODE_CHAR (gc);
6241 it->len = CHAR_BYTES (it->c);
6242
6243 /* The entry may contain a face id to use. Such a face id is
6244 the id of a Lisp face, not a realized face. A face id of
6245 zero means no face is specified. */
6246 if (it->dpvec_face_id >= 0)
6247 it->face_id = it->dpvec_face_id;
6248 else
6249 {
6250 int lface_id = GLYPH_CODE_FACE (gc);
6251 if (lface_id > 0)
6252 it->face_id = merge_faces (it->f, Qt, lface_id,
6253 it->saved_face_id);
6254 }
6255 }
6256 else
6257 /* Display table entry is invalid. Return a space. */
6258 it->c = ' ', it->len = 1;
6259
6260 /* Don't change position and object of the iterator here. They are
6261 still the values of the character that had this display table
6262 entry or was translated, and that's what we want. */
6263 it->what = IT_CHARACTER;
6264 return 1;
6265 }
6266
6267
6268 /* Load IT with the next display element from Lisp string IT->string.
6269 IT->current.string_pos is the current position within the string.
6270 If IT->current.overlay_string_index >= 0, the Lisp string is an
6271 overlay string. */
6272
6273 static int
6274 next_element_from_string (it)
6275 struct it *it;
6276 {
6277 struct text_pos position;
6278
6279 xassert (STRINGP (it->string));
6280 xassert (IT_STRING_CHARPOS (*it) >= 0);
6281 position = it->current.string_pos;
6282
6283 /* Time to check for invisible text? */
6284 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6285 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6286 {
6287 handle_stop (it);
6288
6289 /* Since a handler may have changed IT->method, we must
6290 recurse here. */
6291 return GET_NEXT_DISPLAY_ELEMENT (it);
6292 }
6293
6294 if (it->current.overlay_string_index >= 0)
6295 {
6296 /* Get the next character from an overlay string. In overlay
6297 strings, There is no field width or padding with spaces to
6298 do. */
6299 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6300 {
6301 it->what = IT_EOB;
6302 return 0;
6303 }
6304 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6305 IT_STRING_BYTEPOS (*it))
6306 && next_element_from_composition (it))
6307 {
6308 return 1;
6309 }
6310 else if (STRING_MULTIBYTE (it->string))
6311 {
6312 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6313 const unsigned char *s = (SDATA (it->string)
6314 + IT_STRING_BYTEPOS (*it));
6315 it->c = string_char_and_length (s, remaining, &it->len);
6316 }
6317 else
6318 {
6319 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6320 it->len = 1;
6321 }
6322 }
6323 else
6324 {
6325 /* Get the next character from a Lisp string that is not an
6326 overlay string. Such strings come from the mode line, for
6327 example. We may have to pad with spaces, or truncate the
6328 string. See also next_element_from_c_string. */
6329 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6330 {
6331 it->what = IT_EOB;
6332 return 0;
6333 }
6334 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6335 {
6336 /* Pad with spaces. */
6337 it->c = ' ', it->len = 1;
6338 CHARPOS (position) = BYTEPOS (position) = -1;
6339 }
6340 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6341 IT_STRING_BYTEPOS (*it))
6342 && next_element_from_composition (it))
6343 {
6344 return 1;
6345 }
6346 else if (STRING_MULTIBYTE (it->string))
6347 {
6348 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6349 const unsigned char *s = (SDATA (it->string)
6350 + IT_STRING_BYTEPOS (*it));
6351 it->c = string_char_and_length (s, maxlen, &it->len);
6352 }
6353 else
6354 {
6355 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6356 it->len = 1;
6357 }
6358 }
6359
6360 /* Record what we have and where it came from. */
6361 it->what = IT_CHARACTER;
6362 it->object = it->string;
6363 it->position = position;
6364 return 1;
6365 }
6366
6367
6368 /* Load IT with next display element from C string IT->s.
6369 IT->string_nchars is the maximum number of characters to return
6370 from the string. IT->end_charpos may be greater than
6371 IT->string_nchars when this function is called, in which case we
6372 may have to return padding spaces. Value is zero if end of string
6373 reached, including padding spaces. */
6374
6375 static int
6376 next_element_from_c_string (it)
6377 struct it *it;
6378 {
6379 int success_p = 1;
6380
6381 xassert (it->s);
6382 it->what = IT_CHARACTER;
6383 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6384 it->object = Qnil;
6385
6386 /* IT's position can be greater IT->string_nchars in case a field
6387 width or precision has been specified when the iterator was
6388 initialized. */
6389 if (IT_CHARPOS (*it) >= it->end_charpos)
6390 {
6391 /* End of the game. */
6392 it->what = IT_EOB;
6393 success_p = 0;
6394 }
6395 else if (IT_CHARPOS (*it) >= it->string_nchars)
6396 {
6397 /* Pad with spaces. */
6398 it->c = ' ', it->len = 1;
6399 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6400 }
6401 else if (it->multibyte_p)
6402 {
6403 /* Implementation note: The calls to strlen apparently aren't a
6404 performance problem because there is no noticeable performance
6405 difference between Emacs running in unibyte or multibyte mode. */
6406 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6407 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6408 maxlen, &it->len);
6409 }
6410 else
6411 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6412
6413 return success_p;
6414 }
6415
6416
6417 /* Set up IT to return characters from an ellipsis, if appropriate.
6418 The definition of the ellipsis glyphs may come from a display table
6419 entry. This function Fills IT with the first glyph from the
6420 ellipsis if an ellipsis is to be displayed. */
6421
6422 static int
6423 next_element_from_ellipsis (it)
6424 struct it *it;
6425 {
6426 if (it->selective_display_ellipsis_p)
6427 setup_for_ellipsis (it, it->len);
6428 else
6429 {
6430 /* The face at the current position may be different from the
6431 face we find after the invisible text. Remember what it
6432 was in IT->saved_face_id, and signal that it's there by
6433 setting face_before_selective_p. */
6434 it->saved_face_id = it->face_id;
6435 it->method = GET_FROM_BUFFER;
6436 it->object = it->w->buffer;
6437 reseat_at_next_visible_line_start (it, 1);
6438 it->face_before_selective_p = 1;
6439 }
6440
6441 return GET_NEXT_DISPLAY_ELEMENT (it);
6442 }
6443
6444
6445 /* Deliver an image display element. The iterator IT is already
6446 filled with image information (done in handle_display_prop). Value
6447 is always 1. */
6448
6449
6450 static int
6451 next_element_from_image (it)
6452 struct it *it;
6453 {
6454 it->what = IT_IMAGE;
6455 return 1;
6456 }
6457
6458
6459 /* Fill iterator IT with next display element from a stretch glyph
6460 property. IT->object is the value of the text property. Value is
6461 always 1. */
6462
6463 static int
6464 next_element_from_stretch (it)
6465 struct it *it;
6466 {
6467 it->what = IT_STRETCH;
6468 return 1;
6469 }
6470
6471
6472 /* Load IT with the next display element from current_buffer. Value
6473 is zero if end of buffer reached. IT->stop_charpos is the next
6474 position at which to stop and check for text properties or buffer
6475 end. */
6476
6477 static int
6478 next_element_from_buffer (it)
6479 struct it *it;
6480 {
6481 int success_p = 1;
6482
6483 xassert (IT_CHARPOS (*it) >= BEGV);
6484
6485 if (IT_CHARPOS (*it) >= it->stop_charpos)
6486 {
6487 if (IT_CHARPOS (*it) >= it->end_charpos)
6488 {
6489 int overlay_strings_follow_p;
6490
6491 /* End of the game, except when overlay strings follow that
6492 haven't been returned yet. */
6493 if (it->overlay_strings_at_end_processed_p)
6494 overlay_strings_follow_p = 0;
6495 else
6496 {
6497 it->overlay_strings_at_end_processed_p = 1;
6498 overlay_strings_follow_p = get_overlay_strings (it, 0);
6499 }
6500
6501 if (overlay_strings_follow_p)
6502 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6503 else
6504 {
6505 it->what = IT_EOB;
6506 it->position = it->current.pos;
6507 success_p = 0;
6508 }
6509 }
6510 else
6511 {
6512 handle_stop (it);
6513 return GET_NEXT_DISPLAY_ELEMENT (it);
6514 }
6515 }
6516 else
6517 {
6518 /* No face changes, overlays etc. in sight, so just return a
6519 character from current_buffer. */
6520 unsigned char *p;
6521
6522 /* Maybe run the redisplay end trigger hook. Performance note:
6523 This doesn't seem to cost measurable time. */
6524 if (it->redisplay_end_trigger_charpos
6525 && it->glyph_row
6526 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6527 run_redisplay_end_trigger_hook (it);
6528
6529 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
6530 && next_element_from_composition (it))
6531 {
6532 return 1;
6533 }
6534
6535 /* Get the next character, maybe multibyte. */
6536 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6537 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6538 it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
6539 else
6540 it->c = *p, it->len = 1;
6541
6542 /* Record what we have and where it came from. */
6543 it->what = IT_CHARACTER;
6544 it->object = it->w->buffer;
6545 it->position = it->current.pos;
6546
6547 /* Normally we return the character found above, except when we
6548 really want to return an ellipsis for selective display. */
6549 if (it->selective)
6550 {
6551 if (it->c == '\n')
6552 {
6553 /* A value of selective > 0 means hide lines indented more
6554 than that number of columns. */
6555 if (it->selective > 0
6556 && IT_CHARPOS (*it) + 1 < ZV
6557 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6558 IT_BYTEPOS (*it) + 1,
6559 (double) it->selective)) /* iftc */
6560 {
6561 success_p = next_element_from_ellipsis (it);
6562 it->dpvec_char_len = -1;
6563 }
6564 }
6565 else if (it->c == '\r' && it->selective == -1)
6566 {
6567 /* A value of selective == -1 means that everything from the
6568 CR to the end of the line is invisible, with maybe an
6569 ellipsis displayed for it. */
6570 success_p = next_element_from_ellipsis (it);
6571 it->dpvec_char_len = -1;
6572 }
6573 }
6574 }
6575
6576 /* Value is zero if end of buffer reached. */
6577 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6578 return success_p;
6579 }
6580
6581
6582 /* Run the redisplay end trigger hook for IT. */
6583
6584 static void
6585 run_redisplay_end_trigger_hook (it)
6586 struct it *it;
6587 {
6588 Lisp_Object args[3];
6589
6590 /* IT->glyph_row should be non-null, i.e. we should be actually
6591 displaying something, or otherwise we should not run the hook. */
6592 xassert (it->glyph_row);
6593
6594 /* Set up hook arguments. */
6595 args[0] = Qredisplay_end_trigger_functions;
6596 args[1] = it->window;
6597 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6598 it->redisplay_end_trigger_charpos = 0;
6599
6600 /* Since we are *trying* to run these functions, don't try to run
6601 them again, even if they get an error. */
6602 it->w->redisplay_end_trigger = Qnil;
6603 Frun_hook_with_args (3, args);
6604
6605 /* Notice if it changed the face of the character we are on. */
6606 handle_face_prop (it);
6607 }
6608
6609
6610 /* Deliver a composition display element. Unlike the other
6611 next_element_from_XXX, this function is not registered in the array
6612 get_next_element[]. It is called from next_element_from_buffer and
6613 next_element_from_string when necessary. */
6614
6615 static int
6616 next_element_from_composition (it)
6617 struct it *it;
6618 {
6619 it->what = IT_COMPOSITION;
6620 it->len = it->cmp_it.nbytes;
6621 if (STRINGP (it->string))
6622 {
6623 if (it->c < 0)
6624 {
6625 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6626 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6627 return 0;
6628 }
6629 it->position = it->current.string_pos;
6630 it->object = it->string;
6631 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6632 IT_STRING_BYTEPOS (*it), it->string);
6633 }
6634 else
6635 {
6636 if (it->c < 0)
6637 {
6638 IT_CHARPOS (*it) += it->cmp_it.nchars;
6639 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6640 return 0;
6641 }
6642 it->position = it->current.pos;
6643 it->object = it->w->buffer;
6644 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6645 IT_BYTEPOS (*it), Qnil);
6646 }
6647 return 1;
6648 }
6649
6650
6651 \f
6652 /***********************************************************************
6653 Moving an iterator without producing glyphs
6654 ***********************************************************************/
6655
6656 /* Check if iterator is at a position corresponding to a valid buffer
6657 position after some move_it_ call. */
6658
6659 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6660 ((it)->method == GET_FROM_STRING \
6661 ? IT_STRING_CHARPOS (*it) == 0 \
6662 : 1)
6663
6664
6665 /* Move iterator IT to a specified buffer or X position within one
6666 line on the display without producing glyphs.
6667
6668 OP should be a bit mask including some or all of these bits:
6669 MOVE_TO_X: Stop on reaching x-position TO_X.
6670 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6671 Regardless of OP's value, stop in reaching the end of the display line.
6672
6673 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6674 This means, in particular, that TO_X includes window's horizontal
6675 scroll amount.
6676
6677 The return value has several possible values that
6678 say what condition caused the scan to stop:
6679
6680 MOVE_POS_MATCH_OR_ZV
6681 - when TO_POS or ZV was reached.
6682
6683 MOVE_X_REACHED
6684 -when TO_X was reached before TO_POS or ZV were reached.
6685
6686 MOVE_LINE_CONTINUED
6687 - when we reached the end of the display area and the line must
6688 be continued.
6689
6690 MOVE_LINE_TRUNCATED
6691 - when we reached the end of the display area and the line is
6692 truncated.
6693
6694 MOVE_NEWLINE_OR_CR
6695 - when we stopped at a line end, i.e. a newline or a CR and selective
6696 display is on. */
6697
6698 static enum move_it_result
6699 move_it_in_display_line_to (struct it *it,
6700 EMACS_INT to_charpos, int to_x,
6701 enum move_operation_enum op)
6702 {
6703 enum move_it_result result = MOVE_UNDEFINED;
6704 struct glyph_row *saved_glyph_row;
6705 struct it wrap_it, atpos_it, atx_it;
6706 int may_wrap = 0;
6707
6708 /* Don't produce glyphs in produce_glyphs. */
6709 saved_glyph_row = it->glyph_row;
6710 it->glyph_row = NULL;
6711
6712 /* Use wrap_it to save a copy of IT wherever a word wrap could
6713 occur. Use atpos_it to save a copy of IT at the desired buffer
6714 position, if found, so that we can scan ahead and check if the
6715 word later overshoots the window edge. Use atx_it similarly, for
6716 pixel positions. */
6717 wrap_it.sp = -1;
6718 atpos_it.sp = -1;
6719 atx_it.sp = -1;
6720
6721 #define BUFFER_POS_REACHED_P() \
6722 ((op & MOVE_TO_POS) != 0 \
6723 && BUFFERP (it->object) \
6724 && IT_CHARPOS (*it) >= to_charpos \
6725 && (it->method == GET_FROM_BUFFER \
6726 || (it->method == GET_FROM_DISPLAY_VECTOR \
6727 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6728
6729 /* If there's a line-/wrap-prefix, handle it. */
6730 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
6731 && it->current_y < it->last_visible_y)
6732 handle_line_prefix (it);
6733
6734 while (1)
6735 {
6736 int x, i, ascent = 0, descent = 0;
6737
6738 /* Utility macro to reset an iterator with x, ascent, and descent. */
6739 #define IT_RESET_X_ASCENT_DESCENT(IT) \
6740 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
6741 (IT)->max_descent = descent)
6742
6743 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
6744 glyph). */
6745 if ((op & MOVE_TO_POS) != 0
6746 && BUFFERP (it->object)
6747 && it->method == GET_FROM_BUFFER
6748 && IT_CHARPOS (*it) > to_charpos)
6749 {
6750 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6751 {
6752 result = MOVE_POS_MATCH_OR_ZV;
6753 break;
6754 }
6755 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6756 /* If wrap_it is valid, the current position might be in a
6757 word that is wrapped. So, save the iterator in
6758 atpos_it and continue to see if wrapping happens. */
6759 atpos_it = *it;
6760 }
6761
6762 /* Stop when ZV reached.
6763 We used to stop here when TO_CHARPOS reached as well, but that is
6764 too soon if this glyph does not fit on this line. So we handle it
6765 explicitly below. */
6766 if (!get_next_display_element (it))
6767 {
6768 result = MOVE_POS_MATCH_OR_ZV;
6769 break;
6770 }
6771
6772 if (it->line_wrap == TRUNCATE)
6773 {
6774 if (BUFFER_POS_REACHED_P ())
6775 {
6776 result = MOVE_POS_MATCH_OR_ZV;
6777 break;
6778 }
6779 }
6780 else
6781 {
6782 if (it->line_wrap == WORD_WRAP)
6783 {
6784 if (IT_DISPLAYING_WHITESPACE (it))
6785 may_wrap = 1;
6786 else if (may_wrap)
6787 {
6788 /* We have reached a glyph that follows one or more
6789 whitespace characters. If the position is
6790 already found, we are done. */
6791 if (atpos_it.sp >= 0)
6792 {
6793 *it = atpos_it;
6794 result = MOVE_POS_MATCH_OR_ZV;
6795 goto done;
6796 }
6797 if (atx_it.sp >= 0)
6798 {
6799 *it = atx_it;
6800 result = MOVE_X_REACHED;
6801 goto done;
6802 }
6803 /* Otherwise, we can wrap here. */
6804 wrap_it = *it;
6805 may_wrap = 0;
6806 }
6807 }
6808 }
6809
6810 /* Remember the line height for the current line, in case
6811 the next element doesn't fit on the line. */
6812 ascent = it->max_ascent;
6813 descent = it->max_descent;
6814
6815 /* The call to produce_glyphs will get the metrics of the
6816 display element IT is loaded with. Record the x-position
6817 before this display element, in case it doesn't fit on the
6818 line. */
6819 x = it->current_x;
6820
6821 PRODUCE_GLYPHS (it);
6822
6823 if (it->area != TEXT_AREA)
6824 {
6825 set_iterator_to_next (it, 1);
6826 continue;
6827 }
6828
6829 /* The number of glyphs we get back in IT->nglyphs will normally
6830 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6831 character on a terminal frame, or (iii) a line end. For the
6832 second case, IT->nglyphs - 1 padding glyphs will be present.
6833 (On X frames, there is only one glyph produced for a
6834 composite character.)
6835
6836 The behavior implemented below means, for continuation lines,
6837 that as many spaces of a TAB as fit on the current line are
6838 displayed there. For terminal frames, as many glyphs of a
6839 multi-glyph character are displayed in the current line, too.
6840 This is what the old redisplay code did, and we keep it that
6841 way. Under X, the whole shape of a complex character must
6842 fit on the line or it will be completely displayed in the
6843 next line.
6844
6845 Note that both for tabs and padding glyphs, all glyphs have
6846 the same width. */
6847 if (it->nglyphs)
6848 {
6849 /* More than one glyph or glyph doesn't fit on line. All
6850 glyphs have the same width. */
6851 int single_glyph_width = it->pixel_width / it->nglyphs;
6852 int new_x;
6853 int x_before_this_char = x;
6854 int hpos_before_this_char = it->hpos;
6855
6856 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6857 {
6858 new_x = x + single_glyph_width;
6859
6860 /* We want to leave anything reaching TO_X to the caller. */
6861 if ((op & MOVE_TO_X) && new_x > to_x)
6862 {
6863 if (BUFFER_POS_REACHED_P ())
6864 {
6865 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6866 goto buffer_pos_reached;
6867 if (atpos_it.sp < 0)
6868 {
6869 atpos_it = *it;
6870 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6871 }
6872 }
6873 else
6874 {
6875 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6876 {
6877 it->current_x = x;
6878 result = MOVE_X_REACHED;
6879 break;
6880 }
6881 if (atx_it.sp < 0)
6882 {
6883 atx_it = *it;
6884 IT_RESET_X_ASCENT_DESCENT (&atx_it);
6885 }
6886 }
6887 }
6888
6889 if (/* Lines are continued. */
6890 it->line_wrap != TRUNCATE
6891 && (/* And glyph doesn't fit on the line. */
6892 new_x > it->last_visible_x
6893 /* Or it fits exactly and we're on a window
6894 system frame. */
6895 || (new_x == it->last_visible_x
6896 && FRAME_WINDOW_P (it->f))))
6897 {
6898 if (/* IT->hpos == 0 means the very first glyph
6899 doesn't fit on the line, e.g. a wide image. */
6900 it->hpos == 0
6901 || (new_x == it->last_visible_x
6902 && FRAME_WINDOW_P (it->f)))
6903 {
6904 ++it->hpos;
6905 it->current_x = new_x;
6906
6907 /* The character's last glyph just barely fits
6908 in this row. */
6909 if (i == it->nglyphs - 1)
6910 {
6911 /* If this is the destination position,
6912 return a position *before* it in this row,
6913 now that we know it fits in this row. */
6914 if (BUFFER_POS_REACHED_P ())
6915 {
6916 if (it->line_wrap != WORD_WRAP
6917 || wrap_it.sp < 0)
6918 {
6919 it->hpos = hpos_before_this_char;
6920 it->current_x = x_before_this_char;
6921 result = MOVE_POS_MATCH_OR_ZV;
6922 break;
6923 }
6924 if (it->line_wrap == WORD_WRAP
6925 && atpos_it.sp < 0)
6926 {
6927 atpos_it = *it;
6928 atpos_it.current_x = x_before_this_char;
6929 atpos_it.hpos = hpos_before_this_char;
6930 }
6931 }
6932
6933 set_iterator_to_next (it, 1);
6934 /* On graphical terminals, newlines may
6935 "overflow" into the fringe if
6936 overflow-newline-into-fringe is non-nil.
6937 On text-only terminals, newlines may
6938 overflow into the last glyph on the
6939 display line.*/
6940 if (!FRAME_WINDOW_P (it->f)
6941 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6942 {
6943 if (!get_next_display_element (it))
6944 {
6945 result = MOVE_POS_MATCH_OR_ZV;
6946 break;
6947 }
6948 if (BUFFER_POS_REACHED_P ())
6949 {
6950 if (ITERATOR_AT_END_OF_LINE_P (it))
6951 result = MOVE_POS_MATCH_OR_ZV;
6952 else
6953 result = MOVE_LINE_CONTINUED;
6954 break;
6955 }
6956 if (ITERATOR_AT_END_OF_LINE_P (it))
6957 {
6958 result = MOVE_NEWLINE_OR_CR;
6959 break;
6960 }
6961 }
6962 }
6963 }
6964 else
6965 IT_RESET_X_ASCENT_DESCENT (it);
6966
6967 if (wrap_it.sp >= 0)
6968 {
6969 *it = wrap_it;
6970 atpos_it.sp = -1;
6971 atx_it.sp = -1;
6972 }
6973
6974 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6975 IT_CHARPOS (*it)));
6976 result = MOVE_LINE_CONTINUED;
6977 break;
6978 }
6979
6980 if (BUFFER_POS_REACHED_P ())
6981 {
6982 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6983 goto buffer_pos_reached;
6984 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6985 {
6986 atpos_it = *it;
6987 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6988 }
6989 }
6990
6991 if (new_x > it->first_visible_x)
6992 {
6993 /* Glyph is visible. Increment number of glyphs that
6994 would be displayed. */
6995 ++it->hpos;
6996 }
6997 }
6998
6999 if (result != MOVE_UNDEFINED)
7000 break;
7001 }
7002 else if (BUFFER_POS_REACHED_P ())
7003 {
7004 buffer_pos_reached:
7005 IT_RESET_X_ASCENT_DESCENT (it);
7006 result = MOVE_POS_MATCH_OR_ZV;
7007 break;
7008 }
7009 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7010 {
7011 /* Stop when TO_X specified and reached. This check is
7012 necessary here because of lines consisting of a line end,
7013 only. The line end will not produce any glyphs and we
7014 would never get MOVE_X_REACHED. */
7015 xassert (it->nglyphs == 0);
7016 result = MOVE_X_REACHED;
7017 break;
7018 }
7019
7020 /* Is this a line end? If yes, we're done. */
7021 if (ITERATOR_AT_END_OF_LINE_P (it))
7022 {
7023 result = MOVE_NEWLINE_OR_CR;
7024 break;
7025 }
7026
7027 /* The current display element has been consumed. Advance
7028 to the next. */
7029 set_iterator_to_next (it, 1);
7030
7031 /* Stop if lines are truncated and IT's current x-position is
7032 past the right edge of the window now. */
7033 if (it->line_wrap == TRUNCATE
7034 && it->current_x >= it->last_visible_x)
7035 {
7036 if (!FRAME_WINDOW_P (it->f)
7037 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7038 {
7039 if (!get_next_display_element (it)
7040 || BUFFER_POS_REACHED_P ())
7041 {
7042 result = MOVE_POS_MATCH_OR_ZV;
7043 break;
7044 }
7045 if (ITERATOR_AT_END_OF_LINE_P (it))
7046 {
7047 result = MOVE_NEWLINE_OR_CR;
7048 break;
7049 }
7050 }
7051 result = MOVE_LINE_TRUNCATED;
7052 break;
7053 }
7054 #undef IT_RESET_X_ASCENT_DESCENT
7055 }
7056
7057 #undef BUFFER_POS_REACHED_P
7058
7059 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7060 restore the saved iterator. */
7061 if (atpos_it.sp >= 0)
7062 *it = atpos_it;
7063 else if (atx_it.sp >= 0)
7064 *it = atx_it;
7065
7066 done:
7067
7068 /* Restore the iterator settings altered at the beginning of this
7069 function. */
7070 it->glyph_row = saved_glyph_row;
7071 return result;
7072 }
7073
7074 /* For external use. */
7075 void
7076 move_it_in_display_line (struct it *it,
7077 EMACS_INT to_charpos, int to_x,
7078 enum move_operation_enum op)
7079 {
7080 if (it->line_wrap == WORD_WRAP
7081 && (op & MOVE_TO_X))
7082 {
7083 struct it save_it = *it;
7084 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7085 /* When word-wrap is on, TO_X may lie past the end
7086 of a wrapped line. Then it->current is the
7087 character on the next line, so backtrack to the
7088 space before the wrap point. */
7089 if (skip == MOVE_LINE_CONTINUED)
7090 {
7091 int prev_x = max (it->current_x - 1, 0);
7092 *it = save_it;
7093 move_it_in_display_line_to
7094 (it, -1, prev_x, MOVE_TO_X);
7095 }
7096 }
7097 else
7098 move_it_in_display_line_to (it, to_charpos, to_x, op);
7099 }
7100
7101
7102 /* Move IT forward until it satisfies one or more of the criteria in
7103 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7104
7105 OP is a bit-mask that specifies where to stop, and in particular,
7106 which of those four position arguments makes a difference. See the
7107 description of enum move_operation_enum.
7108
7109 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7110 screen line, this function will set IT to the next position >
7111 TO_CHARPOS. */
7112
7113 void
7114 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7115 struct it *it;
7116 int to_charpos, to_x, to_y, to_vpos;
7117 int op;
7118 {
7119 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7120 int line_height, line_start_x = 0, reached = 0;
7121
7122 for (;;)
7123 {
7124 if (op & MOVE_TO_VPOS)
7125 {
7126 /* If no TO_CHARPOS and no TO_X specified, stop at the
7127 start of the line TO_VPOS. */
7128 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7129 {
7130 if (it->vpos == to_vpos)
7131 {
7132 reached = 1;
7133 break;
7134 }
7135 else
7136 skip = move_it_in_display_line_to (it, -1, -1, 0);
7137 }
7138 else
7139 {
7140 /* TO_VPOS >= 0 means stop at TO_X in the line at
7141 TO_VPOS, or at TO_POS, whichever comes first. */
7142 if (it->vpos == to_vpos)
7143 {
7144 reached = 2;
7145 break;
7146 }
7147
7148 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7149
7150 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7151 {
7152 reached = 3;
7153 break;
7154 }
7155 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7156 {
7157 /* We have reached TO_X but not in the line we want. */
7158 skip = move_it_in_display_line_to (it, to_charpos,
7159 -1, MOVE_TO_POS);
7160 if (skip == MOVE_POS_MATCH_OR_ZV)
7161 {
7162 reached = 4;
7163 break;
7164 }
7165 }
7166 }
7167 }
7168 else if (op & MOVE_TO_Y)
7169 {
7170 struct it it_backup;
7171
7172 if (it->line_wrap == WORD_WRAP)
7173 it_backup = *it;
7174
7175 /* TO_Y specified means stop at TO_X in the line containing
7176 TO_Y---or at TO_CHARPOS if this is reached first. The
7177 problem is that we can't really tell whether the line
7178 contains TO_Y before we have completely scanned it, and
7179 this may skip past TO_X. What we do is to first scan to
7180 TO_X.
7181
7182 If TO_X is not specified, use a TO_X of zero. The reason
7183 is to make the outcome of this function more predictable.
7184 If we didn't use TO_X == 0, we would stop at the end of
7185 the line which is probably not what a caller would expect
7186 to happen. */
7187 skip = move_it_in_display_line_to
7188 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7189 (MOVE_TO_X | (op & MOVE_TO_POS)));
7190
7191 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7192 if (skip == MOVE_POS_MATCH_OR_ZV)
7193 reached = 5;
7194 else if (skip == MOVE_X_REACHED)
7195 {
7196 /* If TO_X was reached, we want to know whether TO_Y is
7197 in the line. We know this is the case if the already
7198 scanned glyphs make the line tall enough. Otherwise,
7199 we must check by scanning the rest of the line. */
7200 line_height = it->max_ascent + it->max_descent;
7201 if (to_y >= it->current_y
7202 && to_y < it->current_y + line_height)
7203 {
7204 reached = 6;
7205 break;
7206 }
7207 it_backup = *it;
7208 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7209 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7210 op & MOVE_TO_POS);
7211 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7212 line_height = it->max_ascent + it->max_descent;
7213 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7214
7215 if (to_y >= it->current_y
7216 && to_y < it->current_y + line_height)
7217 {
7218 /* If TO_Y is in this line and TO_X was reached
7219 above, we scanned too far. We have to restore
7220 IT's settings to the ones before skipping. */
7221 *it = it_backup;
7222 reached = 6;
7223 }
7224 else
7225 {
7226 skip = skip2;
7227 if (skip == MOVE_POS_MATCH_OR_ZV)
7228 reached = 7;
7229 }
7230 }
7231 else
7232 {
7233 /* Check whether TO_Y is in this line. */
7234 line_height = it->max_ascent + it->max_descent;
7235 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7236
7237 if (to_y >= it->current_y
7238 && to_y < it->current_y + line_height)
7239 {
7240 /* When word-wrap is on, TO_X may lie past the end
7241 of a wrapped line. Then it->current is the
7242 character on the next line, so backtrack to the
7243 space before the wrap point. */
7244 if (skip == MOVE_LINE_CONTINUED
7245 && it->line_wrap == WORD_WRAP)
7246 {
7247 int prev_x = max (it->current_x - 1, 0);
7248 *it = it_backup;
7249 skip = move_it_in_display_line_to
7250 (it, -1, prev_x, MOVE_TO_X);
7251 }
7252 reached = 6;
7253 }
7254 }
7255
7256 if (reached)
7257 break;
7258 }
7259 else if (BUFFERP (it->object)
7260 && (it->method == GET_FROM_BUFFER
7261 || it->method == GET_FROM_STRETCH)
7262 && IT_CHARPOS (*it) >= to_charpos)
7263 skip = MOVE_POS_MATCH_OR_ZV;
7264 else
7265 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7266
7267 switch (skip)
7268 {
7269 case MOVE_POS_MATCH_OR_ZV:
7270 reached = 8;
7271 goto out;
7272
7273 case MOVE_NEWLINE_OR_CR:
7274 set_iterator_to_next (it, 1);
7275 it->continuation_lines_width = 0;
7276 break;
7277
7278 case MOVE_LINE_TRUNCATED:
7279 it->continuation_lines_width = 0;
7280 reseat_at_next_visible_line_start (it, 0);
7281 if ((op & MOVE_TO_POS) != 0
7282 && IT_CHARPOS (*it) > to_charpos)
7283 {
7284 reached = 9;
7285 goto out;
7286 }
7287 break;
7288
7289 case MOVE_LINE_CONTINUED:
7290 /* For continued lines ending in a tab, some of the glyphs
7291 associated with the tab are displayed on the current
7292 line. Since it->current_x does not include these glyphs,
7293 we use it->last_visible_x instead. */
7294 if (it->c == '\t')
7295 {
7296 it->continuation_lines_width += it->last_visible_x;
7297 /* When moving by vpos, ensure that the iterator really
7298 advances to the next line (bug#847, bug#969). Fixme:
7299 do we need to do this in other circumstances? */
7300 if (it->current_x != it->last_visible_x
7301 && (op & MOVE_TO_VPOS)
7302 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7303 {
7304 line_start_x = it->current_x + it->pixel_width
7305 - it->last_visible_x;
7306 set_iterator_to_next (it, 0);
7307 }
7308 }
7309 else
7310 it->continuation_lines_width += it->current_x;
7311 break;
7312
7313 default:
7314 abort ();
7315 }
7316
7317 /* Reset/increment for the next run. */
7318 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7319 it->current_x = line_start_x;
7320 line_start_x = 0;
7321 it->hpos = 0;
7322 it->current_y += it->max_ascent + it->max_descent;
7323 ++it->vpos;
7324 last_height = it->max_ascent + it->max_descent;
7325 last_max_ascent = it->max_ascent;
7326 it->max_ascent = it->max_descent = 0;
7327 }
7328
7329 out:
7330
7331 /* On text terminals, we may stop at the end of a line in the middle
7332 of a multi-character glyph. If the glyph itself is continued,
7333 i.e. it is actually displayed on the next line, don't treat this
7334 stopping point as valid; move to the next line instead (unless
7335 that brings us offscreen). */
7336 if (!FRAME_WINDOW_P (it->f)
7337 && op & MOVE_TO_POS
7338 && IT_CHARPOS (*it) == to_charpos
7339 && it->what == IT_CHARACTER
7340 && it->nglyphs > 1
7341 && it->line_wrap == WINDOW_WRAP
7342 && it->current_x == it->last_visible_x - 1
7343 && it->c != '\n'
7344 && it->c != '\t'
7345 && it->vpos < XFASTINT (it->w->window_end_vpos))
7346 {
7347 it->continuation_lines_width += it->current_x;
7348 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7349 it->current_y += it->max_ascent + it->max_descent;
7350 ++it->vpos;
7351 last_height = it->max_ascent + it->max_descent;
7352 last_max_ascent = it->max_ascent;
7353 }
7354
7355 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7356 }
7357
7358
7359 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7360
7361 If DY > 0, move IT backward at least that many pixels. DY = 0
7362 means move IT backward to the preceding line start or BEGV. This
7363 function may move over more than DY pixels if IT->current_y - DY
7364 ends up in the middle of a line; in this case IT->current_y will be
7365 set to the top of the line moved to. */
7366
7367 void
7368 move_it_vertically_backward (it, dy)
7369 struct it *it;
7370 int dy;
7371 {
7372 int nlines, h;
7373 struct it it2, it3;
7374 int start_pos;
7375
7376 move_further_back:
7377 xassert (dy >= 0);
7378
7379 start_pos = IT_CHARPOS (*it);
7380
7381 /* Estimate how many newlines we must move back. */
7382 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7383
7384 /* Set the iterator's position that many lines back. */
7385 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7386 back_to_previous_visible_line_start (it);
7387
7388 /* Reseat the iterator here. When moving backward, we don't want
7389 reseat to skip forward over invisible text, set up the iterator
7390 to deliver from overlay strings at the new position etc. So,
7391 use reseat_1 here. */
7392 reseat_1 (it, it->current.pos, 1);
7393
7394 /* We are now surely at a line start. */
7395 it->current_x = it->hpos = 0;
7396 it->continuation_lines_width = 0;
7397
7398 /* Move forward and see what y-distance we moved. First move to the
7399 start of the next line so that we get its height. We need this
7400 height to be able to tell whether we reached the specified
7401 y-distance. */
7402 it2 = *it;
7403 it2.max_ascent = it2.max_descent = 0;
7404 do
7405 {
7406 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7407 MOVE_TO_POS | MOVE_TO_VPOS);
7408 }
7409 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7410 xassert (IT_CHARPOS (*it) >= BEGV);
7411 it3 = it2;
7412
7413 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7414 xassert (IT_CHARPOS (*it) >= BEGV);
7415 /* H is the actual vertical distance from the position in *IT
7416 and the starting position. */
7417 h = it2.current_y - it->current_y;
7418 /* NLINES is the distance in number of lines. */
7419 nlines = it2.vpos - it->vpos;
7420
7421 /* Correct IT's y and vpos position
7422 so that they are relative to the starting point. */
7423 it->vpos -= nlines;
7424 it->current_y -= h;
7425
7426 if (dy == 0)
7427 {
7428 /* DY == 0 means move to the start of the screen line. The
7429 value of nlines is > 0 if continuation lines were involved. */
7430 if (nlines > 0)
7431 move_it_by_lines (it, nlines, 1);
7432 }
7433 else
7434 {
7435 /* The y-position we try to reach, relative to *IT.
7436 Note that H has been subtracted in front of the if-statement. */
7437 int target_y = it->current_y + h - dy;
7438 int y0 = it3.current_y;
7439 int y1 = line_bottom_y (&it3);
7440 int line_height = y1 - y0;
7441
7442 /* If we did not reach target_y, try to move further backward if
7443 we can. If we moved too far backward, try to move forward. */
7444 if (target_y < it->current_y
7445 /* This is heuristic. In a window that's 3 lines high, with
7446 a line height of 13 pixels each, recentering with point
7447 on the bottom line will try to move -39/2 = 19 pixels
7448 backward. Try to avoid moving into the first line. */
7449 && (it->current_y - target_y
7450 > min (window_box_height (it->w), line_height * 2 / 3))
7451 && IT_CHARPOS (*it) > BEGV)
7452 {
7453 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7454 target_y - it->current_y));
7455 dy = it->current_y - target_y;
7456 goto move_further_back;
7457 }
7458 else if (target_y >= it->current_y + line_height
7459 && IT_CHARPOS (*it) < ZV)
7460 {
7461 /* Should move forward by at least one line, maybe more.
7462
7463 Note: Calling move_it_by_lines can be expensive on
7464 terminal frames, where compute_motion is used (via
7465 vmotion) to do the job, when there are very long lines
7466 and truncate-lines is nil. That's the reason for
7467 treating terminal frames specially here. */
7468
7469 if (!FRAME_WINDOW_P (it->f))
7470 move_it_vertically (it, target_y - (it->current_y + line_height));
7471 else
7472 {
7473 do
7474 {
7475 move_it_by_lines (it, 1, 1);
7476 }
7477 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7478 }
7479 }
7480 }
7481 }
7482
7483
7484 /* Move IT by a specified amount of pixel lines DY. DY negative means
7485 move backwards. DY = 0 means move to start of screen line. At the
7486 end, IT will be on the start of a screen line. */
7487
7488 void
7489 move_it_vertically (it, dy)
7490 struct it *it;
7491 int dy;
7492 {
7493 if (dy <= 0)
7494 move_it_vertically_backward (it, -dy);
7495 else
7496 {
7497 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7498 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7499 MOVE_TO_POS | MOVE_TO_Y);
7500 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7501
7502 /* If buffer ends in ZV without a newline, move to the start of
7503 the line to satisfy the post-condition. */
7504 if (IT_CHARPOS (*it) == ZV
7505 && ZV > BEGV
7506 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7507 move_it_by_lines (it, 0, 0);
7508 }
7509 }
7510
7511
7512 /* Move iterator IT past the end of the text line it is in. */
7513
7514 void
7515 move_it_past_eol (it)
7516 struct it *it;
7517 {
7518 enum move_it_result rc;
7519
7520 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7521 if (rc == MOVE_NEWLINE_OR_CR)
7522 set_iterator_to_next (it, 0);
7523 }
7524
7525
7526 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7527 negative means move up. DVPOS == 0 means move to the start of the
7528 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7529 NEED_Y_P is zero, IT->current_y will be left unchanged.
7530
7531 Further optimization ideas: If we would know that IT->f doesn't use
7532 a face with proportional font, we could be faster for
7533 truncate-lines nil. */
7534
7535 void
7536 move_it_by_lines (it, dvpos, need_y_p)
7537 struct it *it;
7538 int dvpos, need_y_p;
7539 {
7540 struct position pos;
7541
7542 /* The commented-out optimization uses vmotion on terminals. This
7543 gives bad results, because elements like it->what, on which
7544 callers such as pos_visible_p rely, aren't updated. */
7545 /* if (!FRAME_WINDOW_P (it->f))
7546 {
7547 struct text_pos textpos;
7548
7549 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7550 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7551 reseat (it, textpos, 1);
7552 it->vpos += pos.vpos;
7553 it->current_y += pos.vpos;
7554 }
7555 else */
7556
7557 if (dvpos == 0)
7558 {
7559 /* DVPOS == 0 means move to the start of the screen line. */
7560 move_it_vertically_backward (it, 0);
7561 xassert (it->current_x == 0 && it->hpos == 0);
7562 /* Let next call to line_bottom_y calculate real line height */
7563 last_height = 0;
7564 }
7565 else if (dvpos > 0)
7566 {
7567 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7568 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7569 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7570 }
7571 else
7572 {
7573 struct it it2;
7574 int start_charpos, i;
7575
7576 /* Start at the beginning of the screen line containing IT's
7577 position. This may actually move vertically backwards,
7578 in case of overlays, so adjust dvpos accordingly. */
7579 dvpos += it->vpos;
7580 move_it_vertically_backward (it, 0);
7581 dvpos -= it->vpos;
7582
7583 /* Go back -DVPOS visible lines and reseat the iterator there. */
7584 start_charpos = IT_CHARPOS (*it);
7585 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7586 back_to_previous_visible_line_start (it);
7587 reseat (it, it->current.pos, 1);
7588
7589 /* Move further back if we end up in a string or an image. */
7590 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7591 {
7592 /* First try to move to start of display line. */
7593 dvpos += it->vpos;
7594 move_it_vertically_backward (it, 0);
7595 dvpos -= it->vpos;
7596 if (IT_POS_VALID_AFTER_MOVE_P (it))
7597 break;
7598 /* If start of line is still in string or image,
7599 move further back. */
7600 back_to_previous_visible_line_start (it);
7601 reseat (it, it->current.pos, 1);
7602 dvpos--;
7603 }
7604
7605 it->current_x = it->hpos = 0;
7606
7607 /* Above call may have moved too far if continuation lines
7608 are involved. Scan forward and see if it did. */
7609 it2 = *it;
7610 it2.vpos = it2.current_y = 0;
7611 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7612 it->vpos -= it2.vpos;
7613 it->current_y -= it2.current_y;
7614 it->current_x = it->hpos = 0;
7615
7616 /* If we moved too far back, move IT some lines forward. */
7617 if (it2.vpos > -dvpos)
7618 {
7619 int delta = it2.vpos + dvpos;
7620 it2 = *it;
7621 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7622 /* Move back again if we got too far ahead. */
7623 if (IT_CHARPOS (*it) >= start_charpos)
7624 *it = it2;
7625 }
7626 }
7627 }
7628
7629 /* Return 1 if IT points into the middle of a display vector. */
7630
7631 int
7632 in_display_vector_p (it)
7633 struct it *it;
7634 {
7635 return (it->method == GET_FROM_DISPLAY_VECTOR
7636 && it->current.dpvec_index > 0
7637 && it->dpvec + it->current.dpvec_index != it->dpend);
7638 }
7639
7640 \f
7641 /***********************************************************************
7642 Messages
7643 ***********************************************************************/
7644
7645
7646 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7647 to *Messages*. */
7648
7649 void
7650 add_to_log (format, arg1, arg2)
7651 char *format;
7652 Lisp_Object arg1, arg2;
7653 {
7654 Lisp_Object args[3];
7655 Lisp_Object msg, fmt;
7656 char *buffer;
7657 int len;
7658 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7659 USE_SAFE_ALLOCA;
7660
7661 /* Do nothing if called asynchronously. Inserting text into
7662 a buffer may call after-change-functions and alike and
7663 that would means running Lisp asynchronously. */
7664 if (handling_signal)
7665 return;
7666
7667 fmt = msg = Qnil;
7668 GCPRO4 (fmt, msg, arg1, arg2);
7669
7670 args[0] = fmt = build_string (format);
7671 args[1] = arg1;
7672 args[2] = arg2;
7673 msg = Fformat (3, args);
7674
7675 len = SBYTES (msg) + 1;
7676 SAFE_ALLOCA (buffer, char *, len);
7677 bcopy (SDATA (msg), buffer, len);
7678
7679 message_dolog (buffer, len - 1, 1, 0);
7680 SAFE_FREE ();
7681
7682 UNGCPRO;
7683 }
7684
7685
7686 /* Output a newline in the *Messages* buffer if "needs" one. */
7687
7688 void
7689 message_log_maybe_newline ()
7690 {
7691 if (message_log_need_newline)
7692 message_dolog ("", 0, 1, 0);
7693 }
7694
7695
7696 /* Add a string M of length NBYTES to the message log, optionally
7697 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7698 nonzero, means interpret the contents of M as multibyte. This
7699 function calls low-level routines in order to bypass text property
7700 hooks, etc. which might not be safe to run.
7701
7702 This may GC (insert may run before/after change hooks),
7703 so the buffer M must NOT point to a Lisp string. */
7704
7705 void
7706 message_dolog (m, nbytes, nlflag, multibyte)
7707 const char *m;
7708 int nbytes, nlflag, multibyte;
7709 {
7710 if (!NILP (Vmemory_full))
7711 return;
7712
7713 if (!NILP (Vmessage_log_max))
7714 {
7715 struct buffer *oldbuf;
7716 Lisp_Object oldpoint, oldbegv, oldzv;
7717 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7718 int point_at_end = 0;
7719 int zv_at_end = 0;
7720 Lisp_Object old_deactivate_mark, tem;
7721 struct gcpro gcpro1;
7722
7723 old_deactivate_mark = Vdeactivate_mark;
7724 oldbuf = current_buffer;
7725 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7726 current_buffer->undo_list = Qt;
7727
7728 oldpoint = message_dolog_marker1;
7729 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7730 oldbegv = message_dolog_marker2;
7731 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7732 oldzv = message_dolog_marker3;
7733 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7734 GCPRO1 (old_deactivate_mark);
7735
7736 if (PT == Z)
7737 point_at_end = 1;
7738 if (ZV == Z)
7739 zv_at_end = 1;
7740
7741 BEGV = BEG;
7742 BEGV_BYTE = BEG_BYTE;
7743 ZV = Z;
7744 ZV_BYTE = Z_BYTE;
7745 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7746
7747 /* Insert the string--maybe converting multibyte to single byte
7748 or vice versa, so that all the text fits the buffer. */
7749 if (multibyte
7750 && NILP (current_buffer->enable_multibyte_characters))
7751 {
7752 int i, c, char_bytes;
7753 unsigned char work[1];
7754
7755 /* Convert a multibyte string to single-byte
7756 for the *Message* buffer. */
7757 for (i = 0; i < nbytes; i += char_bytes)
7758 {
7759 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7760 work[0] = (ASCII_CHAR_P (c)
7761 ? c
7762 : multibyte_char_to_unibyte (c, Qnil));
7763 insert_1_both (work, 1, 1, 1, 0, 0);
7764 }
7765 }
7766 else if (! multibyte
7767 && ! NILP (current_buffer->enable_multibyte_characters))
7768 {
7769 int i, c, char_bytes;
7770 unsigned char *msg = (unsigned char *) m;
7771 unsigned char str[MAX_MULTIBYTE_LENGTH];
7772 /* Convert a single-byte string to multibyte
7773 for the *Message* buffer. */
7774 for (i = 0; i < nbytes; i++)
7775 {
7776 c = msg[i];
7777 MAKE_CHAR_MULTIBYTE (c);
7778 char_bytes = CHAR_STRING (c, str);
7779 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7780 }
7781 }
7782 else if (nbytes)
7783 insert_1 (m, nbytes, 1, 0, 0);
7784
7785 if (nlflag)
7786 {
7787 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7788 insert_1 ("\n", 1, 1, 0, 0);
7789
7790 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7791 this_bol = PT;
7792 this_bol_byte = PT_BYTE;
7793
7794 /* See if this line duplicates the previous one.
7795 If so, combine duplicates. */
7796 if (this_bol > BEG)
7797 {
7798 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7799 prev_bol = PT;
7800 prev_bol_byte = PT_BYTE;
7801
7802 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7803 this_bol, this_bol_byte);
7804 if (dup)
7805 {
7806 del_range_both (prev_bol, prev_bol_byte,
7807 this_bol, this_bol_byte, 0);
7808 if (dup > 1)
7809 {
7810 char dupstr[40];
7811 int duplen;
7812
7813 /* If you change this format, don't forget to also
7814 change message_log_check_duplicate. */
7815 sprintf (dupstr, " [%d times]", dup);
7816 duplen = strlen (dupstr);
7817 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7818 insert_1 (dupstr, duplen, 1, 0, 1);
7819 }
7820 }
7821 }
7822
7823 /* If we have more than the desired maximum number of lines
7824 in the *Messages* buffer now, delete the oldest ones.
7825 This is safe because we don't have undo in this buffer. */
7826
7827 if (NATNUMP (Vmessage_log_max))
7828 {
7829 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7830 -XFASTINT (Vmessage_log_max) - 1, 0);
7831 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7832 }
7833 }
7834 BEGV = XMARKER (oldbegv)->charpos;
7835 BEGV_BYTE = marker_byte_position (oldbegv);
7836
7837 if (zv_at_end)
7838 {
7839 ZV = Z;
7840 ZV_BYTE = Z_BYTE;
7841 }
7842 else
7843 {
7844 ZV = XMARKER (oldzv)->charpos;
7845 ZV_BYTE = marker_byte_position (oldzv);
7846 }
7847
7848 if (point_at_end)
7849 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7850 else
7851 /* We can't do Fgoto_char (oldpoint) because it will run some
7852 Lisp code. */
7853 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7854 XMARKER (oldpoint)->bytepos);
7855
7856 UNGCPRO;
7857 unchain_marker (XMARKER (oldpoint));
7858 unchain_marker (XMARKER (oldbegv));
7859 unchain_marker (XMARKER (oldzv));
7860
7861 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7862 set_buffer_internal (oldbuf);
7863 if (NILP (tem))
7864 windows_or_buffers_changed = old_windows_or_buffers_changed;
7865 message_log_need_newline = !nlflag;
7866 Vdeactivate_mark = old_deactivate_mark;
7867 }
7868 }
7869
7870
7871 /* We are at the end of the buffer after just having inserted a newline.
7872 (Note: We depend on the fact we won't be crossing the gap.)
7873 Check to see if the most recent message looks a lot like the previous one.
7874 Return 0 if different, 1 if the new one should just replace it, or a
7875 value N > 1 if we should also append " [N times]". */
7876
7877 static int
7878 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7879 int prev_bol, this_bol;
7880 int prev_bol_byte, this_bol_byte;
7881 {
7882 int i;
7883 int len = Z_BYTE - 1 - this_bol_byte;
7884 int seen_dots = 0;
7885 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7886 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7887
7888 for (i = 0; i < len; i++)
7889 {
7890 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7891 seen_dots = 1;
7892 if (p1[i] != p2[i])
7893 return seen_dots;
7894 }
7895 p1 += len;
7896 if (*p1 == '\n')
7897 return 2;
7898 if (*p1++ == ' ' && *p1++ == '[')
7899 {
7900 int n = 0;
7901 while (*p1 >= '0' && *p1 <= '9')
7902 n = n * 10 + *p1++ - '0';
7903 if (strncmp (p1, " times]\n", 8) == 0)
7904 return n+1;
7905 }
7906 return 0;
7907 }
7908 \f
7909
7910 /* Display an echo area message M with a specified length of NBYTES
7911 bytes. The string may include null characters. If M is 0, clear
7912 out any existing message, and let the mini-buffer text show
7913 through.
7914
7915 This may GC, so the buffer M must NOT point to a Lisp string. */
7916
7917 void
7918 message2 (m, nbytes, multibyte)
7919 const char *m;
7920 int nbytes;
7921 int multibyte;
7922 {
7923 /* First flush out any partial line written with print. */
7924 message_log_maybe_newline ();
7925 if (m)
7926 message_dolog (m, nbytes, 1, multibyte);
7927 message2_nolog (m, nbytes, multibyte);
7928 }
7929
7930
7931 /* The non-logging counterpart of message2. */
7932
7933 void
7934 message2_nolog (m, nbytes, multibyte)
7935 const char *m;
7936 int nbytes, multibyte;
7937 {
7938 struct frame *sf = SELECTED_FRAME ();
7939 message_enable_multibyte = multibyte;
7940
7941 if (FRAME_INITIAL_P (sf))
7942 {
7943 if (noninteractive_need_newline)
7944 putc ('\n', stderr);
7945 noninteractive_need_newline = 0;
7946 if (m)
7947 fwrite (m, nbytes, 1, stderr);
7948 if (cursor_in_echo_area == 0)
7949 fprintf (stderr, "\n");
7950 fflush (stderr);
7951 }
7952 /* A null message buffer means that the frame hasn't really been
7953 initialized yet. Error messages get reported properly by
7954 cmd_error, so this must be just an informative message; toss it. */
7955 else if (INTERACTIVE
7956 && sf->glyphs_initialized_p
7957 && FRAME_MESSAGE_BUF (sf))
7958 {
7959 Lisp_Object mini_window;
7960 struct frame *f;
7961
7962 /* Get the frame containing the mini-buffer
7963 that the selected frame is using. */
7964 mini_window = FRAME_MINIBUF_WINDOW (sf);
7965 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7966
7967 FRAME_SAMPLE_VISIBILITY (f);
7968 if (FRAME_VISIBLE_P (sf)
7969 && ! FRAME_VISIBLE_P (f))
7970 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7971
7972 if (m)
7973 {
7974 set_message (m, Qnil, nbytes, multibyte);
7975 if (minibuffer_auto_raise)
7976 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7977 }
7978 else
7979 clear_message (1, 1);
7980
7981 do_pending_window_change (0);
7982 echo_area_display (1);
7983 do_pending_window_change (0);
7984 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7985 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7986 }
7987 }
7988
7989
7990 /* Display an echo area message M with a specified length of NBYTES
7991 bytes. The string may include null characters. If M is not a
7992 string, clear out any existing message, and let the mini-buffer
7993 text show through.
7994
7995 This function cancels echoing. */
7996
7997 void
7998 message3 (m, nbytes, multibyte)
7999 Lisp_Object m;
8000 int nbytes;
8001 int multibyte;
8002 {
8003 struct gcpro gcpro1;
8004
8005 GCPRO1 (m);
8006 clear_message (1,1);
8007 cancel_echoing ();
8008
8009 /* First flush out any partial line written with print. */
8010 message_log_maybe_newline ();
8011 if (STRINGP (m))
8012 {
8013 char *buffer;
8014 USE_SAFE_ALLOCA;
8015
8016 SAFE_ALLOCA (buffer, char *, nbytes);
8017 bcopy (SDATA (m), buffer, nbytes);
8018 message_dolog (buffer, nbytes, 1, multibyte);
8019 SAFE_FREE ();
8020 }
8021 message3_nolog (m, nbytes, multibyte);
8022
8023 UNGCPRO;
8024 }
8025
8026
8027 /* The non-logging version of message3.
8028 This does not cancel echoing, because it is used for echoing.
8029 Perhaps we need to make a separate function for echoing
8030 and make this cancel echoing. */
8031
8032 void
8033 message3_nolog (m, nbytes, multibyte)
8034 Lisp_Object m;
8035 int nbytes, multibyte;
8036 {
8037 struct frame *sf = SELECTED_FRAME ();
8038 message_enable_multibyte = multibyte;
8039
8040 if (FRAME_INITIAL_P (sf))
8041 {
8042 if (noninteractive_need_newline)
8043 putc ('\n', stderr);
8044 noninteractive_need_newline = 0;
8045 if (STRINGP (m))
8046 fwrite (SDATA (m), nbytes, 1, stderr);
8047 if (cursor_in_echo_area == 0)
8048 fprintf (stderr, "\n");
8049 fflush (stderr);
8050 }
8051 /* A null message buffer means that the frame hasn't really been
8052 initialized yet. Error messages get reported properly by
8053 cmd_error, so this must be just an informative message; toss it. */
8054 else if (INTERACTIVE
8055 && sf->glyphs_initialized_p
8056 && FRAME_MESSAGE_BUF (sf))
8057 {
8058 Lisp_Object mini_window;
8059 Lisp_Object frame;
8060 struct frame *f;
8061
8062 /* Get the frame containing the mini-buffer
8063 that the selected frame is using. */
8064 mini_window = FRAME_MINIBUF_WINDOW (sf);
8065 frame = XWINDOW (mini_window)->frame;
8066 f = XFRAME (frame);
8067
8068 FRAME_SAMPLE_VISIBILITY (f);
8069 if (FRAME_VISIBLE_P (sf)
8070 && !FRAME_VISIBLE_P (f))
8071 Fmake_frame_visible (frame);
8072
8073 if (STRINGP (m) && SCHARS (m) > 0)
8074 {
8075 set_message (NULL, m, nbytes, multibyte);
8076 if (minibuffer_auto_raise)
8077 Fraise_frame (frame);
8078 /* Assume we are not echoing.
8079 (If we are, echo_now will override this.) */
8080 echo_message_buffer = Qnil;
8081 }
8082 else
8083 clear_message (1, 1);
8084
8085 do_pending_window_change (0);
8086 echo_area_display (1);
8087 do_pending_window_change (0);
8088 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8089 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8090 }
8091 }
8092
8093
8094 /* Display a null-terminated echo area message M. If M is 0, clear
8095 out any existing message, and let the mini-buffer text show through.
8096
8097 The buffer M must continue to exist until after the echo area gets
8098 cleared or some other message gets displayed there. Do not pass
8099 text that is stored in a Lisp string. Do not pass text in a buffer
8100 that was alloca'd. */
8101
8102 void
8103 message1 (m)
8104 char *m;
8105 {
8106 message2 (m, (m ? strlen (m) : 0), 0);
8107 }
8108
8109
8110 /* The non-logging counterpart of message1. */
8111
8112 void
8113 message1_nolog (m)
8114 char *m;
8115 {
8116 message2_nolog (m, (m ? strlen (m) : 0), 0);
8117 }
8118
8119 /* Display a message M which contains a single %s
8120 which gets replaced with STRING. */
8121
8122 void
8123 message_with_string (m, string, log)
8124 char *m;
8125 Lisp_Object string;
8126 int log;
8127 {
8128 CHECK_STRING (string);
8129
8130 if (noninteractive)
8131 {
8132 if (m)
8133 {
8134 if (noninteractive_need_newline)
8135 putc ('\n', stderr);
8136 noninteractive_need_newline = 0;
8137 fprintf (stderr, m, SDATA (string));
8138 if (!cursor_in_echo_area)
8139 fprintf (stderr, "\n");
8140 fflush (stderr);
8141 }
8142 }
8143 else if (INTERACTIVE)
8144 {
8145 /* The frame whose minibuffer we're going to display the message on.
8146 It may be larger than the selected frame, so we need
8147 to use its buffer, not the selected frame's buffer. */
8148 Lisp_Object mini_window;
8149 struct frame *f, *sf = SELECTED_FRAME ();
8150
8151 /* Get the frame containing the minibuffer
8152 that the selected frame is using. */
8153 mini_window = FRAME_MINIBUF_WINDOW (sf);
8154 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8155
8156 /* A null message buffer means that the frame hasn't really been
8157 initialized yet. Error messages get reported properly by
8158 cmd_error, so this must be just an informative message; toss it. */
8159 if (FRAME_MESSAGE_BUF (f))
8160 {
8161 Lisp_Object args[2], message;
8162 struct gcpro gcpro1, gcpro2;
8163
8164 args[0] = build_string (m);
8165 args[1] = message = string;
8166 GCPRO2 (args[0], message);
8167 gcpro1.nvars = 2;
8168
8169 message = Fformat (2, args);
8170
8171 if (log)
8172 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8173 else
8174 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8175
8176 UNGCPRO;
8177
8178 /* Print should start at the beginning of the message
8179 buffer next time. */
8180 message_buf_print = 0;
8181 }
8182 }
8183 }
8184
8185
8186 /* Dump an informative message to the minibuf. If M is 0, clear out
8187 any existing message, and let the mini-buffer text show through. */
8188
8189 /* VARARGS 1 */
8190 void
8191 message (m, a1, a2, a3)
8192 char *m;
8193 EMACS_INT a1, a2, a3;
8194 {
8195 if (noninteractive)
8196 {
8197 if (m)
8198 {
8199 if (noninteractive_need_newline)
8200 putc ('\n', stderr);
8201 noninteractive_need_newline = 0;
8202 fprintf (stderr, m, a1, a2, a3);
8203 if (cursor_in_echo_area == 0)
8204 fprintf (stderr, "\n");
8205 fflush (stderr);
8206 }
8207 }
8208 else if (INTERACTIVE)
8209 {
8210 /* The frame whose mini-buffer we're going to display the message
8211 on. It may be larger than the selected frame, so we need to
8212 use its buffer, not the selected frame's buffer. */
8213 Lisp_Object mini_window;
8214 struct frame *f, *sf = SELECTED_FRAME ();
8215
8216 /* Get the frame containing the mini-buffer
8217 that the selected frame is using. */
8218 mini_window = FRAME_MINIBUF_WINDOW (sf);
8219 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8220
8221 /* A null message buffer means that the frame hasn't really been
8222 initialized yet. Error messages get reported properly by
8223 cmd_error, so this must be just an informative message; toss
8224 it. */
8225 if (FRAME_MESSAGE_BUF (f))
8226 {
8227 if (m)
8228 {
8229 int len;
8230 #ifdef NO_ARG_ARRAY
8231 char *a[3];
8232 a[0] = (char *) a1;
8233 a[1] = (char *) a2;
8234 a[2] = (char *) a3;
8235
8236 len = doprnt (FRAME_MESSAGE_BUF (f),
8237 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
8238 #else
8239 len = doprnt (FRAME_MESSAGE_BUF (f),
8240 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
8241 (char **) &a1);
8242 #endif /* NO_ARG_ARRAY */
8243
8244 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8245 }
8246 else
8247 message1 (0);
8248
8249 /* Print should start at the beginning of the message
8250 buffer next time. */
8251 message_buf_print = 0;
8252 }
8253 }
8254 }
8255
8256
8257 /* The non-logging version of message. */
8258
8259 void
8260 message_nolog (m, a1, a2, a3)
8261 char *m;
8262 EMACS_INT a1, a2, a3;
8263 {
8264 Lisp_Object old_log_max;
8265 old_log_max = Vmessage_log_max;
8266 Vmessage_log_max = Qnil;
8267 message (m, a1, a2, a3);
8268 Vmessage_log_max = old_log_max;
8269 }
8270
8271
8272 /* Display the current message in the current mini-buffer. This is
8273 only called from error handlers in process.c, and is not time
8274 critical. */
8275
8276 void
8277 update_echo_area ()
8278 {
8279 if (!NILP (echo_area_buffer[0]))
8280 {
8281 Lisp_Object string;
8282 string = Fcurrent_message ();
8283 message3 (string, SBYTES (string),
8284 !NILP (current_buffer->enable_multibyte_characters));
8285 }
8286 }
8287
8288
8289 /* Make sure echo area buffers in `echo_buffers' are live.
8290 If they aren't, make new ones. */
8291
8292 static void
8293 ensure_echo_area_buffers ()
8294 {
8295 int i;
8296
8297 for (i = 0; i < 2; ++i)
8298 if (!BUFFERP (echo_buffer[i])
8299 || NILP (XBUFFER (echo_buffer[i])->name))
8300 {
8301 char name[30];
8302 Lisp_Object old_buffer;
8303 int j;
8304
8305 old_buffer = echo_buffer[i];
8306 sprintf (name, " *Echo Area %d*", i);
8307 echo_buffer[i] = Fget_buffer_create (build_string (name));
8308 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8309 /* to force word wrap in echo area -
8310 it was decided to postpone this*/
8311 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8312
8313 for (j = 0; j < 2; ++j)
8314 if (EQ (old_buffer, echo_area_buffer[j]))
8315 echo_area_buffer[j] = echo_buffer[i];
8316 }
8317 }
8318
8319
8320 /* Call FN with args A1..A4 with either the current or last displayed
8321 echo_area_buffer as current buffer.
8322
8323 WHICH zero means use the current message buffer
8324 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8325 from echo_buffer[] and clear it.
8326
8327 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8328 suitable buffer from echo_buffer[] and clear it.
8329
8330 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8331 that the current message becomes the last displayed one, make
8332 choose a suitable buffer for echo_area_buffer[0], and clear it.
8333
8334 Value is what FN returns. */
8335
8336 static int
8337 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
8338 struct window *w;
8339 int which;
8340 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
8341 EMACS_INT a1;
8342 Lisp_Object a2;
8343 EMACS_INT a3, a4;
8344 {
8345 Lisp_Object buffer;
8346 int this_one, the_other, clear_buffer_p, rc;
8347 int count = SPECPDL_INDEX ();
8348
8349 /* If buffers aren't live, make new ones. */
8350 ensure_echo_area_buffers ();
8351
8352 clear_buffer_p = 0;
8353
8354 if (which == 0)
8355 this_one = 0, the_other = 1;
8356 else if (which > 0)
8357 this_one = 1, the_other = 0;
8358 else
8359 {
8360 this_one = 0, the_other = 1;
8361 clear_buffer_p = 1;
8362
8363 /* We need a fresh one in case the current echo buffer equals
8364 the one containing the last displayed echo area message. */
8365 if (!NILP (echo_area_buffer[this_one])
8366 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8367 echo_area_buffer[this_one] = Qnil;
8368 }
8369
8370 /* Choose a suitable buffer from echo_buffer[] is we don't
8371 have one. */
8372 if (NILP (echo_area_buffer[this_one]))
8373 {
8374 echo_area_buffer[this_one]
8375 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8376 ? echo_buffer[the_other]
8377 : echo_buffer[this_one]);
8378 clear_buffer_p = 1;
8379 }
8380
8381 buffer = echo_area_buffer[this_one];
8382
8383 /* Don't get confused by reusing the buffer used for echoing
8384 for a different purpose. */
8385 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8386 cancel_echoing ();
8387
8388 record_unwind_protect (unwind_with_echo_area_buffer,
8389 with_echo_area_buffer_unwind_data (w));
8390
8391 /* Make the echo area buffer current. Note that for display
8392 purposes, it is not necessary that the displayed window's buffer
8393 == current_buffer, except for text property lookup. So, let's
8394 only set that buffer temporarily here without doing a full
8395 Fset_window_buffer. We must also change w->pointm, though,
8396 because otherwise an assertions in unshow_buffer fails, and Emacs
8397 aborts. */
8398 set_buffer_internal_1 (XBUFFER (buffer));
8399 if (w)
8400 {
8401 w->buffer = buffer;
8402 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8403 }
8404
8405 current_buffer->undo_list = Qt;
8406 current_buffer->read_only = Qnil;
8407 specbind (Qinhibit_read_only, Qt);
8408 specbind (Qinhibit_modification_hooks, Qt);
8409
8410 if (clear_buffer_p && Z > BEG)
8411 del_range (BEG, Z);
8412
8413 xassert (BEGV >= BEG);
8414 xassert (ZV <= Z && ZV >= BEGV);
8415
8416 rc = fn (a1, a2, a3, a4);
8417
8418 xassert (BEGV >= BEG);
8419 xassert (ZV <= Z && ZV >= BEGV);
8420
8421 unbind_to (count, Qnil);
8422 return rc;
8423 }
8424
8425
8426 /* Save state that should be preserved around the call to the function
8427 FN called in with_echo_area_buffer. */
8428
8429 static Lisp_Object
8430 with_echo_area_buffer_unwind_data (w)
8431 struct window *w;
8432 {
8433 int i = 0;
8434 Lisp_Object vector, tmp;
8435
8436 /* Reduce consing by keeping one vector in
8437 Vwith_echo_area_save_vector. */
8438 vector = Vwith_echo_area_save_vector;
8439 Vwith_echo_area_save_vector = Qnil;
8440
8441 if (NILP (vector))
8442 vector = Fmake_vector (make_number (7), Qnil);
8443
8444 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8445 ASET (vector, i, Vdeactivate_mark); ++i;
8446 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8447
8448 if (w)
8449 {
8450 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8451 ASET (vector, i, w->buffer); ++i;
8452 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8453 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8454 }
8455 else
8456 {
8457 int end = i + 4;
8458 for (; i < end; ++i)
8459 ASET (vector, i, Qnil);
8460 }
8461
8462 xassert (i == ASIZE (vector));
8463 return vector;
8464 }
8465
8466
8467 /* Restore global state from VECTOR which was created by
8468 with_echo_area_buffer_unwind_data. */
8469
8470 static Lisp_Object
8471 unwind_with_echo_area_buffer (vector)
8472 Lisp_Object vector;
8473 {
8474 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8475 Vdeactivate_mark = AREF (vector, 1);
8476 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8477
8478 if (WINDOWP (AREF (vector, 3)))
8479 {
8480 struct window *w;
8481 Lisp_Object buffer, charpos, bytepos;
8482
8483 w = XWINDOW (AREF (vector, 3));
8484 buffer = AREF (vector, 4);
8485 charpos = AREF (vector, 5);
8486 bytepos = AREF (vector, 6);
8487
8488 w->buffer = buffer;
8489 set_marker_both (w->pointm, buffer,
8490 XFASTINT (charpos), XFASTINT (bytepos));
8491 }
8492
8493 Vwith_echo_area_save_vector = vector;
8494 return Qnil;
8495 }
8496
8497
8498 /* Set up the echo area for use by print functions. MULTIBYTE_P
8499 non-zero means we will print multibyte. */
8500
8501 void
8502 setup_echo_area_for_printing (multibyte_p)
8503 int multibyte_p;
8504 {
8505 /* If we can't find an echo area any more, exit. */
8506 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8507 Fkill_emacs (Qnil);
8508
8509 ensure_echo_area_buffers ();
8510
8511 if (!message_buf_print)
8512 {
8513 /* A message has been output since the last time we printed.
8514 Choose a fresh echo area buffer. */
8515 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8516 echo_area_buffer[0] = echo_buffer[1];
8517 else
8518 echo_area_buffer[0] = echo_buffer[0];
8519
8520 /* Switch to that buffer and clear it. */
8521 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8522 current_buffer->truncate_lines = Qnil;
8523
8524 if (Z > BEG)
8525 {
8526 int count = SPECPDL_INDEX ();
8527 specbind (Qinhibit_read_only, Qt);
8528 /* Note that undo recording is always disabled. */
8529 del_range (BEG, Z);
8530 unbind_to (count, Qnil);
8531 }
8532 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8533
8534 /* Set up the buffer for the multibyteness we need. */
8535 if (multibyte_p
8536 != !NILP (current_buffer->enable_multibyte_characters))
8537 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8538
8539 /* Raise the frame containing the echo area. */
8540 if (minibuffer_auto_raise)
8541 {
8542 struct frame *sf = SELECTED_FRAME ();
8543 Lisp_Object mini_window;
8544 mini_window = FRAME_MINIBUF_WINDOW (sf);
8545 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8546 }
8547
8548 message_log_maybe_newline ();
8549 message_buf_print = 1;
8550 }
8551 else
8552 {
8553 if (NILP (echo_area_buffer[0]))
8554 {
8555 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8556 echo_area_buffer[0] = echo_buffer[1];
8557 else
8558 echo_area_buffer[0] = echo_buffer[0];
8559 }
8560
8561 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8562 {
8563 /* Someone switched buffers between print requests. */
8564 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8565 current_buffer->truncate_lines = Qnil;
8566 }
8567 }
8568 }
8569
8570
8571 /* Display an echo area message in window W. Value is non-zero if W's
8572 height is changed. If display_last_displayed_message_p is
8573 non-zero, display the message that was last displayed, otherwise
8574 display the current message. */
8575
8576 static int
8577 display_echo_area (w)
8578 struct window *w;
8579 {
8580 int i, no_message_p, window_height_changed_p, count;
8581
8582 /* Temporarily disable garbage collections while displaying the echo
8583 area. This is done because a GC can print a message itself.
8584 That message would modify the echo area buffer's contents while a
8585 redisplay of the buffer is going on, and seriously confuse
8586 redisplay. */
8587 count = inhibit_garbage_collection ();
8588
8589 /* If there is no message, we must call display_echo_area_1
8590 nevertheless because it resizes the window. But we will have to
8591 reset the echo_area_buffer in question to nil at the end because
8592 with_echo_area_buffer will sets it to an empty buffer. */
8593 i = display_last_displayed_message_p ? 1 : 0;
8594 no_message_p = NILP (echo_area_buffer[i]);
8595
8596 window_height_changed_p
8597 = with_echo_area_buffer (w, display_last_displayed_message_p,
8598 display_echo_area_1,
8599 (EMACS_INT) w, Qnil, 0, 0);
8600
8601 if (no_message_p)
8602 echo_area_buffer[i] = Qnil;
8603
8604 unbind_to (count, Qnil);
8605 return window_height_changed_p;
8606 }
8607
8608
8609 /* Helper for display_echo_area. Display the current buffer which
8610 contains the current echo area message in window W, a mini-window,
8611 a pointer to which is passed in A1. A2..A4 are currently not used.
8612 Change the height of W so that all of the message is displayed.
8613 Value is non-zero if height of W was changed. */
8614
8615 static int
8616 display_echo_area_1 (a1, a2, a3, a4)
8617 EMACS_INT a1;
8618 Lisp_Object a2;
8619 EMACS_INT a3, a4;
8620 {
8621 struct window *w = (struct window *) a1;
8622 Lisp_Object window;
8623 struct text_pos start;
8624 int window_height_changed_p = 0;
8625
8626 /* Do this before displaying, so that we have a large enough glyph
8627 matrix for the display. If we can't get enough space for the
8628 whole text, display the last N lines. That works by setting w->start. */
8629 window_height_changed_p = resize_mini_window (w, 0);
8630
8631 /* Use the starting position chosen by resize_mini_window. */
8632 SET_TEXT_POS_FROM_MARKER (start, w->start);
8633
8634 /* Display. */
8635 clear_glyph_matrix (w->desired_matrix);
8636 XSETWINDOW (window, w);
8637 try_window (window, start, 0);
8638
8639 return window_height_changed_p;
8640 }
8641
8642
8643 /* Resize the echo area window to exactly the size needed for the
8644 currently displayed message, if there is one. If a mini-buffer
8645 is active, don't shrink it. */
8646
8647 void
8648 resize_echo_area_exactly ()
8649 {
8650 if (BUFFERP (echo_area_buffer[0])
8651 && WINDOWP (echo_area_window))
8652 {
8653 struct window *w = XWINDOW (echo_area_window);
8654 int resized_p;
8655 Lisp_Object resize_exactly;
8656
8657 if (minibuf_level == 0)
8658 resize_exactly = Qt;
8659 else
8660 resize_exactly = Qnil;
8661
8662 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8663 (EMACS_INT) w, resize_exactly, 0, 0);
8664 if (resized_p)
8665 {
8666 ++windows_or_buffers_changed;
8667 ++update_mode_lines;
8668 redisplay_internal (0);
8669 }
8670 }
8671 }
8672
8673
8674 /* Callback function for with_echo_area_buffer, when used from
8675 resize_echo_area_exactly. A1 contains a pointer to the window to
8676 resize, EXACTLY non-nil means resize the mini-window exactly to the
8677 size of the text displayed. A3 and A4 are not used. Value is what
8678 resize_mini_window returns. */
8679
8680 static int
8681 resize_mini_window_1 (a1, exactly, a3, a4)
8682 EMACS_INT a1;
8683 Lisp_Object exactly;
8684 EMACS_INT a3, a4;
8685 {
8686 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8687 }
8688
8689
8690 /* Resize mini-window W to fit the size of its contents. EXACT_P
8691 means size the window exactly to the size needed. Otherwise, it's
8692 only enlarged until W's buffer is empty.
8693
8694 Set W->start to the right place to begin display. If the whole
8695 contents fit, start at the beginning. Otherwise, start so as
8696 to make the end of the contents appear. This is particularly
8697 important for y-or-n-p, but seems desirable generally.
8698
8699 Value is non-zero if the window height has been changed. */
8700
8701 int
8702 resize_mini_window (w, exact_p)
8703 struct window *w;
8704 int exact_p;
8705 {
8706 struct frame *f = XFRAME (w->frame);
8707 int window_height_changed_p = 0;
8708
8709 xassert (MINI_WINDOW_P (w));
8710
8711 /* By default, start display at the beginning. */
8712 set_marker_both (w->start, w->buffer,
8713 BUF_BEGV (XBUFFER (w->buffer)),
8714 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8715
8716 /* Don't resize windows while redisplaying a window; it would
8717 confuse redisplay functions when the size of the window they are
8718 displaying changes from under them. Such a resizing can happen,
8719 for instance, when which-func prints a long message while
8720 we are running fontification-functions. We're running these
8721 functions with safe_call which binds inhibit-redisplay to t. */
8722 if (!NILP (Vinhibit_redisplay))
8723 return 0;
8724
8725 /* Nil means don't try to resize. */
8726 if (NILP (Vresize_mini_windows)
8727 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8728 return 0;
8729
8730 if (!FRAME_MINIBUF_ONLY_P (f))
8731 {
8732 struct it it;
8733 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8734 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8735 int height, max_height;
8736 int unit = FRAME_LINE_HEIGHT (f);
8737 struct text_pos start;
8738 struct buffer *old_current_buffer = NULL;
8739
8740 if (current_buffer != XBUFFER (w->buffer))
8741 {
8742 old_current_buffer = current_buffer;
8743 set_buffer_internal (XBUFFER (w->buffer));
8744 }
8745
8746 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8747
8748 /* Compute the max. number of lines specified by the user. */
8749 if (FLOATP (Vmax_mini_window_height))
8750 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8751 else if (INTEGERP (Vmax_mini_window_height))
8752 max_height = XINT (Vmax_mini_window_height);
8753 else
8754 max_height = total_height / 4;
8755
8756 /* Correct that max. height if it's bogus. */
8757 max_height = max (1, max_height);
8758 max_height = min (total_height, max_height);
8759
8760 /* Find out the height of the text in the window. */
8761 if (it.line_wrap == TRUNCATE)
8762 height = 1;
8763 else
8764 {
8765 last_height = 0;
8766 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8767 if (it.max_ascent == 0 && it.max_descent == 0)
8768 height = it.current_y + last_height;
8769 else
8770 height = it.current_y + it.max_ascent + it.max_descent;
8771 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8772 height = (height + unit - 1) / unit;
8773 }
8774
8775 /* Compute a suitable window start. */
8776 if (height > max_height)
8777 {
8778 height = max_height;
8779 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8780 move_it_vertically_backward (&it, (height - 1) * unit);
8781 start = it.current.pos;
8782 }
8783 else
8784 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8785 SET_MARKER_FROM_TEXT_POS (w->start, start);
8786
8787 if (EQ (Vresize_mini_windows, Qgrow_only))
8788 {
8789 /* Let it grow only, until we display an empty message, in which
8790 case the window shrinks again. */
8791 if (height > WINDOW_TOTAL_LINES (w))
8792 {
8793 int old_height = WINDOW_TOTAL_LINES (w);
8794 freeze_window_starts (f, 1);
8795 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8796 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8797 }
8798 else if (height < WINDOW_TOTAL_LINES (w)
8799 && (exact_p || BEGV == ZV))
8800 {
8801 int old_height = WINDOW_TOTAL_LINES (w);
8802 freeze_window_starts (f, 0);
8803 shrink_mini_window (w);
8804 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8805 }
8806 }
8807 else
8808 {
8809 /* Always resize to exact size needed. */
8810 if (height > WINDOW_TOTAL_LINES (w))
8811 {
8812 int old_height = WINDOW_TOTAL_LINES (w);
8813 freeze_window_starts (f, 1);
8814 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8815 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8816 }
8817 else if (height < WINDOW_TOTAL_LINES (w))
8818 {
8819 int old_height = WINDOW_TOTAL_LINES (w);
8820 freeze_window_starts (f, 0);
8821 shrink_mini_window (w);
8822
8823 if (height)
8824 {
8825 freeze_window_starts (f, 1);
8826 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8827 }
8828
8829 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8830 }
8831 }
8832
8833 if (old_current_buffer)
8834 set_buffer_internal (old_current_buffer);
8835 }
8836
8837 return window_height_changed_p;
8838 }
8839
8840
8841 /* Value is the current message, a string, or nil if there is no
8842 current message. */
8843
8844 Lisp_Object
8845 current_message ()
8846 {
8847 Lisp_Object msg;
8848
8849 if (!BUFFERP (echo_area_buffer[0]))
8850 msg = Qnil;
8851 else
8852 {
8853 with_echo_area_buffer (0, 0, current_message_1,
8854 (EMACS_INT) &msg, Qnil, 0, 0);
8855 if (NILP (msg))
8856 echo_area_buffer[0] = Qnil;
8857 }
8858
8859 return msg;
8860 }
8861
8862
8863 static int
8864 current_message_1 (a1, a2, a3, a4)
8865 EMACS_INT a1;
8866 Lisp_Object a2;
8867 EMACS_INT a3, a4;
8868 {
8869 Lisp_Object *msg = (Lisp_Object *) a1;
8870
8871 if (Z > BEG)
8872 *msg = make_buffer_string (BEG, Z, 1);
8873 else
8874 *msg = Qnil;
8875 return 0;
8876 }
8877
8878
8879 /* Push the current message on Vmessage_stack for later restauration
8880 by restore_message. Value is non-zero if the current message isn't
8881 empty. This is a relatively infrequent operation, so it's not
8882 worth optimizing. */
8883
8884 int
8885 push_message ()
8886 {
8887 Lisp_Object msg;
8888 msg = current_message ();
8889 Vmessage_stack = Fcons (msg, Vmessage_stack);
8890 return STRINGP (msg);
8891 }
8892
8893
8894 /* Restore message display from the top of Vmessage_stack. */
8895
8896 void
8897 restore_message ()
8898 {
8899 Lisp_Object msg;
8900
8901 xassert (CONSP (Vmessage_stack));
8902 msg = XCAR (Vmessage_stack);
8903 if (STRINGP (msg))
8904 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8905 else
8906 message3_nolog (msg, 0, 0);
8907 }
8908
8909
8910 /* Handler for record_unwind_protect calling pop_message. */
8911
8912 Lisp_Object
8913 pop_message_unwind (dummy)
8914 Lisp_Object dummy;
8915 {
8916 pop_message ();
8917 return Qnil;
8918 }
8919
8920 /* Pop the top-most entry off Vmessage_stack. */
8921
8922 void
8923 pop_message ()
8924 {
8925 xassert (CONSP (Vmessage_stack));
8926 Vmessage_stack = XCDR (Vmessage_stack);
8927 }
8928
8929
8930 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8931 exits. If the stack is not empty, we have a missing pop_message
8932 somewhere. */
8933
8934 void
8935 check_message_stack ()
8936 {
8937 if (!NILP (Vmessage_stack))
8938 abort ();
8939 }
8940
8941
8942 /* Truncate to NCHARS what will be displayed in the echo area the next
8943 time we display it---but don't redisplay it now. */
8944
8945 void
8946 truncate_echo_area (nchars)
8947 int nchars;
8948 {
8949 if (nchars == 0)
8950 echo_area_buffer[0] = Qnil;
8951 /* A null message buffer means that the frame hasn't really been
8952 initialized yet. Error messages get reported properly by
8953 cmd_error, so this must be just an informative message; toss it. */
8954 else if (!noninteractive
8955 && INTERACTIVE
8956 && !NILP (echo_area_buffer[0]))
8957 {
8958 struct frame *sf = SELECTED_FRAME ();
8959 if (FRAME_MESSAGE_BUF (sf))
8960 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8961 }
8962 }
8963
8964
8965 /* Helper function for truncate_echo_area. Truncate the current
8966 message to at most NCHARS characters. */
8967
8968 static int
8969 truncate_message_1 (nchars, a2, a3, a4)
8970 EMACS_INT nchars;
8971 Lisp_Object a2;
8972 EMACS_INT a3, a4;
8973 {
8974 if (BEG + nchars < Z)
8975 del_range (BEG + nchars, Z);
8976 if (Z == BEG)
8977 echo_area_buffer[0] = Qnil;
8978 return 0;
8979 }
8980
8981
8982 /* Set the current message to a substring of S or STRING.
8983
8984 If STRING is a Lisp string, set the message to the first NBYTES
8985 bytes from STRING. NBYTES zero means use the whole string. If
8986 STRING is multibyte, the message will be displayed multibyte.
8987
8988 If S is not null, set the message to the first LEN bytes of S. LEN
8989 zero means use the whole string. MULTIBYTE_P non-zero means S is
8990 multibyte. Display the message multibyte in that case.
8991
8992 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8993 to t before calling set_message_1 (which calls insert).
8994 */
8995
8996 void
8997 set_message (s, string, nbytes, multibyte_p)
8998 const char *s;
8999 Lisp_Object string;
9000 int nbytes, multibyte_p;
9001 {
9002 message_enable_multibyte
9003 = ((s && multibyte_p)
9004 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9005
9006 with_echo_area_buffer (0, -1, set_message_1,
9007 (EMACS_INT) s, string, nbytes, multibyte_p);
9008 message_buf_print = 0;
9009 help_echo_showing_p = 0;
9010 }
9011
9012
9013 /* Helper function for set_message. Arguments have the same meaning
9014 as there, with A1 corresponding to S and A2 corresponding to STRING
9015 This function is called with the echo area buffer being
9016 current. */
9017
9018 static int
9019 set_message_1 (a1, a2, nbytes, multibyte_p)
9020 EMACS_INT a1;
9021 Lisp_Object a2;
9022 EMACS_INT nbytes, multibyte_p;
9023 {
9024 const char *s = (const char *) a1;
9025 Lisp_Object string = a2;
9026
9027 /* Change multibyteness of the echo buffer appropriately. */
9028 if (message_enable_multibyte
9029 != !NILP (current_buffer->enable_multibyte_characters))
9030 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9031
9032 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9033
9034 /* Insert new message at BEG. */
9035 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9036
9037 if (STRINGP (string))
9038 {
9039 int nchars;
9040
9041 if (nbytes == 0)
9042 nbytes = SBYTES (string);
9043 nchars = string_byte_to_char (string, nbytes);
9044
9045 /* This function takes care of single/multibyte conversion. We
9046 just have to ensure that the echo area buffer has the right
9047 setting of enable_multibyte_characters. */
9048 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9049 }
9050 else if (s)
9051 {
9052 if (nbytes == 0)
9053 nbytes = strlen (s);
9054
9055 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9056 {
9057 /* Convert from multi-byte to single-byte. */
9058 int i, c, n;
9059 unsigned char work[1];
9060
9061 /* Convert a multibyte string to single-byte. */
9062 for (i = 0; i < nbytes; i += n)
9063 {
9064 c = string_char_and_length (s + i, nbytes - i, &n);
9065 work[0] = (ASCII_CHAR_P (c)
9066 ? c
9067 : multibyte_char_to_unibyte (c, Qnil));
9068 insert_1_both (work, 1, 1, 1, 0, 0);
9069 }
9070 }
9071 else if (!multibyte_p
9072 && !NILP (current_buffer->enable_multibyte_characters))
9073 {
9074 /* Convert from single-byte to multi-byte. */
9075 int i, c, n;
9076 const unsigned char *msg = (const unsigned char *) s;
9077 unsigned char str[MAX_MULTIBYTE_LENGTH];
9078
9079 /* Convert a single-byte string to multibyte. */
9080 for (i = 0; i < nbytes; i++)
9081 {
9082 c = msg[i];
9083 MAKE_CHAR_MULTIBYTE (c);
9084 n = CHAR_STRING (c, str);
9085 insert_1_both (str, 1, n, 1, 0, 0);
9086 }
9087 }
9088 else
9089 insert_1 (s, nbytes, 1, 0, 0);
9090 }
9091
9092 return 0;
9093 }
9094
9095
9096 /* Clear messages. CURRENT_P non-zero means clear the current
9097 message. LAST_DISPLAYED_P non-zero means clear the message
9098 last displayed. */
9099
9100 void
9101 clear_message (current_p, last_displayed_p)
9102 int current_p, last_displayed_p;
9103 {
9104 if (current_p)
9105 {
9106 echo_area_buffer[0] = Qnil;
9107 message_cleared_p = 1;
9108 }
9109
9110 if (last_displayed_p)
9111 echo_area_buffer[1] = Qnil;
9112
9113 message_buf_print = 0;
9114 }
9115
9116 /* Clear garbaged frames.
9117
9118 This function is used where the old redisplay called
9119 redraw_garbaged_frames which in turn called redraw_frame which in
9120 turn called clear_frame. The call to clear_frame was a source of
9121 flickering. I believe a clear_frame is not necessary. It should
9122 suffice in the new redisplay to invalidate all current matrices,
9123 and ensure a complete redisplay of all windows. */
9124
9125 static void
9126 clear_garbaged_frames ()
9127 {
9128 if (frame_garbaged)
9129 {
9130 Lisp_Object tail, frame;
9131 int changed_count = 0;
9132
9133 FOR_EACH_FRAME (tail, frame)
9134 {
9135 struct frame *f = XFRAME (frame);
9136
9137 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9138 {
9139 if (f->resized_p)
9140 {
9141 Fredraw_frame (frame);
9142 f->force_flush_display_p = 1;
9143 }
9144 clear_current_matrices (f);
9145 changed_count++;
9146 f->garbaged = 0;
9147 f->resized_p = 0;
9148 }
9149 }
9150
9151 frame_garbaged = 0;
9152 if (changed_count)
9153 ++windows_or_buffers_changed;
9154 }
9155 }
9156
9157
9158 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9159 is non-zero update selected_frame. Value is non-zero if the
9160 mini-windows height has been changed. */
9161
9162 static int
9163 echo_area_display (update_frame_p)
9164 int update_frame_p;
9165 {
9166 Lisp_Object mini_window;
9167 struct window *w;
9168 struct frame *f;
9169 int window_height_changed_p = 0;
9170 struct frame *sf = SELECTED_FRAME ();
9171
9172 mini_window = FRAME_MINIBUF_WINDOW (sf);
9173 w = XWINDOW (mini_window);
9174 f = XFRAME (WINDOW_FRAME (w));
9175
9176 /* Don't display if frame is invisible or not yet initialized. */
9177 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9178 return 0;
9179
9180 #ifdef HAVE_WINDOW_SYSTEM
9181 /* When Emacs starts, selected_frame may be the initial terminal
9182 frame. If we let this through, a message would be displayed on
9183 the terminal. */
9184 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9185 return 0;
9186 #endif /* HAVE_WINDOW_SYSTEM */
9187
9188 /* Redraw garbaged frames. */
9189 if (frame_garbaged)
9190 clear_garbaged_frames ();
9191
9192 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9193 {
9194 echo_area_window = mini_window;
9195 window_height_changed_p = display_echo_area (w);
9196 w->must_be_updated_p = 1;
9197
9198 /* Update the display, unless called from redisplay_internal.
9199 Also don't update the screen during redisplay itself. The
9200 update will happen at the end of redisplay, and an update
9201 here could cause confusion. */
9202 if (update_frame_p && !redisplaying_p)
9203 {
9204 int n = 0;
9205
9206 /* If the display update has been interrupted by pending
9207 input, update mode lines in the frame. Due to the
9208 pending input, it might have been that redisplay hasn't
9209 been called, so that mode lines above the echo area are
9210 garbaged. This looks odd, so we prevent it here. */
9211 if (!display_completed)
9212 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9213
9214 if (window_height_changed_p
9215 /* Don't do this if Emacs is shutting down. Redisplay
9216 needs to run hooks. */
9217 && !NILP (Vrun_hooks))
9218 {
9219 /* Must update other windows. Likewise as in other
9220 cases, don't let this update be interrupted by
9221 pending input. */
9222 int count = SPECPDL_INDEX ();
9223 specbind (Qredisplay_dont_pause, Qt);
9224 windows_or_buffers_changed = 1;
9225 redisplay_internal (0);
9226 unbind_to (count, Qnil);
9227 }
9228 else if (FRAME_WINDOW_P (f) && n == 0)
9229 {
9230 /* Window configuration is the same as before.
9231 Can do with a display update of the echo area,
9232 unless we displayed some mode lines. */
9233 update_single_window (w, 1);
9234 FRAME_RIF (f)->flush_display (f);
9235 }
9236 else
9237 update_frame (f, 1, 1);
9238
9239 /* If cursor is in the echo area, make sure that the next
9240 redisplay displays the minibuffer, so that the cursor will
9241 be replaced with what the minibuffer wants. */
9242 if (cursor_in_echo_area)
9243 ++windows_or_buffers_changed;
9244 }
9245 }
9246 else if (!EQ (mini_window, selected_window))
9247 windows_or_buffers_changed++;
9248
9249 /* Last displayed message is now the current message. */
9250 echo_area_buffer[1] = echo_area_buffer[0];
9251 /* Inform read_char that we're not echoing. */
9252 echo_message_buffer = Qnil;
9253
9254 /* Prevent redisplay optimization in redisplay_internal by resetting
9255 this_line_start_pos. This is done because the mini-buffer now
9256 displays the message instead of its buffer text. */
9257 if (EQ (mini_window, selected_window))
9258 CHARPOS (this_line_start_pos) = 0;
9259
9260 return window_height_changed_p;
9261 }
9262
9263
9264 \f
9265 /***********************************************************************
9266 Mode Lines and Frame Titles
9267 ***********************************************************************/
9268
9269 /* A buffer for constructing non-propertized mode-line strings and
9270 frame titles in it; allocated from the heap in init_xdisp and
9271 resized as needed in store_mode_line_noprop_char. */
9272
9273 static char *mode_line_noprop_buf;
9274
9275 /* The buffer's end, and a current output position in it. */
9276
9277 static char *mode_line_noprop_buf_end;
9278 static char *mode_line_noprop_ptr;
9279
9280 #define MODE_LINE_NOPROP_LEN(start) \
9281 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9282
9283 static enum {
9284 MODE_LINE_DISPLAY = 0,
9285 MODE_LINE_TITLE,
9286 MODE_LINE_NOPROP,
9287 MODE_LINE_STRING
9288 } mode_line_target;
9289
9290 /* Alist that caches the results of :propertize.
9291 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9292 static Lisp_Object mode_line_proptrans_alist;
9293
9294 /* List of strings making up the mode-line. */
9295 static Lisp_Object mode_line_string_list;
9296
9297 /* Base face property when building propertized mode line string. */
9298 static Lisp_Object mode_line_string_face;
9299 static Lisp_Object mode_line_string_face_prop;
9300
9301
9302 /* Unwind data for mode line strings */
9303
9304 static Lisp_Object Vmode_line_unwind_vector;
9305
9306 static Lisp_Object
9307 format_mode_line_unwind_data (struct buffer *obuf,
9308 Lisp_Object owin,
9309 int save_proptrans)
9310 {
9311 Lisp_Object vector, tmp;
9312
9313 /* Reduce consing by keeping one vector in
9314 Vwith_echo_area_save_vector. */
9315 vector = Vmode_line_unwind_vector;
9316 Vmode_line_unwind_vector = Qnil;
9317
9318 if (NILP (vector))
9319 vector = Fmake_vector (make_number (8), Qnil);
9320
9321 ASET (vector, 0, make_number (mode_line_target));
9322 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9323 ASET (vector, 2, mode_line_string_list);
9324 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9325 ASET (vector, 4, mode_line_string_face);
9326 ASET (vector, 5, mode_line_string_face_prop);
9327
9328 if (obuf)
9329 XSETBUFFER (tmp, obuf);
9330 else
9331 tmp = Qnil;
9332 ASET (vector, 6, tmp);
9333 ASET (vector, 7, owin);
9334
9335 return vector;
9336 }
9337
9338 static Lisp_Object
9339 unwind_format_mode_line (vector)
9340 Lisp_Object vector;
9341 {
9342 mode_line_target = XINT (AREF (vector, 0));
9343 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9344 mode_line_string_list = AREF (vector, 2);
9345 if (! EQ (AREF (vector, 3), Qt))
9346 mode_line_proptrans_alist = AREF (vector, 3);
9347 mode_line_string_face = AREF (vector, 4);
9348 mode_line_string_face_prop = AREF (vector, 5);
9349
9350 if (!NILP (AREF (vector, 7)))
9351 /* Select window before buffer, since it may change the buffer. */
9352 Fselect_window (AREF (vector, 7), Qt);
9353
9354 if (!NILP (AREF (vector, 6)))
9355 {
9356 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9357 ASET (vector, 6, Qnil);
9358 }
9359
9360 Vmode_line_unwind_vector = vector;
9361 return Qnil;
9362 }
9363
9364
9365 /* Store a single character C for the frame title in mode_line_noprop_buf.
9366 Re-allocate mode_line_noprop_buf if necessary. */
9367
9368 static void
9369 #ifdef PROTOTYPES
9370 store_mode_line_noprop_char (char c)
9371 #else
9372 store_mode_line_noprop_char (c)
9373 char c;
9374 #endif
9375 {
9376 /* If output position has reached the end of the allocated buffer,
9377 double the buffer's size. */
9378 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9379 {
9380 int len = MODE_LINE_NOPROP_LEN (0);
9381 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9382 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9383 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9384 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9385 }
9386
9387 *mode_line_noprop_ptr++ = c;
9388 }
9389
9390
9391 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9392 mode_line_noprop_ptr. STR is the string to store. Do not copy
9393 characters that yield more columns than PRECISION; PRECISION <= 0
9394 means copy the whole string. Pad with spaces until FIELD_WIDTH
9395 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9396 pad. Called from display_mode_element when it is used to build a
9397 frame title. */
9398
9399 static int
9400 store_mode_line_noprop (str, field_width, precision)
9401 const unsigned char *str;
9402 int field_width, precision;
9403 {
9404 int n = 0;
9405 int dummy, nbytes;
9406
9407 /* Copy at most PRECISION chars from STR. */
9408 nbytes = strlen (str);
9409 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9410 while (nbytes--)
9411 store_mode_line_noprop_char (*str++);
9412
9413 /* Fill up with spaces until FIELD_WIDTH reached. */
9414 while (field_width > 0
9415 && n < field_width)
9416 {
9417 store_mode_line_noprop_char (' ');
9418 ++n;
9419 }
9420
9421 return n;
9422 }
9423
9424 /***********************************************************************
9425 Frame Titles
9426 ***********************************************************************/
9427
9428 #ifdef HAVE_WINDOW_SYSTEM
9429
9430 /* Set the title of FRAME, if it has changed. The title format is
9431 Vicon_title_format if FRAME is iconified, otherwise it is
9432 frame_title_format. */
9433
9434 static void
9435 x_consider_frame_title (frame)
9436 Lisp_Object frame;
9437 {
9438 struct frame *f = XFRAME (frame);
9439
9440 if (FRAME_WINDOW_P (f)
9441 || FRAME_MINIBUF_ONLY_P (f)
9442 || f->explicit_name)
9443 {
9444 /* Do we have more than one visible frame on this X display? */
9445 Lisp_Object tail;
9446 Lisp_Object fmt;
9447 int title_start;
9448 char *title;
9449 int len;
9450 struct it it;
9451 int count = SPECPDL_INDEX ();
9452
9453 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9454 {
9455 Lisp_Object other_frame = XCAR (tail);
9456 struct frame *tf = XFRAME (other_frame);
9457
9458 if (tf != f
9459 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9460 && !FRAME_MINIBUF_ONLY_P (tf)
9461 && !EQ (other_frame, tip_frame)
9462 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9463 break;
9464 }
9465
9466 /* Set global variable indicating that multiple frames exist. */
9467 multiple_frames = CONSP (tail);
9468
9469 /* Switch to the buffer of selected window of the frame. Set up
9470 mode_line_target so that display_mode_element will output into
9471 mode_line_noprop_buf; then display the title. */
9472 record_unwind_protect (unwind_format_mode_line,
9473 format_mode_line_unwind_data
9474 (current_buffer, selected_window, 0));
9475
9476 Fselect_window (f->selected_window, Qt);
9477 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9478 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9479
9480 mode_line_target = MODE_LINE_TITLE;
9481 title_start = MODE_LINE_NOPROP_LEN (0);
9482 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9483 NULL, DEFAULT_FACE_ID);
9484 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9485 len = MODE_LINE_NOPROP_LEN (title_start);
9486 title = mode_line_noprop_buf + title_start;
9487 unbind_to (count, Qnil);
9488
9489 /* Set the title only if it's changed. This avoids consing in
9490 the common case where it hasn't. (If it turns out that we've
9491 already wasted too much time by walking through the list with
9492 display_mode_element, then we might need to optimize at a
9493 higher level than this.) */
9494 if (! STRINGP (f->name)
9495 || SBYTES (f->name) != len
9496 || bcmp (title, SDATA (f->name), len) != 0)
9497 {
9498 #ifdef HAVE_NS
9499 if (FRAME_NS_P (f))
9500 {
9501 if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
9502 {
9503 if (EQ (fmt, Qt))
9504 ns_set_name_as_filename (f);
9505 else
9506 x_implicitly_set_name (f, make_string(title, len),
9507 Qnil);
9508 }
9509 }
9510 else
9511 #endif
9512 x_implicitly_set_name (f, make_string (title, len), Qnil);
9513 }
9514 #ifdef HAVE_NS
9515 if (FRAME_NS_P (f))
9516 {
9517 /* do this also for frames with explicit names */
9518 ns_implicitly_set_icon_type(f);
9519 ns_set_doc_edited(f, Fbuffer_modified_p
9520 (XWINDOW (f->selected_window)->buffer), Qnil);
9521 }
9522 #endif
9523 }
9524 }
9525
9526 #endif /* not HAVE_WINDOW_SYSTEM */
9527
9528
9529
9530 \f
9531 /***********************************************************************
9532 Menu Bars
9533 ***********************************************************************/
9534
9535
9536 /* Prepare for redisplay by updating menu-bar item lists when
9537 appropriate. This can call eval. */
9538
9539 void
9540 prepare_menu_bars ()
9541 {
9542 int all_windows;
9543 struct gcpro gcpro1, gcpro2;
9544 struct frame *f;
9545 Lisp_Object tooltip_frame;
9546
9547 #ifdef HAVE_WINDOW_SYSTEM
9548 tooltip_frame = tip_frame;
9549 #else
9550 tooltip_frame = Qnil;
9551 #endif
9552
9553 /* Update all frame titles based on their buffer names, etc. We do
9554 this before the menu bars so that the buffer-menu will show the
9555 up-to-date frame titles. */
9556 #ifdef HAVE_WINDOW_SYSTEM
9557 if (windows_or_buffers_changed || update_mode_lines)
9558 {
9559 Lisp_Object tail, frame;
9560
9561 FOR_EACH_FRAME (tail, frame)
9562 {
9563 f = XFRAME (frame);
9564 if (!EQ (frame, tooltip_frame)
9565 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9566 x_consider_frame_title (frame);
9567 }
9568 }
9569 #endif /* HAVE_WINDOW_SYSTEM */
9570
9571 /* Update the menu bar item lists, if appropriate. This has to be
9572 done before any actual redisplay or generation of display lines. */
9573 all_windows = (update_mode_lines
9574 || buffer_shared > 1
9575 || windows_or_buffers_changed);
9576 if (all_windows)
9577 {
9578 Lisp_Object tail, frame;
9579 int count = SPECPDL_INDEX ();
9580 /* 1 means that update_menu_bar has run its hooks
9581 so any further calls to update_menu_bar shouldn't do so again. */
9582 int menu_bar_hooks_run = 0;
9583
9584 record_unwind_save_match_data ();
9585
9586 FOR_EACH_FRAME (tail, frame)
9587 {
9588 f = XFRAME (frame);
9589
9590 /* Ignore tooltip frame. */
9591 if (EQ (frame, tooltip_frame))
9592 continue;
9593
9594 /* If a window on this frame changed size, report that to
9595 the user and clear the size-change flag. */
9596 if (FRAME_WINDOW_SIZES_CHANGED (f))
9597 {
9598 Lisp_Object functions;
9599
9600 /* Clear flag first in case we get an error below. */
9601 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9602 functions = Vwindow_size_change_functions;
9603 GCPRO2 (tail, functions);
9604
9605 while (CONSP (functions))
9606 {
9607 if (!EQ (XCAR (functions), Qt))
9608 call1 (XCAR (functions), frame);
9609 functions = XCDR (functions);
9610 }
9611 UNGCPRO;
9612 }
9613
9614 GCPRO1 (tail);
9615 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9616 #ifdef HAVE_WINDOW_SYSTEM
9617 update_tool_bar (f, 0);
9618 #endif
9619 UNGCPRO;
9620 }
9621
9622 unbind_to (count, Qnil);
9623 }
9624 else
9625 {
9626 struct frame *sf = SELECTED_FRAME ();
9627 update_menu_bar (sf, 1, 0);
9628 #ifdef HAVE_WINDOW_SYSTEM
9629 update_tool_bar (sf, 1);
9630 #endif
9631 }
9632
9633 /* Motif needs this. See comment in xmenu.c. Turn it off when
9634 pending_menu_activation is not defined. */
9635 #ifdef USE_X_TOOLKIT
9636 pending_menu_activation = 0;
9637 #endif
9638 }
9639
9640
9641 /* Update the menu bar item list for frame F. This has to be done
9642 before we start to fill in any display lines, because it can call
9643 eval.
9644
9645 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9646
9647 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9648 already ran the menu bar hooks for this redisplay, so there
9649 is no need to run them again. The return value is the
9650 updated value of this flag, to pass to the next call. */
9651
9652 static int
9653 update_menu_bar (f, save_match_data, hooks_run)
9654 struct frame *f;
9655 int save_match_data;
9656 int hooks_run;
9657 {
9658 Lisp_Object window;
9659 register struct window *w;
9660
9661 /* If called recursively during a menu update, do nothing. This can
9662 happen when, for instance, an activate-menubar-hook causes a
9663 redisplay. */
9664 if (inhibit_menubar_update)
9665 return hooks_run;
9666
9667 window = FRAME_SELECTED_WINDOW (f);
9668 w = XWINDOW (window);
9669
9670 if (FRAME_WINDOW_P (f)
9671 ?
9672 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9673 || defined (HAVE_NS) || defined (USE_GTK)
9674 FRAME_EXTERNAL_MENU_BAR (f)
9675 #else
9676 FRAME_MENU_BAR_LINES (f) > 0
9677 #endif
9678 : FRAME_MENU_BAR_LINES (f) > 0)
9679 {
9680 /* If the user has switched buffers or windows, we need to
9681 recompute to reflect the new bindings. But we'll
9682 recompute when update_mode_lines is set too; that means
9683 that people can use force-mode-line-update to request
9684 that the menu bar be recomputed. The adverse effect on
9685 the rest of the redisplay algorithm is about the same as
9686 windows_or_buffers_changed anyway. */
9687 if (windows_or_buffers_changed
9688 /* This used to test w->update_mode_line, but we believe
9689 there is no need to recompute the menu in that case. */
9690 || update_mode_lines
9691 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9692 < BUF_MODIFF (XBUFFER (w->buffer)))
9693 != !NILP (w->last_had_star))
9694 || ((!NILP (Vtransient_mark_mode)
9695 && !NILP (XBUFFER (w->buffer)->mark_active))
9696 != !NILP (w->region_showing)))
9697 {
9698 struct buffer *prev = current_buffer;
9699 int count = SPECPDL_INDEX ();
9700
9701 specbind (Qinhibit_menubar_update, Qt);
9702
9703 set_buffer_internal_1 (XBUFFER (w->buffer));
9704 if (save_match_data)
9705 record_unwind_save_match_data ();
9706 if (NILP (Voverriding_local_map_menu_flag))
9707 {
9708 specbind (Qoverriding_terminal_local_map, Qnil);
9709 specbind (Qoverriding_local_map, Qnil);
9710 }
9711
9712 if (!hooks_run)
9713 {
9714 /* Run the Lucid hook. */
9715 safe_run_hooks (Qactivate_menubar_hook);
9716
9717 /* If it has changed current-menubar from previous value,
9718 really recompute the menu-bar from the value. */
9719 if (! NILP (Vlucid_menu_bar_dirty_flag))
9720 call0 (Qrecompute_lucid_menubar);
9721
9722 safe_run_hooks (Qmenu_bar_update_hook);
9723
9724 hooks_run = 1;
9725 }
9726
9727 XSETFRAME (Vmenu_updating_frame, f);
9728 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9729
9730 /* Redisplay the menu bar in case we changed it. */
9731 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9732 || defined (HAVE_NS) || defined (USE_GTK)
9733 if (FRAME_WINDOW_P (f))
9734 {
9735 #if defined (HAVE_NS)
9736 /* All frames on Mac OS share the same menubar. So only
9737 the selected frame should be allowed to set it. */
9738 if (f == SELECTED_FRAME ())
9739 #endif
9740 set_frame_menubar (f, 0, 0);
9741 }
9742 else
9743 /* On a terminal screen, the menu bar is an ordinary screen
9744 line, and this makes it get updated. */
9745 w->update_mode_line = Qt;
9746 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9747 /* In the non-toolkit version, the menu bar is an ordinary screen
9748 line, and this makes it get updated. */
9749 w->update_mode_line = Qt;
9750 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9751
9752 unbind_to (count, Qnil);
9753 set_buffer_internal_1 (prev);
9754 }
9755 }
9756
9757 return hooks_run;
9758 }
9759
9760
9761 \f
9762 /***********************************************************************
9763 Output Cursor
9764 ***********************************************************************/
9765
9766 #ifdef HAVE_WINDOW_SYSTEM
9767
9768 /* EXPORT:
9769 Nominal cursor position -- where to draw output.
9770 HPOS and VPOS are window relative glyph matrix coordinates.
9771 X and Y are window relative pixel coordinates. */
9772
9773 struct cursor_pos output_cursor;
9774
9775
9776 /* EXPORT:
9777 Set the global variable output_cursor to CURSOR. All cursor
9778 positions are relative to updated_window. */
9779
9780 void
9781 set_output_cursor (cursor)
9782 struct cursor_pos *cursor;
9783 {
9784 output_cursor.hpos = cursor->hpos;
9785 output_cursor.vpos = cursor->vpos;
9786 output_cursor.x = cursor->x;
9787 output_cursor.y = cursor->y;
9788 }
9789
9790
9791 /* EXPORT for RIF:
9792 Set a nominal cursor position.
9793
9794 HPOS and VPOS are column/row positions in a window glyph matrix. X
9795 and Y are window text area relative pixel positions.
9796
9797 If this is done during an update, updated_window will contain the
9798 window that is being updated and the position is the future output
9799 cursor position for that window. If updated_window is null, use
9800 selected_window and display the cursor at the given position. */
9801
9802 void
9803 x_cursor_to (vpos, hpos, y, x)
9804 int vpos, hpos, y, x;
9805 {
9806 struct window *w;
9807
9808 /* If updated_window is not set, work on selected_window. */
9809 if (updated_window)
9810 w = updated_window;
9811 else
9812 w = XWINDOW (selected_window);
9813
9814 /* Set the output cursor. */
9815 output_cursor.hpos = hpos;
9816 output_cursor.vpos = vpos;
9817 output_cursor.x = x;
9818 output_cursor.y = y;
9819
9820 /* If not called as part of an update, really display the cursor.
9821 This will also set the cursor position of W. */
9822 if (updated_window == NULL)
9823 {
9824 BLOCK_INPUT;
9825 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9826 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9827 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9828 UNBLOCK_INPUT;
9829 }
9830 }
9831
9832 #endif /* HAVE_WINDOW_SYSTEM */
9833
9834 \f
9835 /***********************************************************************
9836 Tool-bars
9837 ***********************************************************************/
9838
9839 #ifdef HAVE_WINDOW_SYSTEM
9840
9841 /* Where the mouse was last time we reported a mouse event. */
9842
9843 FRAME_PTR last_mouse_frame;
9844
9845 /* Tool-bar item index of the item on which a mouse button was pressed
9846 or -1. */
9847
9848 int last_tool_bar_item;
9849
9850
9851 static Lisp_Object
9852 update_tool_bar_unwind (frame)
9853 Lisp_Object frame;
9854 {
9855 selected_frame = frame;
9856 return Qnil;
9857 }
9858
9859 /* Update the tool-bar item list for frame F. This has to be done
9860 before we start to fill in any display lines. Called from
9861 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9862 and restore it here. */
9863
9864 static void
9865 update_tool_bar (f, save_match_data)
9866 struct frame *f;
9867 int save_match_data;
9868 {
9869 #if defined (USE_GTK) || defined (HAVE_NS)
9870 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9871 #else
9872 int do_update = WINDOWP (f->tool_bar_window)
9873 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9874 #endif
9875
9876 if (do_update)
9877 {
9878 Lisp_Object window;
9879 struct window *w;
9880
9881 window = FRAME_SELECTED_WINDOW (f);
9882 w = XWINDOW (window);
9883
9884 /* If the user has switched buffers or windows, we need to
9885 recompute to reflect the new bindings. But we'll
9886 recompute when update_mode_lines is set too; that means
9887 that people can use force-mode-line-update to request
9888 that the menu bar be recomputed. The adverse effect on
9889 the rest of the redisplay algorithm is about the same as
9890 windows_or_buffers_changed anyway. */
9891 if (windows_or_buffers_changed
9892 || !NILP (w->update_mode_line)
9893 || update_mode_lines
9894 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9895 < BUF_MODIFF (XBUFFER (w->buffer)))
9896 != !NILP (w->last_had_star))
9897 || ((!NILP (Vtransient_mark_mode)
9898 && !NILP (XBUFFER (w->buffer)->mark_active))
9899 != !NILP (w->region_showing)))
9900 {
9901 struct buffer *prev = current_buffer;
9902 int count = SPECPDL_INDEX ();
9903 Lisp_Object frame, new_tool_bar;
9904 int new_n_tool_bar;
9905 struct gcpro gcpro1;
9906
9907 /* Set current_buffer to the buffer of the selected
9908 window of the frame, so that we get the right local
9909 keymaps. */
9910 set_buffer_internal_1 (XBUFFER (w->buffer));
9911
9912 /* Save match data, if we must. */
9913 if (save_match_data)
9914 record_unwind_save_match_data ();
9915
9916 /* Make sure that we don't accidentally use bogus keymaps. */
9917 if (NILP (Voverriding_local_map_menu_flag))
9918 {
9919 specbind (Qoverriding_terminal_local_map, Qnil);
9920 specbind (Qoverriding_local_map, Qnil);
9921 }
9922
9923 GCPRO1 (new_tool_bar);
9924
9925 /* We must temporarily set the selected frame to this frame
9926 before calling tool_bar_items, because the calculation of
9927 the tool-bar keymap uses the selected frame (see
9928 `tool-bar-make-keymap' in tool-bar.el). */
9929 record_unwind_protect (update_tool_bar_unwind, selected_frame);
9930 XSETFRAME (frame, f);
9931 selected_frame = frame;
9932
9933 /* Build desired tool-bar items from keymaps. */
9934 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9935 &new_n_tool_bar);
9936
9937 /* Redisplay the tool-bar if we changed it. */
9938 if (new_n_tool_bar != f->n_tool_bar_items
9939 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9940 {
9941 /* Redisplay that happens asynchronously due to an expose event
9942 may access f->tool_bar_items. Make sure we update both
9943 variables within BLOCK_INPUT so no such event interrupts. */
9944 BLOCK_INPUT;
9945 f->tool_bar_items = new_tool_bar;
9946 f->n_tool_bar_items = new_n_tool_bar;
9947 w->update_mode_line = Qt;
9948 UNBLOCK_INPUT;
9949 }
9950
9951 UNGCPRO;
9952
9953 unbind_to (count, Qnil);
9954 set_buffer_internal_1 (prev);
9955 }
9956 }
9957 }
9958
9959
9960 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9961 F's desired tool-bar contents. F->tool_bar_items must have
9962 been set up previously by calling prepare_menu_bars. */
9963
9964 static void
9965 build_desired_tool_bar_string (f)
9966 struct frame *f;
9967 {
9968 int i, size, size_needed;
9969 struct gcpro gcpro1, gcpro2, gcpro3;
9970 Lisp_Object image, plist, props;
9971
9972 image = plist = props = Qnil;
9973 GCPRO3 (image, plist, props);
9974
9975 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9976 Otherwise, make a new string. */
9977
9978 /* The size of the string we might be able to reuse. */
9979 size = (STRINGP (f->desired_tool_bar_string)
9980 ? SCHARS (f->desired_tool_bar_string)
9981 : 0);
9982
9983 /* We need one space in the string for each image. */
9984 size_needed = f->n_tool_bar_items;
9985
9986 /* Reuse f->desired_tool_bar_string, if possible. */
9987 if (size < size_needed || NILP (f->desired_tool_bar_string))
9988 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9989 make_number (' '));
9990 else
9991 {
9992 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9993 Fremove_text_properties (make_number (0), make_number (size),
9994 props, f->desired_tool_bar_string);
9995 }
9996
9997 /* Put a `display' property on the string for the images to display,
9998 put a `menu_item' property on tool-bar items with a value that
9999 is the index of the item in F's tool-bar item vector. */
10000 for (i = 0; i < f->n_tool_bar_items; ++i)
10001 {
10002 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10003
10004 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10005 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10006 int hmargin, vmargin, relief, idx, end;
10007 extern Lisp_Object QCrelief, QCmargin, QCconversion;
10008
10009 /* If image is a vector, choose the image according to the
10010 button state. */
10011 image = PROP (TOOL_BAR_ITEM_IMAGES);
10012 if (VECTORP (image))
10013 {
10014 if (enabled_p)
10015 idx = (selected_p
10016 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10017 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10018 else
10019 idx = (selected_p
10020 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10021 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10022
10023 xassert (ASIZE (image) >= idx);
10024 image = AREF (image, idx);
10025 }
10026 else
10027 idx = -1;
10028
10029 /* Ignore invalid image specifications. */
10030 if (!valid_image_p (image))
10031 continue;
10032
10033 /* Display the tool-bar button pressed, or depressed. */
10034 plist = Fcopy_sequence (XCDR (image));
10035
10036 /* Compute margin and relief to draw. */
10037 relief = (tool_bar_button_relief >= 0
10038 ? tool_bar_button_relief
10039 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10040 hmargin = vmargin = relief;
10041
10042 if (INTEGERP (Vtool_bar_button_margin)
10043 && XINT (Vtool_bar_button_margin) > 0)
10044 {
10045 hmargin += XFASTINT (Vtool_bar_button_margin);
10046 vmargin += XFASTINT (Vtool_bar_button_margin);
10047 }
10048 else if (CONSP (Vtool_bar_button_margin))
10049 {
10050 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10051 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10052 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10053
10054 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10055 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10056 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10057 }
10058
10059 if (auto_raise_tool_bar_buttons_p)
10060 {
10061 /* Add a `:relief' property to the image spec if the item is
10062 selected. */
10063 if (selected_p)
10064 {
10065 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10066 hmargin -= relief;
10067 vmargin -= relief;
10068 }
10069 }
10070 else
10071 {
10072 /* If image is selected, display it pressed, i.e. with a
10073 negative relief. If it's not selected, display it with a
10074 raised relief. */
10075 plist = Fplist_put (plist, QCrelief,
10076 (selected_p
10077 ? make_number (-relief)
10078 : make_number (relief)));
10079 hmargin -= relief;
10080 vmargin -= relief;
10081 }
10082
10083 /* Put a margin around the image. */
10084 if (hmargin || vmargin)
10085 {
10086 if (hmargin == vmargin)
10087 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10088 else
10089 plist = Fplist_put (plist, QCmargin,
10090 Fcons (make_number (hmargin),
10091 make_number (vmargin)));
10092 }
10093
10094 /* If button is not enabled, and we don't have special images
10095 for the disabled state, make the image appear disabled by
10096 applying an appropriate algorithm to it. */
10097 if (!enabled_p && idx < 0)
10098 plist = Fplist_put (plist, QCconversion, Qdisabled);
10099
10100 /* Put a `display' text property on the string for the image to
10101 display. Put a `menu-item' property on the string that gives
10102 the start of this item's properties in the tool-bar items
10103 vector. */
10104 image = Fcons (Qimage, plist);
10105 props = list4 (Qdisplay, image,
10106 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10107
10108 /* Let the last image hide all remaining spaces in the tool bar
10109 string. The string can be longer than needed when we reuse a
10110 previous string. */
10111 if (i + 1 == f->n_tool_bar_items)
10112 end = SCHARS (f->desired_tool_bar_string);
10113 else
10114 end = i + 1;
10115 Fadd_text_properties (make_number (i), make_number (end),
10116 props, f->desired_tool_bar_string);
10117 #undef PROP
10118 }
10119
10120 UNGCPRO;
10121 }
10122
10123
10124 /* Display one line of the tool-bar of frame IT->f.
10125
10126 HEIGHT specifies the desired height of the tool-bar line.
10127 If the actual height of the glyph row is less than HEIGHT, the
10128 row's height is increased to HEIGHT, and the icons are centered
10129 vertically in the new height.
10130
10131 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10132 count a final empty row in case the tool-bar width exactly matches
10133 the window width.
10134 */
10135
10136 static void
10137 display_tool_bar_line (it, height)
10138 struct it *it;
10139 int height;
10140 {
10141 struct glyph_row *row = it->glyph_row;
10142 int max_x = it->last_visible_x;
10143 struct glyph *last;
10144
10145 prepare_desired_row (row);
10146 row->y = it->current_y;
10147
10148 /* Note that this isn't made use of if the face hasn't a box,
10149 so there's no need to check the face here. */
10150 it->start_of_box_run_p = 1;
10151
10152 while (it->current_x < max_x)
10153 {
10154 int x, n_glyphs_before, i, nglyphs;
10155 struct it it_before;
10156
10157 /* Get the next display element. */
10158 if (!get_next_display_element (it))
10159 {
10160 /* Don't count empty row if we are counting needed tool-bar lines. */
10161 if (height < 0 && !it->hpos)
10162 return;
10163 break;
10164 }
10165
10166 /* Produce glyphs. */
10167 n_glyphs_before = row->used[TEXT_AREA];
10168 it_before = *it;
10169
10170 PRODUCE_GLYPHS (it);
10171
10172 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10173 i = 0;
10174 x = it_before.current_x;
10175 while (i < nglyphs)
10176 {
10177 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10178
10179 if (x + glyph->pixel_width > max_x)
10180 {
10181 /* Glyph doesn't fit on line. Backtrack. */
10182 row->used[TEXT_AREA] = n_glyphs_before;
10183 *it = it_before;
10184 /* If this is the only glyph on this line, it will never fit on the
10185 toolbar, so skip it. But ensure there is at least one glyph,
10186 so we don't accidentally disable the tool-bar. */
10187 if (n_glyphs_before == 0
10188 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10189 break;
10190 goto out;
10191 }
10192
10193 ++it->hpos;
10194 x += glyph->pixel_width;
10195 ++i;
10196 }
10197
10198 /* Stop at line ends. */
10199 if (ITERATOR_AT_END_OF_LINE_P (it))
10200 break;
10201
10202 set_iterator_to_next (it, 1);
10203 }
10204
10205 out:;
10206
10207 row->displays_text_p = row->used[TEXT_AREA] != 0;
10208
10209 /* Use default face for the border below the tool bar.
10210
10211 FIXME: When auto-resize-tool-bars is grow-only, there is
10212 no additional border below the possibly empty tool-bar lines.
10213 So to make the extra empty lines look "normal", we have to
10214 use the tool-bar face for the border too. */
10215 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10216 it->face_id = DEFAULT_FACE_ID;
10217
10218 extend_face_to_end_of_line (it);
10219 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10220 last->right_box_line_p = 1;
10221 if (last == row->glyphs[TEXT_AREA])
10222 last->left_box_line_p = 1;
10223
10224 /* Make line the desired height and center it vertically. */
10225 if ((height -= it->max_ascent + it->max_descent) > 0)
10226 {
10227 /* Don't add more than one line height. */
10228 height %= FRAME_LINE_HEIGHT (it->f);
10229 it->max_ascent += height / 2;
10230 it->max_descent += (height + 1) / 2;
10231 }
10232
10233 compute_line_metrics (it);
10234
10235 /* If line is empty, make it occupy the rest of the tool-bar. */
10236 if (!row->displays_text_p)
10237 {
10238 row->height = row->phys_height = it->last_visible_y - row->y;
10239 row->visible_height = row->height;
10240 row->ascent = row->phys_ascent = 0;
10241 row->extra_line_spacing = 0;
10242 }
10243
10244 row->full_width_p = 1;
10245 row->continued_p = 0;
10246 row->truncated_on_left_p = 0;
10247 row->truncated_on_right_p = 0;
10248
10249 it->current_x = it->hpos = 0;
10250 it->current_y += row->height;
10251 ++it->vpos;
10252 ++it->glyph_row;
10253 }
10254
10255
10256 /* Max tool-bar height. */
10257
10258 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10259 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10260
10261 /* Value is the number of screen lines needed to make all tool-bar
10262 items of frame F visible. The number of actual rows needed is
10263 returned in *N_ROWS if non-NULL. */
10264
10265 static int
10266 tool_bar_lines_needed (f, n_rows)
10267 struct frame *f;
10268 int *n_rows;
10269 {
10270 struct window *w = XWINDOW (f->tool_bar_window);
10271 struct it it;
10272 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10273 the desired matrix, so use (unused) mode-line row as temporary row to
10274 avoid destroying the first tool-bar row. */
10275 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10276
10277 /* Initialize an iterator for iteration over
10278 F->desired_tool_bar_string in the tool-bar window of frame F. */
10279 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10280 it.first_visible_x = 0;
10281 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10282 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10283
10284 while (!ITERATOR_AT_END_P (&it))
10285 {
10286 clear_glyph_row (temp_row);
10287 it.glyph_row = temp_row;
10288 display_tool_bar_line (&it, -1);
10289 }
10290 clear_glyph_row (temp_row);
10291
10292 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10293 if (n_rows)
10294 *n_rows = it.vpos > 0 ? it.vpos : -1;
10295
10296 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10297 }
10298
10299
10300 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10301 0, 1, 0,
10302 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10303 (frame)
10304 Lisp_Object frame;
10305 {
10306 struct frame *f;
10307 struct window *w;
10308 int nlines = 0;
10309
10310 if (NILP (frame))
10311 frame = selected_frame;
10312 else
10313 CHECK_FRAME (frame);
10314 f = XFRAME (frame);
10315
10316 if (WINDOWP (f->tool_bar_window)
10317 || (w = XWINDOW (f->tool_bar_window),
10318 WINDOW_TOTAL_LINES (w) > 0))
10319 {
10320 update_tool_bar (f, 1);
10321 if (f->n_tool_bar_items)
10322 {
10323 build_desired_tool_bar_string (f);
10324 nlines = tool_bar_lines_needed (f, NULL);
10325 }
10326 }
10327
10328 return make_number (nlines);
10329 }
10330
10331
10332 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10333 height should be changed. */
10334
10335 static int
10336 redisplay_tool_bar (f)
10337 struct frame *f;
10338 {
10339 struct window *w;
10340 struct it it;
10341 struct glyph_row *row;
10342
10343 #if defined (USE_GTK) || defined (HAVE_NS)
10344 if (FRAME_EXTERNAL_TOOL_BAR (f))
10345 update_frame_tool_bar (f);
10346 return 0;
10347 #endif
10348
10349 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10350 do anything. This means you must start with tool-bar-lines
10351 non-zero to get the auto-sizing effect. Or in other words, you
10352 can turn off tool-bars by specifying tool-bar-lines zero. */
10353 if (!WINDOWP (f->tool_bar_window)
10354 || (w = XWINDOW (f->tool_bar_window),
10355 WINDOW_TOTAL_LINES (w) == 0))
10356 return 0;
10357
10358 /* Set up an iterator for the tool-bar window. */
10359 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10360 it.first_visible_x = 0;
10361 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10362 row = it.glyph_row;
10363
10364 /* Build a string that represents the contents of the tool-bar. */
10365 build_desired_tool_bar_string (f);
10366 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10367
10368 if (f->n_tool_bar_rows == 0)
10369 {
10370 int nlines;
10371
10372 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10373 nlines != WINDOW_TOTAL_LINES (w)))
10374 {
10375 extern Lisp_Object Qtool_bar_lines;
10376 Lisp_Object frame;
10377 int old_height = WINDOW_TOTAL_LINES (w);
10378
10379 XSETFRAME (frame, f);
10380 Fmodify_frame_parameters (frame,
10381 Fcons (Fcons (Qtool_bar_lines,
10382 make_number (nlines)),
10383 Qnil));
10384 if (WINDOW_TOTAL_LINES (w) != old_height)
10385 {
10386 clear_glyph_matrix (w->desired_matrix);
10387 fonts_changed_p = 1;
10388 return 1;
10389 }
10390 }
10391 }
10392
10393 /* Display as many lines as needed to display all tool-bar items. */
10394
10395 if (f->n_tool_bar_rows > 0)
10396 {
10397 int border, rows, height, extra;
10398
10399 if (INTEGERP (Vtool_bar_border))
10400 border = XINT (Vtool_bar_border);
10401 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10402 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10403 else if (EQ (Vtool_bar_border, Qborder_width))
10404 border = f->border_width;
10405 else
10406 border = 0;
10407 if (border < 0)
10408 border = 0;
10409
10410 rows = f->n_tool_bar_rows;
10411 height = max (1, (it.last_visible_y - border) / rows);
10412 extra = it.last_visible_y - border - height * rows;
10413
10414 while (it.current_y < it.last_visible_y)
10415 {
10416 int h = 0;
10417 if (extra > 0 && rows-- > 0)
10418 {
10419 h = (extra + rows - 1) / rows;
10420 extra -= h;
10421 }
10422 display_tool_bar_line (&it, height + h);
10423 }
10424 }
10425 else
10426 {
10427 while (it.current_y < it.last_visible_y)
10428 display_tool_bar_line (&it, 0);
10429 }
10430
10431 /* It doesn't make much sense to try scrolling in the tool-bar
10432 window, so don't do it. */
10433 w->desired_matrix->no_scrolling_p = 1;
10434 w->must_be_updated_p = 1;
10435
10436 if (!NILP (Vauto_resize_tool_bars))
10437 {
10438 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10439 int change_height_p = 0;
10440
10441 /* If we couldn't display everything, change the tool-bar's
10442 height if there is room for more. */
10443 if (IT_STRING_CHARPOS (it) < it.end_charpos
10444 && it.current_y < max_tool_bar_height)
10445 change_height_p = 1;
10446
10447 row = it.glyph_row - 1;
10448
10449 /* If there are blank lines at the end, except for a partially
10450 visible blank line at the end that is smaller than
10451 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10452 if (!row->displays_text_p
10453 && row->height >= FRAME_LINE_HEIGHT (f))
10454 change_height_p = 1;
10455
10456 /* If row displays tool-bar items, but is partially visible,
10457 change the tool-bar's height. */
10458 if (row->displays_text_p
10459 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10460 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10461 change_height_p = 1;
10462
10463 /* Resize windows as needed by changing the `tool-bar-lines'
10464 frame parameter. */
10465 if (change_height_p)
10466 {
10467 extern Lisp_Object Qtool_bar_lines;
10468 Lisp_Object frame;
10469 int old_height = WINDOW_TOTAL_LINES (w);
10470 int nrows;
10471 int nlines = tool_bar_lines_needed (f, &nrows);
10472
10473 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10474 && !f->minimize_tool_bar_window_p)
10475 ? (nlines > old_height)
10476 : (nlines != old_height));
10477 f->minimize_tool_bar_window_p = 0;
10478
10479 if (change_height_p)
10480 {
10481 XSETFRAME (frame, f);
10482 Fmodify_frame_parameters (frame,
10483 Fcons (Fcons (Qtool_bar_lines,
10484 make_number (nlines)),
10485 Qnil));
10486 if (WINDOW_TOTAL_LINES (w) != old_height)
10487 {
10488 clear_glyph_matrix (w->desired_matrix);
10489 f->n_tool_bar_rows = nrows;
10490 fonts_changed_p = 1;
10491 return 1;
10492 }
10493 }
10494 }
10495 }
10496
10497 f->minimize_tool_bar_window_p = 0;
10498 return 0;
10499 }
10500
10501
10502 /* Get information about the tool-bar item which is displayed in GLYPH
10503 on frame F. Return in *PROP_IDX the index where tool-bar item
10504 properties start in F->tool_bar_items. Value is zero if
10505 GLYPH doesn't display a tool-bar item. */
10506
10507 static int
10508 tool_bar_item_info (f, glyph, prop_idx)
10509 struct frame *f;
10510 struct glyph *glyph;
10511 int *prop_idx;
10512 {
10513 Lisp_Object prop;
10514 int success_p;
10515 int charpos;
10516
10517 /* This function can be called asynchronously, which means we must
10518 exclude any possibility that Fget_text_property signals an
10519 error. */
10520 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10521 charpos = max (0, charpos);
10522
10523 /* Get the text property `menu-item' at pos. The value of that
10524 property is the start index of this item's properties in
10525 F->tool_bar_items. */
10526 prop = Fget_text_property (make_number (charpos),
10527 Qmenu_item, f->current_tool_bar_string);
10528 if (INTEGERP (prop))
10529 {
10530 *prop_idx = XINT (prop);
10531 success_p = 1;
10532 }
10533 else
10534 success_p = 0;
10535
10536 return success_p;
10537 }
10538
10539 \f
10540 /* Get information about the tool-bar item at position X/Y on frame F.
10541 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10542 the current matrix of the tool-bar window of F, or NULL if not
10543 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10544 item in F->tool_bar_items. Value is
10545
10546 -1 if X/Y is not on a tool-bar item
10547 0 if X/Y is on the same item that was highlighted before.
10548 1 otherwise. */
10549
10550 static int
10551 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10552 struct frame *f;
10553 int x, y;
10554 struct glyph **glyph;
10555 int *hpos, *vpos, *prop_idx;
10556 {
10557 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10558 struct window *w = XWINDOW (f->tool_bar_window);
10559 int area;
10560
10561 /* Find the glyph under X/Y. */
10562 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10563 if (*glyph == NULL)
10564 return -1;
10565
10566 /* Get the start of this tool-bar item's properties in
10567 f->tool_bar_items. */
10568 if (!tool_bar_item_info (f, *glyph, prop_idx))
10569 return -1;
10570
10571 /* Is mouse on the highlighted item? */
10572 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10573 && *vpos >= dpyinfo->mouse_face_beg_row
10574 && *vpos <= dpyinfo->mouse_face_end_row
10575 && (*vpos > dpyinfo->mouse_face_beg_row
10576 || *hpos >= dpyinfo->mouse_face_beg_col)
10577 && (*vpos < dpyinfo->mouse_face_end_row
10578 || *hpos < dpyinfo->mouse_face_end_col
10579 || dpyinfo->mouse_face_past_end))
10580 return 0;
10581
10582 return 1;
10583 }
10584
10585
10586 /* EXPORT:
10587 Handle mouse button event on the tool-bar of frame F, at
10588 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10589 0 for button release. MODIFIERS is event modifiers for button
10590 release. */
10591
10592 void
10593 handle_tool_bar_click (f, x, y, down_p, modifiers)
10594 struct frame *f;
10595 int x, y, down_p;
10596 unsigned int modifiers;
10597 {
10598 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10599 struct window *w = XWINDOW (f->tool_bar_window);
10600 int hpos, vpos, prop_idx;
10601 struct glyph *glyph;
10602 Lisp_Object enabled_p;
10603
10604 /* If not on the highlighted tool-bar item, return. */
10605 frame_to_window_pixel_xy (w, &x, &y);
10606 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10607 return;
10608
10609 /* If item is disabled, do nothing. */
10610 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10611 if (NILP (enabled_p))
10612 return;
10613
10614 if (down_p)
10615 {
10616 /* Show item in pressed state. */
10617 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10618 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10619 last_tool_bar_item = prop_idx;
10620 }
10621 else
10622 {
10623 Lisp_Object key, frame;
10624 struct input_event event;
10625 EVENT_INIT (event);
10626
10627 /* Show item in released state. */
10628 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10629 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10630
10631 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10632
10633 XSETFRAME (frame, f);
10634 event.kind = TOOL_BAR_EVENT;
10635 event.frame_or_window = frame;
10636 event.arg = frame;
10637 kbd_buffer_store_event (&event);
10638
10639 event.kind = TOOL_BAR_EVENT;
10640 event.frame_or_window = frame;
10641 event.arg = key;
10642 event.modifiers = modifiers;
10643 kbd_buffer_store_event (&event);
10644 last_tool_bar_item = -1;
10645 }
10646 }
10647
10648
10649 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10650 tool-bar window-relative coordinates X/Y. Called from
10651 note_mouse_highlight. */
10652
10653 static void
10654 note_tool_bar_highlight (f, x, y)
10655 struct frame *f;
10656 int x, y;
10657 {
10658 Lisp_Object window = f->tool_bar_window;
10659 struct window *w = XWINDOW (window);
10660 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10661 int hpos, vpos;
10662 struct glyph *glyph;
10663 struct glyph_row *row;
10664 int i;
10665 Lisp_Object enabled_p;
10666 int prop_idx;
10667 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10668 int mouse_down_p, rc;
10669
10670 /* Function note_mouse_highlight is called with negative x(y
10671 values when mouse moves outside of the frame. */
10672 if (x <= 0 || y <= 0)
10673 {
10674 clear_mouse_face (dpyinfo);
10675 return;
10676 }
10677
10678 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10679 if (rc < 0)
10680 {
10681 /* Not on tool-bar item. */
10682 clear_mouse_face (dpyinfo);
10683 return;
10684 }
10685 else if (rc == 0)
10686 /* On same tool-bar item as before. */
10687 goto set_help_echo;
10688
10689 clear_mouse_face (dpyinfo);
10690
10691 /* Mouse is down, but on different tool-bar item? */
10692 mouse_down_p = (dpyinfo->grabbed
10693 && f == last_mouse_frame
10694 && FRAME_LIVE_P (f));
10695 if (mouse_down_p
10696 && last_tool_bar_item != prop_idx)
10697 return;
10698
10699 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10700 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10701
10702 /* If tool-bar item is not enabled, don't highlight it. */
10703 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10704 if (!NILP (enabled_p))
10705 {
10706 /* Compute the x-position of the glyph. In front and past the
10707 image is a space. We include this in the highlighted area. */
10708 row = MATRIX_ROW (w->current_matrix, vpos);
10709 for (i = x = 0; i < hpos; ++i)
10710 x += row->glyphs[TEXT_AREA][i].pixel_width;
10711
10712 /* Record this as the current active region. */
10713 dpyinfo->mouse_face_beg_col = hpos;
10714 dpyinfo->mouse_face_beg_row = vpos;
10715 dpyinfo->mouse_face_beg_x = x;
10716 dpyinfo->mouse_face_beg_y = row->y;
10717 dpyinfo->mouse_face_past_end = 0;
10718
10719 dpyinfo->mouse_face_end_col = hpos + 1;
10720 dpyinfo->mouse_face_end_row = vpos;
10721 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10722 dpyinfo->mouse_face_end_y = row->y;
10723 dpyinfo->mouse_face_window = window;
10724 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10725
10726 /* Display it as active. */
10727 show_mouse_face (dpyinfo, draw);
10728 dpyinfo->mouse_face_image_state = draw;
10729 }
10730
10731 set_help_echo:
10732
10733 /* Set help_echo_string to a help string to display for this tool-bar item.
10734 XTread_socket does the rest. */
10735 help_echo_object = help_echo_window = Qnil;
10736 help_echo_pos = -1;
10737 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10738 if (NILP (help_echo_string))
10739 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10740 }
10741
10742 #endif /* HAVE_WINDOW_SYSTEM */
10743
10744
10745 \f
10746 /************************************************************************
10747 Horizontal scrolling
10748 ************************************************************************/
10749
10750 static int hscroll_window_tree P_ ((Lisp_Object));
10751 static int hscroll_windows P_ ((Lisp_Object));
10752
10753 /* For all leaf windows in the window tree rooted at WINDOW, set their
10754 hscroll value so that PT is (i) visible in the window, and (ii) so
10755 that it is not within a certain margin at the window's left and
10756 right border. Value is non-zero if any window's hscroll has been
10757 changed. */
10758
10759 static int
10760 hscroll_window_tree (window)
10761 Lisp_Object window;
10762 {
10763 int hscrolled_p = 0;
10764 int hscroll_relative_p = FLOATP (Vhscroll_step);
10765 int hscroll_step_abs = 0;
10766 double hscroll_step_rel = 0;
10767
10768 if (hscroll_relative_p)
10769 {
10770 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10771 if (hscroll_step_rel < 0)
10772 {
10773 hscroll_relative_p = 0;
10774 hscroll_step_abs = 0;
10775 }
10776 }
10777 else if (INTEGERP (Vhscroll_step))
10778 {
10779 hscroll_step_abs = XINT (Vhscroll_step);
10780 if (hscroll_step_abs < 0)
10781 hscroll_step_abs = 0;
10782 }
10783 else
10784 hscroll_step_abs = 0;
10785
10786 while (WINDOWP (window))
10787 {
10788 struct window *w = XWINDOW (window);
10789
10790 if (WINDOWP (w->hchild))
10791 hscrolled_p |= hscroll_window_tree (w->hchild);
10792 else if (WINDOWP (w->vchild))
10793 hscrolled_p |= hscroll_window_tree (w->vchild);
10794 else if (w->cursor.vpos >= 0)
10795 {
10796 int h_margin;
10797 int text_area_width;
10798 struct glyph_row *current_cursor_row
10799 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10800 struct glyph_row *desired_cursor_row
10801 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10802 struct glyph_row *cursor_row
10803 = (desired_cursor_row->enabled_p
10804 ? desired_cursor_row
10805 : current_cursor_row);
10806
10807 text_area_width = window_box_width (w, TEXT_AREA);
10808
10809 /* Scroll when cursor is inside this scroll margin. */
10810 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10811
10812 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10813 && ((XFASTINT (w->hscroll)
10814 && w->cursor.x <= h_margin)
10815 || (cursor_row->enabled_p
10816 && cursor_row->truncated_on_right_p
10817 && (w->cursor.x >= text_area_width - h_margin))))
10818 {
10819 struct it it;
10820 int hscroll;
10821 struct buffer *saved_current_buffer;
10822 int pt;
10823 int wanted_x;
10824
10825 /* Find point in a display of infinite width. */
10826 saved_current_buffer = current_buffer;
10827 current_buffer = XBUFFER (w->buffer);
10828
10829 if (w == XWINDOW (selected_window))
10830 pt = BUF_PT (current_buffer);
10831 else
10832 {
10833 pt = marker_position (w->pointm);
10834 pt = max (BEGV, pt);
10835 pt = min (ZV, pt);
10836 }
10837
10838 /* Move iterator to pt starting at cursor_row->start in
10839 a line with infinite width. */
10840 init_to_row_start (&it, w, cursor_row);
10841 it.last_visible_x = INFINITY;
10842 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10843 current_buffer = saved_current_buffer;
10844
10845 /* Position cursor in window. */
10846 if (!hscroll_relative_p && hscroll_step_abs == 0)
10847 hscroll = max (0, (it.current_x
10848 - (ITERATOR_AT_END_OF_LINE_P (&it)
10849 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10850 : (text_area_width / 2))))
10851 / FRAME_COLUMN_WIDTH (it.f);
10852 else if (w->cursor.x >= text_area_width - h_margin)
10853 {
10854 if (hscroll_relative_p)
10855 wanted_x = text_area_width * (1 - hscroll_step_rel)
10856 - h_margin;
10857 else
10858 wanted_x = text_area_width
10859 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10860 - h_margin;
10861 hscroll
10862 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10863 }
10864 else
10865 {
10866 if (hscroll_relative_p)
10867 wanted_x = text_area_width * hscroll_step_rel
10868 + h_margin;
10869 else
10870 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10871 + h_margin;
10872 hscroll
10873 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10874 }
10875 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10876
10877 /* Don't call Fset_window_hscroll if value hasn't
10878 changed because it will prevent redisplay
10879 optimizations. */
10880 if (XFASTINT (w->hscroll) != hscroll)
10881 {
10882 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10883 w->hscroll = make_number (hscroll);
10884 hscrolled_p = 1;
10885 }
10886 }
10887 }
10888
10889 window = w->next;
10890 }
10891
10892 /* Value is non-zero if hscroll of any leaf window has been changed. */
10893 return hscrolled_p;
10894 }
10895
10896
10897 /* Set hscroll so that cursor is visible and not inside horizontal
10898 scroll margins for all windows in the tree rooted at WINDOW. See
10899 also hscroll_window_tree above. Value is non-zero if any window's
10900 hscroll has been changed. If it has, desired matrices on the frame
10901 of WINDOW are cleared. */
10902
10903 static int
10904 hscroll_windows (window)
10905 Lisp_Object window;
10906 {
10907 int hscrolled_p = hscroll_window_tree (window);
10908 if (hscrolled_p)
10909 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10910 return hscrolled_p;
10911 }
10912
10913
10914 \f
10915 /************************************************************************
10916 Redisplay
10917 ************************************************************************/
10918
10919 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10920 to a non-zero value. This is sometimes handy to have in a debugger
10921 session. */
10922
10923 #if GLYPH_DEBUG
10924
10925 /* First and last unchanged row for try_window_id. */
10926
10927 int debug_first_unchanged_at_end_vpos;
10928 int debug_last_unchanged_at_beg_vpos;
10929
10930 /* Delta vpos and y. */
10931
10932 int debug_dvpos, debug_dy;
10933
10934 /* Delta in characters and bytes for try_window_id. */
10935
10936 int debug_delta, debug_delta_bytes;
10937
10938 /* Values of window_end_pos and window_end_vpos at the end of
10939 try_window_id. */
10940
10941 EMACS_INT debug_end_pos, debug_end_vpos;
10942
10943 /* Append a string to W->desired_matrix->method. FMT is a printf
10944 format string. A1...A9 are a supplement for a variable-length
10945 argument list. If trace_redisplay_p is non-zero also printf the
10946 resulting string to stderr. */
10947
10948 static void
10949 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10950 struct window *w;
10951 char *fmt;
10952 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10953 {
10954 char buffer[512];
10955 char *method = w->desired_matrix->method;
10956 int len = strlen (method);
10957 int size = sizeof w->desired_matrix->method;
10958 int remaining = size - len - 1;
10959
10960 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10961 if (len && remaining)
10962 {
10963 method[len] = '|';
10964 --remaining, ++len;
10965 }
10966
10967 strncpy (method + len, buffer, remaining);
10968
10969 if (trace_redisplay_p)
10970 fprintf (stderr, "%p (%s): %s\n",
10971 w,
10972 ((BUFFERP (w->buffer)
10973 && STRINGP (XBUFFER (w->buffer)->name))
10974 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10975 : "no buffer"),
10976 buffer);
10977 }
10978
10979 #endif /* GLYPH_DEBUG */
10980
10981
10982 /* Value is non-zero if all changes in window W, which displays
10983 current_buffer, are in the text between START and END. START is a
10984 buffer position, END is given as a distance from Z. Used in
10985 redisplay_internal for display optimization. */
10986
10987 static INLINE int
10988 text_outside_line_unchanged_p (w, start, end)
10989 struct window *w;
10990 int start, end;
10991 {
10992 int unchanged_p = 1;
10993
10994 /* If text or overlays have changed, see where. */
10995 if (XFASTINT (w->last_modified) < MODIFF
10996 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10997 {
10998 /* Gap in the line? */
10999 if (GPT < start || Z - GPT < end)
11000 unchanged_p = 0;
11001
11002 /* Changes start in front of the line, or end after it? */
11003 if (unchanged_p
11004 && (BEG_UNCHANGED < start - 1
11005 || END_UNCHANGED < end))
11006 unchanged_p = 0;
11007
11008 /* If selective display, can't optimize if changes start at the
11009 beginning of the line. */
11010 if (unchanged_p
11011 && INTEGERP (current_buffer->selective_display)
11012 && XINT (current_buffer->selective_display) > 0
11013 && (BEG_UNCHANGED < start || GPT <= start))
11014 unchanged_p = 0;
11015
11016 /* If there are overlays at the start or end of the line, these
11017 may have overlay strings with newlines in them. A change at
11018 START, for instance, may actually concern the display of such
11019 overlay strings as well, and they are displayed on different
11020 lines. So, quickly rule out this case. (For the future, it
11021 might be desirable to implement something more telling than
11022 just BEG/END_UNCHANGED.) */
11023 if (unchanged_p)
11024 {
11025 if (BEG + BEG_UNCHANGED == start
11026 && overlay_touches_p (start))
11027 unchanged_p = 0;
11028 if (END_UNCHANGED == end
11029 && overlay_touches_p (Z - end))
11030 unchanged_p = 0;
11031 }
11032 }
11033
11034 return unchanged_p;
11035 }
11036
11037
11038 /* Do a frame update, taking possible shortcuts into account. This is
11039 the main external entry point for redisplay.
11040
11041 If the last redisplay displayed an echo area message and that message
11042 is no longer requested, we clear the echo area or bring back the
11043 mini-buffer if that is in use. */
11044
11045 void
11046 redisplay ()
11047 {
11048 redisplay_internal (0);
11049 }
11050
11051
11052 static Lisp_Object
11053 overlay_arrow_string_or_property (var)
11054 Lisp_Object var;
11055 {
11056 Lisp_Object val;
11057
11058 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11059 return val;
11060
11061 return Voverlay_arrow_string;
11062 }
11063
11064 /* Return 1 if there are any overlay-arrows in current_buffer. */
11065 static int
11066 overlay_arrow_in_current_buffer_p ()
11067 {
11068 Lisp_Object vlist;
11069
11070 for (vlist = Voverlay_arrow_variable_list;
11071 CONSP (vlist);
11072 vlist = XCDR (vlist))
11073 {
11074 Lisp_Object var = XCAR (vlist);
11075 Lisp_Object val;
11076
11077 if (!SYMBOLP (var))
11078 continue;
11079 val = find_symbol_value (var);
11080 if (MARKERP (val)
11081 && current_buffer == XMARKER (val)->buffer)
11082 return 1;
11083 }
11084 return 0;
11085 }
11086
11087
11088 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11089 has changed. */
11090
11091 static int
11092 overlay_arrows_changed_p ()
11093 {
11094 Lisp_Object vlist;
11095
11096 for (vlist = Voverlay_arrow_variable_list;
11097 CONSP (vlist);
11098 vlist = XCDR (vlist))
11099 {
11100 Lisp_Object var = XCAR (vlist);
11101 Lisp_Object val, pstr;
11102
11103 if (!SYMBOLP (var))
11104 continue;
11105 val = find_symbol_value (var);
11106 if (!MARKERP (val))
11107 continue;
11108 if (! EQ (COERCE_MARKER (val),
11109 Fget (var, Qlast_arrow_position))
11110 || ! (pstr = overlay_arrow_string_or_property (var),
11111 EQ (pstr, Fget (var, Qlast_arrow_string))))
11112 return 1;
11113 }
11114 return 0;
11115 }
11116
11117 /* Mark overlay arrows to be updated on next redisplay. */
11118
11119 static void
11120 update_overlay_arrows (up_to_date)
11121 int up_to_date;
11122 {
11123 Lisp_Object vlist;
11124
11125 for (vlist = Voverlay_arrow_variable_list;
11126 CONSP (vlist);
11127 vlist = XCDR (vlist))
11128 {
11129 Lisp_Object var = XCAR (vlist);
11130
11131 if (!SYMBOLP (var))
11132 continue;
11133
11134 if (up_to_date > 0)
11135 {
11136 Lisp_Object val = find_symbol_value (var);
11137 Fput (var, Qlast_arrow_position,
11138 COERCE_MARKER (val));
11139 Fput (var, Qlast_arrow_string,
11140 overlay_arrow_string_or_property (var));
11141 }
11142 else if (up_to_date < 0
11143 || !NILP (Fget (var, Qlast_arrow_position)))
11144 {
11145 Fput (var, Qlast_arrow_position, Qt);
11146 Fput (var, Qlast_arrow_string, Qt);
11147 }
11148 }
11149 }
11150
11151
11152 /* Return overlay arrow string to display at row.
11153 Return integer (bitmap number) for arrow bitmap in left fringe.
11154 Return nil if no overlay arrow. */
11155
11156 static Lisp_Object
11157 overlay_arrow_at_row (it, row)
11158 struct it *it;
11159 struct glyph_row *row;
11160 {
11161 Lisp_Object vlist;
11162
11163 for (vlist = Voverlay_arrow_variable_list;
11164 CONSP (vlist);
11165 vlist = XCDR (vlist))
11166 {
11167 Lisp_Object var = XCAR (vlist);
11168 Lisp_Object val;
11169
11170 if (!SYMBOLP (var))
11171 continue;
11172
11173 val = find_symbol_value (var);
11174
11175 if (MARKERP (val)
11176 && current_buffer == XMARKER (val)->buffer
11177 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11178 {
11179 if (FRAME_WINDOW_P (it->f)
11180 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11181 {
11182 #ifdef HAVE_WINDOW_SYSTEM
11183 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11184 {
11185 int fringe_bitmap;
11186 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11187 return make_number (fringe_bitmap);
11188 }
11189 #endif
11190 return make_number (-1); /* Use default arrow bitmap */
11191 }
11192 return overlay_arrow_string_or_property (var);
11193 }
11194 }
11195
11196 return Qnil;
11197 }
11198
11199 /* Return 1 if point moved out of or into a composition. Otherwise
11200 return 0. PREV_BUF and PREV_PT are the last point buffer and
11201 position. BUF and PT are the current point buffer and position. */
11202
11203 int
11204 check_point_in_composition (prev_buf, prev_pt, buf, pt)
11205 struct buffer *prev_buf, *buf;
11206 int prev_pt, pt;
11207 {
11208 EMACS_INT start, end;
11209 Lisp_Object prop;
11210 Lisp_Object buffer;
11211
11212 XSETBUFFER (buffer, buf);
11213 /* Check a composition at the last point if point moved within the
11214 same buffer. */
11215 if (prev_buf == buf)
11216 {
11217 if (prev_pt == pt)
11218 /* Point didn't move. */
11219 return 0;
11220
11221 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11222 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11223 && COMPOSITION_VALID_P (start, end, prop)
11224 && start < prev_pt && end > prev_pt)
11225 /* The last point was within the composition. Return 1 iff
11226 point moved out of the composition. */
11227 return (pt <= start || pt >= end);
11228 }
11229
11230 /* Check a composition at the current point. */
11231 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11232 && find_composition (pt, -1, &start, &end, &prop, buffer)
11233 && COMPOSITION_VALID_P (start, end, prop)
11234 && start < pt && end > pt);
11235 }
11236
11237
11238 /* Reconsider the setting of B->clip_changed which is displayed
11239 in window W. */
11240
11241 static INLINE void
11242 reconsider_clip_changes (w, b)
11243 struct window *w;
11244 struct buffer *b;
11245 {
11246 if (b->clip_changed
11247 && !NILP (w->window_end_valid)
11248 && w->current_matrix->buffer == b
11249 && w->current_matrix->zv == BUF_ZV (b)
11250 && w->current_matrix->begv == BUF_BEGV (b))
11251 b->clip_changed = 0;
11252
11253 /* If display wasn't paused, and W is not a tool bar window, see if
11254 point has been moved into or out of a composition. In that case,
11255 we set b->clip_changed to 1 to force updating the screen. If
11256 b->clip_changed has already been set to 1, we can skip this
11257 check. */
11258 if (!b->clip_changed
11259 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11260 {
11261 int pt;
11262
11263 if (w == XWINDOW (selected_window))
11264 pt = BUF_PT (current_buffer);
11265 else
11266 pt = marker_position (w->pointm);
11267
11268 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11269 || pt != XINT (w->last_point))
11270 && check_point_in_composition (w->current_matrix->buffer,
11271 XINT (w->last_point),
11272 XBUFFER (w->buffer), pt))
11273 b->clip_changed = 1;
11274 }
11275 }
11276 \f
11277
11278 /* Select FRAME to forward the values of frame-local variables into C
11279 variables so that the redisplay routines can access those values
11280 directly. */
11281
11282 static void
11283 select_frame_for_redisplay (frame)
11284 Lisp_Object frame;
11285 {
11286 Lisp_Object tail, symbol, val;
11287 Lisp_Object old = selected_frame;
11288 struct Lisp_Symbol *sym;
11289
11290 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11291
11292 selected_frame = frame;
11293
11294 do
11295 {
11296 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11297 if (CONSP (XCAR (tail))
11298 && (symbol = XCAR (XCAR (tail)),
11299 SYMBOLP (symbol))
11300 && (sym = indirect_variable (XSYMBOL (symbol)),
11301 val = sym->value,
11302 (BUFFER_LOCAL_VALUEP (val)))
11303 && XBUFFER_LOCAL_VALUE (val)->check_frame)
11304 /* Use find_symbol_value rather than Fsymbol_value
11305 to avoid an error if it is void. */
11306 find_symbol_value (symbol);
11307 } while (!EQ (frame, old) && (frame = old, 1));
11308 }
11309
11310
11311 #define STOP_POLLING \
11312 do { if (! polling_stopped_here) stop_polling (); \
11313 polling_stopped_here = 1; } while (0)
11314
11315 #define RESUME_POLLING \
11316 do { if (polling_stopped_here) start_polling (); \
11317 polling_stopped_here = 0; } while (0)
11318
11319
11320 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11321 response to any user action; therefore, we should preserve the echo
11322 area. (Actually, our caller does that job.) Perhaps in the future
11323 avoid recentering windows if it is not necessary; currently that
11324 causes some problems. */
11325
11326 static void
11327 redisplay_internal (preserve_echo_area)
11328 int preserve_echo_area;
11329 {
11330 struct window *w = XWINDOW (selected_window);
11331 struct frame *f;
11332 int pause;
11333 int must_finish = 0;
11334 struct text_pos tlbufpos, tlendpos;
11335 int number_of_visible_frames;
11336 int count, count1;
11337 struct frame *sf;
11338 int polling_stopped_here = 0;
11339 Lisp_Object old_frame = selected_frame;
11340
11341 /* Non-zero means redisplay has to consider all windows on all
11342 frames. Zero means, only selected_window is considered. */
11343 int consider_all_windows_p;
11344
11345 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11346
11347 /* No redisplay if running in batch mode or frame is not yet fully
11348 initialized, or redisplay is explicitly turned off by setting
11349 Vinhibit_redisplay. */
11350 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11351 || !NILP (Vinhibit_redisplay))
11352 return;
11353
11354 /* Don't examine these until after testing Vinhibit_redisplay.
11355 When Emacs is shutting down, perhaps because its connection to
11356 X has dropped, we should not look at them at all. */
11357 f = XFRAME (w->frame);
11358 sf = SELECTED_FRAME ();
11359
11360 if (!f->glyphs_initialized_p)
11361 return;
11362
11363 /* The flag redisplay_performed_directly_p is set by
11364 direct_output_for_insert when it already did the whole screen
11365 update necessary. */
11366 if (redisplay_performed_directly_p)
11367 {
11368 redisplay_performed_directly_p = 0;
11369 if (!hscroll_windows (selected_window))
11370 return;
11371 }
11372
11373 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11374 if (popup_activated ())
11375 return;
11376 #endif
11377
11378 /* I don't think this happens but let's be paranoid. */
11379 if (redisplaying_p)
11380 return;
11381
11382 /* Record a function that resets redisplaying_p to its old value
11383 when we leave this function. */
11384 count = SPECPDL_INDEX ();
11385 record_unwind_protect (unwind_redisplay,
11386 Fcons (make_number (redisplaying_p), selected_frame));
11387 ++redisplaying_p;
11388 specbind (Qinhibit_free_realized_faces, Qnil);
11389
11390 {
11391 Lisp_Object tail, frame;
11392
11393 FOR_EACH_FRAME (tail, frame)
11394 {
11395 struct frame *f = XFRAME (frame);
11396 f->already_hscrolled_p = 0;
11397 }
11398 }
11399
11400 retry:
11401 if (!EQ (old_frame, selected_frame)
11402 && FRAME_LIVE_P (XFRAME (old_frame)))
11403 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11404 selected_frame and selected_window to be temporarily out-of-sync so
11405 when we come back here via `goto retry', we need to resync because we
11406 may need to run Elisp code (via prepare_menu_bars). */
11407 select_frame_for_redisplay (old_frame);
11408
11409 pause = 0;
11410 reconsider_clip_changes (w, current_buffer);
11411 last_escape_glyph_frame = NULL;
11412 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11413
11414 /* If new fonts have been loaded that make a glyph matrix adjustment
11415 necessary, do it. */
11416 if (fonts_changed_p)
11417 {
11418 adjust_glyphs (NULL);
11419 ++windows_or_buffers_changed;
11420 fonts_changed_p = 0;
11421 }
11422
11423 /* If face_change_count is non-zero, init_iterator will free all
11424 realized faces, which includes the faces referenced from current
11425 matrices. So, we can't reuse current matrices in this case. */
11426 if (face_change_count)
11427 ++windows_or_buffers_changed;
11428
11429 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11430 && FRAME_TTY (sf)->previous_frame != sf)
11431 {
11432 /* Since frames on a single ASCII terminal share the same
11433 display area, displaying a different frame means redisplay
11434 the whole thing. */
11435 windows_or_buffers_changed++;
11436 SET_FRAME_GARBAGED (sf);
11437 #ifndef DOS_NT
11438 set_tty_color_mode (FRAME_TTY (sf), sf);
11439 #endif
11440 FRAME_TTY (sf)->previous_frame = sf;
11441 }
11442
11443 /* Set the visible flags for all frames. Do this before checking
11444 for resized or garbaged frames; they want to know if their frames
11445 are visible. See the comment in frame.h for
11446 FRAME_SAMPLE_VISIBILITY. */
11447 {
11448 Lisp_Object tail, frame;
11449
11450 number_of_visible_frames = 0;
11451
11452 FOR_EACH_FRAME (tail, frame)
11453 {
11454 struct frame *f = XFRAME (frame);
11455
11456 FRAME_SAMPLE_VISIBILITY (f);
11457 if (FRAME_VISIBLE_P (f))
11458 ++number_of_visible_frames;
11459 clear_desired_matrices (f);
11460 }
11461 }
11462
11463 /* Notice any pending interrupt request to change frame size. */
11464 do_pending_window_change (1);
11465
11466 /* Clear frames marked as garbaged. */
11467 if (frame_garbaged)
11468 clear_garbaged_frames ();
11469
11470 /* Build menubar and tool-bar items. */
11471 if (NILP (Vmemory_full))
11472 prepare_menu_bars ();
11473
11474 if (windows_or_buffers_changed)
11475 update_mode_lines++;
11476
11477 /* Detect case that we need to write or remove a star in the mode line. */
11478 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11479 {
11480 w->update_mode_line = Qt;
11481 if (buffer_shared > 1)
11482 update_mode_lines++;
11483 }
11484
11485 /* Avoid invocation of point motion hooks by `current_column' below. */
11486 count1 = SPECPDL_INDEX ();
11487 specbind (Qinhibit_point_motion_hooks, Qt);
11488
11489 /* If %c is in the mode line, update it if needed. */
11490 if (!NILP (w->column_number_displayed)
11491 /* This alternative quickly identifies a common case
11492 where no change is needed. */
11493 && !(PT == XFASTINT (w->last_point)
11494 && XFASTINT (w->last_modified) >= MODIFF
11495 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11496 && (XFASTINT (w->column_number_displayed)
11497 != (int) current_column ())) /* iftc */
11498 w->update_mode_line = Qt;
11499
11500 unbind_to (count1, Qnil);
11501
11502 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11503
11504 /* The variable buffer_shared is set in redisplay_window and
11505 indicates that we redisplay a buffer in different windows. See
11506 there. */
11507 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11508 || cursor_type_changed);
11509
11510 /* If specs for an arrow have changed, do thorough redisplay
11511 to ensure we remove any arrow that should no longer exist. */
11512 if (overlay_arrows_changed_p ())
11513 consider_all_windows_p = windows_or_buffers_changed = 1;
11514
11515 /* Normally the message* functions will have already displayed and
11516 updated the echo area, but the frame may have been trashed, or
11517 the update may have been preempted, so display the echo area
11518 again here. Checking message_cleared_p captures the case that
11519 the echo area should be cleared. */
11520 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11521 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11522 || (message_cleared_p
11523 && minibuf_level == 0
11524 /* If the mini-window is currently selected, this means the
11525 echo-area doesn't show through. */
11526 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11527 {
11528 int window_height_changed_p = echo_area_display (0);
11529 must_finish = 1;
11530
11531 /* If we don't display the current message, don't clear the
11532 message_cleared_p flag, because, if we did, we wouldn't clear
11533 the echo area in the next redisplay which doesn't preserve
11534 the echo area. */
11535 if (!display_last_displayed_message_p)
11536 message_cleared_p = 0;
11537
11538 if (fonts_changed_p)
11539 goto retry;
11540 else if (window_height_changed_p)
11541 {
11542 consider_all_windows_p = 1;
11543 ++update_mode_lines;
11544 ++windows_or_buffers_changed;
11545
11546 /* If window configuration was changed, frames may have been
11547 marked garbaged. Clear them or we will experience
11548 surprises wrt scrolling. */
11549 if (frame_garbaged)
11550 clear_garbaged_frames ();
11551 }
11552 }
11553 else if (EQ (selected_window, minibuf_window)
11554 && (current_buffer->clip_changed
11555 || XFASTINT (w->last_modified) < MODIFF
11556 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11557 && resize_mini_window (w, 0))
11558 {
11559 /* Resized active mini-window to fit the size of what it is
11560 showing if its contents might have changed. */
11561 must_finish = 1;
11562 /* FIXME: this causes all frames to be updated, which seems unnecessary
11563 since only the current frame needs to be considered. This function needs
11564 to be rewritten with two variables, consider_all_windows and
11565 consider_all_frames. */
11566 consider_all_windows_p = 1;
11567 ++windows_or_buffers_changed;
11568 ++update_mode_lines;
11569
11570 /* If window configuration was changed, frames may have been
11571 marked garbaged. Clear them or we will experience
11572 surprises wrt scrolling. */
11573 if (frame_garbaged)
11574 clear_garbaged_frames ();
11575 }
11576
11577
11578 /* If showing the region, and mark has changed, we must redisplay
11579 the whole window. The assignment to this_line_start_pos prevents
11580 the optimization directly below this if-statement. */
11581 if (((!NILP (Vtransient_mark_mode)
11582 && !NILP (XBUFFER (w->buffer)->mark_active))
11583 != !NILP (w->region_showing))
11584 || (!NILP (w->region_showing)
11585 && !EQ (w->region_showing,
11586 Fmarker_position (XBUFFER (w->buffer)->mark))))
11587 CHARPOS (this_line_start_pos) = 0;
11588
11589 /* Optimize the case that only the line containing the cursor in the
11590 selected window has changed. Variables starting with this_ are
11591 set in display_line and record information about the line
11592 containing the cursor. */
11593 tlbufpos = this_line_start_pos;
11594 tlendpos = this_line_end_pos;
11595 if (!consider_all_windows_p
11596 && CHARPOS (tlbufpos) > 0
11597 && NILP (w->update_mode_line)
11598 && !current_buffer->clip_changed
11599 && !current_buffer->prevent_redisplay_optimizations_p
11600 && FRAME_VISIBLE_P (XFRAME (w->frame))
11601 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11602 /* Make sure recorded data applies to current buffer, etc. */
11603 && this_line_buffer == current_buffer
11604 && current_buffer == XBUFFER (w->buffer)
11605 && NILP (w->force_start)
11606 && NILP (w->optional_new_start)
11607 /* Point must be on the line that we have info recorded about. */
11608 && PT >= CHARPOS (tlbufpos)
11609 && PT <= Z - CHARPOS (tlendpos)
11610 /* All text outside that line, including its final newline,
11611 must be unchanged. */
11612 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11613 CHARPOS (tlendpos)))
11614 {
11615 if (CHARPOS (tlbufpos) > BEGV
11616 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11617 && (CHARPOS (tlbufpos) == ZV
11618 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11619 /* Former continuation line has disappeared by becoming empty. */
11620 goto cancel;
11621 else if (XFASTINT (w->last_modified) < MODIFF
11622 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11623 || MINI_WINDOW_P (w))
11624 {
11625 /* We have to handle the case of continuation around a
11626 wide-column character (see the comment in indent.c around
11627 line 1340).
11628
11629 For instance, in the following case:
11630
11631 -------- Insert --------
11632 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11633 J_I_ ==> J_I_ `^^' are cursors.
11634 ^^ ^^
11635 -------- --------
11636
11637 As we have to redraw the line above, we cannot use this
11638 optimization. */
11639
11640 struct it it;
11641 int line_height_before = this_line_pixel_height;
11642
11643 /* Note that start_display will handle the case that the
11644 line starting at tlbufpos is a continuation line. */
11645 start_display (&it, w, tlbufpos);
11646
11647 /* Implementation note: It this still necessary? */
11648 if (it.current_x != this_line_start_x)
11649 goto cancel;
11650
11651 TRACE ((stderr, "trying display optimization 1\n"));
11652 w->cursor.vpos = -1;
11653 overlay_arrow_seen = 0;
11654 it.vpos = this_line_vpos;
11655 it.current_y = this_line_y;
11656 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11657 display_line (&it);
11658
11659 /* If line contains point, is not continued,
11660 and ends at same distance from eob as before, we win. */
11661 if (w->cursor.vpos >= 0
11662 /* Line is not continued, otherwise this_line_start_pos
11663 would have been set to 0 in display_line. */
11664 && CHARPOS (this_line_start_pos)
11665 /* Line ends as before. */
11666 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11667 /* Line has same height as before. Otherwise other lines
11668 would have to be shifted up or down. */
11669 && this_line_pixel_height == line_height_before)
11670 {
11671 /* If this is not the window's last line, we must adjust
11672 the charstarts of the lines below. */
11673 if (it.current_y < it.last_visible_y)
11674 {
11675 struct glyph_row *row
11676 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11677 int delta, delta_bytes;
11678
11679 /* We used to distinguish between two cases here,
11680 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11681 when the line ends in a newline or the end of the
11682 buffer's accessible portion. But both cases did
11683 the same, so they were collapsed. */
11684 delta = (Z
11685 - CHARPOS (tlendpos)
11686 - MATRIX_ROW_START_CHARPOS (row));
11687 delta_bytes = (Z_BYTE
11688 - BYTEPOS (tlendpos)
11689 - MATRIX_ROW_START_BYTEPOS (row));
11690
11691 increment_matrix_positions (w->current_matrix,
11692 this_line_vpos + 1,
11693 w->current_matrix->nrows,
11694 delta, delta_bytes);
11695 }
11696
11697 /* If this row displays text now but previously didn't,
11698 or vice versa, w->window_end_vpos may have to be
11699 adjusted. */
11700 if ((it.glyph_row - 1)->displays_text_p)
11701 {
11702 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11703 XSETINT (w->window_end_vpos, this_line_vpos);
11704 }
11705 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11706 && this_line_vpos > 0)
11707 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11708 w->window_end_valid = Qnil;
11709
11710 /* Update hint: No need to try to scroll in update_window. */
11711 w->desired_matrix->no_scrolling_p = 1;
11712
11713 #if GLYPH_DEBUG
11714 *w->desired_matrix->method = 0;
11715 debug_method_add (w, "optimization 1");
11716 #endif
11717 #ifdef HAVE_WINDOW_SYSTEM
11718 update_window_fringes (w, 0);
11719 #endif
11720 goto update;
11721 }
11722 else
11723 goto cancel;
11724 }
11725 else if (/* Cursor position hasn't changed. */
11726 PT == XFASTINT (w->last_point)
11727 /* Make sure the cursor was last displayed
11728 in this window. Otherwise we have to reposition it. */
11729 && 0 <= w->cursor.vpos
11730 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11731 {
11732 if (!must_finish)
11733 {
11734 do_pending_window_change (1);
11735
11736 /* We used to always goto end_of_redisplay here, but this
11737 isn't enough if we have a blinking cursor. */
11738 if (w->cursor_off_p == w->last_cursor_off_p)
11739 goto end_of_redisplay;
11740 }
11741 goto update;
11742 }
11743 /* If highlighting the region, or if the cursor is in the echo area,
11744 then we can't just move the cursor. */
11745 else if (! (!NILP (Vtransient_mark_mode)
11746 && !NILP (current_buffer->mark_active))
11747 && (EQ (selected_window, current_buffer->last_selected_window)
11748 || highlight_nonselected_windows)
11749 && NILP (w->region_showing)
11750 && NILP (Vshow_trailing_whitespace)
11751 && !cursor_in_echo_area)
11752 {
11753 struct it it;
11754 struct glyph_row *row;
11755
11756 /* Skip from tlbufpos to PT and see where it is. Note that
11757 PT may be in invisible text. If so, we will end at the
11758 next visible position. */
11759 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11760 NULL, DEFAULT_FACE_ID);
11761 it.current_x = this_line_start_x;
11762 it.current_y = this_line_y;
11763 it.vpos = this_line_vpos;
11764
11765 /* The call to move_it_to stops in front of PT, but
11766 moves over before-strings. */
11767 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11768
11769 if (it.vpos == this_line_vpos
11770 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11771 row->enabled_p))
11772 {
11773 xassert (this_line_vpos == it.vpos);
11774 xassert (this_line_y == it.current_y);
11775 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11776 #if GLYPH_DEBUG
11777 *w->desired_matrix->method = 0;
11778 debug_method_add (w, "optimization 3");
11779 #endif
11780 goto update;
11781 }
11782 else
11783 goto cancel;
11784 }
11785
11786 cancel:
11787 /* Text changed drastically or point moved off of line. */
11788 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11789 }
11790
11791 CHARPOS (this_line_start_pos) = 0;
11792 consider_all_windows_p |= buffer_shared > 1;
11793 ++clear_face_cache_count;
11794 #ifdef HAVE_WINDOW_SYSTEM
11795 ++clear_image_cache_count;
11796 #endif
11797
11798 /* Build desired matrices, and update the display. If
11799 consider_all_windows_p is non-zero, do it for all windows on all
11800 frames. Otherwise do it for selected_window, only. */
11801
11802 if (consider_all_windows_p)
11803 {
11804 Lisp_Object tail, frame;
11805
11806 FOR_EACH_FRAME (tail, frame)
11807 XFRAME (frame)->updated_p = 0;
11808
11809 /* Recompute # windows showing selected buffer. This will be
11810 incremented each time such a window is displayed. */
11811 buffer_shared = 0;
11812
11813 FOR_EACH_FRAME (tail, frame)
11814 {
11815 struct frame *f = XFRAME (frame);
11816
11817 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11818 {
11819 if (! EQ (frame, selected_frame))
11820 /* Select the frame, for the sake of frame-local
11821 variables. */
11822 select_frame_for_redisplay (frame);
11823
11824 /* Mark all the scroll bars to be removed; we'll redeem
11825 the ones we want when we redisplay their windows. */
11826 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11827 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11828
11829 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11830 redisplay_windows (FRAME_ROOT_WINDOW (f));
11831
11832 /* The X error handler may have deleted that frame. */
11833 if (!FRAME_LIVE_P (f))
11834 continue;
11835
11836 /* Any scroll bars which redisplay_windows should have
11837 nuked should now go away. */
11838 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11839 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11840
11841 /* If fonts changed, display again. */
11842 /* ??? rms: I suspect it is a mistake to jump all the way
11843 back to retry here. It should just retry this frame. */
11844 if (fonts_changed_p)
11845 goto retry;
11846
11847 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11848 {
11849 /* See if we have to hscroll. */
11850 if (!f->already_hscrolled_p)
11851 {
11852 f->already_hscrolled_p = 1;
11853 if (hscroll_windows (f->root_window))
11854 goto retry;
11855 }
11856
11857 /* Prevent various kinds of signals during display
11858 update. stdio is not robust about handling
11859 signals, which can cause an apparent I/O
11860 error. */
11861 if (interrupt_input)
11862 unrequest_sigio ();
11863 STOP_POLLING;
11864
11865 /* Update the display. */
11866 set_window_update_flags (XWINDOW (f->root_window), 1);
11867 pause |= update_frame (f, 0, 0);
11868 f->updated_p = 1;
11869 }
11870 }
11871 }
11872
11873 if (!EQ (old_frame, selected_frame)
11874 && FRAME_LIVE_P (XFRAME (old_frame)))
11875 /* We played a bit fast-and-loose above and allowed selected_frame
11876 and selected_window to be temporarily out-of-sync but let's make
11877 sure this stays contained. */
11878 select_frame_for_redisplay (old_frame);
11879 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
11880
11881 if (!pause)
11882 {
11883 /* Do the mark_window_display_accurate after all windows have
11884 been redisplayed because this call resets flags in buffers
11885 which are needed for proper redisplay. */
11886 FOR_EACH_FRAME (tail, frame)
11887 {
11888 struct frame *f = XFRAME (frame);
11889 if (f->updated_p)
11890 {
11891 mark_window_display_accurate (f->root_window, 1);
11892 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11893 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11894 }
11895 }
11896 }
11897 }
11898 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11899 {
11900 Lisp_Object mini_window;
11901 struct frame *mini_frame;
11902
11903 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11904 /* Use list_of_error, not Qerror, so that
11905 we catch only errors and don't run the debugger. */
11906 internal_condition_case_1 (redisplay_window_1, selected_window,
11907 list_of_error,
11908 redisplay_window_error);
11909
11910 /* Compare desired and current matrices, perform output. */
11911
11912 update:
11913 /* If fonts changed, display again. */
11914 if (fonts_changed_p)
11915 goto retry;
11916
11917 /* Prevent various kinds of signals during display update.
11918 stdio is not robust about handling signals,
11919 which can cause an apparent I/O error. */
11920 if (interrupt_input)
11921 unrequest_sigio ();
11922 STOP_POLLING;
11923
11924 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11925 {
11926 if (hscroll_windows (selected_window))
11927 goto retry;
11928
11929 XWINDOW (selected_window)->must_be_updated_p = 1;
11930 pause = update_frame (sf, 0, 0);
11931 }
11932
11933 /* We may have called echo_area_display at the top of this
11934 function. If the echo area is on another frame, that may
11935 have put text on a frame other than the selected one, so the
11936 above call to update_frame would not have caught it. Catch
11937 it here. */
11938 mini_window = FRAME_MINIBUF_WINDOW (sf);
11939 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11940
11941 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11942 {
11943 XWINDOW (mini_window)->must_be_updated_p = 1;
11944 pause |= update_frame (mini_frame, 0, 0);
11945 if (!pause && hscroll_windows (mini_window))
11946 goto retry;
11947 }
11948 }
11949
11950 /* If display was paused because of pending input, make sure we do a
11951 thorough update the next time. */
11952 if (pause)
11953 {
11954 /* Prevent the optimization at the beginning of
11955 redisplay_internal that tries a single-line update of the
11956 line containing the cursor in the selected window. */
11957 CHARPOS (this_line_start_pos) = 0;
11958
11959 /* Let the overlay arrow be updated the next time. */
11960 update_overlay_arrows (0);
11961
11962 /* If we pause after scrolling, some rows in the current
11963 matrices of some windows are not valid. */
11964 if (!WINDOW_FULL_WIDTH_P (w)
11965 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11966 update_mode_lines = 1;
11967 }
11968 else
11969 {
11970 if (!consider_all_windows_p)
11971 {
11972 /* This has already been done above if
11973 consider_all_windows_p is set. */
11974 mark_window_display_accurate_1 (w, 1);
11975
11976 /* Say overlay arrows are up to date. */
11977 update_overlay_arrows (1);
11978
11979 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11980 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11981 }
11982
11983 update_mode_lines = 0;
11984 windows_or_buffers_changed = 0;
11985 cursor_type_changed = 0;
11986 }
11987
11988 /* Start SIGIO interrupts coming again. Having them off during the
11989 code above makes it less likely one will discard output, but not
11990 impossible, since there might be stuff in the system buffer here.
11991 But it is much hairier to try to do anything about that. */
11992 if (interrupt_input)
11993 request_sigio ();
11994 RESUME_POLLING;
11995
11996 /* If a frame has become visible which was not before, redisplay
11997 again, so that we display it. Expose events for such a frame
11998 (which it gets when becoming visible) don't call the parts of
11999 redisplay constructing glyphs, so simply exposing a frame won't
12000 display anything in this case. So, we have to display these
12001 frames here explicitly. */
12002 if (!pause)
12003 {
12004 Lisp_Object tail, frame;
12005 int new_count = 0;
12006
12007 FOR_EACH_FRAME (tail, frame)
12008 {
12009 int this_is_visible = 0;
12010
12011 if (XFRAME (frame)->visible)
12012 this_is_visible = 1;
12013 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12014 if (XFRAME (frame)->visible)
12015 this_is_visible = 1;
12016
12017 if (this_is_visible)
12018 new_count++;
12019 }
12020
12021 if (new_count != number_of_visible_frames)
12022 windows_or_buffers_changed++;
12023 }
12024
12025 /* Change frame size now if a change is pending. */
12026 do_pending_window_change (1);
12027
12028 /* If we just did a pending size change, or have additional
12029 visible frames, redisplay again. */
12030 if (windows_or_buffers_changed && !pause)
12031 goto retry;
12032
12033 /* Clear the face cache eventually. */
12034 if (consider_all_windows_p)
12035 {
12036 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12037 {
12038 clear_face_cache (0);
12039 clear_face_cache_count = 0;
12040 }
12041 #ifdef HAVE_WINDOW_SYSTEM
12042 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12043 {
12044 clear_image_caches (Qnil);
12045 clear_image_cache_count = 0;
12046 }
12047 #endif /* HAVE_WINDOW_SYSTEM */
12048 }
12049
12050 end_of_redisplay:
12051 unbind_to (count, Qnil);
12052 RESUME_POLLING;
12053 }
12054
12055
12056 /* Redisplay, but leave alone any recent echo area message unless
12057 another message has been requested in its place.
12058
12059 This is useful in situations where you need to redisplay but no
12060 user action has occurred, making it inappropriate for the message
12061 area to be cleared. See tracking_off and
12062 wait_reading_process_output for examples of these situations.
12063
12064 FROM_WHERE is an integer saying from where this function was
12065 called. This is useful for debugging. */
12066
12067 void
12068 redisplay_preserve_echo_area (from_where)
12069 int from_where;
12070 {
12071 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12072
12073 if (!NILP (echo_area_buffer[1]))
12074 {
12075 /* We have a previously displayed message, but no current
12076 message. Redisplay the previous message. */
12077 display_last_displayed_message_p = 1;
12078 redisplay_internal (1);
12079 display_last_displayed_message_p = 0;
12080 }
12081 else
12082 redisplay_internal (1);
12083
12084 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12085 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12086 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12087 }
12088
12089
12090 /* Function registered with record_unwind_protect in
12091 redisplay_internal. Reset redisplaying_p to the value it had
12092 before redisplay_internal was called, and clear
12093 prevent_freeing_realized_faces_p. It also selects the previously
12094 selected frame, unless it has been deleted (by an X connection
12095 failure during redisplay, for example). */
12096
12097 static Lisp_Object
12098 unwind_redisplay (val)
12099 Lisp_Object val;
12100 {
12101 Lisp_Object old_redisplaying_p, old_frame;
12102
12103 old_redisplaying_p = XCAR (val);
12104 redisplaying_p = XFASTINT (old_redisplaying_p);
12105 old_frame = XCDR (val);
12106 if (! EQ (old_frame, selected_frame)
12107 && FRAME_LIVE_P (XFRAME (old_frame)))
12108 select_frame_for_redisplay (old_frame);
12109 return Qnil;
12110 }
12111
12112
12113 /* Mark the display of window W as accurate or inaccurate. If
12114 ACCURATE_P is non-zero mark display of W as accurate. If
12115 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12116 redisplay_internal is called. */
12117
12118 static void
12119 mark_window_display_accurate_1 (w, accurate_p)
12120 struct window *w;
12121 int accurate_p;
12122 {
12123 if (BUFFERP (w->buffer))
12124 {
12125 struct buffer *b = XBUFFER (w->buffer);
12126
12127 w->last_modified
12128 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12129 w->last_overlay_modified
12130 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12131 w->last_had_star
12132 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12133
12134 if (accurate_p)
12135 {
12136 b->clip_changed = 0;
12137 b->prevent_redisplay_optimizations_p = 0;
12138
12139 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12140 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12141 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12142 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12143
12144 w->current_matrix->buffer = b;
12145 w->current_matrix->begv = BUF_BEGV (b);
12146 w->current_matrix->zv = BUF_ZV (b);
12147
12148 w->last_cursor = w->cursor;
12149 w->last_cursor_off_p = w->cursor_off_p;
12150
12151 if (w == XWINDOW (selected_window))
12152 w->last_point = make_number (BUF_PT (b));
12153 else
12154 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12155 }
12156 }
12157
12158 if (accurate_p)
12159 {
12160 w->window_end_valid = w->buffer;
12161 w->update_mode_line = Qnil;
12162 }
12163 }
12164
12165
12166 /* Mark the display of windows in the window tree rooted at WINDOW as
12167 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12168 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12169 be redisplayed the next time redisplay_internal is called. */
12170
12171 void
12172 mark_window_display_accurate (window, accurate_p)
12173 Lisp_Object window;
12174 int accurate_p;
12175 {
12176 struct window *w;
12177
12178 for (; !NILP (window); window = w->next)
12179 {
12180 w = XWINDOW (window);
12181 mark_window_display_accurate_1 (w, accurate_p);
12182
12183 if (!NILP (w->vchild))
12184 mark_window_display_accurate (w->vchild, accurate_p);
12185 if (!NILP (w->hchild))
12186 mark_window_display_accurate (w->hchild, accurate_p);
12187 }
12188
12189 if (accurate_p)
12190 {
12191 update_overlay_arrows (1);
12192 }
12193 else
12194 {
12195 /* Force a thorough redisplay the next time by setting
12196 last_arrow_position and last_arrow_string to t, which is
12197 unequal to any useful value of Voverlay_arrow_... */
12198 update_overlay_arrows (-1);
12199 }
12200 }
12201
12202
12203 /* Return value in display table DP (Lisp_Char_Table *) for character
12204 C. Since a display table doesn't have any parent, we don't have to
12205 follow parent. Do not call this function directly but use the
12206 macro DISP_CHAR_VECTOR. */
12207
12208 Lisp_Object
12209 disp_char_vector (dp, c)
12210 struct Lisp_Char_Table *dp;
12211 int c;
12212 {
12213 Lisp_Object val;
12214
12215 if (ASCII_CHAR_P (c))
12216 {
12217 val = dp->ascii;
12218 if (SUB_CHAR_TABLE_P (val))
12219 val = XSUB_CHAR_TABLE (val)->contents[c];
12220 }
12221 else
12222 {
12223 Lisp_Object table;
12224
12225 XSETCHAR_TABLE (table, dp);
12226 val = char_table_ref (table, c);
12227 }
12228 if (NILP (val))
12229 val = dp->defalt;
12230 return val;
12231 }
12232
12233
12234 \f
12235 /***********************************************************************
12236 Window Redisplay
12237 ***********************************************************************/
12238
12239 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12240
12241 static void
12242 redisplay_windows (window)
12243 Lisp_Object window;
12244 {
12245 while (!NILP (window))
12246 {
12247 struct window *w = XWINDOW (window);
12248
12249 if (!NILP (w->hchild))
12250 redisplay_windows (w->hchild);
12251 else if (!NILP (w->vchild))
12252 redisplay_windows (w->vchild);
12253 else if (!NILP (w->buffer))
12254 {
12255 displayed_buffer = XBUFFER (w->buffer);
12256 /* Use list_of_error, not Qerror, so that
12257 we catch only errors and don't run the debugger. */
12258 internal_condition_case_1 (redisplay_window_0, window,
12259 list_of_error,
12260 redisplay_window_error);
12261 }
12262
12263 window = w->next;
12264 }
12265 }
12266
12267 static Lisp_Object
12268 redisplay_window_error ()
12269 {
12270 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12271 return Qnil;
12272 }
12273
12274 static Lisp_Object
12275 redisplay_window_0 (window)
12276 Lisp_Object window;
12277 {
12278 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12279 redisplay_window (window, 0);
12280 return Qnil;
12281 }
12282
12283 static Lisp_Object
12284 redisplay_window_1 (window)
12285 Lisp_Object window;
12286 {
12287 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12288 redisplay_window (window, 1);
12289 return Qnil;
12290 }
12291 \f
12292
12293 /* Increment GLYPH until it reaches END or CONDITION fails while
12294 adding (GLYPH)->pixel_width to X. */
12295
12296 #define SKIP_GLYPHS(glyph, end, x, condition) \
12297 do \
12298 { \
12299 (x) += (glyph)->pixel_width; \
12300 ++(glyph); \
12301 } \
12302 while ((glyph) < (end) && (condition))
12303
12304
12305 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12306 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12307 which positions recorded in ROW differ from current buffer
12308 positions.
12309
12310 Return 0 if cursor is not on this row, 1 otherwise. */
12311
12312 int
12313 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12314 struct window *w;
12315 struct glyph_row *row;
12316 struct glyph_matrix *matrix;
12317 int delta, delta_bytes, dy, dvpos;
12318 {
12319 struct glyph *glyph = row->glyphs[TEXT_AREA];
12320 struct glyph *end = glyph + row->used[TEXT_AREA];
12321 struct glyph *cursor = NULL;
12322 /* The first glyph that starts a sequence of glyphs from a string
12323 that is a value of a display property. */
12324 struct glyph *string_start;
12325 /* The X coordinate of string_start. */
12326 int string_start_x;
12327 /* The last known character position in row. */
12328 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12329 /* The last known character position before string_start. */
12330 int string_before_pos;
12331 int x = row->x;
12332 int cursor_x = x;
12333 /* Last buffer position covered by an overlay. */
12334 int cursor_from_overlay_pos = 0;
12335 int pt_old = PT - delta;
12336
12337 /* Skip over glyphs not having an object at the start of the row.
12338 These are special glyphs like truncation marks on terminal
12339 frames. */
12340 if (row->displays_text_p)
12341 while (glyph < end
12342 && INTEGERP (glyph->object)
12343 && glyph->charpos < 0)
12344 {
12345 x += glyph->pixel_width;
12346 ++glyph;
12347 }
12348
12349 string_start = NULL;
12350 while (glyph < end
12351 && !INTEGERP (glyph->object)
12352 && (!BUFFERP (glyph->object)
12353 || (last_pos = glyph->charpos) < pt_old
12354 || glyph->avoid_cursor_p))
12355 {
12356 if (! STRINGP (glyph->object))
12357 {
12358 string_start = NULL;
12359 x += glyph->pixel_width;
12360 ++glyph;
12361 /* If we are beyond the cursor position computed from the
12362 last overlay seen, that overlay is not in effect for
12363 current cursor position. Reset the cursor information
12364 computed from that overlay. */
12365 if (cursor_from_overlay_pos
12366 && last_pos >= cursor_from_overlay_pos)
12367 {
12368 cursor_from_overlay_pos = 0;
12369 cursor = NULL;
12370 }
12371 }
12372 else
12373 {
12374 if (string_start == NULL)
12375 {
12376 string_before_pos = last_pos;
12377 string_start = glyph;
12378 string_start_x = x;
12379 }
12380 /* Skip all glyphs from a string. */
12381 do
12382 {
12383 Lisp_Object cprop;
12384 int pos;
12385 if ((cursor == NULL || glyph > cursor)
12386 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
12387 Qcursor, (glyph)->object),
12388 !NILP (cprop))
12389 && (pos = string_buffer_position (w, glyph->object,
12390 string_before_pos),
12391 (pos == 0 /* from overlay */
12392 || pos == pt_old)))
12393 {
12394 /* Compute the first buffer position after the overlay.
12395 If the `cursor' property tells us how many positions
12396 are associated with the overlay, use that. Otherwise,
12397 estimate from the buffer positions of the glyphs
12398 before and after the overlay. */
12399 cursor_from_overlay_pos = (pos ? 0 : last_pos
12400 + (INTEGERP (cprop) ? XINT (cprop) : 0));
12401 cursor = glyph;
12402 cursor_x = x;
12403 }
12404 x += glyph->pixel_width;
12405 ++glyph;
12406 }
12407 while (glyph < end && EQ (glyph->object, string_start->object));
12408 }
12409 }
12410
12411 if (cursor != NULL)
12412 {
12413 glyph = cursor;
12414 x = cursor_x;
12415 }
12416 else if (row->ends_in_ellipsis_p && glyph == end)
12417 {
12418 /* Scan back over the ellipsis glyphs, decrementing positions. */
12419 while (glyph > row->glyphs[TEXT_AREA]
12420 && (glyph - 1)->charpos == last_pos)
12421 glyph--, x -= glyph->pixel_width;
12422 /* That loop always goes one position too far, including the
12423 glyph before the ellipsis. So scan forward over that one. */
12424 x += glyph->pixel_width;
12425 glyph++;
12426 }
12427 else if (string_start
12428 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12429 {
12430 /* We may have skipped over point because the previous glyphs
12431 are from string. As there's no easy way to know the
12432 character position of the current glyph, find the correct
12433 glyph on point by scanning from string_start again. */
12434 Lisp_Object limit;
12435 Lisp_Object string;
12436 struct glyph *stop = glyph;
12437 int pos;
12438
12439 limit = make_number (pt_old + 1);
12440 glyph = string_start;
12441 x = string_start_x;
12442 string = glyph->object;
12443 pos = string_buffer_position (w, string, string_before_pos);
12444 /* If POS == 0, STRING is from overlay. We skip such glyphs
12445 because we always put the cursor after overlay strings. */
12446 while (pos == 0 && glyph < stop)
12447 {
12448 string = glyph->object;
12449 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12450 if (glyph < stop)
12451 pos = string_buffer_position (w, glyph->object, string_before_pos);
12452 }
12453
12454 while (glyph < stop)
12455 {
12456 pos = XINT (Fnext_single_char_property_change
12457 (make_number (pos), Qdisplay, Qnil, limit));
12458 if (pos > pt_old)
12459 break;
12460 /* Skip glyphs from the same string. */
12461 string = glyph->object;
12462 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12463 /* Skip glyphs from an overlay. */
12464 while (glyph < stop
12465 && ! string_buffer_position (w, glyph->object, pos))
12466 {
12467 string = glyph->object;
12468 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12469 }
12470 }
12471
12472 /* If we reached the end of the line, and END was from a string,
12473 the cursor is not on this line. */
12474 if (glyph == end && row->continued_p)
12475 return 0;
12476 }
12477
12478 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12479 w->cursor.x = x;
12480 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12481 w->cursor.y = row->y + dy;
12482
12483 if (w == XWINDOW (selected_window))
12484 {
12485 if (!row->continued_p
12486 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12487 && row->x == 0)
12488 {
12489 this_line_buffer = XBUFFER (w->buffer);
12490
12491 CHARPOS (this_line_start_pos)
12492 = MATRIX_ROW_START_CHARPOS (row) + delta;
12493 BYTEPOS (this_line_start_pos)
12494 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12495
12496 CHARPOS (this_line_end_pos)
12497 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12498 BYTEPOS (this_line_end_pos)
12499 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12500
12501 this_line_y = w->cursor.y;
12502 this_line_pixel_height = row->height;
12503 this_line_vpos = w->cursor.vpos;
12504 this_line_start_x = row->x;
12505 }
12506 else
12507 CHARPOS (this_line_start_pos) = 0;
12508 }
12509
12510 return 1;
12511 }
12512
12513
12514 /* Run window scroll functions, if any, for WINDOW with new window
12515 start STARTP. Sets the window start of WINDOW to that position.
12516
12517 We assume that the window's buffer is really current. */
12518
12519 static INLINE struct text_pos
12520 run_window_scroll_functions (window, startp)
12521 Lisp_Object window;
12522 struct text_pos startp;
12523 {
12524 struct window *w = XWINDOW (window);
12525 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12526
12527 if (current_buffer != XBUFFER (w->buffer))
12528 abort ();
12529
12530 if (!NILP (Vwindow_scroll_functions))
12531 {
12532 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12533 make_number (CHARPOS (startp)));
12534 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12535 /* In case the hook functions switch buffers. */
12536 if (current_buffer != XBUFFER (w->buffer))
12537 set_buffer_internal_1 (XBUFFER (w->buffer));
12538 }
12539
12540 return startp;
12541 }
12542
12543
12544 /* Make sure the line containing the cursor is fully visible.
12545 A value of 1 means there is nothing to be done.
12546 (Either the line is fully visible, or it cannot be made so,
12547 or we cannot tell.)
12548
12549 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12550 is higher than window.
12551
12552 A value of 0 means the caller should do scrolling
12553 as if point had gone off the screen. */
12554
12555 static int
12556 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12557 struct window *w;
12558 int force_p;
12559 int current_matrix_p;
12560 {
12561 struct glyph_matrix *matrix;
12562 struct glyph_row *row;
12563 int window_height;
12564
12565 if (!make_cursor_line_fully_visible_p)
12566 return 1;
12567
12568 /* It's not always possible to find the cursor, e.g, when a window
12569 is full of overlay strings. Don't do anything in that case. */
12570 if (w->cursor.vpos < 0)
12571 return 1;
12572
12573 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12574 row = MATRIX_ROW (matrix, w->cursor.vpos);
12575
12576 /* If the cursor row is not partially visible, there's nothing to do. */
12577 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12578 return 1;
12579
12580 /* If the row the cursor is in is taller than the window's height,
12581 it's not clear what to do, so do nothing. */
12582 window_height = window_box_height (w);
12583 if (row->height >= window_height)
12584 {
12585 if (!force_p || MINI_WINDOW_P (w)
12586 || w->vscroll || w->cursor.vpos == 0)
12587 return 1;
12588 }
12589 return 0;
12590 }
12591
12592
12593 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12594 non-zero means only WINDOW is redisplayed in redisplay_internal.
12595 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12596 in redisplay_window to bring a partially visible line into view in
12597 the case that only the cursor has moved.
12598
12599 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12600 last screen line's vertical height extends past the end of the screen.
12601
12602 Value is
12603
12604 1 if scrolling succeeded
12605
12606 0 if scrolling didn't find point.
12607
12608 -1 if new fonts have been loaded so that we must interrupt
12609 redisplay, adjust glyph matrices, and try again. */
12610
12611 enum
12612 {
12613 SCROLLING_SUCCESS,
12614 SCROLLING_FAILED,
12615 SCROLLING_NEED_LARGER_MATRICES
12616 };
12617
12618 static int
12619 try_scrolling (window, just_this_one_p, scroll_conservatively,
12620 scroll_step, temp_scroll_step, last_line_misfit)
12621 Lisp_Object window;
12622 int just_this_one_p;
12623 EMACS_INT scroll_conservatively, scroll_step;
12624 int temp_scroll_step;
12625 int last_line_misfit;
12626 {
12627 struct window *w = XWINDOW (window);
12628 struct frame *f = XFRAME (w->frame);
12629 struct text_pos pos, startp;
12630 struct it it;
12631 int this_scroll_margin, scroll_max, rc, height;
12632 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
12633 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12634 Lisp_Object aggressive;
12635 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
12636
12637 #if GLYPH_DEBUG
12638 debug_method_add (w, "try_scrolling");
12639 #endif
12640
12641 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12642
12643 /* Compute scroll margin height in pixels. We scroll when point is
12644 within this distance from the top or bottom of the window. */
12645 if (scroll_margin > 0)
12646 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
12647 * FRAME_LINE_HEIGHT (f);
12648 else
12649 this_scroll_margin = 0;
12650
12651 /* Force scroll_conservatively to have a reasonable value, to avoid
12652 overflow while computing how much to scroll. Note that the user
12653 can supply scroll-conservatively equal to `most-positive-fixnum',
12654 which can be larger than INT_MAX. */
12655 if (scroll_conservatively > scroll_limit)
12656 {
12657 scroll_conservatively = scroll_limit;
12658 scroll_max = INT_MAX;
12659 }
12660 else if (scroll_step || scroll_conservatively || temp_scroll_step)
12661 /* Compute how much we should try to scroll maximally to bring
12662 point into view. */
12663 scroll_max = (max (scroll_step,
12664 max (scroll_conservatively, temp_scroll_step))
12665 * FRAME_LINE_HEIGHT (f));
12666 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12667 || NUMBERP (current_buffer->scroll_up_aggressively))
12668 /* We're trying to scroll because of aggressive scrolling but no
12669 scroll_step is set. Choose an arbitrary one. */
12670 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
12671 else
12672 scroll_max = 0;
12673
12674 too_near_end:
12675
12676 /* Decide whether to scroll down. */
12677 if (PT > CHARPOS (startp))
12678 {
12679 int scroll_margin_y;
12680
12681 /* Compute the pixel ypos of the scroll margin, then move it to
12682 either that ypos or PT, whichever comes first. */
12683 start_display (&it, w, startp);
12684 scroll_margin_y = it.last_visible_y - this_scroll_margin
12685 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
12686 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
12687 (MOVE_TO_POS | MOVE_TO_Y));
12688
12689 if (PT > CHARPOS (it.current.pos))
12690 {
12691 int y0 = line_bottom_y (&it);
12692
12693 /* Compute the distance from the scroll margin to PT
12694 (including the height of the cursor line). Moving the
12695 iterator unconditionally to PT can be slow if PT is far
12696 away, so stop 10 lines past the window bottom (is there a
12697 way to do the right thing quickly?). */
12698 move_it_to (&it, PT, -1,
12699 it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
12700 -1, MOVE_TO_POS | MOVE_TO_Y);
12701 dy = line_bottom_y (&it) - y0;
12702
12703 if (dy > scroll_max)
12704 return SCROLLING_FAILED;
12705
12706 scroll_down_p = 1;
12707 }
12708 }
12709
12710 if (scroll_down_p)
12711 {
12712 /* Point is in or below the bottom scroll margin, so move the
12713 window start down. If scrolling conservatively, move it just
12714 enough down to make point visible. If scroll_step is set,
12715 move it down by scroll_step. */
12716 if (scroll_conservatively)
12717 amount_to_scroll
12718 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12719 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12720 else if (scroll_step || temp_scroll_step)
12721 amount_to_scroll = scroll_max;
12722 else
12723 {
12724 aggressive = current_buffer->scroll_up_aggressively;
12725 height = WINDOW_BOX_TEXT_HEIGHT (w);
12726 if (NUMBERP (aggressive))
12727 {
12728 double float_amount = XFLOATINT (aggressive) * height;
12729 amount_to_scroll = float_amount;
12730 if (amount_to_scroll == 0 && float_amount > 0)
12731 amount_to_scroll = 1;
12732 }
12733 }
12734
12735 if (amount_to_scroll <= 0)
12736 return SCROLLING_FAILED;
12737
12738 start_display (&it, w, startp);
12739 move_it_vertically (&it, amount_to_scroll);
12740
12741 /* If STARTP is unchanged, move it down another screen line. */
12742 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12743 move_it_by_lines (&it, 1, 1);
12744 startp = it.current.pos;
12745 }
12746 else
12747 {
12748 struct text_pos scroll_margin_pos = startp;
12749
12750 /* See if point is inside the scroll margin at the top of the
12751 window. */
12752 if (this_scroll_margin)
12753 {
12754 start_display (&it, w, startp);
12755 move_it_vertically (&it, this_scroll_margin);
12756 scroll_margin_pos = it.current.pos;
12757 }
12758
12759 if (PT < CHARPOS (scroll_margin_pos))
12760 {
12761 /* Point is in the scroll margin at the top of the window or
12762 above what is displayed in the window. */
12763 int y0;
12764
12765 /* Compute the vertical distance from PT to the scroll
12766 margin position. Give up if distance is greater than
12767 scroll_max. */
12768 SET_TEXT_POS (pos, PT, PT_BYTE);
12769 start_display (&it, w, pos);
12770 y0 = it.current_y;
12771 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12772 it.last_visible_y, -1,
12773 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12774 dy = it.current_y - y0;
12775 if (dy > scroll_max)
12776 return SCROLLING_FAILED;
12777
12778 /* Compute new window start. */
12779 start_display (&it, w, startp);
12780
12781 if (scroll_conservatively)
12782 amount_to_scroll
12783 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12784 else if (scroll_step || temp_scroll_step)
12785 amount_to_scroll = scroll_max;
12786 else
12787 {
12788 aggressive = current_buffer->scroll_down_aggressively;
12789 height = WINDOW_BOX_TEXT_HEIGHT (w);
12790 if (NUMBERP (aggressive))
12791 {
12792 double float_amount = XFLOATINT (aggressive) * height;
12793 amount_to_scroll = float_amount;
12794 if (amount_to_scroll == 0 && float_amount > 0)
12795 amount_to_scroll = 1;
12796 }
12797 }
12798
12799 if (amount_to_scroll <= 0)
12800 return SCROLLING_FAILED;
12801
12802 move_it_vertically_backward (&it, amount_to_scroll);
12803 startp = it.current.pos;
12804 }
12805 }
12806
12807 /* Run window scroll functions. */
12808 startp = run_window_scroll_functions (window, startp);
12809
12810 /* Display the window. Give up if new fonts are loaded, or if point
12811 doesn't appear. */
12812 if (!try_window (window, startp, 0))
12813 rc = SCROLLING_NEED_LARGER_MATRICES;
12814 else if (w->cursor.vpos < 0)
12815 {
12816 clear_glyph_matrix (w->desired_matrix);
12817 rc = SCROLLING_FAILED;
12818 }
12819 else
12820 {
12821 /* Maybe forget recorded base line for line number display. */
12822 if (!just_this_one_p
12823 || current_buffer->clip_changed
12824 || BEG_UNCHANGED < CHARPOS (startp))
12825 w->base_line_number = Qnil;
12826
12827 /* If cursor ends up on a partially visible line,
12828 treat that as being off the bottom of the screen. */
12829 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12830 {
12831 clear_glyph_matrix (w->desired_matrix);
12832 ++extra_scroll_margin_lines;
12833 goto too_near_end;
12834 }
12835 rc = SCROLLING_SUCCESS;
12836 }
12837
12838 return rc;
12839 }
12840
12841
12842 /* Compute a suitable window start for window W if display of W starts
12843 on a continuation line. Value is non-zero if a new window start
12844 was computed.
12845
12846 The new window start will be computed, based on W's width, starting
12847 from the start of the continued line. It is the start of the
12848 screen line with the minimum distance from the old start W->start. */
12849
12850 static int
12851 compute_window_start_on_continuation_line (w)
12852 struct window *w;
12853 {
12854 struct text_pos pos, start_pos;
12855 int window_start_changed_p = 0;
12856
12857 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12858
12859 /* If window start is on a continuation line... Window start may be
12860 < BEGV in case there's invisible text at the start of the
12861 buffer (M-x rmail, for example). */
12862 if (CHARPOS (start_pos) > BEGV
12863 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12864 {
12865 struct it it;
12866 struct glyph_row *row;
12867
12868 /* Handle the case that the window start is out of range. */
12869 if (CHARPOS (start_pos) < BEGV)
12870 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12871 else if (CHARPOS (start_pos) > ZV)
12872 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12873
12874 /* Find the start of the continued line. This should be fast
12875 because scan_buffer is fast (newline cache). */
12876 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12877 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12878 row, DEFAULT_FACE_ID);
12879 reseat_at_previous_visible_line_start (&it);
12880
12881 /* If the line start is "too far" away from the window start,
12882 say it takes too much time to compute a new window start. */
12883 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12884 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12885 {
12886 int min_distance, distance;
12887
12888 /* Move forward by display lines to find the new window
12889 start. If window width was enlarged, the new start can
12890 be expected to be > the old start. If window width was
12891 decreased, the new window start will be < the old start.
12892 So, we're looking for the display line start with the
12893 minimum distance from the old window start. */
12894 pos = it.current.pos;
12895 min_distance = INFINITY;
12896 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12897 distance < min_distance)
12898 {
12899 min_distance = distance;
12900 pos = it.current.pos;
12901 move_it_by_lines (&it, 1, 0);
12902 }
12903
12904 /* Set the window start there. */
12905 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12906 window_start_changed_p = 1;
12907 }
12908 }
12909
12910 return window_start_changed_p;
12911 }
12912
12913
12914 /* Try cursor movement in case text has not changed in window WINDOW,
12915 with window start STARTP. Value is
12916
12917 CURSOR_MOVEMENT_SUCCESS if successful
12918
12919 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12920
12921 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12922 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12923 we want to scroll as if scroll-step were set to 1. See the code.
12924
12925 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12926 which case we have to abort this redisplay, and adjust matrices
12927 first. */
12928
12929 enum
12930 {
12931 CURSOR_MOVEMENT_SUCCESS,
12932 CURSOR_MOVEMENT_CANNOT_BE_USED,
12933 CURSOR_MOVEMENT_MUST_SCROLL,
12934 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12935 };
12936
12937 static int
12938 try_cursor_movement (window, startp, scroll_step)
12939 Lisp_Object window;
12940 struct text_pos startp;
12941 int *scroll_step;
12942 {
12943 struct window *w = XWINDOW (window);
12944 struct frame *f = XFRAME (w->frame);
12945 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12946
12947 #if GLYPH_DEBUG
12948 if (inhibit_try_cursor_movement)
12949 return rc;
12950 #endif
12951
12952 /* Handle case where text has not changed, only point, and it has
12953 not moved off the frame. */
12954 if (/* Point may be in this window. */
12955 PT >= CHARPOS (startp)
12956 /* Selective display hasn't changed. */
12957 && !current_buffer->clip_changed
12958 /* Function force-mode-line-update is used to force a thorough
12959 redisplay. It sets either windows_or_buffers_changed or
12960 update_mode_lines. So don't take a shortcut here for these
12961 cases. */
12962 && !update_mode_lines
12963 && !windows_or_buffers_changed
12964 && !cursor_type_changed
12965 /* Can't use this case if highlighting a region. When a
12966 region exists, cursor movement has to do more than just
12967 set the cursor. */
12968 && !(!NILP (Vtransient_mark_mode)
12969 && !NILP (current_buffer->mark_active))
12970 && NILP (w->region_showing)
12971 && NILP (Vshow_trailing_whitespace)
12972 /* Right after splitting windows, last_point may be nil. */
12973 && INTEGERP (w->last_point)
12974 /* This code is not used for mini-buffer for the sake of the case
12975 of redisplaying to replace an echo area message; since in
12976 that case the mini-buffer contents per se are usually
12977 unchanged. This code is of no real use in the mini-buffer
12978 since the handling of this_line_start_pos, etc., in redisplay
12979 handles the same cases. */
12980 && !EQ (window, minibuf_window)
12981 /* When splitting windows or for new windows, it happens that
12982 redisplay is called with a nil window_end_vpos or one being
12983 larger than the window. This should really be fixed in
12984 window.c. I don't have this on my list, now, so we do
12985 approximately the same as the old redisplay code. --gerd. */
12986 && INTEGERP (w->window_end_vpos)
12987 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12988 && (FRAME_WINDOW_P (f)
12989 || !overlay_arrow_in_current_buffer_p ()))
12990 {
12991 int this_scroll_margin, top_scroll_margin;
12992 struct glyph_row *row = NULL;
12993
12994 #if GLYPH_DEBUG
12995 debug_method_add (w, "cursor movement");
12996 #endif
12997
12998 /* Scroll if point within this distance from the top or bottom
12999 of the window. This is a pixel value. */
13000 if (scroll_margin > 0)
13001 {
13002 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13003 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13004 }
13005 else
13006 this_scroll_margin = 0;
13007
13008 top_scroll_margin = this_scroll_margin;
13009 if (WINDOW_WANTS_HEADER_LINE_P (w))
13010 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13011
13012 /* Start with the row the cursor was displayed during the last
13013 not paused redisplay. Give up if that row is not valid. */
13014 if (w->last_cursor.vpos < 0
13015 || w->last_cursor.vpos >= w->current_matrix->nrows)
13016 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13017 else
13018 {
13019 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13020 if (row->mode_line_p)
13021 ++row;
13022 if (!row->enabled_p)
13023 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13024 }
13025
13026 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13027 {
13028 int scroll_p = 0;
13029 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13030
13031 if (PT > XFASTINT (w->last_point))
13032 {
13033 /* Point has moved forward. */
13034 while (MATRIX_ROW_END_CHARPOS (row) < PT
13035 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13036 {
13037 xassert (row->enabled_p);
13038 ++row;
13039 }
13040
13041 /* The end position of a row equals the start position
13042 of the next row. If PT is there, we would rather
13043 display it in the next line. */
13044 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13045 && MATRIX_ROW_END_CHARPOS (row) == PT
13046 && !cursor_row_p (w, row))
13047 ++row;
13048
13049 /* If within the scroll margin, scroll. Note that
13050 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13051 the next line would be drawn, and that
13052 this_scroll_margin can be zero. */
13053 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13054 || PT > MATRIX_ROW_END_CHARPOS (row)
13055 /* Line is completely visible last line in window
13056 and PT is to be set in the next line. */
13057 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13058 && PT == MATRIX_ROW_END_CHARPOS (row)
13059 && !row->ends_at_zv_p
13060 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13061 scroll_p = 1;
13062 }
13063 else if (PT < XFASTINT (w->last_point))
13064 {
13065 /* Cursor has to be moved backward. Note that PT >=
13066 CHARPOS (startp) because of the outer if-statement. */
13067 while (!row->mode_line_p
13068 && (MATRIX_ROW_START_CHARPOS (row) > PT
13069 || (MATRIX_ROW_START_CHARPOS (row) == PT
13070 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13071 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13072 row > w->current_matrix->rows
13073 && (row-1)->ends_in_newline_from_string_p))))
13074 && (row->y > top_scroll_margin
13075 || CHARPOS (startp) == BEGV))
13076 {
13077 xassert (row->enabled_p);
13078 --row;
13079 }
13080
13081 /* Consider the following case: Window starts at BEGV,
13082 there is invisible, intangible text at BEGV, so that
13083 display starts at some point START > BEGV. It can
13084 happen that we are called with PT somewhere between
13085 BEGV and START. Try to handle that case. */
13086 if (row < w->current_matrix->rows
13087 || row->mode_line_p)
13088 {
13089 row = w->current_matrix->rows;
13090 if (row->mode_line_p)
13091 ++row;
13092 }
13093
13094 /* Due to newlines in overlay strings, we may have to
13095 skip forward over overlay strings. */
13096 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13097 && MATRIX_ROW_END_CHARPOS (row) == PT
13098 && !cursor_row_p (w, row))
13099 ++row;
13100
13101 /* If within the scroll margin, scroll. */
13102 if (row->y < top_scroll_margin
13103 && CHARPOS (startp) != BEGV)
13104 scroll_p = 1;
13105 }
13106 else
13107 {
13108 /* Cursor did not move. So don't scroll even if cursor line
13109 is partially visible, as it was so before. */
13110 rc = CURSOR_MOVEMENT_SUCCESS;
13111 }
13112
13113 if (PT < MATRIX_ROW_START_CHARPOS (row)
13114 || PT > MATRIX_ROW_END_CHARPOS (row))
13115 {
13116 /* if PT is not in the glyph row, give up. */
13117 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13118 }
13119 else if (rc != CURSOR_MOVEMENT_SUCCESS
13120 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13121 && make_cursor_line_fully_visible_p)
13122 {
13123 if (PT == MATRIX_ROW_END_CHARPOS (row)
13124 && !row->ends_at_zv_p
13125 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13126 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13127 else if (row->height > window_box_height (w))
13128 {
13129 /* If we end up in a partially visible line, let's
13130 make it fully visible, except when it's taller
13131 than the window, in which case we can't do much
13132 about it. */
13133 *scroll_step = 1;
13134 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13135 }
13136 else
13137 {
13138 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13139 if (!cursor_row_fully_visible_p (w, 0, 1))
13140 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13141 else
13142 rc = CURSOR_MOVEMENT_SUCCESS;
13143 }
13144 }
13145 else if (scroll_p)
13146 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13147 else
13148 {
13149 do
13150 {
13151 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13152 {
13153 rc = CURSOR_MOVEMENT_SUCCESS;
13154 break;
13155 }
13156 ++row;
13157 }
13158 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13159 && MATRIX_ROW_START_CHARPOS (row) == PT
13160 && cursor_row_p (w, row));
13161 }
13162 }
13163 }
13164
13165 return rc;
13166 }
13167
13168 void
13169 set_vertical_scroll_bar (w)
13170 struct window *w;
13171 {
13172 int start, end, whole;
13173
13174 /* Calculate the start and end positions for the current window.
13175 At some point, it would be nice to choose between scrollbars
13176 which reflect the whole buffer size, with special markers
13177 indicating narrowing, and scrollbars which reflect only the
13178 visible region.
13179
13180 Note that mini-buffers sometimes aren't displaying any text. */
13181 if (!MINI_WINDOW_P (w)
13182 || (w == XWINDOW (minibuf_window)
13183 && NILP (echo_area_buffer[0])))
13184 {
13185 struct buffer *buf = XBUFFER (w->buffer);
13186 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13187 start = marker_position (w->start) - BUF_BEGV (buf);
13188 /* I don't think this is guaranteed to be right. For the
13189 moment, we'll pretend it is. */
13190 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13191
13192 if (end < start)
13193 end = start;
13194 if (whole < (end - start))
13195 whole = end - start;
13196 }
13197 else
13198 start = end = whole = 0;
13199
13200 /* Indicate what this scroll bar ought to be displaying now. */
13201 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13202 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13203 (w, end - start, whole, start);
13204 }
13205
13206
13207 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13208 selected_window is redisplayed.
13209
13210 We can return without actually redisplaying the window if
13211 fonts_changed_p is nonzero. In that case, redisplay_internal will
13212 retry. */
13213
13214 static void
13215 redisplay_window (window, just_this_one_p)
13216 Lisp_Object window;
13217 int just_this_one_p;
13218 {
13219 struct window *w = XWINDOW (window);
13220 struct frame *f = XFRAME (w->frame);
13221 struct buffer *buffer = XBUFFER (w->buffer);
13222 struct buffer *old = current_buffer;
13223 struct text_pos lpoint, opoint, startp;
13224 int update_mode_line;
13225 int tem;
13226 struct it it;
13227 /* Record it now because it's overwritten. */
13228 int current_matrix_up_to_date_p = 0;
13229 int used_current_matrix_p = 0;
13230 /* This is less strict than current_matrix_up_to_date_p.
13231 It indictes that the buffer contents and narrowing are unchanged. */
13232 int buffer_unchanged_p = 0;
13233 int temp_scroll_step = 0;
13234 int count = SPECPDL_INDEX ();
13235 int rc;
13236 int centering_position = -1;
13237 int last_line_misfit = 0;
13238 int beg_unchanged, end_unchanged;
13239
13240 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13241 opoint = lpoint;
13242
13243 /* W must be a leaf window here. */
13244 xassert (!NILP (w->buffer));
13245 #if GLYPH_DEBUG
13246 *w->desired_matrix->method = 0;
13247 #endif
13248
13249 restart:
13250 reconsider_clip_changes (w, buffer);
13251
13252 /* Has the mode line to be updated? */
13253 update_mode_line = (!NILP (w->update_mode_line)
13254 || update_mode_lines
13255 || buffer->clip_changed
13256 || buffer->prevent_redisplay_optimizations_p);
13257
13258 if (MINI_WINDOW_P (w))
13259 {
13260 if (w == XWINDOW (echo_area_window)
13261 && !NILP (echo_area_buffer[0]))
13262 {
13263 if (update_mode_line)
13264 /* We may have to update a tty frame's menu bar or a
13265 tool-bar. Example `M-x C-h C-h C-g'. */
13266 goto finish_menu_bars;
13267 else
13268 /* We've already displayed the echo area glyphs in this window. */
13269 goto finish_scroll_bars;
13270 }
13271 else if ((w != XWINDOW (minibuf_window)
13272 || minibuf_level == 0)
13273 /* When buffer is nonempty, redisplay window normally. */
13274 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13275 /* Quail displays non-mini buffers in minibuffer window.
13276 In that case, redisplay the window normally. */
13277 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13278 {
13279 /* W is a mini-buffer window, but it's not active, so clear
13280 it. */
13281 int yb = window_text_bottom_y (w);
13282 struct glyph_row *row;
13283 int y;
13284
13285 for (y = 0, row = w->desired_matrix->rows;
13286 y < yb;
13287 y += row->height, ++row)
13288 blank_row (w, row, y);
13289 goto finish_scroll_bars;
13290 }
13291
13292 clear_glyph_matrix (w->desired_matrix);
13293 }
13294
13295 /* Otherwise set up data on this window; select its buffer and point
13296 value. */
13297 /* Really select the buffer, for the sake of buffer-local
13298 variables. */
13299 set_buffer_internal_1 (XBUFFER (w->buffer));
13300
13301 current_matrix_up_to_date_p
13302 = (!NILP (w->window_end_valid)
13303 && !current_buffer->clip_changed
13304 && !current_buffer->prevent_redisplay_optimizations_p
13305 && XFASTINT (w->last_modified) >= MODIFF
13306 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13307
13308 /* Run the window-bottom-change-functions
13309 if it is possible that the text on the screen has changed
13310 (either due to modification of the text, or any other reason). */
13311 if (!current_matrix_up_to_date_p
13312 && !NILP (Vwindow_text_change_functions))
13313 {
13314 safe_run_hooks (Qwindow_text_change_functions);
13315 goto restart;
13316 }
13317
13318 beg_unchanged = BEG_UNCHANGED;
13319 end_unchanged = END_UNCHANGED;
13320
13321 SET_TEXT_POS (opoint, PT, PT_BYTE);
13322
13323 specbind (Qinhibit_point_motion_hooks, Qt);
13324
13325 buffer_unchanged_p
13326 = (!NILP (w->window_end_valid)
13327 && !current_buffer->clip_changed
13328 && XFASTINT (w->last_modified) >= MODIFF
13329 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13330
13331 /* When windows_or_buffers_changed is non-zero, we can't rely on
13332 the window end being valid, so set it to nil there. */
13333 if (windows_or_buffers_changed)
13334 {
13335 /* If window starts on a continuation line, maybe adjust the
13336 window start in case the window's width changed. */
13337 if (XMARKER (w->start)->buffer == current_buffer)
13338 compute_window_start_on_continuation_line (w);
13339
13340 w->window_end_valid = Qnil;
13341 }
13342
13343 /* Some sanity checks. */
13344 CHECK_WINDOW_END (w);
13345 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13346 abort ();
13347 if (BYTEPOS (opoint) < CHARPOS (opoint))
13348 abort ();
13349
13350 /* If %c is in mode line, update it if needed. */
13351 if (!NILP (w->column_number_displayed)
13352 /* This alternative quickly identifies a common case
13353 where no change is needed. */
13354 && !(PT == XFASTINT (w->last_point)
13355 && XFASTINT (w->last_modified) >= MODIFF
13356 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13357 && (XFASTINT (w->column_number_displayed)
13358 != (int) current_column ())) /* iftc */
13359 update_mode_line = 1;
13360
13361 /* Count number of windows showing the selected buffer. An indirect
13362 buffer counts as its base buffer. */
13363 if (!just_this_one_p)
13364 {
13365 struct buffer *current_base, *window_base;
13366 current_base = current_buffer;
13367 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13368 if (current_base->base_buffer)
13369 current_base = current_base->base_buffer;
13370 if (window_base->base_buffer)
13371 window_base = window_base->base_buffer;
13372 if (current_base == window_base)
13373 buffer_shared++;
13374 }
13375
13376 /* Point refers normally to the selected window. For any other
13377 window, set up appropriate value. */
13378 if (!EQ (window, selected_window))
13379 {
13380 int new_pt = XMARKER (w->pointm)->charpos;
13381 int new_pt_byte = marker_byte_position (w->pointm);
13382 if (new_pt < BEGV)
13383 {
13384 new_pt = BEGV;
13385 new_pt_byte = BEGV_BYTE;
13386 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13387 }
13388 else if (new_pt > (ZV - 1))
13389 {
13390 new_pt = ZV;
13391 new_pt_byte = ZV_BYTE;
13392 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13393 }
13394
13395 /* We don't use SET_PT so that the point-motion hooks don't run. */
13396 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13397 }
13398
13399 /* If any of the character widths specified in the display table
13400 have changed, invalidate the width run cache. It's true that
13401 this may be a bit late to catch such changes, but the rest of
13402 redisplay goes (non-fatally) haywire when the display table is
13403 changed, so why should we worry about doing any better? */
13404 if (current_buffer->width_run_cache)
13405 {
13406 struct Lisp_Char_Table *disptab = buffer_display_table ();
13407
13408 if (! disptab_matches_widthtab (disptab,
13409 XVECTOR (current_buffer->width_table)))
13410 {
13411 invalidate_region_cache (current_buffer,
13412 current_buffer->width_run_cache,
13413 BEG, Z);
13414 recompute_width_table (current_buffer, disptab);
13415 }
13416 }
13417
13418 /* If window-start is screwed up, choose a new one. */
13419 if (XMARKER (w->start)->buffer != current_buffer)
13420 goto recenter;
13421
13422 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13423
13424 /* If someone specified a new starting point but did not insist,
13425 check whether it can be used. */
13426 if (!NILP (w->optional_new_start)
13427 && CHARPOS (startp) >= BEGV
13428 && CHARPOS (startp) <= ZV)
13429 {
13430 w->optional_new_start = Qnil;
13431 start_display (&it, w, startp);
13432 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13433 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13434 if (IT_CHARPOS (it) == PT)
13435 w->force_start = Qt;
13436 /* IT may overshoot PT if text at PT is invisible. */
13437 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13438 w->force_start = Qt;
13439 }
13440
13441 force_start:
13442
13443 /* Handle case where place to start displaying has been specified,
13444 unless the specified location is outside the accessible range. */
13445 if (!NILP (w->force_start)
13446 || w->frozen_window_start_p)
13447 {
13448 /* We set this later on if we have to adjust point. */
13449 int new_vpos = -1;
13450
13451 w->force_start = Qnil;
13452 w->vscroll = 0;
13453 w->window_end_valid = Qnil;
13454
13455 /* Forget any recorded base line for line number display. */
13456 if (!buffer_unchanged_p)
13457 w->base_line_number = Qnil;
13458
13459 /* Redisplay the mode line. Select the buffer properly for that.
13460 Also, run the hook window-scroll-functions
13461 because we have scrolled. */
13462 /* Note, we do this after clearing force_start because
13463 if there's an error, it is better to forget about force_start
13464 than to get into an infinite loop calling the hook functions
13465 and having them get more errors. */
13466 if (!update_mode_line
13467 || ! NILP (Vwindow_scroll_functions))
13468 {
13469 update_mode_line = 1;
13470 w->update_mode_line = Qt;
13471 startp = run_window_scroll_functions (window, startp);
13472 }
13473
13474 w->last_modified = make_number (0);
13475 w->last_overlay_modified = make_number (0);
13476 if (CHARPOS (startp) < BEGV)
13477 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13478 else if (CHARPOS (startp) > ZV)
13479 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13480
13481 /* Redisplay, then check if cursor has been set during the
13482 redisplay. Give up if new fonts were loaded. */
13483 /* We used to issue a CHECK_MARGINS argument to try_window here,
13484 but this causes scrolling to fail when point begins inside
13485 the scroll margin (bug#148) -- cyd */
13486 if (!try_window (window, startp, 0))
13487 {
13488 w->force_start = Qt;
13489 clear_glyph_matrix (w->desired_matrix);
13490 goto need_larger_matrices;
13491 }
13492
13493 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13494 {
13495 /* If point does not appear, try to move point so it does
13496 appear. The desired matrix has been built above, so we
13497 can use it here. */
13498 new_vpos = window_box_height (w) / 2;
13499 }
13500
13501 if (!cursor_row_fully_visible_p (w, 0, 0))
13502 {
13503 /* Point does appear, but on a line partly visible at end of window.
13504 Move it back to a fully-visible line. */
13505 new_vpos = window_box_height (w);
13506 }
13507
13508 /* If we need to move point for either of the above reasons,
13509 now actually do it. */
13510 if (new_vpos >= 0)
13511 {
13512 struct glyph_row *row;
13513
13514 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13515 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13516 ++row;
13517
13518 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13519 MATRIX_ROW_START_BYTEPOS (row));
13520
13521 if (w != XWINDOW (selected_window))
13522 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13523 else if (current_buffer == old)
13524 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13525
13526 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13527
13528 /* If we are highlighting the region, then we just changed
13529 the region, so redisplay to show it. */
13530 if (!NILP (Vtransient_mark_mode)
13531 && !NILP (current_buffer->mark_active))
13532 {
13533 clear_glyph_matrix (w->desired_matrix);
13534 if (!try_window (window, startp, 0))
13535 goto need_larger_matrices;
13536 }
13537 }
13538
13539 #if GLYPH_DEBUG
13540 debug_method_add (w, "forced window start");
13541 #endif
13542 goto done;
13543 }
13544
13545 /* Handle case where text has not changed, only point, and it has
13546 not moved off the frame, and we are not retrying after hscroll.
13547 (current_matrix_up_to_date_p is nonzero when retrying.) */
13548 if (current_matrix_up_to_date_p
13549 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13550 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13551 {
13552 switch (rc)
13553 {
13554 case CURSOR_MOVEMENT_SUCCESS:
13555 used_current_matrix_p = 1;
13556 goto done;
13557
13558 case CURSOR_MOVEMENT_MUST_SCROLL:
13559 goto try_to_scroll;
13560
13561 default:
13562 abort ();
13563 }
13564 }
13565 /* If current starting point was originally the beginning of a line
13566 but no longer is, find a new starting point. */
13567 else if (!NILP (w->start_at_line_beg)
13568 && !(CHARPOS (startp) <= BEGV
13569 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13570 {
13571 #if GLYPH_DEBUG
13572 debug_method_add (w, "recenter 1");
13573 #endif
13574 goto recenter;
13575 }
13576
13577 /* Try scrolling with try_window_id. Value is > 0 if update has
13578 been done, it is -1 if we know that the same window start will
13579 not work. It is 0 if unsuccessful for some other reason. */
13580 else if ((tem = try_window_id (w)) != 0)
13581 {
13582 #if GLYPH_DEBUG
13583 debug_method_add (w, "try_window_id %d", tem);
13584 #endif
13585
13586 if (fonts_changed_p)
13587 goto need_larger_matrices;
13588 if (tem > 0)
13589 goto done;
13590
13591 /* Otherwise try_window_id has returned -1 which means that we
13592 don't want the alternative below this comment to execute. */
13593 }
13594 else if (CHARPOS (startp) >= BEGV
13595 && CHARPOS (startp) <= ZV
13596 && PT >= CHARPOS (startp)
13597 && (CHARPOS (startp) < ZV
13598 /* Avoid starting at end of buffer. */
13599 || CHARPOS (startp) == BEGV
13600 || (XFASTINT (w->last_modified) >= MODIFF
13601 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13602 {
13603
13604 /* If first window line is a continuation line, and window start
13605 is inside the modified region, but the first change is before
13606 current window start, we must select a new window start.
13607
13608 However, if this is the result of a down-mouse event (e.g. by
13609 extending the mouse-drag-overlay), we don't want to select a
13610 new window start, since that would change the position under
13611 the mouse, resulting in an unwanted mouse-movement rather
13612 than a simple mouse-click. */
13613 if (NILP (w->start_at_line_beg)
13614 && NILP (do_mouse_tracking)
13615 && CHARPOS (startp) > BEGV
13616 && CHARPOS (startp) > BEG + beg_unchanged
13617 && CHARPOS (startp) <= Z - end_unchanged
13618 /* Even if w->start_at_line_beg is nil, a new window may
13619 start at a line_beg, since that's how set_buffer_window
13620 sets it. So, we need to check the return value of
13621 compute_window_start_on_continuation_line. (See also
13622 bug#197). */
13623 && XMARKER (w->start)->buffer == current_buffer
13624 && compute_window_start_on_continuation_line (w))
13625 {
13626 w->force_start = Qt;
13627 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13628 goto force_start;
13629 }
13630
13631 #if GLYPH_DEBUG
13632 debug_method_add (w, "same window start");
13633 #endif
13634
13635 /* Try to redisplay starting at same place as before.
13636 If point has not moved off frame, accept the results. */
13637 if (!current_matrix_up_to_date_p
13638 /* Don't use try_window_reusing_current_matrix in this case
13639 because a window scroll function can have changed the
13640 buffer. */
13641 || !NILP (Vwindow_scroll_functions)
13642 || MINI_WINDOW_P (w)
13643 || !(used_current_matrix_p
13644 = try_window_reusing_current_matrix (w)))
13645 {
13646 IF_DEBUG (debug_method_add (w, "1"));
13647 if (try_window (window, startp, 1) < 0)
13648 /* -1 means we need to scroll.
13649 0 means we need new matrices, but fonts_changed_p
13650 is set in that case, so we will detect it below. */
13651 goto try_to_scroll;
13652 }
13653
13654 if (fonts_changed_p)
13655 goto need_larger_matrices;
13656
13657 if (w->cursor.vpos >= 0)
13658 {
13659 if (!just_this_one_p
13660 || current_buffer->clip_changed
13661 || BEG_UNCHANGED < CHARPOS (startp))
13662 /* Forget any recorded base line for line number display. */
13663 w->base_line_number = Qnil;
13664
13665 if (!cursor_row_fully_visible_p (w, 1, 0))
13666 {
13667 clear_glyph_matrix (w->desired_matrix);
13668 last_line_misfit = 1;
13669 }
13670 /* Drop through and scroll. */
13671 else
13672 goto done;
13673 }
13674 else
13675 clear_glyph_matrix (w->desired_matrix);
13676 }
13677
13678 try_to_scroll:
13679
13680 w->last_modified = make_number (0);
13681 w->last_overlay_modified = make_number (0);
13682
13683 /* Redisplay the mode line. Select the buffer properly for that. */
13684 if (!update_mode_line)
13685 {
13686 update_mode_line = 1;
13687 w->update_mode_line = Qt;
13688 }
13689
13690 /* Try to scroll by specified few lines. */
13691 if ((scroll_conservatively
13692 || scroll_step
13693 || temp_scroll_step
13694 || NUMBERP (current_buffer->scroll_up_aggressively)
13695 || NUMBERP (current_buffer->scroll_down_aggressively))
13696 && !current_buffer->clip_changed
13697 && CHARPOS (startp) >= BEGV
13698 && CHARPOS (startp) <= ZV)
13699 {
13700 /* The function returns -1 if new fonts were loaded, 1 if
13701 successful, 0 if not successful. */
13702 int rc = try_scrolling (window, just_this_one_p,
13703 scroll_conservatively,
13704 scroll_step,
13705 temp_scroll_step, last_line_misfit);
13706 switch (rc)
13707 {
13708 case SCROLLING_SUCCESS:
13709 goto done;
13710
13711 case SCROLLING_NEED_LARGER_MATRICES:
13712 goto need_larger_matrices;
13713
13714 case SCROLLING_FAILED:
13715 break;
13716
13717 default:
13718 abort ();
13719 }
13720 }
13721
13722 /* Finally, just choose place to start which centers point */
13723
13724 recenter:
13725 if (centering_position < 0)
13726 centering_position = window_box_height (w) / 2;
13727
13728 #if GLYPH_DEBUG
13729 debug_method_add (w, "recenter");
13730 #endif
13731
13732 /* w->vscroll = 0; */
13733
13734 /* Forget any previously recorded base line for line number display. */
13735 if (!buffer_unchanged_p)
13736 w->base_line_number = Qnil;
13737
13738 /* Move backward half the height of the window. */
13739 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13740 it.current_y = it.last_visible_y;
13741 move_it_vertically_backward (&it, centering_position);
13742 xassert (IT_CHARPOS (it) >= BEGV);
13743
13744 /* The function move_it_vertically_backward may move over more
13745 than the specified y-distance. If it->w is small, e.g. a
13746 mini-buffer window, we may end up in front of the window's
13747 display area. Start displaying at the start of the line
13748 containing PT in this case. */
13749 if (it.current_y <= 0)
13750 {
13751 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13752 move_it_vertically_backward (&it, 0);
13753 it.current_y = 0;
13754 }
13755
13756 it.current_x = it.hpos = 0;
13757
13758 /* Set startp here explicitly in case that helps avoid an infinite loop
13759 in case the window-scroll-functions functions get errors. */
13760 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13761
13762 /* Run scroll hooks. */
13763 startp = run_window_scroll_functions (window, it.current.pos);
13764
13765 /* Redisplay the window. */
13766 if (!current_matrix_up_to_date_p
13767 || windows_or_buffers_changed
13768 || cursor_type_changed
13769 /* Don't use try_window_reusing_current_matrix in this case
13770 because it can have changed the buffer. */
13771 || !NILP (Vwindow_scroll_functions)
13772 || !just_this_one_p
13773 || MINI_WINDOW_P (w)
13774 || !(used_current_matrix_p
13775 = try_window_reusing_current_matrix (w)))
13776 try_window (window, startp, 0);
13777
13778 /* If new fonts have been loaded (due to fontsets), give up. We
13779 have to start a new redisplay since we need to re-adjust glyph
13780 matrices. */
13781 if (fonts_changed_p)
13782 goto need_larger_matrices;
13783
13784 /* If cursor did not appear assume that the middle of the window is
13785 in the first line of the window. Do it again with the next line.
13786 (Imagine a window of height 100, displaying two lines of height
13787 60. Moving back 50 from it->last_visible_y will end in the first
13788 line.) */
13789 if (w->cursor.vpos < 0)
13790 {
13791 if (!NILP (w->window_end_valid)
13792 && PT >= Z - XFASTINT (w->window_end_pos))
13793 {
13794 clear_glyph_matrix (w->desired_matrix);
13795 move_it_by_lines (&it, 1, 0);
13796 try_window (window, it.current.pos, 0);
13797 }
13798 else if (PT < IT_CHARPOS (it))
13799 {
13800 clear_glyph_matrix (w->desired_matrix);
13801 move_it_by_lines (&it, -1, 0);
13802 try_window (window, it.current.pos, 0);
13803 }
13804 else
13805 {
13806 /* Not much we can do about it. */
13807 }
13808 }
13809
13810 /* Consider the following case: Window starts at BEGV, there is
13811 invisible, intangible text at BEGV, so that display starts at
13812 some point START > BEGV. It can happen that we are called with
13813 PT somewhere between BEGV and START. Try to handle that case. */
13814 if (w->cursor.vpos < 0)
13815 {
13816 struct glyph_row *row = w->current_matrix->rows;
13817 if (row->mode_line_p)
13818 ++row;
13819 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13820 }
13821
13822 if (!cursor_row_fully_visible_p (w, 0, 0))
13823 {
13824 /* If vscroll is enabled, disable it and try again. */
13825 if (w->vscroll)
13826 {
13827 w->vscroll = 0;
13828 clear_glyph_matrix (w->desired_matrix);
13829 goto recenter;
13830 }
13831
13832 /* If centering point failed to make the whole line visible,
13833 put point at the top instead. That has to make the whole line
13834 visible, if it can be done. */
13835 if (centering_position == 0)
13836 goto done;
13837
13838 clear_glyph_matrix (w->desired_matrix);
13839 centering_position = 0;
13840 goto recenter;
13841 }
13842
13843 done:
13844
13845 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13846 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13847 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13848 ? Qt : Qnil);
13849
13850 /* Display the mode line, if we must. */
13851 if ((update_mode_line
13852 /* If window not full width, must redo its mode line
13853 if (a) the window to its side is being redone and
13854 (b) we do a frame-based redisplay. This is a consequence
13855 of how inverted lines are drawn in frame-based redisplay. */
13856 || (!just_this_one_p
13857 && !FRAME_WINDOW_P (f)
13858 && !WINDOW_FULL_WIDTH_P (w))
13859 /* Line number to display. */
13860 || INTEGERP (w->base_line_pos)
13861 /* Column number is displayed and different from the one displayed. */
13862 || (!NILP (w->column_number_displayed)
13863 && (XFASTINT (w->column_number_displayed)
13864 != (int) current_column ()))) /* iftc */
13865 /* This means that the window has a mode line. */
13866 && (WINDOW_WANTS_MODELINE_P (w)
13867 || WINDOW_WANTS_HEADER_LINE_P (w)))
13868 {
13869 display_mode_lines (w);
13870
13871 /* If mode line height has changed, arrange for a thorough
13872 immediate redisplay using the correct mode line height. */
13873 if (WINDOW_WANTS_MODELINE_P (w)
13874 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13875 {
13876 fonts_changed_p = 1;
13877 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13878 = DESIRED_MODE_LINE_HEIGHT (w);
13879 }
13880
13881 /* If header line height has changed, arrange for a thorough
13882 immediate redisplay using the correct header line height. */
13883 if (WINDOW_WANTS_HEADER_LINE_P (w)
13884 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13885 {
13886 fonts_changed_p = 1;
13887 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13888 = DESIRED_HEADER_LINE_HEIGHT (w);
13889 }
13890
13891 if (fonts_changed_p)
13892 goto need_larger_matrices;
13893 }
13894
13895 if (!line_number_displayed
13896 && !BUFFERP (w->base_line_pos))
13897 {
13898 w->base_line_pos = Qnil;
13899 w->base_line_number = Qnil;
13900 }
13901
13902 finish_menu_bars:
13903
13904 /* When we reach a frame's selected window, redo the frame's menu bar. */
13905 if (update_mode_line
13906 && EQ (FRAME_SELECTED_WINDOW (f), window))
13907 {
13908 int redisplay_menu_p = 0;
13909 int redisplay_tool_bar_p = 0;
13910
13911 if (FRAME_WINDOW_P (f))
13912 {
13913 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
13914 || defined (HAVE_NS) || defined (USE_GTK)
13915 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13916 #else
13917 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13918 #endif
13919 }
13920 else
13921 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13922
13923 if (redisplay_menu_p)
13924 display_menu_bar (w);
13925
13926 #ifdef HAVE_WINDOW_SYSTEM
13927 if (FRAME_WINDOW_P (f))
13928 {
13929 #if defined (USE_GTK) || defined (HAVE_NS)
13930 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13931 #else
13932 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13933 && (FRAME_TOOL_BAR_LINES (f) > 0
13934 || !NILP (Vauto_resize_tool_bars));
13935 #endif
13936
13937 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13938 {
13939 extern int ignore_mouse_drag_p;
13940 ignore_mouse_drag_p = 1;
13941 }
13942 }
13943 #endif
13944 }
13945
13946 #ifdef HAVE_WINDOW_SYSTEM
13947 if (FRAME_WINDOW_P (f)
13948 && update_window_fringes (w, (just_this_one_p
13949 || (!used_current_matrix_p && !overlay_arrow_seen)
13950 || w->pseudo_window_p)))
13951 {
13952 update_begin (f);
13953 BLOCK_INPUT;
13954 if (draw_window_fringes (w, 1))
13955 x_draw_vertical_border (w);
13956 UNBLOCK_INPUT;
13957 update_end (f);
13958 }
13959 #endif /* HAVE_WINDOW_SYSTEM */
13960
13961 /* We go to this label, with fonts_changed_p nonzero,
13962 if it is necessary to try again using larger glyph matrices.
13963 We have to redeem the scroll bar even in this case,
13964 because the loop in redisplay_internal expects that. */
13965 need_larger_matrices:
13966 ;
13967 finish_scroll_bars:
13968
13969 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13970 {
13971 /* Set the thumb's position and size. */
13972 set_vertical_scroll_bar (w);
13973
13974 /* Note that we actually used the scroll bar attached to this
13975 window, so it shouldn't be deleted at the end of redisplay. */
13976 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13977 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13978 }
13979
13980 /* Restore current_buffer and value of point in it. */
13981 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13982 set_buffer_internal_1 (old);
13983 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13984 shorter. This can be caused by log truncation in *Messages*. */
13985 if (CHARPOS (lpoint) <= ZV)
13986 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13987
13988 unbind_to (count, Qnil);
13989 }
13990
13991
13992 /* Build the complete desired matrix of WINDOW with a window start
13993 buffer position POS.
13994
13995 Value is 1 if successful. It is zero if fonts were loaded during
13996 redisplay which makes re-adjusting glyph matrices necessary, and -1
13997 if point would appear in the scroll margins.
13998 (We check that only if CHECK_MARGINS is nonzero. */
13999
14000 int
14001 try_window (window, pos, check_margins)
14002 Lisp_Object window;
14003 struct text_pos pos;
14004 int check_margins;
14005 {
14006 struct window *w = XWINDOW (window);
14007 struct it it;
14008 struct glyph_row *last_text_row = NULL;
14009 struct frame *f = XFRAME (w->frame);
14010
14011 /* Make POS the new window start. */
14012 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14013
14014 /* Mark cursor position as unknown. No overlay arrow seen. */
14015 w->cursor.vpos = -1;
14016 overlay_arrow_seen = 0;
14017
14018 /* Initialize iterator and info to start at POS. */
14019 start_display (&it, w, pos);
14020
14021 /* Display all lines of W. */
14022 while (it.current_y < it.last_visible_y)
14023 {
14024 if (display_line (&it))
14025 last_text_row = it.glyph_row - 1;
14026 if (fonts_changed_p)
14027 return 0;
14028 }
14029
14030 /* Don't let the cursor end in the scroll margins. */
14031 if (check_margins
14032 && !MINI_WINDOW_P (w))
14033 {
14034 int this_scroll_margin;
14035
14036 if (scroll_margin > 0)
14037 {
14038 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14039 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14040 }
14041 else
14042 this_scroll_margin = 0;
14043
14044 if ((w->cursor.y >= 0 /* not vscrolled */
14045 && w->cursor.y < this_scroll_margin
14046 && CHARPOS (pos) > BEGV
14047 && IT_CHARPOS (it) < ZV)
14048 /* rms: considering make_cursor_line_fully_visible_p here
14049 seems to give wrong results. We don't want to recenter
14050 when the last line is partly visible, we want to allow
14051 that case to be handled in the usual way. */
14052 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14053 {
14054 w->cursor.vpos = -1;
14055 clear_glyph_matrix (w->desired_matrix);
14056 return -1;
14057 }
14058 }
14059
14060 /* If bottom moved off end of frame, change mode line percentage. */
14061 if (XFASTINT (w->window_end_pos) <= 0
14062 && Z != IT_CHARPOS (it))
14063 w->update_mode_line = Qt;
14064
14065 /* Set window_end_pos to the offset of the last character displayed
14066 on the window from the end of current_buffer. Set
14067 window_end_vpos to its row number. */
14068 if (last_text_row)
14069 {
14070 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14071 w->window_end_bytepos
14072 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14073 w->window_end_pos
14074 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14075 w->window_end_vpos
14076 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14077 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14078 ->displays_text_p);
14079 }
14080 else
14081 {
14082 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14083 w->window_end_pos = make_number (Z - ZV);
14084 w->window_end_vpos = make_number (0);
14085 }
14086
14087 /* But that is not valid info until redisplay finishes. */
14088 w->window_end_valid = Qnil;
14089 return 1;
14090 }
14091
14092
14093 \f
14094 /************************************************************************
14095 Window redisplay reusing current matrix when buffer has not changed
14096 ************************************************************************/
14097
14098 /* Try redisplay of window W showing an unchanged buffer with a
14099 different window start than the last time it was displayed by
14100 reusing its current matrix. Value is non-zero if successful.
14101 W->start is the new window start. */
14102
14103 static int
14104 try_window_reusing_current_matrix (w)
14105 struct window *w;
14106 {
14107 struct frame *f = XFRAME (w->frame);
14108 struct glyph_row *row, *bottom_row;
14109 struct it it;
14110 struct run run;
14111 struct text_pos start, new_start;
14112 int nrows_scrolled, i;
14113 struct glyph_row *last_text_row;
14114 struct glyph_row *last_reused_text_row;
14115 struct glyph_row *start_row;
14116 int start_vpos, min_y, max_y;
14117
14118 #if GLYPH_DEBUG
14119 if (inhibit_try_window_reusing)
14120 return 0;
14121 #endif
14122
14123 if (/* This function doesn't handle terminal frames. */
14124 !FRAME_WINDOW_P (f)
14125 /* Don't try to reuse the display if windows have been split
14126 or such. */
14127 || windows_or_buffers_changed
14128 || cursor_type_changed)
14129 return 0;
14130
14131 /* Can't do this if region may have changed. */
14132 if ((!NILP (Vtransient_mark_mode)
14133 && !NILP (current_buffer->mark_active))
14134 || !NILP (w->region_showing)
14135 || !NILP (Vshow_trailing_whitespace))
14136 return 0;
14137
14138 /* If top-line visibility has changed, give up. */
14139 if (WINDOW_WANTS_HEADER_LINE_P (w)
14140 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14141 return 0;
14142
14143 /* Give up if old or new display is scrolled vertically. We could
14144 make this function handle this, but right now it doesn't. */
14145 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14146 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14147 return 0;
14148
14149 /* The variable new_start now holds the new window start. The old
14150 start `start' can be determined from the current matrix. */
14151 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14152 start = start_row->start.pos;
14153 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14154
14155 /* Clear the desired matrix for the display below. */
14156 clear_glyph_matrix (w->desired_matrix);
14157
14158 if (CHARPOS (new_start) <= CHARPOS (start))
14159 {
14160 int first_row_y;
14161
14162 /* Don't use this method if the display starts with an ellipsis
14163 displayed for invisible text. It's not easy to handle that case
14164 below, and it's certainly not worth the effort since this is
14165 not a frequent case. */
14166 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14167 return 0;
14168
14169 IF_DEBUG (debug_method_add (w, "twu1"));
14170
14171 /* Display up to a row that can be reused. The variable
14172 last_text_row is set to the last row displayed that displays
14173 text. Note that it.vpos == 0 if or if not there is a
14174 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14175 start_display (&it, w, new_start);
14176 first_row_y = it.current_y;
14177 w->cursor.vpos = -1;
14178 last_text_row = last_reused_text_row = NULL;
14179
14180 while (it.current_y < it.last_visible_y
14181 && !fonts_changed_p)
14182 {
14183 /* If we have reached into the characters in the START row,
14184 that means the line boundaries have changed. So we
14185 can't start copying with the row START. Maybe it will
14186 work to start copying with the following row. */
14187 while (IT_CHARPOS (it) > CHARPOS (start))
14188 {
14189 /* Advance to the next row as the "start". */
14190 start_row++;
14191 start = start_row->start.pos;
14192 /* If there are no more rows to try, or just one, give up. */
14193 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14194 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14195 || CHARPOS (start) == ZV)
14196 {
14197 clear_glyph_matrix (w->desired_matrix);
14198 return 0;
14199 }
14200
14201 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14202 }
14203 /* If we have reached alignment,
14204 we can copy the rest of the rows. */
14205 if (IT_CHARPOS (it) == CHARPOS (start))
14206 break;
14207
14208 if (display_line (&it))
14209 last_text_row = it.glyph_row - 1;
14210 }
14211
14212 /* A value of current_y < last_visible_y means that we stopped
14213 at the previous window start, which in turn means that we
14214 have at least one reusable row. */
14215 if (it.current_y < it.last_visible_y)
14216 {
14217 /* IT.vpos always starts from 0; it counts text lines. */
14218 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14219
14220 /* Find PT if not already found in the lines displayed. */
14221 if (w->cursor.vpos < 0)
14222 {
14223 int dy = it.current_y - start_row->y;
14224
14225 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14226 row = row_containing_pos (w, PT, row, NULL, dy);
14227 if (row)
14228 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14229 dy, nrows_scrolled);
14230 else
14231 {
14232 clear_glyph_matrix (w->desired_matrix);
14233 return 0;
14234 }
14235 }
14236
14237 /* Scroll the display. Do it before the current matrix is
14238 changed. The problem here is that update has not yet
14239 run, i.e. part of the current matrix is not up to date.
14240 scroll_run_hook will clear the cursor, and use the
14241 current matrix to get the height of the row the cursor is
14242 in. */
14243 run.current_y = start_row->y;
14244 run.desired_y = it.current_y;
14245 run.height = it.last_visible_y - it.current_y;
14246
14247 if (run.height > 0 && run.current_y != run.desired_y)
14248 {
14249 update_begin (f);
14250 FRAME_RIF (f)->update_window_begin_hook (w);
14251 FRAME_RIF (f)->clear_window_mouse_face (w);
14252 FRAME_RIF (f)->scroll_run_hook (w, &run);
14253 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14254 update_end (f);
14255 }
14256
14257 /* Shift current matrix down by nrows_scrolled lines. */
14258 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14259 rotate_matrix (w->current_matrix,
14260 start_vpos,
14261 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14262 nrows_scrolled);
14263
14264 /* Disable lines that must be updated. */
14265 for (i = 0; i < nrows_scrolled; ++i)
14266 (start_row + i)->enabled_p = 0;
14267
14268 /* Re-compute Y positions. */
14269 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14270 max_y = it.last_visible_y;
14271 for (row = start_row + nrows_scrolled;
14272 row < bottom_row;
14273 ++row)
14274 {
14275 row->y = it.current_y;
14276 row->visible_height = row->height;
14277
14278 if (row->y < min_y)
14279 row->visible_height -= min_y - row->y;
14280 if (row->y + row->height > max_y)
14281 row->visible_height -= row->y + row->height - max_y;
14282 row->redraw_fringe_bitmaps_p = 1;
14283
14284 it.current_y += row->height;
14285
14286 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14287 last_reused_text_row = row;
14288 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14289 break;
14290 }
14291
14292 /* Disable lines in the current matrix which are now
14293 below the window. */
14294 for (++row; row < bottom_row; ++row)
14295 row->enabled_p = row->mode_line_p = 0;
14296 }
14297
14298 /* Update window_end_pos etc.; last_reused_text_row is the last
14299 reused row from the current matrix containing text, if any.
14300 The value of last_text_row is the last displayed line
14301 containing text. */
14302 if (last_reused_text_row)
14303 {
14304 w->window_end_bytepos
14305 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14306 w->window_end_pos
14307 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14308 w->window_end_vpos
14309 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14310 w->current_matrix));
14311 }
14312 else if (last_text_row)
14313 {
14314 w->window_end_bytepos
14315 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14316 w->window_end_pos
14317 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14318 w->window_end_vpos
14319 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14320 }
14321 else
14322 {
14323 /* This window must be completely empty. */
14324 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14325 w->window_end_pos = make_number (Z - ZV);
14326 w->window_end_vpos = make_number (0);
14327 }
14328 w->window_end_valid = Qnil;
14329
14330 /* Update hint: don't try scrolling again in update_window. */
14331 w->desired_matrix->no_scrolling_p = 1;
14332
14333 #if GLYPH_DEBUG
14334 debug_method_add (w, "try_window_reusing_current_matrix 1");
14335 #endif
14336 return 1;
14337 }
14338 else if (CHARPOS (new_start) > CHARPOS (start))
14339 {
14340 struct glyph_row *pt_row, *row;
14341 struct glyph_row *first_reusable_row;
14342 struct glyph_row *first_row_to_display;
14343 int dy;
14344 int yb = window_text_bottom_y (w);
14345
14346 /* Find the row starting at new_start, if there is one. Don't
14347 reuse a partially visible line at the end. */
14348 first_reusable_row = start_row;
14349 while (first_reusable_row->enabled_p
14350 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14351 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14352 < CHARPOS (new_start)))
14353 ++first_reusable_row;
14354
14355 /* Give up if there is no row to reuse. */
14356 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14357 || !first_reusable_row->enabled_p
14358 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14359 != CHARPOS (new_start)))
14360 return 0;
14361
14362 /* We can reuse fully visible rows beginning with
14363 first_reusable_row to the end of the window. Set
14364 first_row_to_display to the first row that cannot be reused.
14365 Set pt_row to the row containing point, if there is any. */
14366 pt_row = NULL;
14367 for (first_row_to_display = first_reusable_row;
14368 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14369 ++first_row_to_display)
14370 {
14371 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14372 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14373 pt_row = first_row_to_display;
14374 }
14375
14376 /* Start displaying at the start of first_row_to_display. */
14377 xassert (first_row_to_display->y < yb);
14378 init_to_row_start (&it, w, first_row_to_display);
14379
14380 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14381 - start_vpos);
14382 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14383 - nrows_scrolled);
14384 it.current_y = (first_row_to_display->y - first_reusable_row->y
14385 + WINDOW_HEADER_LINE_HEIGHT (w));
14386
14387 /* Display lines beginning with first_row_to_display in the
14388 desired matrix. Set last_text_row to the last row displayed
14389 that displays text. */
14390 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14391 if (pt_row == NULL)
14392 w->cursor.vpos = -1;
14393 last_text_row = NULL;
14394 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14395 if (display_line (&it))
14396 last_text_row = it.glyph_row - 1;
14397
14398 /* If point is in a reused row, adjust y and vpos of the cursor
14399 position. */
14400 if (pt_row)
14401 {
14402 w->cursor.vpos -= nrows_scrolled;
14403 w->cursor.y -= first_reusable_row->y - start_row->y;
14404 }
14405
14406 /* Give up if point isn't in a row displayed or reused. (This
14407 also handles the case where w->cursor.vpos < nrows_scrolled
14408 after the calls to display_line, which can happen with scroll
14409 margins. See bug#1295.) */
14410 if (w->cursor.vpos < 0)
14411 {
14412 clear_glyph_matrix (w->desired_matrix);
14413 return 0;
14414 }
14415
14416 /* Scroll the display. */
14417 run.current_y = first_reusable_row->y;
14418 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14419 run.height = it.last_visible_y - run.current_y;
14420 dy = run.current_y - run.desired_y;
14421
14422 if (run.height)
14423 {
14424 update_begin (f);
14425 FRAME_RIF (f)->update_window_begin_hook (w);
14426 FRAME_RIF (f)->clear_window_mouse_face (w);
14427 FRAME_RIF (f)->scroll_run_hook (w, &run);
14428 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14429 update_end (f);
14430 }
14431
14432 /* Adjust Y positions of reused rows. */
14433 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14434 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14435 max_y = it.last_visible_y;
14436 for (row = first_reusable_row; row < first_row_to_display; ++row)
14437 {
14438 row->y -= dy;
14439 row->visible_height = row->height;
14440 if (row->y < min_y)
14441 row->visible_height -= min_y - row->y;
14442 if (row->y + row->height > max_y)
14443 row->visible_height -= row->y + row->height - max_y;
14444 row->redraw_fringe_bitmaps_p = 1;
14445 }
14446
14447 /* Scroll the current matrix. */
14448 xassert (nrows_scrolled > 0);
14449 rotate_matrix (w->current_matrix,
14450 start_vpos,
14451 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14452 -nrows_scrolled);
14453
14454 /* Disable rows not reused. */
14455 for (row -= nrows_scrolled; row < bottom_row; ++row)
14456 row->enabled_p = 0;
14457
14458 /* Point may have moved to a different line, so we cannot assume that
14459 the previous cursor position is valid; locate the correct row. */
14460 if (pt_row)
14461 {
14462 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14463 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14464 row++)
14465 {
14466 w->cursor.vpos++;
14467 w->cursor.y = row->y;
14468 }
14469 if (row < bottom_row)
14470 {
14471 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14472 struct glyph *end = glyph + row->used[TEXT_AREA];
14473
14474 for (; glyph < end
14475 && (!BUFFERP (glyph->object)
14476 || glyph->charpos < PT);
14477 glyph++)
14478 {
14479 w->cursor.hpos++;
14480 w->cursor.x += glyph->pixel_width;
14481 }
14482 }
14483 }
14484
14485 /* Adjust window end. A null value of last_text_row means that
14486 the window end is in reused rows which in turn means that
14487 only its vpos can have changed. */
14488 if (last_text_row)
14489 {
14490 w->window_end_bytepos
14491 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14492 w->window_end_pos
14493 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14494 w->window_end_vpos
14495 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14496 }
14497 else
14498 {
14499 w->window_end_vpos
14500 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14501 }
14502
14503 w->window_end_valid = Qnil;
14504 w->desired_matrix->no_scrolling_p = 1;
14505
14506 #if GLYPH_DEBUG
14507 debug_method_add (w, "try_window_reusing_current_matrix 2");
14508 #endif
14509 return 1;
14510 }
14511
14512 return 0;
14513 }
14514
14515
14516 \f
14517 /************************************************************************
14518 Window redisplay reusing current matrix when buffer has changed
14519 ************************************************************************/
14520
14521 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14522 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14523 int *, int *));
14524 static struct glyph_row *
14525 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14526 struct glyph_row *));
14527
14528
14529 /* Return the last row in MATRIX displaying text. If row START is
14530 non-null, start searching with that row. IT gives the dimensions
14531 of the display. Value is null if matrix is empty; otherwise it is
14532 a pointer to the row found. */
14533
14534 static struct glyph_row *
14535 find_last_row_displaying_text (matrix, it, start)
14536 struct glyph_matrix *matrix;
14537 struct it *it;
14538 struct glyph_row *start;
14539 {
14540 struct glyph_row *row, *row_found;
14541
14542 /* Set row_found to the last row in IT->w's current matrix
14543 displaying text. The loop looks funny but think of partially
14544 visible lines. */
14545 row_found = NULL;
14546 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14547 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14548 {
14549 xassert (row->enabled_p);
14550 row_found = row;
14551 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14552 break;
14553 ++row;
14554 }
14555
14556 return row_found;
14557 }
14558
14559
14560 /* Return the last row in the current matrix of W that is not affected
14561 by changes at the start of current_buffer that occurred since W's
14562 current matrix was built. Value is null if no such row exists.
14563
14564 BEG_UNCHANGED us the number of characters unchanged at the start of
14565 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14566 first changed character in current_buffer. Characters at positions <
14567 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14568 when the current matrix was built. */
14569
14570 static struct glyph_row *
14571 find_last_unchanged_at_beg_row (w)
14572 struct window *w;
14573 {
14574 int first_changed_pos = BEG + BEG_UNCHANGED;
14575 struct glyph_row *row;
14576 struct glyph_row *row_found = NULL;
14577 int yb = window_text_bottom_y (w);
14578
14579 /* Find the last row displaying unchanged text. */
14580 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14581 MATRIX_ROW_DISPLAYS_TEXT_P (row)
14582 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
14583 ++row)
14584 {
14585 if (/* If row ends before first_changed_pos, it is unchanged,
14586 except in some case. */
14587 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14588 /* When row ends in ZV and we write at ZV it is not
14589 unchanged. */
14590 && !row->ends_at_zv_p
14591 /* When first_changed_pos is the end of a continued line,
14592 row is not unchanged because it may be no longer
14593 continued. */
14594 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14595 && (row->continued_p
14596 || row->exact_window_width_line_p)))
14597 row_found = row;
14598
14599 /* Stop if last visible row. */
14600 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14601 break;
14602 }
14603
14604 return row_found;
14605 }
14606
14607
14608 /* Find the first glyph row in the current matrix of W that is not
14609 affected by changes at the end of current_buffer since the
14610 time W's current matrix was built.
14611
14612 Return in *DELTA the number of chars by which buffer positions in
14613 unchanged text at the end of current_buffer must be adjusted.
14614
14615 Return in *DELTA_BYTES the corresponding number of bytes.
14616
14617 Value is null if no such row exists, i.e. all rows are affected by
14618 changes. */
14619
14620 static struct glyph_row *
14621 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14622 struct window *w;
14623 int *delta, *delta_bytes;
14624 {
14625 struct glyph_row *row;
14626 struct glyph_row *row_found = NULL;
14627
14628 *delta = *delta_bytes = 0;
14629
14630 /* Display must not have been paused, otherwise the current matrix
14631 is not up to date. */
14632 eassert (!NILP (w->window_end_valid));
14633
14634 /* A value of window_end_pos >= END_UNCHANGED means that the window
14635 end is in the range of changed text. If so, there is no
14636 unchanged row at the end of W's current matrix. */
14637 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14638 return NULL;
14639
14640 /* Set row to the last row in W's current matrix displaying text. */
14641 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14642
14643 /* If matrix is entirely empty, no unchanged row exists. */
14644 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14645 {
14646 /* The value of row is the last glyph row in the matrix having a
14647 meaningful buffer position in it. The end position of row
14648 corresponds to window_end_pos. This allows us to translate
14649 buffer positions in the current matrix to current buffer
14650 positions for characters not in changed text. */
14651 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14652 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14653 int last_unchanged_pos, last_unchanged_pos_old;
14654 struct glyph_row *first_text_row
14655 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14656
14657 *delta = Z - Z_old;
14658 *delta_bytes = Z_BYTE - Z_BYTE_old;
14659
14660 /* Set last_unchanged_pos to the buffer position of the last
14661 character in the buffer that has not been changed. Z is the
14662 index + 1 of the last character in current_buffer, i.e. by
14663 subtracting END_UNCHANGED we get the index of the last
14664 unchanged character, and we have to add BEG to get its buffer
14665 position. */
14666 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14667 last_unchanged_pos_old = last_unchanged_pos - *delta;
14668
14669 /* Search backward from ROW for a row displaying a line that
14670 starts at a minimum position >= last_unchanged_pos_old. */
14671 for (; row > first_text_row; --row)
14672 {
14673 /* This used to abort, but it can happen.
14674 It is ok to just stop the search instead here. KFS. */
14675 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14676 break;
14677
14678 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14679 row_found = row;
14680 }
14681 }
14682
14683 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
14684
14685 return row_found;
14686 }
14687
14688
14689 /* Make sure that glyph rows in the current matrix of window W
14690 reference the same glyph memory as corresponding rows in the
14691 frame's frame matrix. This function is called after scrolling W's
14692 current matrix on a terminal frame in try_window_id and
14693 try_window_reusing_current_matrix. */
14694
14695 static void
14696 sync_frame_with_window_matrix_rows (w)
14697 struct window *w;
14698 {
14699 struct frame *f = XFRAME (w->frame);
14700 struct glyph_row *window_row, *window_row_end, *frame_row;
14701
14702 /* Preconditions: W must be a leaf window and full-width. Its frame
14703 must have a frame matrix. */
14704 xassert (NILP (w->hchild) && NILP (w->vchild));
14705 xassert (WINDOW_FULL_WIDTH_P (w));
14706 xassert (!FRAME_WINDOW_P (f));
14707
14708 /* If W is a full-width window, glyph pointers in W's current matrix
14709 have, by definition, to be the same as glyph pointers in the
14710 corresponding frame matrix. Note that frame matrices have no
14711 marginal areas (see build_frame_matrix). */
14712 window_row = w->current_matrix->rows;
14713 window_row_end = window_row + w->current_matrix->nrows;
14714 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14715 while (window_row < window_row_end)
14716 {
14717 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14718 struct glyph *end = window_row->glyphs[LAST_AREA];
14719
14720 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14721 frame_row->glyphs[TEXT_AREA] = start;
14722 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14723 frame_row->glyphs[LAST_AREA] = end;
14724
14725 /* Disable frame rows whose corresponding window rows have
14726 been disabled in try_window_id. */
14727 if (!window_row->enabled_p)
14728 frame_row->enabled_p = 0;
14729
14730 ++window_row, ++frame_row;
14731 }
14732 }
14733
14734
14735 /* Find the glyph row in window W containing CHARPOS. Consider all
14736 rows between START and END (not inclusive). END null means search
14737 all rows to the end of the display area of W. Value is the row
14738 containing CHARPOS or null. */
14739
14740 struct glyph_row *
14741 row_containing_pos (w, charpos, start, end, dy)
14742 struct window *w;
14743 int charpos;
14744 struct glyph_row *start, *end;
14745 int dy;
14746 {
14747 struct glyph_row *row = start;
14748 int last_y;
14749
14750 /* If we happen to start on a header-line, skip that. */
14751 if (row->mode_line_p)
14752 ++row;
14753
14754 if ((end && row >= end) || !row->enabled_p)
14755 return NULL;
14756
14757 last_y = window_text_bottom_y (w) - dy;
14758
14759 while (1)
14760 {
14761 /* Give up if we have gone too far. */
14762 if (end && row >= end)
14763 return NULL;
14764 /* This formerly returned if they were equal.
14765 I think that both quantities are of a "last plus one" type;
14766 if so, when they are equal, the row is within the screen. -- rms. */
14767 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14768 return NULL;
14769
14770 /* If it is in this row, return this row. */
14771 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14772 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14773 /* The end position of a row equals the start
14774 position of the next row. If CHARPOS is there, we
14775 would rather display it in the next line, except
14776 when this line ends in ZV. */
14777 && !row->ends_at_zv_p
14778 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14779 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14780 return row;
14781 ++row;
14782 }
14783 }
14784
14785
14786 /* Try to redisplay window W by reusing its existing display. W's
14787 current matrix must be up to date when this function is called,
14788 i.e. window_end_valid must not be nil.
14789
14790 Value is
14791
14792 1 if display has been updated
14793 0 if otherwise unsuccessful
14794 -1 if redisplay with same window start is known not to succeed
14795
14796 The following steps are performed:
14797
14798 1. Find the last row in the current matrix of W that is not
14799 affected by changes at the start of current_buffer. If no such row
14800 is found, give up.
14801
14802 2. Find the first row in W's current matrix that is not affected by
14803 changes at the end of current_buffer. Maybe there is no such row.
14804
14805 3. Display lines beginning with the row + 1 found in step 1 to the
14806 row found in step 2 or, if step 2 didn't find a row, to the end of
14807 the window.
14808
14809 4. If cursor is not known to appear on the window, give up.
14810
14811 5. If display stopped at the row found in step 2, scroll the
14812 display and current matrix as needed.
14813
14814 6. Maybe display some lines at the end of W, if we must. This can
14815 happen under various circumstances, like a partially visible line
14816 becoming fully visible, or because newly displayed lines are displayed
14817 in smaller font sizes.
14818
14819 7. Update W's window end information. */
14820
14821 static int
14822 try_window_id (w)
14823 struct window *w;
14824 {
14825 struct frame *f = XFRAME (w->frame);
14826 struct glyph_matrix *current_matrix = w->current_matrix;
14827 struct glyph_matrix *desired_matrix = w->desired_matrix;
14828 struct glyph_row *last_unchanged_at_beg_row;
14829 struct glyph_row *first_unchanged_at_end_row;
14830 struct glyph_row *row;
14831 struct glyph_row *bottom_row;
14832 int bottom_vpos;
14833 struct it it;
14834 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14835 struct text_pos start_pos;
14836 struct run run;
14837 int first_unchanged_at_end_vpos = 0;
14838 struct glyph_row *last_text_row, *last_text_row_at_end;
14839 struct text_pos start;
14840 int first_changed_charpos, last_changed_charpos;
14841
14842 #if GLYPH_DEBUG
14843 if (inhibit_try_window_id)
14844 return 0;
14845 #endif
14846
14847 /* This is handy for debugging. */
14848 #if 0
14849 #define GIVE_UP(X) \
14850 do { \
14851 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14852 return 0; \
14853 } while (0)
14854 #else
14855 #define GIVE_UP(X) return 0
14856 #endif
14857
14858 SET_TEXT_POS_FROM_MARKER (start, w->start);
14859
14860 /* Don't use this for mini-windows because these can show
14861 messages and mini-buffers, and we don't handle that here. */
14862 if (MINI_WINDOW_P (w))
14863 GIVE_UP (1);
14864
14865 /* This flag is used to prevent redisplay optimizations. */
14866 if (windows_or_buffers_changed || cursor_type_changed)
14867 GIVE_UP (2);
14868
14869 /* Verify that narrowing has not changed.
14870 Also verify that we were not told to prevent redisplay optimizations.
14871 It would be nice to further
14872 reduce the number of cases where this prevents try_window_id. */
14873 if (current_buffer->clip_changed
14874 || current_buffer->prevent_redisplay_optimizations_p)
14875 GIVE_UP (3);
14876
14877 /* Window must either use window-based redisplay or be full width. */
14878 if (!FRAME_WINDOW_P (f)
14879 && (!FRAME_LINE_INS_DEL_OK (f)
14880 || !WINDOW_FULL_WIDTH_P (w)))
14881 GIVE_UP (4);
14882
14883 /* Give up if point is known NOT to appear in W. */
14884 if (PT < CHARPOS (start))
14885 GIVE_UP (5);
14886
14887 /* Another way to prevent redisplay optimizations. */
14888 if (XFASTINT (w->last_modified) == 0)
14889 GIVE_UP (6);
14890
14891 /* Verify that window is not hscrolled. */
14892 if (XFASTINT (w->hscroll) != 0)
14893 GIVE_UP (7);
14894
14895 /* Verify that display wasn't paused. */
14896 if (NILP (w->window_end_valid))
14897 GIVE_UP (8);
14898
14899 /* Can't use this if highlighting a region because a cursor movement
14900 will do more than just set the cursor. */
14901 if (!NILP (Vtransient_mark_mode)
14902 && !NILP (current_buffer->mark_active))
14903 GIVE_UP (9);
14904
14905 /* Likewise if highlighting trailing whitespace. */
14906 if (!NILP (Vshow_trailing_whitespace))
14907 GIVE_UP (11);
14908
14909 /* Likewise if showing a region. */
14910 if (!NILP (w->region_showing))
14911 GIVE_UP (10);
14912
14913 /* Can't use this if overlay arrow position and/or string have
14914 changed. */
14915 if (overlay_arrows_changed_p ())
14916 GIVE_UP (12);
14917
14918 /* When word-wrap is on, adding a space to the first word of a
14919 wrapped line can change the wrap position, altering the line
14920 above it. It might be worthwhile to handle this more
14921 intelligently, but for now just redisplay from scratch. */
14922 if (!NILP (XBUFFER (w->buffer)->word_wrap))
14923 GIVE_UP (21);
14924
14925 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14926 only if buffer has really changed. The reason is that the gap is
14927 initially at Z for freshly visited files. The code below would
14928 set end_unchanged to 0 in that case. */
14929 if (MODIFF > SAVE_MODIFF
14930 /* This seems to happen sometimes after saving a buffer. */
14931 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14932 {
14933 if (GPT - BEG < BEG_UNCHANGED)
14934 BEG_UNCHANGED = GPT - BEG;
14935 if (Z - GPT < END_UNCHANGED)
14936 END_UNCHANGED = Z - GPT;
14937 }
14938
14939 /* The position of the first and last character that has been changed. */
14940 first_changed_charpos = BEG + BEG_UNCHANGED;
14941 last_changed_charpos = Z - END_UNCHANGED;
14942
14943 /* If window starts after a line end, and the last change is in
14944 front of that newline, then changes don't affect the display.
14945 This case happens with stealth-fontification. Note that although
14946 the display is unchanged, glyph positions in the matrix have to
14947 be adjusted, of course. */
14948 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14949 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14950 && ((last_changed_charpos < CHARPOS (start)
14951 && CHARPOS (start) == BEGV)
14952 || (last_changed_charpos < CHARPOS (start) - 1
14953 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14954 {
14955 int Z_old, delta, Z_BYTE_old, delta_bytes;
14956 struct glyph_row *r0;
14957
14958 /* Compute how many chars/bytes have been added to or removed
14959 from the buffer. */
14960 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14961 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14962 delta = Z - Z_old;
14963 delta_bytes = Z_BYTE - Z_BYTE_old;
14964
14965 /* Give up if PT is not in the window. Note that it already has
14966 been checked at the start of try_window_id that PT is not in
14967 front of the window start. */
14968 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14969 GIVE_UP (13);
14970
14971 /* If window start is unchanged, we can reuse the whole matrix
14972 as is, after adjusting glyph positions. No need to compute
14973 the window end again, since its offset from Z hasn't changed. */
14974 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14975 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14976 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14977 /* PT must not be in a partially visible line. */
14978 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14979 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14980 {
14981 /* Adjust positions in the glyph matrix. */
14982 if (delta || delta_bytes)
14983 {
14984 struct glyph_row *r1
14985 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14986 increment_matrix_positions (w->current_matrix,
14987 MATRIX_ROW_VPOS (r0, current_matrix),
14988 MATRIX_ROW_VPOS (r1, current_matrix),
14989 delta, delta_bytes);
14990 }
14991
14992 /* Set the cursor. */
14993 row = row_containing_pos (w, PT, r0, NULL, 0);
14994 if (row)
14995 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14996 else
14997 abort ();
14998 return 1;
14999 }
15000 }
15001
15002 /* Handle the case that changes are all below what is displayed in
15003 the window, and that PT is in the window. This shortcut cannot
15004 be taken if ZV is visible in the window, and text has been added
15005 there that is visible in the window. */
15006 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15007 /* ZV is not visible in the window, or there are no
15008 changes at ZV, actually. */
15009 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15010 || first_changed_charpos == last_changed_charpos))
15011 {
15012 struct glyph_row *r0;
15013
15014 /* Give up if PT is not in the window. Note that it already has
15015 been checked at the start of try_window_id that PT is not in
15016 front of the window start. */
15017 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15018 GIVE_UP (14);
15019
15020 /* If window start is unchanged, we can reuse the whole matrix
15021 as is, without changing glyph positions since no text has
15022 been added/removed in front of the window end. */
15023 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15024 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
15025 /* PT must not be in a partially visible line. */
15026 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15027 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15028 {
15029 /* We have to compute the window end anew since text
15030 can have been added/removed after it. */
15031 w->window_end_pos
15032 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15033 w->window_end_bytepos
15034 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15035
15036 /* Set the cursor. */
15037 row = row_containing_pos (w, PT, r0, NULL, 0);
15038 if (row)
15039 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15040 else
15041 abort ();
15042 return 2;
15043 }
15044 }
15045
15046 /* Give up if window start is in the changed area.
15047
15048 The condition used to read
15049
15050 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15051
15052 but why that was tested escapes me at the moment. */
15053 if (CHARPOS (start) >= first_changed_charpos
15054 && CHARPOS (start) <= last_changed_charpos)
15055 GIVE_UP (15);
15056
15057 /* Check that window start agrees with the start of the first glyph
15058 row in its current matrix. Check this after we know the window
15059 start is not in changed text, otherwise positions would not be
15060 comparable. */
15061 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15062 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
15063 GIVE_UP (16);
15064
15065 /* Give up if the window ends in strings. Overlay strings
15066 at the end are difficult to handle, so don't try. */
15067 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15068 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15069 GIVE_UP (20);
15070
15071 /* Compute the position at which we have to start displaying new
15072 lines. Some of the lines at the top of the window might be
15073 reusable because they are not displaying changed text. Find the
15074 last row in W's current matrix not affected by changes at the
15075 start of current_buffer. Value is null if changes start in the
15076 first line of window. */
15077 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15078 if (last_unchanged_at_beg_row)
15079 {
15080 /* Avoid starting to display in the moddle of a character, a TAB
15081 for instance. This is easier than to set up the iterator
15082 exactly, and it's not a frequent case, so the additional
15083 effort wouldn't really pay off. */
15084 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15085 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15086 && last_unchanged_at_beg_row > w->current_matrix->rows)
15087 --last_unchanged_at_beg_row;
15088
15089 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15090 GIVE_UP (17);
15091
15092 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15093 GIVE_UP (18);
15094 start_pos = it.current.pos;
15095
15096 /* Start displaying new lines in the desired matrix at the same
15097 vpos we would use in the current matrix, i.e. below
15098 last_unchanged_at_beg_row. */
15099 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15100 current_matrix);
15101 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15102 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15103
15104 xassert (it.hpos == 0 && it.current_x == 0);
15105 }
15106 else
15107 {
15108 /* There are no reusable lines at the start of the window.
15109 Start displaying in the first text line. */
15110 start_display (&it, w, start);
15111 it.vpos = it.first_vpos;
15112 start_pos = it.current.pos;
15113 }
15114
15115 /* Find the first row that is not affected by changes at the end of
15116 the buffer. Value will be null if there is no unchanged row, in
15117 which case we must redisplay to the end of the window. delta
15118 will be set to the value by which buffer positions beginning with
15119 first_unchanged_at_end_row have to be adjusted due to text
15120 changes. */
15121 first_unchanged_at_end_row
15122 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15123 IF_DEBUG (debug_delta = delta);
15124 IF_DEBUG (debug_delta_bytes = delta_bytes);
15125
15126 /* Set stop_pos to the buffer position up to which we will have to
15127 display new lines. If first_unchanged_at_end_row != NULL, this
15128 is the buffer position of the start of the line displayed in that
15129 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15130 that we don't stop at a buffer position. */
15131 stop_pos = 0;
15132 if (first_unchanged_at_end_row)
15133 {
15134 xassert (last_unchanged_at_beg_row == NULL
15135 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15136
15137 /* If this is a continuation line, move forward to the next one
15138 that isn't. Changes in lines above affect this line.
15139 Caution: this may move first_unchanged_at_end_row to a row
15140 not displaying text. */
15141 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15142 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15143 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15144 < it.last_visible_y))
15145 ++first_unchanged_at_end_row;
15146
15147 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15148 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15149 >= it.last_visible_y))
15150 first_unchanged_at_end_row = NULL;
15151 else
15152 {
15153 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15154 + delta);
15155 first_unchanged_at_end_vpos
15156 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15157 xassert (stop_pos >= Z - END_UNCHANGED);
15158 }
15159 }
15160 else if (last_unchanged_at_beg_row == NULL)
15161 GIVE_UP (19);
15162
15163
15164 #if GLYPH_DEBUG
15165
15166 /* Either there is no unchanged row at the end, or the one we have
15167 now displays text. This is a necessary condition for the window
15168 end pos calculation at the end of this function. */
15169 xassert (first_unchanged_at_end_row == NULL
15170 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15171
15172 debug_last_unchanged_at_beg_vpos
15173 = (last_unchanged_at_beg_row
15174 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15175 : -1);
15176 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15177
15178 #endif /* GLYPH_DEBUG != 0 */
15179
15180
15181 /* Display new lines. Set last_text_row to the last new line
15182 displayed which has text on it, i.e. might end up as being the
15183 line where the window_end_vpos is. */
15184 w->cursor.vpos = -1;
15185 last_text_row = NULL;
15186 overlay_arrow_seen = 0;
15187 while (it.current_y < it.last_visible_y
15188 && !fonts_changed_p
15189 && (first_unchanged_at_end_row == NULL
15190 || IT_CHARPOS (it) < stop_pos))
15191 {
15192 if (display_line (&it))
15193 last_text_row = it.glyph_row - 1;
15194 }
15195
15196 if (fonts_changed_p)
15197 return -1;
15198
15199
15200 /* Compute differences in buffer positions, y-positions etc. for
15201 lines reused at the bottom of the window. Compute what we can
15202 scroll. */
15203 if (first_unchanged_at_end_row
15204 /* No lines reused because we displayed everything up to the
15205 bottom of the window. */
15206 && it.current_y < it.last_visible_y)
15207 {
15208 dvpos = (it.vpos
15209 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15210 current_matrix));
15211 dy = it.current_y - first_unchanged_at_end_row->y;
15212 run.current_y = first_unchanged_at_end_row->y;
15213 run.desired_y = run.current_y + dy;
15214 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15215 }
15216 else
15217 {
15218 delta = delta_bytes = dvpos = dy
15219 = run.current_y = run.desired_y = run.height = 0;
15220 first_unchanged_at_end_row = NULL;
15221 }
15222 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15223
15224
15225 /* Find the cursor if not already found. We have to decide whether
15226 PT will appear on this window (it sometimes doesn't, but this is
15227 not a very frequent case.) This decision has to be made before
15228 the current matrix is altered. A value of cursor.vpos < 0 means
15229 that PT is either in one of the lines beginning at
15230 first_unchanged_at_end_row or below the window. Don't care for
15231 lines that might be displayed later at the window end; as
15232 mentioned, this is not a frequent case. */
15233 if (w->cursor.vpos < 0)
15234 {
15235 /* Cursor in unchanged rows at the top? */
15236 if (PT < CHARPOS (start_pos)
15237 && last_unchanged_at_beg_row)
15238 {
15239 row = row_containing_pos (w, PT,
15240 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15241 last_unchanged_at_beg_row + 1, 0);
15242 if (row)
15243 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15244 }
15245
15246 /* Start from first_unchanged_at_end_row looking for PT. */
15247 else if (first_unchanged_at_end_row)
15248 {
15249 row = row_containing_pos (w, PT - delta,
15250 first_unchanged_at_end_row, NULL, 0);
15251 if (row)
15252 set_cursor_from_row (w, row, w->current_matrix, delta,
15253 delta_bytes, dy, dvpos);
15254 }
15255
15256 /* Give up if cursor was not found. */
15257 if (w->cursor.vpos < 0)
15258 {
15259 clear_glyph_matrix (w->desired_matrix);
15260 return -1;
15261 }
15262 }
15263
15264 /* Don't let the cursor end in the scroll margins. */
15265 {
15266 int this_scroll_margin, cursor_height;
15267
15268 this_scroll_margin = max (0, scroll_margin);
15269 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15270 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15271 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15272
15273 if ((w->cursor.y < this_scroll_margin
15274 && CHARPOS (start) > BEGV)
15275 /* Old redisplay didn't take scroll margin into account at the bottom,
15276 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15277 || (w->cursor.y + (make_cursor_line_fully_visible_p
15278 ? cursor_height + this_scroll_margin
15279 : 1)) > it.last_visible_y)
15280 {
15281 w->cursor.vpos = -1;
15282 clear_glyph_matrix (w->desired_matrix);
15283 return -1;
15284 }
15285 }
15286
15287 /* Scroll the display. Do it before changing the current matrix so
15288 that xterm.c doesn't get confused about where the cursor glyph is
15289 found. */
15290 if (dy && run.height)
15291 {
15292 update_begin (f);
15293
15294 if (FRAME_WINDOW_P (f))
15295 {
15296 FRAME_RIF (f)->update_window_begin_hook (w);
15297 FRAME_RIF (f)->clear_window_mouse_face (w);
15298 FRAME_RIF (f)->scroll_run_hook (w, &run);
15299 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15300 }
15301 else
15302 {
15303 /* Terminal frame. In this case, dvpos gives the number of
15304 lines to scroll by; dvpos < 0 means scroll up. */
15305 int first_unchanged_at_end_vpos
15306 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15307 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15308 int end = (WINDOW_TOP_EDGE_LINE (w)
15309 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15310 + window_internal_height (w));
15311
15312 /* Perform the operation on the screen. */
15313 if (dvpos > 0)
15314 {
15315 /* Scroll last_unchanged_at_beg_row to the end of the
15316 window down dvpos lines. */
15317 set_terminal_window (f, end);
15318
15319 /* On dumb terminals delete dvpos lines at the end
15320 before inserting dvpos empty lines. */
15321 if (!FRAME_SCROLL_REGION_OK (f))
15322 ins_del_lines (f, end - dvpos, -dvpos);
15323
15324 /* Insert dvpos empty lines in front of
15325 last_unchanged_at_beg_row. */
15326 ins_del_lines (f, from, dvpos);
15327 }
15328 else if (dvpos < 0)
15329 {
15330 /* Scroll up last_unchanged_at_beg_vpos to the end of
15331 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15332 set_terminal_window (f, end);
15333
15334 /* Delete dvpos lines in front of
15335 last_unchanged_at_beg_vpos. ins_del_lines will set
15336 the cursor to the given vpos and emit |dvpos| delete
15337 line sequences. */
15338 ins_del_lines (f, from + dvpos, dvpos);
15339
15340 /* On a dumb terminal insert dvpos empty lines at the
15341 end. */
15342 if (!FRAME_SCROLL_REGION_OK (f))
15343 ins_del_lines (f, end + dvpos, -dvpos);
15344 }
15345
15346 set_terminal_window (f, 0);
15347 }
15348
15349 update_end (f);
15350 }
15351
15352 /* Shift reused rows of the current matrix to the right position.
15353 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15354 text. */
15355 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15356 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15357 if (dvpos < 0)
15358 {
15359 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15360 bottom_vpos, dvpos);
15361 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15362 bottom_vpos, 0);
15363 }
15364 else if (dvpos > 0)
15365 {
15366 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15367 bottom_vpos, dvpos);
15368 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15369 first_unchanged_at_end_vpos + dvpos, 0);
15370 }
15371
15372 /* For frame-based redisplay, make sure that current frame and window
15373 matrix are in sync with respect to glyph memory. */
15374 if (!FRAME_WINDOW_P (f))
15375 sync_frame_with_window_matrix_rows (w);
15376
15377 /* Adjust buffer positions in reused rows. */
15378 if (delta || delta_bytes)
15379 increment_matrix_positions (current_matrix,
15380 first_unchanged_at_end_vpos + dvpos,
15381 bottom_vpos, delta, delta_bytes);
15382
15383 /* Adjust Y positions. */
15384 if (dy)
15385 shift_glyph_matrix (w, current_matrix,
15386 first_unchanged_at_end_vpos + dvpos,
15387 bottom_vpos, dy);
15388
15389 if (first_unchanged_at_end_row)
15390 {
15391 first_unchanged_at_end_row += dvpos;
15392 if (first_unchanged_at_end_row->y >= it.last_visible_y
15393 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15394 first_unchanged_at_end_row = NULL;
15395 }
15396
15397 /* If scrolling up, there may be some lines to display at the end of
15398 the window. */
15399 last_text_row_at_end = NULL;
15400 if (dy < 0)
15401 {
15402 /* Scrolling up can leave for example a partially visible line
15403 at the end of the window to be redisplayed. */
15404 /* Set last_row to the glyph row in the current matrix where the
15405 window end line is found. It has been moved up or down in
15406 the matrix by dvpos. */
15407 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15408 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15409
15410 /* If last_row is the window end line, it should display text. */
15411 xassert (last_row->displays_text_p);
15412
15413 /* If window end line was partially visible before, begin
15414 displaying at that line. Otherwise begin displaying with the
15415 line following it. */
15416 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
15417 {
15418 init_to_row_start (&it, w, last_row);
15419 it.vpos = last_vpos;
15420 it.current_y = last_row->y;
15421 }
15422 else
15423 {
15424 init_to_row_end (&it, w, last_row);
15425 it.vpos = 1 + last_vpos;
15426 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
15427 ++last_row;
15428 }
15429
15430 /* We may start in a continuation line. If so, we have to
15431 get the right continuation_lines_width and current_x. */
15432 it.continuation_lines_width = last_row->continuation_lines_width;
15433 it.hpos = it.current_x = 0;
15434
15435 /* Display the rest of the lines at the window end. */
15436 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15437 while (it.current_y < it.last_visible_y
15438 && !fonts_changed_p)
15439 {
15440 /* Is it always sure that the display agrees with lines in
15441 the current matrix? I don't think so, so we mark rows
15442 displayed invalid in the current matrix by setting their
15443 enabled_p flag to zero. */
15444 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15445 if (display_line (&it))
15446 last_text_row_at_end = it.glyph_row - 1;
15447 }
15448 }
15449
15450 /* Update window_end_pos and window_end_vpos. */
15451 if (first_unchanged_at_end_row
15452 && !last_text_row_at_end)
15453 {
15454 /* Window end line if one of the preserved rows from the current
15455 matrix. Set row to the last row displaying text in current
15456 matrix starting at first_unchanged_at_end_row, after
15457 scrolling. */
15458 xassert (first_unchanged_at_end_row->displays_text_p);
15459 row = find_last_row_displaying_text (w->current_matrix, &it,
15460 first_unchanged_at_end_row);
15461 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15462
15463 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15464 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15465 w->window_end_vpos
15466 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15467 xassert (w->window_end_bytepos >= 0);
15468 IF_DEBUG (debug_method_add (w, "A"));
15469 }
15470 else if (last_text_row_at_end)
15471 {
15472 w->window_end_pos
15473 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15474 w->window_end_bytepos
15475 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15476 w->window_end_vpos
15477 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15478 xassert (w->window_end_bytepos >= 0);
15479 IF_DEBUG (debug_method_add (w, "B"));
15480 }
15481 else if (last_text_row)
15482 {
15483 /* We have displayed either to the end of the window or at the
15484 end of the window, i.e. the last row with text is to be found
15485 in the desired matrix. */
15486 w->window_end_pos
15487 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15488 w->window_end_bytepos
15489 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15490 w->window_end_vpos
15491 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15492 xassert (w->window_end_bytepos >= 0);
15493 }
15494 else if (first_unchanged_at_end_row == NULL
15495 && last_text_row == NULL
15496 && last_text_row_at_end == NULL)
15497 {
15498 /* Displayed to end of window, but no line containing text was
15499 displayed. Lines were deleted at the end of the window. */
15500 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15501 int vpos = XFASTINT (w->window_end_vpos);
15502 struct glyph_row *current_row = current_matrix->rows + vpos;
15503 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15504
15505 for (row = NULL;
15506 row == NULL && vpos >= first_vpos;
15507 --vpos, --current_row, --desired_row)
15508 {
15509 if (desired_row->enabled_p)
15510 {
15511 if (desired_row->displays_text_p)
15512 row = desired_row;
15513 }
15514 else if (current_row->displays_text_p)
15515 row = current_row;
15516 }
15517
15518 xassert (row != NULL);
15519 w->window_end_vpos = make_number (vpos + 1);
15520 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15521 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15522 xassert (w->window_end_bytepos >= 0);
15523 IF_DEBUG (debug_method_add (w, "C"));
15524 }
15525 else
15526 abort ();
15527
15528 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15529 debug_end_vpos = XFASTINT (w->window_end_vpos));
15530
15531 /* Record that display has not been completed. */
15532 w->window_end_valid = Qnil;
15533 w->desired_matrix->no_scrolling_p = 1;
15534 return 3;
15535
15536 #undef GIVE_UP
15537 }
15538
15539
15540 \f
15541 /***********************************************************************
15542 More debugging support
15543 ***********************************************************************/
15544
15545 #if GLYPH_DEBUG
15546
15547 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15548 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15549 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15550
15551
15552 /* Dump the contents of glyph matrix MATRIX on stderr.
15553
15554 GLYPHS 0 means don't show glyph contents.
15555 GLYPHS 1 means show glyphs in short form
15556 GLYPHS > 1 means show glyphs in long form. */
15557
15558 void
15559 dump_glyph_matrix (matrix, glyphs)
15560 struct glyph_matrix *matrix;
15561 int glyphs;
15562 {
15563 int i;
15564 for (i = 0; i < matrix->nrows; ++i)
15565 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15566 }
15567
15568
15569 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15570 the glyph row and area where the glyph comes from. */
15571
15572 void
15573 dump_glyph (row, glyph, area)
15574 struct glyph_row *row;
15575 struct glyph *glyph;
15576 int area;
15577 {
15578 if (glyph->type == CHAR_GLYPH)
15579 {
15580 fprintf (stderr,
15581 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15582 glyph - row->glyphs[TEXT_AREA],
15583 'C',
15584 glyph->charpos,
15585 (BUFFERP (glyph->object)
15586 ? 'B'
15587 : (STRINGP (glyph->object)
15588 ? 'S'
15589 : '-')),
15590 glyph->pixel_width,
15591 glyph->u.ch,
15592 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15593 ? glyph->u.ch
15594 : '.'),
15595 glyph->face_id,
15596 glyph->left_box_line_p,
15597 glyph->right_box_line_p);
15598 }
15599 else if (glyph->type == STRETCH_GLYPH)
15600 {
15601 fprintf (stderr,
15602 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15603 glyph - row->glyphs[TEXT_AREA],
15604 'S',
15605 glyph->charpos,
15606 (BUFFERP (glyph->object)
15607 ? 'B'
15608 : (STRINGP (glyph->object)
15609 ? 'S'
15610 : '-')),
15611 glyph->pixel_width,
15612 0,
15613 '.',
15614 glyph->face_id,
15615 glyph->left_box_line_p,
15616 glyph->right_box_line_p);
15617 }
15618 else if (glyph->type == IMAGE_GLYPH)
15619 {
15620 fprintf (stderr,
15621 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15622 glyph - row->glyphs[TEXT_AREA],
15623 'I',
15624 glyph->charpos,
15625 (BUFFERP (glyph->object)
15626 ? 'B'
15627 : (STRINGP (glyph->object)
15628 ? 'S'
15629 : '-')),
15630 glyph->pixel_width,
15631 glyph->u.img_id,
15632 '.',
15633 glyph->face_id,
15634 glyph->left_box_line_p,
15635 glyph->right_box_line_p);
15636 }
15637 else if (glyph->type == COMPOSITE_GLYPH)
15638 {
15639 fprintf (stderr,
15640 " %5d %4c %6d %c %3d 0x%05x",
15641 glyph - row->glyphs[TEXT_AREA],
15642 '+',
15643 glyph->charpos,
15644 (BUFFERP (glyph->object)
15645 ? 'B'
15646 : (STRINGP (glyph->object)
15647 ? 'S'
15648 : '-')),
15649 glyph->pixel_width,
15650 glyph->u.cmp.id);
15651 if (glyph->u.cmp.automatic)
15652 fprintf (stderr,
15653 "[%d-%d]",
15654 glyph->u.cmp.from, glyph->u.cmp.to);
15655 fprintf (stderr, " . %4d %1.1d%1.1d\n",
15656 glyph->face_id,
15657 glyph->left_box_line_p,
15658 glyph->right_box_line_p);
15659 }
15660 }
15661
15662
15663 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15664 GLYPHS 0 means don't show glyph contents.
15665 GLYPHS 1 means show glyphs in short form
15666 GLYPHS > 1 means show glyphs in long form. */
15667
15668 void
15669 dump_glyph_row (row, vpos, glyphs)
15670 struct glyph_row *row;
15671 int vpos, glyphs;
15672 {
15673 if (glyphs != 1)
15674 {
15675 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15676 fprintf (stderr, "======================================================================\n");
15677
15678 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15679 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15680 vpos,
15681 MATRIX_ROW_START_CHARPOS (row),
15682 MATRIX_ROW_END_CHARPOS (row),
15683 row->used[TEXT_AREA],
15684 row->contains_overlapping_glyphs_p,
15685 row->enabled_p,
15686 row->truncated_on_left_p,
15687 row->truncated_on_right_p,
15688 row->continued_p,
15689 MATRIX_ROW_CONTINUATION_LINE_P (row),
15690 row->displays_text_p,
15691 row->ends_at_zv_p,
15692 row->fill_line_p,
15693 row->ends_in_middle_of_char_p,
15694 row->starts_in_middle_of_char_p,
15695 row->mouse_face_p,
15696 row->x,
15697 row->y,
15698 row->pixel_width,
15699 row->height,
15700 row->visible_height,
15701 row->ascent,
15702 row->phys_ascent);
15703 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15704 row->end.overlay_string_index,
15705 row->continuation_lines_width);
15706 fprintf (stderr, "%9d %5d\n",
15707 CHARPOS (row->start.string_pos),
15708 CHARPOS (row->end.string_pos));
15709 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15710 row->end.dpvec_index);
15711 }
15712
15713 if (glyphs > 1)
15714 {
15715 int area;
15716
15717 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15718 {
15719 struct glyph *glyph = row->glyphs[area];
15720 struct glyph *glyph_end = glyph + row->used[area];
15721
15722 /* Glyph for a line end in text. */
15723 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15724 ++glyph_end;
15725
15726 if (glyph < glyph_end)
15727 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15728
15729 for (; glyph < glyph_end; ++glyph)
15730 dump_glyph (row, glyph, area);
15731 }
15732 }
15733 else if (glyphs == 1)
15734 {
15735 int area;
15736
15737 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15738 {
15739 char *s = (char *) alloca (row->used[area] + 1);
15740 int i;
15741
15742 for (i = 0; i < row->used[area]; ++i)
15743 {
15744 struct glyph *glyph = row->glyphs[area] + i;
15745 if (glyph->type == CHAR_GLYPH
15746 && glyph->u.ch < 0x80
15747 && glyph->u.ch >= ' ')
15748 s[i] = glyph->u.ch;
15749 else
15750 s[i] = '.';
15751 }
15752
15753 s[i] = '\0';
15754 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15755 }
15756 }
15757 }
15758
15759
15760 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15761 Sdump_glyph_matrix, 0, 1, "p",
15762 doc: /* Dump the current matrix of the selected window to stderr.
15763 Shows contents of glyph row structures. With non-nil
15764 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15765 glyphs in short form, otherwise show glyphs in long form. */)
15766 (glyphs)
15767 Lisp_Object glyphs;
15768 {
15769 struct window *w = XWINDOW (selected_window);
15770 struct buffer *buffer = XBUFFER (w->buffer);
15771
15772 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15773 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15774 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15775 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15776 fprintf (stderr, "=============================================\n");
15777 dump_glyph_matrix (w->current_matrix,
15778 NILP (glyphs) ? 0 : XINT (glyphs));
15779 return Qnil;
15780 }
15781
15782
15783 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15784 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15785 ()
15786 {
15787 struct frame *f = XFRAME (selected_frame);
15788 dump_glyph_matrix (f->current_matrix, 1);
15789 return Qnil;
15790 }
15791
15792
15793 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15794 doc: /* Dump glyph row ROW to stderr.
15795 GLYPH 0 means don't dump glyphs.
15796 GLYPH 1 means dump glyphs in short form.
15797 GLYPH > 1 or omitted means dump glyphs in long form. */)
15798 (row, glyphs)
15799 Lisp_Object row, glyphs;
15800 {
15801 struct glyph_matrix *matrix;
15802 int vpos;
15803
15804 CHECK_NUMBER (row);
15805 matrix = XWINDOW (selected_window)->current_matrix;
15806 vpos = XINT (row);
15807 if (vpos >= 0 && vpos < matrix->nrows)
15808 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15809 vpos,
15810 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15811 return Qnil;
15812 }
15813
15814
15815 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15816 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15817 GLYPH 0 means don't dump glyphs.
15818 GLYPH 1 means dump glyphs in short form.
15819 GLYPH > 1 or omitted means dump glyphs in long form. */)
15820 (row, glyphs)
15821 Lisp_Object row, glyphs;
15822 {
15823 struct frame *sf = SELECTED_FRAME ();
15824 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15825 int vpos;
15826
15827 CHECK_NUMBER (row);
15828 vpos = XINT (row);
15829 if (vpos >= 0 && vpos < m->nrows)
15830 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15831 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15832 return Qnil;
15833 }
15834
15835
15836 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15837 doc: /* Toggle tracing of redisplay.
15838 With ARG, turn tracing on if and only if ARG is positive. */)
15839 (arg)
15840 Lisp_Object arg;
15841 {
15842 if (NILP (arg))
15843 trace_redisplay_p = !trace_redisplay_p;
15844 else
15845 {
15846 arg = Fprefix_numeric_value (arg);
15847 trace_redisplay_p = XINT (arg) > 0;
15848 }
15849
15850 return Qnil;
15851 }
15852
15853
15854 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15855 doc: /* Like `format', but print result to stderr.
15856 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15857 (nargs, args)
15858 int nargs;
15859 Lisp_Object *args;
15860 {
15861 Lisp_Object s = Fformat (nargs, args);
15862 fprintf (stderr, "%s", SDATA (s));
15863 return Qnil;
15864 }
15865
15866 #endif /* GLYPH_DEBUG */
15867
15868
15869 \f
15870 /***********************************************************************
15871 Building Desired Matrix Rows
15872 ***********************************************************************/
15873
15874 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15875 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15876
15877 static struct glyph_row *
15878 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15879 struct window *w;
15880 Lisp_Object overlay_arrow_string;
15881 {
15882 struct frame *f = XFRAME (WINDOW_FRAME (w));
15883 struct buffer *buffer = XBUFFER (w->buffer);
15884 struct buffer *old = current_buffer;
15885 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15886 int arrow_len = SCHARS (overlay_arrow_string);
15887 const unsigned char *arrow_end = arrow_string + arrow_len;
15888 const unsigned char *p;
15889 struct it it;
15890 int multibyte_p;
15891 int n_glyphs_before;
15892
15893 set_buffer_temp (buffer);
15894 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15895 it.glyph_row->used[TEXT_AREA] = 0;
15896 SET_TEXT_POS (it.position, 0, 0);
15897
15898 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15899 p = arrow_string;
15900 while (p < arrow_end)
15901 {
15902 Lisp_Object face, ilisp;
15903
15904 /* Get the next character. */
15905 if (multibyte_p)
15906 it.c = string_char_and_length (p, arrow_len, &it.len);
15907 else
15908 it.c = *p, it.len = 1;
15909 p += it.len;
15910
15911 /* Get its face. */
15912 ilisp = make_number (p - arrow_string);
15913 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15914 it.face_id = compute_char_face (f, it.c, face);
15915
15916 /* Compute its width, get its glyphs. */
15917 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15918 SET_TEXT_POS (it.position, -1, -1);
15919 PRODUCE_GLYPHS (&it);
15920
15921 /* If this character doesn't fit any more in the line, we have
15922 to remove some glyphs. */
15923 if (it.current_x > it.last_visible_x)
15924 {
15925 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15926 break;
15927 }
15928 }
15929
15930 set_buffer_temp (old);
15931 return it.glyph_row;
15932 }
15933
15934
15935 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15936 glyphs are only inserted for terminal frames since we can't really
15937 win with truncation glyphs when partially visible glyphs are
15938 involved. Which glyphs to insert is determined by
15939 produce_special_glyphs. */
15940
15941 static void
15942 insert_left_trunc_glyphs (it)
15943 struct it *it;
15944 {
15945 struct it truncate_it;
15946 struct glyph *from, *end, *to, *toend;
15947
15948 xassert (!FRAME_WINDOW_P (it->f));
15949
15950 /* Get the truncation glyphs. */
15951 truncate_it = *it;
15952 truncate_it.current_x = 0;
15953 truncate_it.face_id = DEFAULT_FACE_ID;
15954 truncate_it.glyph_row = &scratch_glyph_row;
15955 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15956 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15957 truncate_it.object = make_number (0);
15958 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15959
15960 /* Overwrite glyphs from IT with truncation glyphs. */
15961 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15962 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15963 to = it->glyph_row->glyphs[TEXT_AREA];
15964 toend = to + it->glyph_row->used[TEXT_AREA];
15965
15966 while (from < end)
15967 *to++ = *from++;
15968
15969 /* There may be padding glyphs left over. Overwrite them too. */
15970 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15971 {
15972 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15973 while (from < end)
15974 *to++ = *from++;
15975 }
15976
15977 if (to > toend)
15978 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15979 }
15980
15981
15982 /* Compute the pixel height and width of IT->glyph_row.
15983
15984 Most of the time, ascent and height of a display line will be equal
15985 to the max_ascent and max_height values of the display iterator
15986 structure. This is not the case if
15987
15988 1. We hit ZV without displaying anything. In this case, max_ascent
15989 and max_height will be zero.
15990
15991 2. We have some glyphs that don't contribute to the line height.
15992 (The glyph row flag contributes_to_line_height_p is for future
15993 pixmap extensions).
15994
15995 The first case is easily covered by using default values because in
15996 these cases, the line height does not really matter, except that it
15997 must not be zero. */
15998
15999 static void
16000 compute_line_metrics (it)
16001 struct it *it;
16002 {
16003 struct glyph_row *row = it->glyph_row;
16004 int area, i;
16005
16006 if (FRAME_WINDOW_P (it->f))
16007 {
16008 int i, min_y, max_y;
16009
16010 /* The line may consist of one space only, that was added to
16011 place the cursor on it. If so, the row's height hasn't been
16012 computed yet. */
16013 if (row->height == 0)
16014 {
16015 if (it->max_ascent + it->max_descent == 0)
16016 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16017 row->ascent = it->max_ascent;
16018 row->height = it->max_ascent + it->max_descent;
16019 row->phys_ascent = it->max_phys_ascent;
16020 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16021 row->extra_line_spacing = it->max_extra_line_spacing;
16022 }
16023
16024 /* Compute the width of this line. */
16025 row->pixel_width = row->x;
16026 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16027 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16028
16029 xassert (row->pixel_width >= 0);
16030 xassert (row->ascent >= 0 && row->height > 0);
16031
16032 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16033 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16034
16035 /* If first line's physical ascent is larger than its logical
16036 ascent, use the physical ascent, and make the row taller.
16037 This makes accented characters fully visible. */
16038 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16039 && row->phys_ascent > row->ascent)
16040 {
16041 row->height += row->phys_ascent - row->ascent;
16042 row->ascent = row->phys_ascent;
16043 }
16044
16045 /* Compute how much of the line is visible. */
16046 row->visible_height = row->height;
16047
16048 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16049 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16050
16051 if (row->y < min_y)
16052 row->visible_height -= min_y - row->y;
16053 if (row->y + row->height > max_y)
16054 row->visible_height -= row->y + row->height - max_y;
16055 }
16056 else
16057 {
16058 row->pixel_width = row->used[TEXT_AREA];
16059 if (row->continued_p)
16060 row->pixel_width -= it->continuation_pixel_width;
16061 else if (row->truncated_on_right_p)
16062 row->pixel_width -= it->truncation_pixel_width;
16063 row->ascent = row->phys_ascent = 0;
16064 row->height = row->phys_height = row->visible_height = 1;
16065 row->extra_line_spacing = 0;
16066 }
16067
16068 /* Compute a hash code for this row. */
16069 row->hash = 0;
16070 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16071 for (i = 0; i < row->used[area]; ++i)
16072 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16073 + row->glyphs[area][i].u.val
16074 + row->glyphs[area][i].face_id
16075 + row->glyphs[area][i].padding_p
16076 + (row->glyphs[area][i].type << 2));
16077
16078 it->max_ascent = it->max_descent = 0;
16079 it->max_phys_ascent = it->max_phys_descent = 0;
16080 }
16081
16082
16083 /* Append one space to the glyph row of iterator IT if doing a
16084 window-based redisplay. The space has the same face as
16085 IT->face_id. Value is non-zero if a space was added.
16086
16087 This function is called to make sure that there is always one glyph
16088 at the end of a glyph row that the cursor can be set on under
16089 window-systems. (If there weren't such a glyph we would not know
16090 how wide and tall a box cursor should be displayed).
16091
16092 At the same time this space let's a nicely handle clearing to the
16093 end of the line if the row ends in italic text. */
16094
16095 static int
16096 append_space_for_newline (it, default_face_p)
16097 struct it *it;
16098 int default_face_p;
16099 {
16100 if (FRAME_WINDOW_P (it->f))
16101 {
16102 int n = it->glyph_row->used[TEXT_AREA];
16103
16104 if (it->glyph_row->glyphs[TEXT_AREA] + n
16105 < it->glyph_row->glyphs[1 + TEXT_AREA])
16106 {
16107 /* Save some values that must not be changed.
16108 Must save IT->c and IT->len because otherwise
16109 ITERATOR_AT_END_P wouldn't work anymore after
16110 append_space_for_newline has been called. */
16111 enum display_element_type saved_what = it->what;
16112 int saved_c = it->c, saved_len = it->len;
16113 int saved_x = it->current_x;
16114 int saved_face_id = it->face_id;
16115 struct text_pos saved_pos;
16116 Lisp_Object saved_object;
16117 struct face *face;
16118
16119 saved_object = it->object;
16120 saved_pos = it->position;
16121
16122 it->what = IT_CHARACTER;
16123 bzero (&it->position, sizeof it->position);
16124 it->object = make_number (0);
16125 it->c = ' ';
16126 it->len = 1;
16127
16128 if (default_face_p)
16129 it->face_id = DEFAULT_FACE_ID;
16130 else if (it->face_before_selective_p)
16131 it->face_id = it->saved_face_id;
16132 face = FACE_FROM_ID (it->f, it->face_id);
16133 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16134
16135 PRODUCE_GLYPHS (it);
16136
16137 it->override_ascent = -1;
16138 it->constrain_row_ascent_descent_p = 0;
16139 it->current_x = saved_x;
16140 it->object = saved_object;
16141 it->position = saved_pos;
16142 it->what = saved_what;
16143 it->face_id = saved_face_id;
16144 it->len = saved_len;
16145 it->c = saved_c;
16146 return 1;
16147 }
16148 }
16149
16150 return 0;
16151 }
16152
16153
16154 /* Extend the face of the last glyph in the text area of IT->glyph_row
16155 to the end of the display line. Called from display_line.
16156 If the glyph row is empty, add a space glyph to it so that we
16157 know the face to draw. Set the glyph row flag fill_line_p. */
16158
16159 static void
16160 extend_face_to_end_of_line (it)
16161 struct it *it;
16162 {
16163 struct face *face;
16164 struct frame *f = it->f;
16165
16166 /* If line is already filled, do nothing. */
16167 if (it->current_x >= it->last_visible_x)
16168 return;
16169
16170 /* Face extension extends the background and box of IT->face_id
16171 to the end of the line. If the background equals the background
16172 of the frame, we don't have to do anything. */
16173 if (it->face_before_selective_p)
16174 face = FACE_FROM_ID (it->f, it->saved_face_id);
16175 else
16176 face = FACE_FROM_ID (f, it->face_id);
16177
16178 if (FRAME_WINDOW_P (f)
16179 && it->glyph_row->displays_text_p
16180 && face->box == FACE_NO_BOX
16181 && face->background == FRAME_BACKGROUND_PIXEL (f)
16182 && !face->stipple)
16183 return;
16184
16185 /* Set the glyph row flag indicating that the face of the last glyph
16186 in the text area has to be drawn to the end of the text area. */
16187 it->glyph_row->fill_line_p = 1;
16188
16189 /* If current character of IT is not ASCII, make sure we have the
16190 ASCII face. This will be automatically undone the next time
16191 get_next_display_element returns a multibyte character. Note
16192 that the character will always be single byte in unibyte
16193 text. */
16194 if (!ASCII_CHAR_P (it->c))
16195 {
16196 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16197 }
16198
16199 if (FRAME_WINDOW_P (f))
16200 {
16201 /* If the row is empty, add a space with the current face of IT,
16202 so that we know which face to draw. */
16203 if (it->glyph_row->used[TEXT_AREA] == 0)
16204 {
16205 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16206 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16207 it->glyph_row->used[TEXT_AREA] = 1;
16208 }
16209 }
16210 else
16211 {
16212 /* Save some values that must not be changed. */
16213 int saved_x = it->current_x;
16214 struct text_pos saved_pos;
16215 Lisp_Object saved_object;
16216 enum display_element_type saved_what = it->what;
16217 int saved_face_id = it->face_id;
16218
16219 saved_object = it->object;
16220 saved_pos = it->position;
16221
16222 it->what = IT_CHARACTER;
16223 bzero (&it->position, sizeof it->position);
16224 it->object = make_number (0);
16225 it->c = ' ';
16226 it->len = 1;
16227 it->face_id = face->id;
16228
16229 PRODUCE_GLYPHS (it);
16230
16231 while (it->current_x <= it->last_visible_x)
16232 PRODUCE_GLYPHS (it);
16233
16234 /* Don't count these blanks really. It would let us insert a left
16235 truncation glyph below and make us set the cursor on them, maybe. */
16236 it->current_x = saved_x;
16237 it->object = saved_object;
16238 it->position = saved_pos;
16239 it->what = saved_what;
16240 it->face_id = saved_face_id;
16241 }
16242 }
16243
16244
16245 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16246 trailing whitespace. */
16247
16248 static int
16249 trailing_whitespace_p (charpos)
16250 int charpos;
16251 {
16252 int bytepos = CHAR_TO_BYTE (charpos);
16253 int c = 0;
16254
16255 while (bytepos < ZV_BYTE
16256 && (c = FETCH_CHAR (bytepos),
16257 c == ' ' || c == '\t'))
16258 ++bytepos;
16259
16260 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16261 {
16262 if (bytepos != PT_BYTE)
16263 return 1;
16264 }
16265 return 0;
16266 }
16267
16268
16269 /* Highlight trailing whitespace, if any, in ROW. */
16270
16271 void
16272 highlight_trailing_whitespace (f, row)
16273 struct frame *f;
16274 struct glyph_row *row;
16275 {
16276 int used = row->used[TEXT_AREA];
16277
16278 if (used)
16279 {
16280 struct glyph *start = row->glyphs[TEXT_AREA];
16281 struct glyph *glyph = start + used - 1;
16282
16283 /* Skip over glyphs inserted to display the cursor at the
16284 end of a line, for extending the face of the last glyph
16285 to the end of the line on terminals, and for truncation
16286 and continuation glyphs. */
16287 while (glyph >= start
16288 && glyph->type == CHAR_GLYPH
16289 && INTEGERP (glyph->object))
16290 --glyph;
16291
16292 /* If last glyph is a space or stretch, and it's trailing
16293 whitespace, set the face of all trailing whitespace glyphs in
16294 IT->glyph_row to `trailing-whitespace'. */
16295 if (glyph >= start
16296 && BUFFERP (glyph->object)
16297 && (glyph->type == STRETCH_GLYPH
16298 || (glyph->type == CHAR_GLYPH
16299 && glyph->u.ch == ' '))
16300 && trailing_whitespace_p (glyph->charpos))
16301 {
16302 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16303 if (face_id < 0)
16304 return;
16305
16306 while (glyph >= start
16307 && BUFFERP (glyph->object)
16308 && (glyph->type == STRETCH_GLYPH
16309 || (glyph->type == CHAR_GLYPH
16310 && glyph->u.ch == ' ')))
16311 (glyph--)->face_id = face_id;
16312 }
16313 }
16314 }
16315
16316
16317 /* Value is non-zero if glyph row ROW in window W should be
16318 used to hold the cursor. */
16319
16320 static int
16321 cursor_row_p (w, row)
16322 struct window *w;
16323 struct glyph_row *row;
16324 {
16325 int cursor_row_p = 1;
16326
16327 if (PT == MATRIX_ROW_END_CHARPOS (row))
16328 {
16329 /* Suppose the row ends on a string.
16330 Unless the row is continued, that means it ends on a newline
16331 in the string. If it's anything other than a display string
16332 (e.g. a before-string from an overlay), we don't want the
16333 cursor there. (This heuristic seems to give the optimal
16334 behavior for the various types of multi-line strings.) */
16335 if (CHARPOS (row->end.string_pos) >= 0)
16336 {
16337 if (row->continued_p)
16338 cursor_row_p = 1;
16339 else
16340 {
16341 /* Check for `display' property. */
16342 struct glyph *beg = row->glyphs[TEXT_AREA];
16343 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
16344 struct glyph *glyph;
16345
16346 cursor_row_p = 0;
16347 for (glyph = end; glyph >= beg; --glyph)
16348 if (STRINGP (glyph->object))
16349 {
16350 Lisp_Object prop
16351 = Fget_char_property (make_number (PT),
16352 Qdisplay, Qnil);
16353 cursor_row_p =
16354 (!NILP (prop)
16355 && display_prop_string_p (prop, glyph->object));
16356 break;
16357 }
16358 }
16359 }
16360 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16361 {
16362 /* If the row ends in middle of a real character,
16363 and the line is continued, we want the cursor here.
16364 That's because MATRIX_ROW_END_CHARPOS would equal
16365 PT if PT is before the character. */
16366 if (!row->ends_in_ellipsis_p)
16367 cursor_row_p = row->continued_p;
16368 else
16369 /* If the row ends in an ellipsis, then
16370 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
16371 We want that position to be displayed after the ellipsis. */
16372 cursor_row_p = 0;
16373 }
16374 /* If the row ends at ZV, display the cursor at the end of that
16375 row instead of at the start of the row below. */
16376 else if (row->ends_at_zv_p)
16377 cursor_row_p = 1;
16378 else
16379 cursor_row_p = 0;
16380 }
16381
16382 return cursor_row_p;
16383 }
16384
16385 \f
16386
16387 /* Push the display property PROP so that it will be rendered at the
16388 current position in IT. */
16389
16390 static void
16391 push_display_prop (struct it *it, Lisp_Object prop)
16392 {
16393 push_it (it);
16394
16395 /* Never display a cursor on the prefix. */
16396 it->avoid_cursor_p = 1;
16397
16398 if (STRINGP (prop))
16399 {
16400 if (SCHARS (prop) == 0)
16401 {
16402 pop_it (it);
16403 return;
16404 }
16405
16406 it->string = prop;
16407 it->multibyte_p = STRING_MULTIBYTE (it->string);
16408 it->current.overlay_string_index = -1;
16409 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
16410 it->end_charpos = it->string_nchars = SCHARS (it->string);
16411 it->method = GET_FROM_STRING;
16412 it->stop_charpos = 0;
16413 }
16414 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
16415 {
16416 it->method = GET_FROM_STRETCH;
16417 it->object = prop;
16418 }
16419 #ifdef HAVE_WINDOW_SYSTEM
16420 else if (IMAGEP (prop))
16421 {
16422 it->what = IT_IMAGE;
16423 it->image_id = lookup_image (it->f, prop);
16424 it->method = GET_FROM_IMAGE;
16425 }
16426 #endif /* HAVE_WINDOW_SYSTEM */
16427 else
16428 {
16429 pop_it (it); /* bogus display property, give up */
16430 return;
16431 }
16432 }
16433
16434 /* Return the character-property PROP at the current position in IT. */
16435
16436 static Lisp_Object
16437 get_it_property (it, prop)
16438 struct it *it;
16439 Lisp_Object prop;
16440 {
16441 Lisp_Object position;
16442
16443 if (STRINGP (it->object))
16444 position = make_number (IT_STRING_CHARPOS (*it));
16445 else if (BUFFERP (it->object))
16446 position = make_number (IT_CHARPOS (*it));
16447 else
16448 return Qnil;
16449
16450 return Fget_char_property (position, prop, it->object);
16451 }
16452
16453 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
16454
16455 static void
16456 handle_line_prefix (struct it *it)
16457 {
16458 Lisp_Object prefix;
16459 if (it->continuation_lines_width > 0)
16460 {
16461 prefix = get_it_property (it, Qwrap_prefix);
16462 if (NILP (prefix))
16463 prefix = Vwrap_prefix;
16464 }
16465 else
16466 {
16467 prefix = get_it_property (it, Qline_prefix);
16468 if (NILP (prefix))
16469 prefix = Vline_prefix;
16470 }
16471 if (! NILP (prefix))
16472 {
16473 push_display_prop (it, prefix);
16474 /* If the prefix is wider than the window, and we try to wrap
16475 it, it would acquire its own wrap prefix, and so on till the
16476 iterator stack overflows. So, don't wrap the prefix. */
16477 it->line_wrap = TRUNCATE;
16478 }
16479 }
16480
16481 \f
16482
16483 /* Construct the glyph row IT->glyph_row in the desired matrix of
16484 IT->w from text at the current position of IT. See dispextern.h
16485 for an overview of struct it. Value is non-zero if
16486 IT->glyph_row displays text, as opposed to a line displaying ZV
16487 only. */
16488
16489 static int
16490 display_line (it)
16491 struct it *it;
16492 {
16493 struct glyph_row *row = it->glyph_row;
16494 Lisp_Object overlay_arrow_string;
16495 struct it wrap_it;
16496 int may_wrap = 0, wrap_x;
16497 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
16498 int wrap_row_phys_ascent, wrap_row_phys_height;
16499 int wrap_row_extra_line_spacing;
16500
16501 /* We always start displaying at hpos zero even if hscrolled. */
16502 xassert (it->hpos == 0 && it->current_x == 0);
16503
16504 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
16505 >= it->w->desired_matrix->nrows)
16506 {
16507 it->w->nrows_scale_factor++;
16508 fonts_changed_p = 1;
16509 return 0;
16510 }
16511
16512 /* Is IT->w showing the region? */
16513 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
16514
16515 /* Clear the result glyph row and enable it. */
16516 prepare_desired_row (row);
16517
16518 row->y = it->current_y;
16519 row->start = it->start;
16520 row->continuation_lines_width = it->continuation_lines_width;
16521 row->displays_text_p = 1;
16522 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
16523 it->starts_in_middle_of_char_p = 0;
16524
16525 /* Arrange the overlays nicely for our purposes. Usually, we call
16526 display_line on only one line at a time, in which case this
16527 can't really hurt too much, or we call it on lines which appear
16528 one after another in the buffer, in which case all calls to
16529 recenter_overlay_lists but the first will be pretty cheap. */
16530 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16531
16532 /* Move over display elements that are not visible because we are
16533 hscrolled. This may stop at an x-position < IT->first_visible_x
16534 if the first glyph is partially visible or if we hit a line end. */
16535 if (it->current_x < it->first_visible_x)
16536 {
16537 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16538 MOVE_TO_POS | MOVE_TO_X);
16539 }
16540 else
16541 {
16542 /* We only do this when not calling `move_it_in_display_line_to'
16543 above, because move_it_in_display_line_to calls
16544 handle_line_prefix itself. */
16545 handle_line_prefix (it);
16546 }
16547
16548 /* Get the initial row height. This is either the height of the
16549 text hscrolled, if there is any, or zero. */
16550 row->ascent = it->max_ascent;
16551 row->height = it->max_ascent + it->max_descent;
16552 row->phys_ascent = it->max_phys_ascent;
16553 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16554 row->extra_line_spacing = it->max_extra_line_spacing;
16555
16556 /* Loop generating characters. The loop is left with IT on the next
16557 character to display. */
16558 while (1)
16559 {
16560 int n_glyphs_before, hpos_before, x_before;
16561 int x, i, nglyphs;
16562 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16563
16564 /* Retrieve the next thing to display. Value is zero if end of
16565 buffer reached. */
16566 if (!get_next_display_element (it))
16567 {
16568 /* Maybe add a space at the end of this line that is used to
16569 display the cursor there under X. Set the charpos of the
16570 first glyph of blank lines not corresponding to any text
16571 to -1. */
16572 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16573 row->exact_window_width_line_p = 1;
16574 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16575 || row->used[TEXT_AREA] == 0)
16576 {
16577 row->glyphs[TEXT_AREA]->charpos = -1;
16578 row->displays_text_p = 0;
16579
16580 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16581 && (!MINI_WINDOW_P (it->w)
16582 || (minibuf_level && EQ (it->window, minibuf_window))))
16583 row->indicate_empty_line_p = 1;
16584 }
16585
16586 it->continuation_lines_width = 0;
16587 row->ends_at_zv_p = 1;
16588 break;
16589 }
16590
16591 /* Now, get the metrics of what we want to display. This also
16592 generates glyphs in `row' (which is IT->glyph_row). */
16593 n_glyphs_before = row->used[TEXT_AREA];
16594 x = it->current_x;
16595
16596 /* Remember the line height so far in case the next element doesn't
16597 fit on the line. */
16598 if (it->line_wrap != TRUNCATE)
16599 {
16600 ascent = it->max_ascent;
16601 descent = it->max_descent;
16602 phys_ascent = it->max_phys_ascent;
16603 phys_descent = it->max_phys_descent;
16604
16605 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
16606 {
16607 if (IT_DISPLAYING_WHITESPACE (it))
16608 may_wrap = 1;
16609 else if (may_wrap)
16610 {
16611 wrap_it = *it;
16612 wrap_x = x;
16613 wrap_row_used = row->used[TEXT_AREA];
16614 wrap_row_ascent = row->ascent;
16615 wrap_row_height = row->height;
16616 wrap_row_phys_ascent = row->phys_ascent;
16617 wrap_row_phys_height = row->phys_height;
16618 wrap_row_extra_line_spacing = row->extra_line_spacing;
16619 may_wrap = 0;
16620 }
16621 }
16622 }
16623
16624 PRODUCE_GLYPHS (it);
16625
16626 /* If this display element was in marginal areas, continue with
16627 the next one. */
16628 if (it->area != TEXT_AREA)
16629 {
16630 row->ascent = max (row->ascent, it->max_ascent);
16631 row->height = max (row->height, it->max_ascent + it->max_descent);
16632 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16633 row->phys_height = max (row->phys_height,
16634 it->max_phys_ascent + it->max_phys_descent);
16635 row->extra_line_spacing = max (row->extra_line_spacing,
16636 it->max_extra_line_spacing);
16637 set_iterator_to_next (it, 1);
16638 continue;
16639 }
16640
16641 /* Does the display element fit on the line? If we truncate
16642 lines, we should draw past the right edge of the window. If
16643 we don't truncate, we want to stop so that we can display the
16644 continuation glyph before the right margin. If lines are
16645 continued, there are two possible strategies for characters
16646 resulting in more than 1 glyph (e.g. tabs): Display as many
16647 glyphs as possible in this line and leave the rest for the
16648 continuation line, or display the whole element in the next
16649 line. Original redisplay did the former, so we do it also. */
16650 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16651 hpos_before = it->hpos;
16652 x_before = x;
16653
16654 if (/* Not a newline. */
16655 nglyphs > 0
16656 /* Glyphs produced fit entirely in the line. */
16657 && it->current_x < it->last_visible_x)
16658 {
16659 it->hpos += nglyphs;
16660 row->ascent = max (row->ascent, it->max_ascent);
16661 row->height = max (row->height, it->max_ascent + it->max_descent);
16662 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16663 row->phys_height = max (row->phys_height,
16664 it->max_phys_ascent + it->max_phys_descent);
16665 row->extra_line_spacing = max (row->extra_line_spacing,
16666 it->max_extra_line_spacing);
16667 if (it->current_x - it->pixel_width < it->first_visible_x)
16668 row->x = x - it->first_visible_x;
16669 }
16670 else
16671 {
16672 int new_x;
16673 struct glyph *glyph;
16674
16675 for (i = 0; i < nglyphs; ++i, x = new_x)
16676 {
16677 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16678 new_x = x + glyph->pixel_width;
16679
16680 if (/* Lines are continued. */
16681 it->line_wrap != TRUNCATE
16682 && (/* Glyph doesn't fit on the line. */
16683 new_x > it->last_visible_x
16684 /* Or it fits exactly on a window system frame. */
16685 || (new_x == it->last_visible_x
16686 && FRAME_WINDOW_P (it->f))))
16687 {
16688 /* End of a continued line. */
16689
16690 if (it->hpos == 0
16691 || (new_x == it->last_visible_x
16692 && FRAME_WINDOW_P (it->f)))
16693 {
16694 /* Current glyph is the only one on the line or
16695 fits exactly on the line. We must continue
16696 the line because we can't draw the cursor
16697 after the glyph. */
16698 row->continued_p = 1;
16699 it->current_x = new_x;
16700 it->continuation_lines_width += new_x;
16701 ++it->hpos;
16702 if (i == nglyphs - 1)
16703 {
16704 /* If line-wrap is on, check if a previous
16705 wrap point was found. */
16706 if (wrap_row_used > 0
16707 /* Even if there is a previous wrap
16708 point, continue the line here as
16709 usual, if (i) the previous character
16710 was a space or tab AND (ii) the
16711 current character is not. */
16712 && (!may_wrap
16713 || IT_DISPLAYING_WHITESPACE (it)))
16714 goto back_to_wrap;
16715
16716 set_iterator_to_next (it, 1);
16717 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16718 {
16719 if (!get_next_display_element (it))
16720 {
16721 row->exact_window_width_line_p = 1;
16722 it->continuation_lines_width = 0;
16723 row->continued_p = 0;
16724 row->ends_at_zv_p = 1;
16725 }
16726 else if (ITERATOR_AT_END_OF_LINE_P (it))
16727 {
16728 row->continued_p = 0;
16729 row->exact_window_width_line_p = 1;
16730 }
16731 }
16732 }
16733 }
16734 else if (CHAR_GLYPH_PADDING_P (*glyph)
16735 && !FRAME_WINDOW_P (it->f))
16736 {
16737 /* A padding glyph that doesn't fit on this line.
16738 This means the whole character doesn't fit
16739 on the line. */
16740 row->used[TEXT_AREA] = n_glyphs_before;
16741
16742 /* Fill the rest of the row with continuation
16743 glyphs like in 20.x. */
16744 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16745 < row->glyphs[1 + TEXT_AREA])
16746 produce_special_glyphs (it, IT_CONTINUATION);
16747
16748 row->continued_p = 1;
16749 it->current_x = x_before;
16750 it->continuation_lines_width += x_before;
16751
16752 /* Restore the height to what it was before the
16753 element not fitting on the line. */
16754 it->max_ascent = ascent;
16755 it->max_descent = descent;
16756 it->max_phys_ascent = phys_ascent;
16757 it->max_phys_descent = phys_descent;
16758 }
16759 else if (wrap_row_used > 0)
16760 {
16761 back_to_wrap:
16762 *it = wrap_it;
16763 it->continuation_lines_width += wrap_x;
16764 row->used[TEXT_AREA] = wrap_row_used;
16765 row->ascent = wrap_row_ascent;
16766 row->height = wrap_row_height;
16767 row->phys_ascent = wrap_row_phys_ascent;
16768 row->phys_height = wrap_row_phys_height;
16769 row->extra_line_spacing = wrap_row_extra_line_spacing;
16770 row->continued_p = 1;
16771 row->ends_at_zv_p = 0;
16772 row->exact_window_width_line_p = 0;
16773 it->continuation_lines_width += x;
16774
16775 /* Make sure that a non-default face is extended
16776 up to the right margin of the window. */
16777 extend_face_to_end_of_line (it);
16778 }
16779 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16780 {
16781 /* A TAB that extends past the right edge of the
16782 window. This produces a single glyph on
16783 window system frames. We leave the glyph in
16784 this row and let it fill the row, but don't
16785 consume the TAB. */
16786 it->continuation_lines_width += it->last_visible_x;
16787 row->ends_in_middle_of_char_p = 1;
16788 row->continued_p = 1;
16789 glyph->pixel_width = it->last_visible_x - x;
16790 it->starts_in_middle_of_char_p = 1;
16791 }
16792 else
16793 {
16794 /* Something other than a TAB that draws past
16795 the right edge of the window. Restore
16796 positions to values before the element. */
16797 row->used[TEXT_AREA] = n_glyphs_before + i;
16798
16799 /* Display continuation glyphs. */
16800 if (!FRAME_WINDOW_P (it->f))
16801 produce_special_glyphs (it, IT_CONTINUATION);
16802 row->continued_p = 1;
16803
16804 it->current_x = x_before;
16805 it->continuation_lines_width += x;
16806 extend_face_to_end_of_line (it);
16807
16808 if (nglyphs > 1 && i > 0)
16809 {
16810 row->ends_in_middle_of_char_p = 1;
16811 it->starts_in_middle_of_char_p = 1;
16812 }
16813
16814 /* Restore the height to what it was before the
16815 element not fitting on the line. */
16816 it->max_ascent = ascent;
16817 it->max_descent = descent;
16818 it->max_phys_ascent = phys_ascent;
16819 it->max_phys_descent = phys_descent;
16820 }
16821
16822 break;
16823 }
16824 else if (new_x > it->first_visible_x)
16825 {
16826 /* Increment number of glyphs actually displayed. */
16827 ++it->hpos;
16828
16829 if (x < it->first_visible_x)
16830 /* Glyph is partially visible, i.e. row starts at
16831 negative X position. */
16832 row->x = x - it->first_visible_x;
16833 }
16834 else
16835 {
16836 /* Glyph is completely off the left margin of the
16837 window. This should not happen because of the
16838 move_it_in_display_line at the start of this
16839 function, unless the text display area of the
16840 window is empty. */
16841 xassert (it->first_visible_x <= it->last_visible_x);
16842 }
16843 }
16844
16845 row->ascent = max (row->ascent, it->max_ascent);
16846 row->height = max (row->height, it->max_ascent + it->max_descent);
16847 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16848 row->phys_height = max (row->phys_height,
16849 it->max_phys_ascent + it->max_phys_descent);
16850 row->extra_line_spacing = max (row->extra_line_spacing,
16851 it->max_extra_line_spacing);
16852
16853 /* End of this display line if row is continued. */
16854 if (row->continued_p || row->ends_at_zv_p)
16855 break;
16856 }
16857
16858 at_end_of_line:
16859 /* Is this a line end? If yes, we're also done, after making
16860 sure that a non-default face is extended up to the right
16861 margin of the window. */
16862 if (ITERATOR_AT_END_OF_LINE_P (it))
16863 {
16864 int used_before = row->used[TEXT_AREA];
16865
16866 row->ends_in_newline_from_string_p = STRINGP (it->object);
16867
16868 /* Add a space at the end of the line that is used to
16869 display the cursor there. */
16870 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16871 append_space_for_newline (it, 0);
16872
16873 /* Extend the face to the end of the line. */
16874 extend_face_to_end_of_line (it);
16875
16876 /* Make sure we have the position. */
16877 if (used_before == 0)
16878 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16879
16880 /* Consume the line end. This skips over invisible lines. */
16881 set_iterator_to_next (it, 1);
16882 it->continuation_lines_width = 0;
16883 break;
16884 }
16885
16886 /* Proceed with next display element. Note that this skips
16887 over lines invisible because of selective display. */
16888 set_iterator_to_next (it, 1);
16889
16890 /* If we truncate lines, we are done when the last displayed
16891 glyphs reach past the right margin of the window. */
16892 if (it->line_wrap == TRUNCATE
16893 && (FRAME_WINDOW_P (it->f)
16894 ? (it->current_x >= it->last_visible_x)
16895 : (it->current_x > it->last_visible_x)))
16896 {
16897 /* Maybe add truncation glyphs. */
16898 if (!FRAME_WINDOW_P (it->f))
16899 {
16900 int i, n;
16901
16902 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16903 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16904 break;
16905
16906 for (n = row->used[TEXT_AREA]; i < n; ++i)
16907 {
16908 row->used[TEXT_AREA] = i;
16909 produce_special_glyphs (it, IT_TRUNCATION);
16910 }
16911 }
16912 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16913 {
16914 /* Don't truncate if we can overflow newline into fringe. */
16915 if (!get_next_display_element (it))
16916 {
16917 it->continuation_lines_width = 0;
16918 row->ends_at_zv_p = 1;
16919 row->exact_window_width_line_p = 1;
16920 break;
16921 }
16922 if (ITERATOR_AT_END_OF_LINE_P (it))
16923 {
16924 row->exact_window_width_line_p = 1;
16925 goto at_end_of_line;
16926 }
16927 }
16928
16929 row->truncated_on_right_p = 1;
16930 it->continuation_lines_width = 0;
16931 reseat_at_next_visible_line_start (it, 0);
16932 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16933 it->hpos = hpos_before;
16934 it->current_x = x_before;
16935 break;
16936 }
16937 }
16938
16939 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16940 at the left window margin. */
16941 if (it->first_visible_x
16942 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16943 {
16944 if (!FRAME_WINDOW_P (it->f))
16945 insert_left_trunc_glyphs (it);
16946 row->truncated_on_left_p = 1;
16947 }
16948
16949 /* If the start of this line is the overlay arrow-position, then
16950 mark this glyph row as the one containing the overlay arrow.
16951 This is clearly a mess with variable size fonts. It would be
16952 better to let it be displayed like cursors under X. */
16953 if ((row->displays_text_p || !overlay_arrow_seen)
16954 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16955 !NILP (overlay_arrow_string)))
16956 {
16957 /* Overlay arrow in window redisplay is a fringe bitmap. */
16958 if (STRINGP (overlay_arrow_string))
16959 {
16960 struct glyph_row *arrow_row
16961 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16962 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16963 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16964 struct glyph *p = row->glyphs[TEXT_AREA];
16965 struct glyph *p2, *end;
16966
16967 /* Copy the arrow glyphs. */
16968 while (glyph < arrow_end)
16969 *p++ = *glyph++;
16970
16971 /* Throw away padding glyphs. */
16972 p2 = p;
16973 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16974 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16975 ++p2;
16976 if (p2 > p)
16977 {
16978 while (p2 < end)
16979 *p++ = *p2++;
16980 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16981 }
16982 }
16983 else
16984 {
16985 xassert (INTEGERP (overlay_arrow_string));
16986 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16987 }
16988 overlay_arrow_seen = 1;
16989 }
16990
16991 /* Compute pixel dimensions of this line. */
16992 compute_line_metrics (it);
16993
16994 /* Remember the position at which this line ends. */
16995 row->end = it->current;
16996
16997 /* Record whether this row ends inside an ellipsis. */
16998 row->ends_in_ellipsis_p
16999 = (it->method == GET_FROM_DISPLAY_VECTOR
17000 && it->ellipsis_p);
17001
17002 /* Save fringe bitmaps in this row. */
17003 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17004 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17005 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17006 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17007
17008 it->left_user_fringe_bitmap = 0;
17009 it->left_user_fringe_face_id = 0;
17010 it->right_user_fringe_bitmap = 0;
17011 it->right_user_fringe_face_id = 0;
17012
17013 /* Maybe set the cursor. */
17014 if (it->w->cursor.vpos < 0
17015 && PT >= MATRIX_ROW_START_CHARPOS (row)
17016 && PT <= MATRIX_ROW_END_CHARPOS (row)
17017 && cursor_row_p (it->w, row))
17018 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17019
17020 /* Highlight trailing whitespace. */
17021 if (!NILP (Vshow_trailing_whitespace))
17022 highlight_trailing_whitespace (it->f, it->glyph_row);
17023
17024 /* Prepare for the next line. This line starts horizontally at (X
17025 HPOS) = (0 0). Vertical positions are incremented. As a
17026 convenience for the caller, IT->glyph_row is set to the next
17027 row to be used. */
17028 it->current_x = it->hpos = 0;
17029 it->current_y += row->height;
17030 ++it->vpos;
17031 ++it->glyph_row;
17032 it->start = it->current;
17033 return row->displays_text_p;
17034 }
17035
17036
17037 \f
17038 /***********************************************************************
17039 Menu Bar
17040 ***********************************************************************/
17041
17042 /* Redisplay the menu bar in the frame for window W.
17043
17044 The menu bar of X frames that don't have X toolkit support is
17045 displayed in a special window W->frame->menu_bar_window.
17046
17047 The menu bar of terminal frames is treated specially as far as
17048 glyph matrices are concerned. Menu bar lines are not part of
17049 windows, so the update is done directly on the frame matrix rows
17050 for the menu bar. */
17051
17052 static void
17053 display_menu_bar (w)
17054 struct window *w;
17055 {
17056 struct frame *f = XFRAME (WINDOW_FRAME (w));
17057 struct it it;
17058 Lisp_Object items;
17059 int i;
17060
17061 /* Don't do all this for graphical frames. */
17062 #ifdef HAVE_NTGUI
17063 if (FRAME_W32_P (f))
17064 return;
17065 #endif
17066 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
17067 if (FRAME_X_P (f))
17068 return;
17069 #endif
17070
17071 #ifdef HAVE_NS
17072 if (FRAME_NS_P (f))
17073 return;
17074 #endif /* HAVE_NS */
17075
17076 #ifdef USE_X_TOOLKIT
17077 xassert (!FRAME_WINDOW_P (f));
17078 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
17079 it.first_visible_x = 0;
17080 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
17081 #else /* not USE_X_TOOLKIT */
17082 if (FRAME_WINDOW_P (f))
17083 {
17084 /* Menu bar lines are displayed in the desired matrix of the
17085 dummy window menu_bar_window. */
17086 struct window *menu_w;
17087 xassert (WINDOWP (f->menu_bar_window));
17088 menu_w = XWINDOW (f->menu_bar_window);
17089 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
17090 MENU_FACE_ID);
17091 it.first_visible_x = 0;
17092 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
17093 }
17094 else
17095 {
17096 /* This is a TTY frame, i.e. character hpos/vpos are used as
17097 pixel x/y. */
17098 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
17099 MENU_FACE_ID);
17100 it.first_visible_x = 0;
17101 it.last_visible_x = FRAME_COLS (f);
17102 }
17103 #endif /* not USE_X_TOOLKIT */
17104
17105 if (! mode_line_inverse_video)
17106 /* Force the menu-bar to be displayed in the default face. */
17107 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
17108
17109 /* Clear all rows of the menu bar. */
17110 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
17111 {
17112 struct glyph_row *row = it.glyph_row + i;
17113 clear_glyph_row (row);
17114 row->enabled_p = 1;
17115 row->full_width_p = 1;
17116 }
17117
17118 /* Display all items of the menu bar. */
17119 items = FRAME_MENU_BAR_ITEMS (it.f);
17120 for (i = 0; i < XVECTOR (items)->size; i += 4)
17121 {
17122 Lisp_Object string;
17123
17124 /* Stop at nil string. */
17125 string = AREF (items, i + 1);
17126 if (NILP (string))
17127 break;
17128
17129 /* Remember where item was displayed. */
17130 ASET (items, i + 3, make_number (it.hpos));
17131
17132 /* Display the item, pad with one space. */
17133 if (it.current_x < it.last_visible_x)
17134 display_string (NULL, string, Qnil, 0, 0, &it,
17135 SCHARS (string) + 1, 0, 0, -1);
17136 }
17137
17138 /* Fill out the line with spaces. */
17139 if (it.current_x < it.last_visible_x)
17140 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
17141
17142 /* Compute the total height of the lines. */
17143 compute_line_metrics (&it);
17144 }
17145
17146
17147 \f
17148 /***********************************************************************
17149 Mode Line
17150 ***********************************************************************/
17151
17152 /* Redisplay mode lines in the window tree whose root is WINDOW. If
17153 FORCE is non-zero, redisplay mode lines unconditionally.
17154 Otherwise, redisplay only mode lines that are garbaged. Value is
17155 the number of windows whose mode lines were redisplayed. */
17156
17157 static int
17158 redisplay_mode_lines (window, force)
17159 Lisp_Object window;
17160 int force;
17161 {
17162 int nwindows = 0;
17163
17164 while (!NILP (window))
17165 {
17166 struct window *w = XWINDOW (window);
17167
17168 if (WINDOWP (w->hchild))
17169 nwindows += redisplay_mode_lines (w->hchild, force);
17170 else if (WINDOWP (w->vchild))
17171 nwindows += redisplay_mode_lines (w->vchild, force);
17172 else if (force
17173 || FRAME_GARBAGED_P (XFRAME (w->frame))
17174 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
17175 {
17176 struct text_pos lpoint;
17177 struct buffer *old = current_buffer;
17178
17179 /* Set the window's buffer for the mode line display. */
17180 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17181 set_buffer_internal_1 (XBUFFER (w->buffer));
17182
17183 /* Point refers normally to the selected window. For any
17184 other window, set up appropriate value. */
17185 if (!EQ (window, selected_window))
17186 {
17187 struct text_pos pt;
17188
17189 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
17190 if (CHARPOS (pt) < BEGV)
17191 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17192 else if (CHARPOS (pt) > (ZV - 1))
17193 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
17194 else
17195 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
17196 }
17197
17198 /* Display mode lines. */
17199 clear_glyph_matrix (w->desired_matrix);
17200 if (display_mode_lines (w))
17201 {
17202 ++nwindows;
17203 w->must_be_updated_p = 1;
17204 }
17205
17206 /* Restore old settings. */
17207 set_buffer_internal_1 (old);
17208 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17209 }
17210
17211 window = w->next;
17212 }
17213
17214 return nwindows;
17215 }
17216
17217
17218 /* Display the mode and/or header line of window W. Value is the
17219 sum number of mode lines and header lines displayed. */
17220
17221 static int
17222 display_mode_lines (w)
17223 struct window *w;
17224 {
17225 Lisp_Object old_selected_window, old_selected_frame;
17226 int n = 0;
17227
17228 old_selected_frame = selected_frame;
17229 selected_frame = w->frame;
17230 old_selected_window = selected_window;
17231 XSETWINDOW (selected_window, w);
17232
17233 /* These will be set while the mode line specs are processed. */
17234 line_number_displayed = 0;
17235 w->column_number_displayed = Qnil;
17236
17237 if (WINDOW_WANTS_MODELINE_P (w))
17238 {
17239 struct window *sel_w = XWINDOW (old_selected_window);
17240
17241 /* Select mode line face based on the real selected window. */
17242 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
17243 current_buffer->mode_line_format);
17244 ++n;
17245 }
17246
17247 if (WINDOW_WANTS_HEADER_LINE_P (w))
17248 {
17249 display_mode_line (w, HEADER_LINE_FACE_ID,
17250 current_buffer->header_line_format);
17251 ++n;
17252 }
17253
17254 selected_frame = old_selected_frame;
17255 selected_window = old_selected_window;
17256 return n;
17257 }
17258
17259
17260 /* Display mode or header line of window W. FACE_ID specifies which
17261 line to display; it is either MODE_LINE_FACE_ID or
17262 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
17263 display. Value is the pixel height of the mode/header line
17264 displayed. */
17265
17266 static int
17267 display_mode_line (w, face_id, format)
17268 struct window *w;
17269 enum face_id face_id;
17270 Lisp_Object format;
17271 {
17272 struct it it;
17273 struct face *face;
17274 int count = SPECPDL_INDEX ();
17275
17276 init_iterator (&it, w, -1, -1, NULL, face_id);
17277 /* Don't extend on a previously drawn mode-line.
17278 This may happen if called from pos_visible_p. */
17279 it.glyph_row->enabled_p = 0;
17280 prepare_desired_row (it.glyph_row);
17281
17282 it.glyph_row->mode_line_p = 1;
17283
17284 if (! mode_line_inverse_video)
17285 /* Force the mode-line to be displayed in the default face. */
17286 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
17287
17288 record_unwind_protect (unwind_format_mode_line,
17289 format_mode_line_unwind_data (NULL, Qnil, 0));
17290
17291 mode_line_target = MODE_LINE_DISPLAY;
17292
17293 /* Temporarily make frame's keyboard the current kboard so that
17294 kboard-local variables in the mode_line_format will get the right
17295 values. */
17296 push_kboard (FRAME_KBOARD (it.f));
17297 record_unwind_save_match_data ();
17298 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17299 pop_kboard ();
17300
17301 unbind_to (count, Qnil);
17302
17303 /* Fill up with spaces. */
17304 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
17305
17306 compute_line_metrics (&it);
17307 it.glyph_row->full_width_p = 1;
17308 it.glyph_row->continued_p = 0;
17309 it.glyph_row->truncated_on_left_p = 0;
17310 it.glyph_row->truncated_on_right_p = 0;
17311
17312 /* Make a 3D mode-line have a shadow at its right end. */
17313 face = FACE_FROM_ID (it.f, face_id);
17314 extend_face_to_end_of_line (&it);
17315 if (face->box != FACE_NO_BOX)
17316 {
17317 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
17318 + it.glyph_row->used[TEXT_AREA] - 1);
17319 last->right_box_line_p = 1;
17320 }
17321
17322 return it.glyph_row->height;
17323 }
17324
17325 /* Move element ELT in LIST to the front of LIST.
17326 Return the updated list. */
17327
17328 static Lisp_Object
17329 move_elt_to_front (elt, list)
17330 Lisp_Object elt, list;
17331 {
17332 register Lisp_Object tail, prev;
17333 register Lisp_Object tem;
17334
17335 tail = list;
17336 prev = Qnil;
17337 while (CONSP (tail))
17338 {
17339 tem = XCAR (tail);
17340
17341 if (EQ (elt, tem))
17342 {
17343 /* Splice out the link TAIL. */
17344 if (NILP (prev))
17345 list = XCDR (tail);
17346 else
17347 Fsetcdr (prev, XCDR (tail));
17348
17349 /* Now make it the first. */
17350 Fsetcdr (tail, list);
17351 return tail;
17352 }
17353 else
17354 prev = tail;
17355 tail = XCDR (tail);
17356 QUIT;
17357 }
17358
17359 /* Not found--return unchanged LIST. */
17360 return list;
17361 }
17362
17363 /* Contribute ELT to the mode line for window IT->w. How it
17364 translates into text depends on its data type.
17365
17366 IT describes the display environment in which we display, as usual.
17367
17368 DEPTH is the depth in recursion. It is used to prevent
17369 infinite recursion here.
17370
17371 FIELD_WIDTH is the number of characters the display of ELT should
17372 occupy in the mode line, and PRECISION is the maximum number of
17373 characters to display from ELT's representation. See
17374 display_string for details.
17375
17376 Returns the hpos of the end of the text generated by ELT.
17377
17378 PROPS is a property list to add to any string we encounter.
17379
17380 If RISKY is nonzero, remove (disregard) any properties in any string
17381 we encounter, and ignore :eval and :propertize.
17382
17383 The global variable `mode_line_target' determines whether the
17384 output is passed to `store_mode_line_noprop',
17385 `store_mode_line_string', or `display_string'. */
17386
17387 static int
17388 display_mode_element (it, depth, field_width, precision, elt, props, risky)
17389 struct it *it;
17390 int depth;
17391 int field_width, precision;
17392 Lisp_Object elt, props;
17393 int risky;
17394 {
17395 int n = 0, field, prec;
17396 int literal = 0;
17397
17398 tail_recurse:
17399 if (depth > 100)
17400 elt = build_string ("*too-deep*");
17401
17402 depth++;
17403
17404 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
17405 {
17406 case Lisp_String:
17407 {
17408 /* A string: output it and check for %-constructs within it. */
17409 unsigned char c;
17410 int offset = 0;
17411
17412 if (SCHARS (elt) > 0
17413 && (!NILP (props) || risky))
17414 {
17415 Lisp_Object oprops, aelt;
17416 oprops = Ftext_properties_at (make_number (0), elt);
17417
17418 /* If the starting string's properties are not what
17419 we want, translate the string. Also, if the string
17420 is risky, do that anyway. */
17421
17422 if (NILP (Fequal (props, oprops)) || risky)
17423 {
17424 /* If the starting string has properties,
17425 merge the specified ones onto the existing ones. */
17426 if (! NILP (oprops) && !risky)
17427 {
17428 Lisp_Object tem;
17429
17430 oprops = Fcopy_sequence (oprops);
17431 tem = props;
17432 while (CONSP (tem))
17433 {
17434 oprops = Fplist_put (oprops, XCAR (tem),
17435 XCAR (XCDR (tem)));
17436 tem = XCDR (XCDR (tem));
17437 }
17438 props = oprops;
17439 }
17440
17441 aelt = Fassoc (elt, mode_line_proptrans_alist);
17442 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
17443 {
17444 /* AELT is what we want. Move it to the front
17445 without consing. */
17446 elt = XCAR (aelt);
17447 mode_line_proptrans_alist
17448 = move_elt_to_front (aelt, mode_line_proptrans_alist);
17449 }
17450 else
17451 {
17452 Lisp_Object tem;
17453
17454 /* If AELT has the wrong props, it is useless.
17455 so get rid of it. */
17456 if (! NILP (aelt))
17457 mode_line_proptrans_alist
17458 = Fdelq (aelt, mode_line_proptrans_alist);
17459
17460 elt = Fcopy_sequence (elt);
17461 Fset_text_properties (make_number (0), Flength (elt),
17462 props, elt);
17463 /* Add this item to mode_line_proptrans_alist. */
17464 mode_line_proptrans_alist
17465 = Fcons (Fcons (elt, props),
17466 mode_line_proptrans_alist);
17467 /* Truncate mode_line_proptrans_alist
17468 to at most 50 elements. */
17469 tem = Fnthcdr (make_number (50),
17470 mode_line_proptrans_alist);
17471 if (! NILP (tem))
17472 XSETCDR (tem, Qnil);
17473 }
17474 }
17475 }
17476
17477 offset = 0;
17478
17479 if (literal)
17480 {
17481 prec = precision - n;
17482 switch (mode_line_target)
17483 {
17484 case MODE_LINE_NOPROP:
17485 case MODE_LINE_TITLE:
17486 n += store_mode_line_noprop (SDATA (elt), -1, prec);
17487 break;
17488 case MODE_LINE_STRING:
17489 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
17490 break;
17491 case MODE_LINE_DISPLAY:
17492 n += display_string (NULL, elt, Qnil, 0, 0, it,
17493 0, prec, 0, STRING_MULTIBYTE (elt));
17494 break;
17495 }
17496
17497 break;
17498 }
17499
17500 /* Handle the non-literal case. */
17501
17502 while ((precision <= 0 || n < precision)
17503 && SREF (elt, offset) != 0
17504 && (mode_line_target != MODE_LINE_DISPLAY
17505 || it->current_x < it->last_visible_x))
17506 {
17507 int last_offset = offset;
17508
17509 /* Advance to end of string or next format specifier. */
17510 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
17511 ;
17512
17513 if (offset - 1 != last_offset)
17514 {
17515 int nchars, nbytes;
17516
17517 /* Output to end of string or up to '%'. Field width
17518 is length of string. Don't output more than
17519 PRECISION allows us. */
17520 offset--;
17521
17522 prec = c_string_width (SDATA (elt) + last_offset,
17523 offset - last_offset, precision - n,
17524 &nchars, &nbytes);
17525
17526 switch (mode_line_target)
17527 {
17528 case MODE_LINE_NOPROP:
17529 case MODE_LINE_TITLE:
17530 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
17531 break;
17532 case MODE_LINE_STRING:
17533 {
17534 int bytepos = last_offset;
17535 int charpos = string_byte_to_char (elt, bytepos);
17536 int endpos = (precision <= 0
17537 ? string_byte_to_char (elt, offset)
17538 : charpos + nchars);
17539
17540 n += store_mode_line_string (NULL,
17541 Fsubstring (elt, make_number (charpos),
17542 make_number (endpos)),
17543 0, 0, 0, Qnil);
17544 }
17545 break;
17546 case MODE_LINE_DISPLAY:
17547 {
17548 int bytepos = last_offset;
17549 int charpos = string_byte_to_char (elt, bytepos);
17550
17551 if (precision <= 0)
17552 nchars = string_byte_to_char (elt, offset) - charpos;
17553 n += display_string (NULL, elt, Qnil, 0, charpos,
17554 it, 0, nchars, 0,
17555 STRING_MULTIBYTE (elt));
17556 }
17557 break;
17558 }
17559 }
17560 else /* c == '%' */
17561 {
17562 int percent_position = offset;
17563
17564 /* Get the specified minimum width. Zero means
17565 don't pad. */
17566 field = 0;
17567 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
17568 field = field * 10 + c - '0';
17569
17570 /* Don't pad beyond the total padding allowed. */
17571 if (field_width - n > 0 && field > field_width - n)
17572 field = field_width - n;
17573
17574 /* Note that either PRECISION <= 0 or N < PRECISION. */
17575 prec = precision - n;
17576
17577 if (c == 'M')
17578 n += display_mode_element (it, depth, field, prec,
17579 Vglobal_mode_string, props,
17580 risky);
17581 else if (c != 0)
17582 {
17583 int multibyte;
17584 int bytepos, charpos;
17585 unsigned char *spec;
17586
17587 bytepos = percent_position;
17588 charpos = (STRING_MULTIBYTE (elt)
17589 ? string_byte_to_char (elt, bytepos)
17590 : bytepos);
17591 spec
17592 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17593
17594 switch (mode_line_target)
17595 {
17596 case MODE_LINE_NOPROP:
17597 case MODE_LINE_TITLE:
17598 n += store_mode_line_noprop (spec, field, prec);
17599 break;
17600 case MODE_LINE_STRING:
17601 {
17602 int len = strlen (spec);
17603 Lisp_Object tem = make_string (spec, len);
17604 props = Ftext_properties_at (make_number (charpos), elt);
17605 /* Should only keep face property in props */
17606 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17607 }
17608 break;
17609 case MODE_LINE_DISPLAY:
17610 {
17611 int nglyphs_before, nwritten;
17612
17613 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17614 nwritten = display_string (spec, Qnil, elt,
17615 charpos, 0, it,
17616 field, prec, 0,
17617 multibyte);
17618
17619 /* Assign to the glyphs written above the
17620 string where the `%x' came from, position
17621 of the `%'. */
17622 if (nwritten > 0)
17623 {
17624 struct glyph *glyph
17625 = (it->glyph_row->glyphs[TEXT_AREA]
17626 + nglyphs_before);
17627 int i;
17628
17629 for (i = 0; i < nwritten; ++i)
17630 {
17631 glyph[i].object = elt;
17632 glyph[i].charpos = charpos;
17633 }
17634
17635 n += nwritten;
17636 }
17637 }
17638 break;
17639 }
17640 }
17641 else /* c == 0 */
17642 break;
17643 }
17644 }
17645 }
17646 break;
17647
17648 case Lisp_Symbol:
17649 /* A symbol: process the value of the symbol recursively
17650 as if it appeared here directly. Avoid error if symbol void.
17651 Special case: if value of symbol is a string, output the string
17652 literally. */
17653 {
17654 register Lisp_Object tem;
17655
17656 /* If the variable is not marked as risky to set
17657 then its contents are risky to use. */
17658 if (NILP (Fget (elt, Qrisky_local_variable)))
17659 risky = 1;
17660
17661 tem = Fboundp (elt);
17662 if (!NILP (tem))
17663 {
17664 tem = Fsymbol_value (elt);
17665 /* If value is a string, output that string literally:
17666 don't check for % within it. */
17667 if (STRINGP (tem))
17668 literal = 1;
17669
17670 if (!EQ (tem, elt))
17671 {
17672 /* Give up right away for nil or t. */
17673 elt = tem;
17674 goto tail_recurse;
17675 }
17676 }
17677 }
17678 break;
17679
17680 case Lisp_Cons:
17681 {
17682 register Lisp_Object car, tem;
17683
17684 /* A cons cell: five distinct cases.
17685 If first element is :eval or :propertize, do something special.
17686 If first element is a string or a cons, process all the elements
17687 and effectively concatenate them.
17688 If first element is a negative number, truncate displaying cdr to
17689 at most that many characters. If positive, pad (with spaces)
17690 to at least that many characters.
17691 If first element is a symbol, process the cadr or caddr recursively
17692 according to whether the symbol's value is non-nil or nil. */
17693 car = XCAR (elt);
17694 if (EQ (car, QCeval))
17695 {
17696 /* An element of the form (:eval FORM) means evaluate FORM
17697 and use the result as mode line elements. */
17698
17699 if (risky)
17700 break;
17701
17702 if (CONSP (XCDR (elt)))
17703 {
17704 Lisp_Object spec;
17705 spec = safe_eval (XCAR (XCDR (elt)));
17706 n += display_mode_element (it, depth, field_width - n,
17707 precision - n, spec, props,
17708 risky);
17709 }
17710 }
17711 else if (EQ (car, QCpropertize))
17712 {
17713 /* An element of the form (:propertize ELT PROPS...)
17714 means display ELT but applying properties PROPS. */
17715
17716 if (risky)
17717 break;
17718
17719 if (CONSP (XCDR (elt)))
17720 n += display_mode_element (it, depth, field_width - n,
17721 precision - n, XCAR (XCDR (elt)),
17722 XCDR (XCDR (elt)), risky);
17723 }
17724 else if (SYMBOLP (car))
17725 {
17726 tem = Fboundp (car);
17727 elt = XCDR (elt);
17728 if (!CONSP (elt))
17729 goto invalid;
17730 /* elt is now the cdr, and we know it is a cons cell.
17731 Use its car if CAR has a non-nil value. */
17732 if (!NILP (tem))
17733 {
17734 tem = Fsymbol_value (car);
17735 if (!NILP (tem))
17736 {
17737 elt = XCAR (elt);
17738 goto tail_recurse;
17739 }
17740 }
17741 /* Symbol's value is nil (or symbol is unbound)
17742 Get the cddr of the original list
17743 and if possible find the caddr and use that. */
17744 elt = XCDR (elt);
17745 if (NILP (elt))
17746 break;
17747 else if (!CONSP (elt))
17748 goto invalid;
17749 elt = XCAR (elt);
17750 goto tail_recurse;
17751 }
17752 else if (INTEGERP (car))
17753 {
17754 register int lim = XINT (car);
17755 elt = XCDR (elt);
17756 if (lim < 0)
17757 {
17758 /* Negative int means reduce maximum width. */
17759 if (precision <= 0)
17760 precision = -lim;
17761 else
17762 precision = min (precision, -lim);
17763 }
17764 else if (lim > 0)
17765 {
17766 /* Padding specified. Don't let it be more than
17767 current maximum. */
17768 if (precision > 0)
17769 lim = min (precision, lim);
17770
17771 /* If that's more padding than already wanted, queue it.
17772 But don't reduce padding already specified even if
17773 that is beyond the current truncation point. */
17774 field_width = max (lim, field_width);
17775 }
17776 goto tail_recurse;
17777 }
17778 else if (STRINGP (car) || CONSP (car))
17779 {
17780 Lisp_Object halftail = elt;
17781 int len = 0;
17782
17783 while (CONSP (elt)
17784 && (precision <= 0 || n < precision))
17785 {
17786 n += display_mode_element (it, depth,
17787 /* Do padding only after the last
17788 element in the list. */
17789 (! CONSP (XCDR (elt))
17790 ? field_width - n
17791 : 0),
17792 precision - n, XCAR (elt),
17793 props, risky);
17794 elt = XCDR (elt);
17795 len++;
17796 if ((len & 1) == 0)
17797 halftail = XCDR (halftail);
17798 /* Check for cycle. */
17799 if (EQ (halftail, elt))
17800 break;
17801 }
17802 }
17803 }
17804 break;
17805
17806 default:
17807 invalid:
17808 elt = build_string ("*invalid*");
17809 goto tail_recurse;
17810 }
17811
17812 /* Pad to FIELD_WIDTH. */
17813 if (field_width > 0 && n < field_width)
17814 {
17815 switch (mode_line_target)
17816 {
17817 case MODE_LINE_NOPROP:
17818 case MODE_LINE_TITLE:
17819 n += store_mode_line_noprop ("", field_width - n, 0);
17820 break;
17821 case MODE_LINE_STRING:
17822 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17823 break;
17824 case MODE_LINE_DISPLAY:
17825 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17826 0, 0, 0);
17827 break;
17828 }
17829 }
17830
17831 return n;
17832 }
17833
17834 /* Store a mode-line string element in mode_line_string_list.
17835
17836 If STRING is non-null, display that C string. Otherwise, the Lisp
17837 string LISP_STRING is displayed.
17838
17839 FIELD_WIDTH is the minimum number of output glyphs to produce.
17840 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17841 with spaces. FIELD_WIDTH <= 0 means don't pad.
17842
17843 PRECISION is the maximum number of characters to output from
17844 STRING. PRECISION <= 0 means don't truncate the string.
17845
17846 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17847 properties to the string.
17848
17849 PROPS are the properties to add to the string.
17850 The mode_line_string_face face property is always added to the string.
17851 */
17852
17853 static int
17854 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17855 char *string;
17856 Lisp_Object lisp_string;
17857 int copy_string;
17858 int field_width;
17859 int precision;
17860 Lisp_Object props;
17861 {
17862 int len;
17863 int n = 0;
17864
17865 if (string != NULL)
17866 {
17867 len = strlen (string);
17868 if (precision > 0 && len > precision)
17869 len = precision;
17870 lisp_string = make_string (string, len);
17871 if (NILP (props))
17872 props = mode_line_string_face_prop;
17873 else if (!NILP (mode_line_string_face))
17874 {
17875 Lisp_Object face = Fplist_get (props, Qface);
17876 props = Fcopy_sequence (props);
17877 if (NILP (face))
17878 face = mode_line_string_face;
17879 else
17880 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17881 props = Fplist_put (props, Qface, face);
17882 }
17883 Fadd_text_properties (make_number (0), make_number (len),
17884 props, lisp_string);
17885 }
17886 else
17887 {
17888 len = XFASTINT (Flength (lisp_string));
17889 if (precision > 0 && len > precision)
17890 {
17891 len = precision;
17892 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17893 precision = -1;
17894 }
17895 if (!NILP (mode_line_string_face))
17896 {
17897 Lisp_Object face;
17898 if (NILP (props))
17899 props = Ftext_properties_at (make_number (0), lisp_string);
17900 face = Fplist_get (props, Qface);
17901 if (NILP (face))
17902 face = mode_line_string_face;
17903 else
17904 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17905 props = Fcons (Qface, Fcons (face, Qnil));
17906 if (copy_string)
17907 lisp_string = Fcopy_sequence (lisp_string);
17908 }
17909 if (!NILP (props))
17910 Fadd_text_properties (make_number (0), make_number (len),
17911 props, lisp_string);
17912 }
17913
17914 if (len > 0)
17915 {
17916 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17917 n += len;
17918 }
17919
17920 if (field_width > len)
17921 {
17922 field_width -= len;
17923 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17924 if (!NILP (props))
17925 Fadd_text_properties (make_number (0), make_number (field_width),
17926 props, lisp_string);
17927 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17928 n += field_width;
17929 }
17930
17931 return n;
17932 }
17933
17934
17935 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17936 1, 4, 0,
17937 doc: /* Format a string out of a mode line format specification.
17938 First arg FORMAT specifies the mode line format (see `mode-line-format'
17939 for details) to use.
17940
17941 Optional second arg FACE specifies the face property to put
17942 on all characters for which no face is specified.
17943 The value t means whatever face the window's mode line currently uses
17944 \(either `mode-line' or `mode-line-inactive', depending).
17945 A value of nil means the default is no face property.
17946 If FACE is an integer, the value string has no text properties.
17947
17948 Optional third and fourth args WINDOW and BUFFER specify the window
17949 and buffer to use as the context for the formatting (defaults
17950 are the selected window and the window's buffer). */)
17951 (format, face, window, buffer)
17952 Lisp_Object format, face, window, buffer;
17953 {
17954 struct it it;
17955 int len;
17956 struct window *w;
17957 struct buffer *old_buffer = NULL;
17958 int face_id = -1;
17959 int no_props = INTEGERP (face);
17960 int count = SPECPDL_INDEX ();
17961 Lisp_Object str;
17962 int string_start = 0;
17963
17964 if (NILP (window))
17965 window = selected_window;
17966 CHECK_WINDOW (window);
17967 w = XWINDOW (window);
17968
17969 if (NILP (buffer))
17970 buffer = w->buffer;
17971 CHECK_BUFFER (buffer);
17972
17973 /* Make formatting the modeline a non-op when noninteractive, otherwise
17974 there will be problems later caused by a partially initialized frame. */
17975 if (NILP (format) || noninteractive)
17976 return empty_unibyte_string;
17977
17978 if (no_props)
17979 face = Qnil;
17980
17981 if (!NILP (face))
17982 {
17983 if (EQ (face, Qt))
17984 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17985 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
17986 }
17987
17988 if (face_id < 0)
17989 face_id = DEFAULT_FACE_ID;
17990
17991 if (XBUFFER (buffer) != current_buffer)
17992 old_buffer = current_buffer;
17993
17994 /* Save things including mode_line_proptrans_alist,
17995 and set that to nil so that we don't alter the outer value. */
17996 record_unwind_protect (unwind_format_mode_line,
17997 format_mode_line_unwind_data
17998 (old_buffer, selected_window, 1));
17999 mode_line_proptrans_alist = Qnil;
18000
18001 Fselect_window (window, Qt);
18002 if (old_buffer)
18003 set_buffer_internal_1 (XBUFFER (buffer));
18004
18005 init_iterator (&it, w, -1, -1, NULL, face_id);
18006
18007 if (no_props)
18008 {
18009 mode_line_target = MODE_LINE_NOPROP;
18010 mode_line_string_face_prop = Qnil;
18011 mode_line_string_list = Qnil;
18012 string_start = MODE_LINE_NOPROP_LEN (0);
18013 }
18014 else
18015 {
18016 mode_line_target = MODE_LINE_STRING;
18017 mode_line_string_list = Qnil;
18018 mode_line_string_face = face;
18019 mode_line_string_face_prop
18020 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
18021 }
18022
18023 push_kboard (FRAME_KBOARD (it.f));
18024 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18025 pop_kboard ();
18026
18027 if (no_props)
18028 {
18029 len = MODE_LINE_NOPROP_LEN (string_start);
18030 str = make_string (mode_line_noprop_buf + string_start, len);
18031 }
18032 else
18033 {
18034 mode_line_string_list = Fnreverse (mode_line_string_list);
18035 str = Fmapconcat (intern ("identity"), mode_line_string_list,
18036 empty_unibyte_string);
18037 }
18038
18039 unbind_to (count, Qnil);
18040 return str;
18041 }
18042
18043 /* Write a null-terminated, right justified decimal representation of
18044 the positive integer D to BUF using a minimal field width WIDTH. */
18045
18046 static void
18047 pint2str (buf, width, d)
18048 register char *buf;
18049 register int width;
18050 register int d;
18051 {
18052 register char *p = buf;
18053
18054 if (d <= 0)
18055 *p++ = '0';
18056 else
18057 {
18058 while (d > 0)
18059 {
18060 *p++ = d % 10 + '0';
18061 d /= 10;
18062 }
18063 }
18064
18065 for (width -= (int) (p - buf); width > 0; --width)
18066 *p++ = ' ';
18067 *p-- = '\0';
18068 while (p > buf)
18069 {
18070 d = *buf;
18071 *buf++ = *p;
18072 *p-- = d;
18073 }
18074 }
18075
18076 /* Write a null-terminated, right justified decimal and "human
18077 readable" representation of the nonnegative integer D to BUF using
18078 a minimal field width WIDTH. D should be smaller than 999.5e24. */
18079
18080 static const char power_letter[] =
18081 {
18082 0, /* not used */
18083 'k', /* kilo */
18084 'M', /* mega */
18085 'G', /* giga */
18086 'T', /* tera */
18087 'P', /* peta */
18088 'E', /* exa */
18089 'Z', /* zetta */
18090 'Y' /* yotta */
18091 };
18092
18093 static void
18094 pint2hrstr (buf, width, d)
18095 char *buf;
18096 int width;
18097 int d;
18098 {
18099 /* We aim to represent the nonnegative integer D as
18100 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
18101 int quotient = d;
18102 int remainder = 0;
18103 /* -1 means: do not use TENTHS. */
18104 int tenths = -1;
18105 int exponent = 0;
18106
18107 /* Length of QUOTIENT.TENTHS as a string. */
18108 int length;
18109
18110 char * psuffix;
18111 char * p;
18112
18113 if (1000 <= quotient)
18114 {
18115 /* Scale to the appropriate EXPONENT. */
18116 do
18117 {
18118 remainder = quotient % 1000;
18119 quotient /= 1000;
18120 exponent++;
18121 }
18122 while (1000 <= quotient);
18123
18124 /* Round to nearest and decide whether to use TENTHS or not. */
18125 if (quotient <= 9)
18126 {
18127 tenths = remainder / 100;
18128 if (50 <= remainder % 100)
18129 {
18130 if (tenths < 9)
18131 tenths++;
18132 else
18133 {
18134 quotient++;
18135 if (quotient == 10)
18136 tenths = -1;
18137 else
18138 tenths = 0;
18139 }
18140 }
18141 }
18142 else
18143 if (500 <= remainder)
18144 {
18145 if (quotient < 999)
18146 quotient++;
18147 else
18148 {
18149 quotient = 1;
18150 exponent++;
18151 tenths = 0;
18152 }
18153 }
18154 }
18155
18156 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
18157 if (tenths == -1 && quotient <= 99)
18158 if (quotient <= 9)
18159 length = 1;
18160 else
18161 length = 2;
18162 else
18163 length = 3;
18164 p = psuffix = buf + max (width, length);
18165
18166 /* Print EXPONENT. */
18167 if (exponent)
18168 *psuffix++ = power_letter[exponent];
18169 *psuffix = '\0';
18170
18171 /* Print TENTHS. */
18172 if (tenths >= 0)
18173 {
18174 *--p = '0' + tenths;
18175 *--p = '.';
18176 }
18177
18178 /* Print QUOTIENT. */
18179 do
18180 {
18181 int digit = quotient % 10;
18182 *--p = '0' + digit;
18183 }
18184 while ((quotient /= 10) != 0);
18185
18186 /* Print leading spaces. */
18187 while (buf < p)
18188 *--p = ' ';
18189 }
18190
18191 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
18192 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
18193 type of CODING_SYSTEM. Return updated pointer into BUF. */
18194
18195 static unsigned char invalid_eol_type[] = "(*invalid*)";
18196
18197 static char *
18198 decode_mode_spec_coding (coding_system, buf, eol_flag)
18199 Lisp_Object coding_system;
18200 register char *buf;
18201 int eol_flag;
18202 {
18203 Lisp_Object val;
18204 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
18205 const unsigned char *eol_str;
18206 int eol_str_len;
18207 /* The EOL conversion we are using. */
18208 Lisp_Object eoltype;
18209
18210 val = CODING_SYSTEM_SPEC (coding_system);
18211 eoltype = Qnil;
18212
18213 if (!VECTORP (val)) /* Not yet decided. */
18214 {
18215 if (multibyte)
18216 *buf++ = '-';
18217 if (eol_flag)
18218 eoltype = eol_mnemonic_undecided;
18219 /* Don't mention EOL conversion if it isn't decided. */
18220 }
18221 else
18222 {
18223 Lisp_Object attrs;
18224 Lisp_Object eolvalue;
18225
18226 attrs = AREF (val, 0);
18227 eolvalue = AREF (val, 2);
18228
18229 if (multibyte)
18230 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
18231
18232 if (eol_flag)
18233 {
18234 /* The EOL conversion that is normal on this system. */
18235
18236 if (NILP (eolvalue)) /* Not yet decided. */
18237 eoltype = eol_mnemonic_undecided;
18238 else if (VECTORP (eolvalue)) /* Not yet decided. */
18239 eoltype = eol_mnemonic_undecided;
18240 else /* eolvalue is Qunix, Qdos, or Qmac. */
18241 eoltype = (EQ (eolvalue, Qunix)
18242 ? eol_mnemonic_unix
18243 : (EQ (eolvalue, Qdos) == 1
18244 ? eol_mnemonic_dos : eol_mnemonic_mac));
18245 }
18246 }
18247
18248 if (eol_flag)
18249 {
18250 /* Mention the EOL conversion if it is not the usual one. */
18251 if (STRINGP (eoltype))
18252 {
18253 eol_str = SDATA (eoltype);
18254 eol_str_len = SBYTES (eoltype);
18255 }
18256 else if (CHARACTERP (eoltype))
18257 {
18258 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
18259 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
18260 eol_str = tmp;
18261 }
18262 else
18263 {
18264 eol_str = invalid_eol_type;
18265 eol_str_len = sizeof (invalid_eol_type) - 1;
18266 }
18267 bcopy (eol_str, buf, eol_str_len);
18268 buf += eol_str_len;
18269 }
18270
18271 return buf;
18272 }
18273
18274 /* Return a string for the output of a mode line %-spec for window W,
18275 generated by character C. PRECISION >= 0 means don't return a
18276 string longer than that value. FIELD_WIDTH > 0 means pad the
18277 string returned with spaces to that value. Return 1 in *MULTIBYTE
18278 if the result is multibyte text.
18279
18280 Note we operate on the current buffer for most purposes,
18281 the exception being w->base_line_pos. */
18282
18283 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
18284
18285 static char *
18286 decode_mode_spec (w, c, field_width, precision, multibyte)
18287 struct window *w;
18288 register int c;
18289 int field_width, precision;
18290 int *multibyte;
18291 {
18292 Lisp_Object obj;
18293 struct frame *f = XFRAME (WINDOW_FRAME (w));
18294 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
18295 struct buffer *b = current_buffer;
18296
18297 obj = Qnil;
18298 *multibyte = 0;
18299
18300 switch (c)
18301 {
18302 case '*':
18303 if (!NILP (b->read_only))
18304 return "%";
18305 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18306 return "*";
18307 return "-";
18308
18309 case '+':
18310 /* This differs from %* only for a modified read-only buffer. */
18311 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18312 return "*";
18313 if (!NILP (b->read_only))
18314 return "%";
18315 return "-";
18316
18317 case '&':
18318 /* This differs from %* in ignoring read-only-ness. */
18319 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
18320 return "*";
18321 return "-";
18322
18323 case '%':
18324 return "%";
18325
18326 case '[':
18327 {
18328 int i;
18329 char *p;
18330
18331 if (command_loop_level > 5)
18332 return "[[[... ";
18333 p = decode_mode_spec_buf;
18334 for (i = 0; i < command_loop_level; i++)
18335 *p++ = '[';
18336 *p = 0;
18337 return decode_mode_spec_buf;
18338 }
18339
18340 case ']':
18341 {
18342 int i;
18343 char *p;
18344
18345 if (command_loop_level > 5)
18346 return " ...]]]";
18347 p = decode_mode_spec_buf;
18348 for (i = 0; i < command_loop_level; i++)
18349 *p++ = ']';
18350 *p = 0;
18351 return decode_mode_spec_buf;
18352 }
18353
18354 case '-':
18355 {
18356 register int i;
18357
18358 /* Let lots_of_dashes be a string of infinite length. */
18359 if (mode_line_target == MODE_LINE_NOPROP ||
18360 mode_line_target == MODE_LINE_STRING)
18361 return "--";
18362 if (field_width <= 0
18363 || field_width > sizeof (lots_of_dashes))
18364 {
18365 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
18366 decode_mode_spec_buf[i] = '-';
18367 decode_mode_spec_buf[i] = '\0';
18368 return decode_mode_spec_buf;
18369 }
18370 else
18371 return lots_of_dashes;
18372 }
18373
18374 case 'b':
18375 obj = b->name;
18376 break;
18377
18378 case 'c':
18379 /* %c and %l are ignored in `frame-title-format'.
18380 (In redisplay_internal, the frame title is drawn _before_ the
18381 windows are updated, so the stuff which depends on actual
18382 window contents (such as %l) may fail to render properly, or
18383 even crash emacs.) */
18384 if (mode_line_target == MODE_LINE_TITLE)
18385 return "";
18386 else
18387 {
18388 int col = (int) current_column (); /* iftc */
18389 w->column_number_displayed = make_number (col);
18390 pint2str (decode_mode_spec_buf, field_width, col);
18391 return decode_mode_spec_buf;
18392 }
18393
18394 case 'e':
18395 #ifndef SYSTEM_MALLOC
18396 {
18397 if (NILP (Vmemory_full))
18398 return "";
18399 else
18400 return "!MEM FULL! ";
18401 }
18402 #else
18403 return "";
18404 #endif
18405
18406 case 'F':
18407 /* %F displays the frame name. */
18408 if (!NILP (f->title))
18409 return (char *) SDATA (f->title);
18410 if (f->explicit_name || ! FRAME_WINDOW_P (f))
18411 return (char *) SDATA (f->name);
18412 return "Emacs";
18413
18414 case 'f':
18415 obj = b->filename;
18416 break;
18417
18418 case 'i':
18419 {
18420 int size = ZV - BEGV;
18421 pint2str (decode_mode_spec_buf, field_width, size);
18422 return decode_mode_spec_buf;
18423 }
18424
18425 case 'I':
18426 {
18427 int size = ZV - BEGV;
18428 pint2hrstr (decode_mode_spec_buf, field_width, size);
18429 return decode_mode_spec_buf;
18430 }
18431
18432 case 'l':
18433 {
18434 int startpos, startpos_byte, line, linepos, linepos_byte;
18435 int topline, nlines, junk, height;
18436
18437 /* %c and %l are ignored in `frame-title-format'. */
18438 if (mode_line_target == MODE_LINE_TITLE)
18439 return "";
18440
18441 startpos = XMARKER (w->start)->charpos;
18442 startpos_byte = marker_byte_position (w->start);
18443 height = WINDOW_TOTAL_LINES (w);
18444
18445 /* If we decided that this buffer isn't suitable for line numbers,
18446 don't forget that too fast. */
18447 if (EQ (w->base_line_pos, w->buffer))
18448 goto no_value;
18449 /* But do forget it, if the window shows a different buffer now. */
18450 else if (BUFFERP (w->base_line_pos))
18451 w->base_line_pos = Qnil;
18452
18453 /* If the buffer is very big, don't waste time. */
18454 if (INTEGERP (Vline_number_display_limit)
18455 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
18456 {
18457 w->base_line_pos = Qnil;
18458 w->base_line_number = Qnil;
18459 goto no_value;
18460 }
18461
18462 if (INTEGERP (w->base_line_number)
18463 && INTEGERP (w->base_line_pos)
18464 && XFASTINT (w->base_line_pos) <= startpos)
18465 {
18466 line = XFASTINT (w->base_line_number);
18467 linepos = XFASTINT (w->base_line_pos);
18468 linepos_byte = buf_charpos_to_bytepos (b, linepos);
18469 }
18470 else
18471 {
18472 line = 1;
18473 linepos = BUF_BEGV (b);
18474 linepos_byte = BUF_BEGV_BYTE (b);
18475 }
18476
18477 /* Count lines from base line to window start position. */
18478 nlines = display_count_lines (linepos, linepos_byte,
18479 startpos_byte,
18480 startpos, &junk);
18481
18482 topline = nlines + line;
18483
18484 /* Determine a new base line, if the old one is too close
18485 or too far away, or if we did not have one.
18486 "Too close" means it's plausible a scroll-down would
18487 go back past it. */
18488 if (startpos == BUF_BEGV (b))
18489 {
18490 w->base_line_number = make_number (topline);
18491 w->base_line_pos = make_number (BUF_BEGV (b));
18492 }
18493 else if (nlines < height + 25 || nlines > height * 3 + 50
18494 || linepos == BUF_BEGV (b))
18495 {
18496 int limit = BUF_BEGV (b);
18497 int limit_byte = BUF_BEGV_BYTE (b);
18498 int position;
18499 int distance = (height * 2 + 30) * line_number_display_limit_width;
18500
18501 if (startpos - distance > limit)
18502 {
18503 limit = startpos - distance;
18504 limit_byte = CHAR_TO_BYTE (limit);
18505 }
18506
18507 nlines = display_count_lines (startpos, startpos_byte,
18508 limit_byte,
18509 - (height * 2 + 30),
18510 &position);
18511 /* If we couldn't find the lines we wanted within
18512 line_number_display_limit_width chars per line,
18513 give up on line numbers for this window. */
18514 if (position == limit_byte && limit == startpos - distance)
18515 {
18516 w->base_line_pos = w->buffer;
18517 w->base_line_number = Qnil;
18518 goto no_value;
18519 }
18520
18521 w->base_line_number = make_number (topline - nlines);
18522 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
18523 }
18524
18525 /* Now count lines from the start pos to point. */
18526 nlines = display_count_lines (startpos, startpos_byte,
18527 PT_BYTE, PT, &junk);
18528
18529 /* Record that we did display the line number. */
18530 line_number_displayed = 1;
18531
18532 /* Make the string to show. */
18533 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
18534 return decode_mode_spec_buf;
18535 no_value:
18536 {
18537 char* p = decode_mode_spec_buf;
18538 int pad = field_width - 2;
18539 while (pad-- > 0)
18540 *p++ = ' ';
18541 *p++ = '?';
18542 *p++ = '?';
18543 *p = '\0';
18544 return decode_mode_spec_buf;
18545 }
18546 }
18547 break;
18548
18549 case 'm':
18550 obj = b->mode_name;
18551 break;
18552
18553 case 'n':
18554 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
18555 return " Narrow";
18556 break;
18557
18558 case 'p':
18559 {
18560 int pos = marker_position (w->start);
18561 int total = BUF_ZV (b) - BUF_BEGV (b);
18562
18563 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
18564 {
18565 if (pos <= BUF_BEGV (b))
18566 return "All";
18567 else
18568 return "Bottom";
18569 }
18570 else if (pos <= BUF_BEGV (b))
18571 return "Top";
18572 else
18573 {
18574 if (total > 1000000)
18575 /* Do it differently for a large value, to avoid overflow. */
18576 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18577 else
18578 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
18579 /* We can't normally display a 3-digit number,
18580 so get us a 2-digit number that is close. */
18581 if (total == 100)
18582 total = 99;
18583 sprintf (decode_mode_spec_buf, "%2d%%", total);
18584 return decode_mode_spec_buf;
18585 }
18586 }
18587
18588 /* Display percentage of size above the bottom of the screen. */
18589 case 'P':
18590 {
18591 int toppos = marker_position (w->start);
18592 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18593 int total = BUF_ZV (b) - BUF_BEGV (b);
18594
18595 if (botpos >= BUF_ZV (b))
18596 {
18597 if (toppos <= BUF_BEGV (b))
18598 return "All";
18599 else
18600 return "Bottom";
18601 }
18602 else
18603 {
18604 if (total > 1000000)
18605 /* Do it differently for a large value, to avoid overflow. */
18606 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18607 else
18608 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18609 /* We can't normally display a 3-digit number,
18610 so get us a 2-digit number that is close. */
18611 if (total == 100)
18612 total = 99;
18613 if (toppos <= BUF_BEGV (b))
18614 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18615 else
18616 sprintf (decode_mode_spec_buf, "%2d%%", total);
18617 return decode_mode_spec_buf;
18618 }
18619 }
18620
18621 case 's':
18622 /* status of process */
18623 obj = Fget_buffer_process (Fcurrent_buffer ());
18624 if (NILP (obj))
18625 return "no process";
18626 #ifdef subprocesses
18627 obj = Fsymbol_name (Fprocess_status (obj));
18628 #endif
18629 break;
18630
18631 case '@':
18632 {
18633 Lisp_Object val;
18634 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18635 if (NILP (val))
18636 return "-";
18637 else
18638 return "@";
18639 }
18640
18641 case 't': /* indicate TEXT or BINARY */
18642 #ifdef MODE_LINE_BINARY_TEXT
18643 return MODE_LINE_BINARY_TEXT (b);
18644 #else
18645 return "T";
18646 #endif
18647
18648 case 'z':
18649 /* coding-system (not including end-of-line format) */
18650 case 'Z':
18651 /* coding-system (including end-of-line type) */
18652 {
18653 int eol_flag = (c == 'Z');
18654 char *p = decode_mode_spec_buf;
18655
18656 if (! FRAME_WINDOW_P (f))
18657 {
18658 /* No need to mention EOL here--the terminal never needs
18659 to do EOL conversion. */
18660 p = decode_mode_spec_coding (CODING_ID_NAME
18661 (FRAME_KEYBOARD_CODING (f)->id),
18662 p, 0);
18663 p = decode_mode_spec_coding (CODING_ID_NAME
18664 (FRAME_TERMINAL_CODING (f)->id),
18665 p, 0);
18666 }
18667 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18668 p, eol_flag);
18669
18670 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18671 #ifdef subprocesses
18672 obj = Fget_buffer_process (Fcurrent_buffer ());
18673 if (PROCESSP (obj))
18674 {
18675 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18676 p, eol_flag);
18677 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18678 p, eol_flag);
18679 }
18680 #endif /* subprocesses */
18681 #endif /* 0 */
18682 *p = 0;
18683 return decode_mode_spec_buf;
18684 }
18685 }
18686
18687 if (STRINGP (obj))
18688 {
18689 *multibyte = STRING_MULTIBYTE (obj);
18690 return (char *) SDATA (obj);
18691 }
18692 else
18693 return "";
18694 }
18695
18696
18697 /* Count up to COUNT lines starting from START / START_BYTE.
18698 But don't go beyond LIMIT_BYTE.
18699 Return the number of lines thus found (always nonnegative).
18700
18701 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18702
18703 static int
18704 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18705 int start, start_byte, limit_byte, count;
18706 int *byte_pos_ptr;
18707 {
18708 register unsigned char *cursor;
18709 unsigned char *base;
18710
18711 register int ceiling;
18712 register unsigned char *ceiling_addr;
18713 int orig_count = count;
18714
18715 /* If we are not in selective display mode,
18716 check only for newlines. */
18717 int selective_display = (!NILP (current_buffer->selective_display)
18718 && !INTEGERP (current_buffer->selective_display));
18719
18720 if (count > 0)
18721 {
18722 while (start_byte < limit_byte)
18723 {
18724 ceiling = BUFFER_CEILING_OF (start_byte);
18725 ceiling = min (limit_byte - 1, ceiling);
18726 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18727 base = (cursor = BYTE_POS_ADDR (start_byte));
18728 while (1)
18729 {
18730 if (selective_display)
18731 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18732 ;
18733 else
18734 while (*cursor != '\n' && ++cursor != ceiling_addr)
18735 ;
18736
18737 if (cursor != ceiling_addr)
18738 {
18739 if (--count == 0)
18740 {
18741 start_byte += cursor - base + 1;
18742 *byte_pos_ptr = start_byte;
18743 return orig_count;
18744 }
18745 else
18746 if (++cursor == ceiling_addr)
18747 break;
18748 }
18749 else
18750 break;
18751 }
18752 start_byte += cursor - base;
18753 }
18754 }
18755 else
18756 {
18757 while (start_byte > limit_byte)
18758 {
18759 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18760 ceiling = max (limit_byte, ceiling);
18761 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18762 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18763 while (1)
18764 {
18765 if (selective_display)
18766 while (--cursor != ceiling_addr
18767 && *cursor != '\n' && *cursor != 015)
18768 ;
18769 else
18770 while (--cursor != ceiling_addr && *cursor != '\n')
18771 ;
18772
18773 if (cursor != ceiling_addr)
18774 {
18775 if (++count == 0)
18776 {
18777 start_byte += cursor - base + 1;
18778 *byte_pos_ptr = start_byte;
18779 /* When scanning backwards, we should
18780 not count the newline posterior to which we stop. */
18781 return - orig_count - 1;
18782 }
18783 }
18784 else
18785 break;
18786 }
18787 /* Here we add 1 to compensate for the last decrement
18788 of CURSOR, which took it past the valid range. */
18789 start_byte += cursor - base + 1;
18790 }
18791 }
18792
18793 *byte_pos_ptr = limit_byte;
18794
18795 if (count < 0)
18796 return - orig_count + count;
18797 return orig_count - count;
18798
18799 }
18800
18801
18802 \f
18803 /***********************************************************************
18804 Displaying strings
18805 ***********************************************************************/
18806
18807 /* Display a NUL-terminated string, starting with index START.
18808
18809 If STRING is non-null, display that C string. Otherwise, the Lisp
18810 string LISP_STRING is displayed.
18811
18812 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18813 FACE_STRING. Display STRING or LISP_STRING with the face at
18814 FACE_STRING_POS in FACE_STRING:
18815
18816 Display the string in the environment given by IT, but use the
18817 standard display table, temporarily.
18818
18819 FIELD_WIDTH is the minimum number of output glyphs to produce.
18820 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18821 with spaces. If STRING has more characters, more than FIELD_WIDTH
18822 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18823
18824 PRECISION is the maximum number of characters to output from
18825 STRING. PRECISION < 0 means don't truncate the string.
18826
18827 This is roughly equivalent to printf format specifiers:
18828
18829 FIELD_WIDTH PRECISION PRINTF
18830 ----------------------------------------
18831 -1 -1 %s
18832 -1 10 %.10s
18833 10 -1 %10s
18834 20 10 %20.10s
18835
18836 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18837 display them, and < 0 means obey the current buffer's value of
18838 enable_multibyte_characters.
18839
18840 Value is the number of columns displayed. */
18841
18842 static int
18843 display_string (string, lisp_string, face_string, face_string_pos,
18844 start, it, field_width, precision, max_x, multibyte)
18845 unsigned char *string;
18846 Lisp_Object lisp_string;
18847 Lisp_Object face_string;
18848 EMACS_INT face_string_pos;
18849 EMACS_INT start;
18850 struct it *it;
18851 int field_width, precision, max_x;
18852 int multibyte;
18853 {
18854 int hpos_at_start = it->hpos;
18855 int saved_face_id = it->face_id;
18856 struct glyph_row *row = it->glyph_row;
18857
18858 /* Initialize the iterator IT for iteration over STRING beginning
18859 with index START. */
18860 reseat_to_string (it, string, lisp_string, start,
18861 precision, field_width, multibyte);
18862
18863 /* If displaying STRING, set up the face of the iterator
18864 from LISP_STRING, if that's given. */
18865 if (STRINGP (face_string))
18866 {
18867 EMACS_INT endptr;
18868 struct face *face;
18869
18870 it->face_id
18871 = face_at_string_position (it->w, face_string, face_string_pos,
18872 0, it->region_beg_charpos,
18873 it->region_end_charpos,
18874 &endptr, it->base_face_id, 0);
18875 face = FACE_FROM_ID (it->f, it->face_id);
18876 it->face_box_p = face->box != FACE_NO_BOX;
18877 }
18878
18879 /* Set max_x to the maximum allowed X position. Don't let it go
18880 beyond the right edge of the window. */
18881 if (max_x <= 0)
18882 max_x = it->last_visible_x;
18883 else
18884 max_x = min (max_x, it->last_visible_x);
18885
18886 /* Skip over display elements that are not visible. because IT->w is
18887 hscrolled. */
18888 if (it->current_x < it->first_visible_x)
18889 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18890 MOVE_TO_POS | MOVE_TO_X);
18891
18892 row->ascent = it->max_ascent;
18893 row->height = it->max_ascent + it->max_descent;
18894 row->phys_ascent = it->max_phys_ascent;
18895 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18896 row->extra_line_spacing = it->max_extra_line_spacing;
18897
18898 /* This condition is for the case that we are called with current_x
18899 past last_visible_x. */
18900 while (it->current_x < max_x)
18901 {
18902 int x_before, x, n_glyphs_before, i, nglyphs;
18903
18904 /* Get the next display element. */
18905 if (!get_next_display_element (it))
18906 break;
18907
18908 /* Produce glyphs. */
18909 x_before = it->current_x;
18910 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18911 PRODUCE_GLYPHS (it);
18912
18913 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18914 i = 0;
18915 x = x_before;
18916 while (i < nglyphs)
18917 {
18918 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18919
18920 if (it->line_wrap != TRUNCATE
18921 && x + glyph->pixel_width > max_x)
18922 {
18923 /* End of continued line or max_x reached. */
18924 if (CHAR_GLYPH_PADDING_P (*glyph))
18925 {
18926 /* A wide character is unbreakable. */
18927 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18928 it->current_x = x_before;
18929 }
18930 else
18931 {
18932 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18933 it->current_x = x;
18934 }
18935 break;
18936 }
18937 else if (x + glyph->pixel_width >= it->first_visible_x)
18938 {
18939 /* Glyph is at least partially visible. */
18940 ++it->hpos;
18941 if (x < it->first_visible_x)
18942 it->glyph_row->x = x - it->first_visible_x;
18943 }
18944 else
18945 {
18946 /* Glyph is off the left margin of the display area.
18947 Should not happen. */
18948 abort ();
18949 }
18950
18951 row->ascent = max (row->ascent, it->max_ascent);
18952 row->height = max (row->height, it->max_ascent + it->max_descent);
18953 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18954 row->phys_height = max (row->phys_height,
18955 it->max_phys_ascent + it->max_phys_descent);
18956 row->extra_line_spacing = max (row->extra_line_spacing,
18957 it->max_extra_line_spacing);
18958 x += glyph->pixel_width;
18959 ++i;
18960 }
18961
18962 /* Stop if max_x reached. */
18963 if (i < nglyphs)
18964 break;
18965
18966 /* Stop at line ends. */
18967 if (ITERATOR_AT_END_OF_LINE_P (it))
18968 {
18969 it->continuation_lines_width = 0;
18970 break;
18971 }
18972
18973 set_iterator_to_next (it, 1);
18974
18975 /* Stop if truncating at the right edge. */
18976 if (it->line_wrap == TRUNCATE
18977 && it->current_x >= it->last_visible_x)
18978 {
18979 /* Add truncation mark, but don't do it if the line is
18980 truncated at a padding space. */
18981 if (IT_CHARPOS (*it) < it->string_nchars)
18982 {
18983 if (!FRAME_WINDOW_P (it->f))
18984 {
18985 int i, n;
18986
18987 if (it->current_x > it->last_visible_x)
18988 {
18989 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18990 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18991 break;
18992 for (n = row->used[TEXT_AREA]; i < n; ++i)
18993 {
18994 row->used[TEXT_AREA] = i;
18995 produce_special_glyphs (it, IT_TRUNCATION);
18996 }
18997 }
18998 produce_special_glyphs (it, IT_TRUNCATION);
18999 }
19000 it->glyph_row->truncated_on_right_p = 1;
19001 }
19002 break;
19003 }
19004 }
19005
19006 /* Maybe insert a truncation at the left. */
19007 if (it->first_visible_x
19008 && IT_CHARPOS (*it) > 0)
19009 {
19010 if (!FRAME_WINDOW_P (it->f))
19011 insert_left_trunc_glyphs (it);
19012 it->glyph_row->truncated_on_left_p = 1;
19013 }
19014
19015 it->face_id = saved_face_id;
19016
19017 /* Value is number of columns displayed. */
19018 return it->hpos - hpos_at_start;
19019 }
19020
19021
19022 \f
19023 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19024 appears as an element of LIST or as the car of an element of LIST.
19025 If PROPVAL is a list, compare each element against LIST in that
19026 way, and return 1/2 if any element of PROPVAL is found in LIST.
19027 Otherwise return 0. This function cannot quit.
19028 The return value is 2 if the text is invisible but with an ellipsis
19029 and 1 if it's invisible and without an ellipsis. */
19030
19031 int
19032 invisible_p (propval, list)
19033 register Lisp_Object propval;
19034 Lisp_Object list;
19035 {
19036 register Lisp_Object tail, proptail;
19037
19038 for (tail = list; CONSP (tail); tail = XCDR (tail))
19039 {
19040 register Lisp_Object tem;
19041 tem = XCAR (tail);
19042 if (EQ (propval, tem))
19043 return 1;
19044 if (CONSP (tem) && EQ (propval, XCAR (tem)))
19045 return NILP (XCDR (tem)) ? 1 : 2;
19046 }
19047
19048 if (CONSP (propval))
19049 {
19050 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
19051 {
19052 Lisp_Object propelt;
19053 propelt = XCAR (proptail);
19054 for (tail = list; CONSP (tail); tail = XCDR (tail))
19055 {
19056 register Lisp_Object tem;
19057 tem = XCAR (tail);
19058 if (EQ (propelt, tem))
19059 return 1;
19060 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
19061 return NILP (XCDR (tem)) ? 1 : 2;
19062 }
19063 }
19064 }
19065
19066 return 0;
19067 }
19068
19069 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
19070 doc: /* Non-nil if the property makes the text invisible.
19071 POS-OR-PROP can be a marker or number, in which case it is taken to be
19072 a position in the current buffer and the value of the `invisible' property
19073 is checked; or it can be some other value, which is then presumed to be the
19074 value of the `invisible' property of the text of interest.
19075 The non-nil value returned can be t for truly invisible text or something
19076 else if the text is replaced by an ellipsis. */)
19077 (pos_or_prop)
19078 Lisp_Object pos_or_prop;
19079 {
19080 Lisp_Object prop
19081 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
19082 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
19083 : pos_or_prop);
19084 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
19085 return (invis == 0 ? Qnil
19086 : invis == 1 ? Qt
19087 : make_number (invis));
19088 }
19089
19090 /* Calculate a width or height in pixels from a specification using
19091 the following elements:
19092
19093 SPEC ::=
19094 NUM - a (fractional) multiple of the default font width/height
19095 (NUM) - specifies exactly NUM pixels
19096 UNIT - a fixed number of pixels, see below.
19097 ELEMENT - size of a display element in pixels, see below.
19098 (NUM . SPEC) - equals NUM * SPEC
19099 (+ SPEC SPEC ...) - add pixel values
19100 (- SPEC SPEC ...) - subtract pixel values
19101 (- SPEC) - negate pixel value
19102
19103 NUM ::=
19104 INT or FLOAT - a number constant
19105 SYMBOL - use symbol's (buffer local) variable binding.
19106
19107 UNIT ::=
19108 in - pixels per inch *)
19109 mm - pixels per 1/1000 meter *)
19110 cm - pixels per 1/100 meter *)
19111 width - width of current font in pixels.
19112 height - height of current font in pixels.
19113
19114 *) using the ratio(s) defined in display-pixels-per-inch.
19115
19116 ELEMENT ::=
19117
19118 left-fringe - left fringe width in pixels
19119 right-fringe - right fringe width in pixels
19120
19121 left-margin - left margin width in pixels
19122 right-margin - right margin width in pixels
19123
19124 scroll-bar - scroll-bar area width in pixels
19125
19126 Examples:
19127
19128 Pixels corresponding to 5 inches:
19129 (5 . in)
19130
19131 Total width of non-text areas on left side of window (if scroll-bar is on left):
19132 '(space :width (+ left-fringe left-margin scroll-bar))
19133
19134 Align to first text column (in header line):
19135 '(space :align-to 0)
19136
19137 Align to middle of text area minus half the width of variable `my-image'
19138 containing a loaded image:
19139 '(space :align-to (0.5 . (- text my-image)))
19140
19141 Width of left margin minus width of 1 character in the default font:
19142 '(space :width (- left-margin 1))
19143
19144 Width of left margin minus width of 2 characters in the current font:
19145 '(space :width (- left-margin (2 . width)))
19146
19147 Center 1 character over left-margin (in header line):
19148 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
19149
19150 Different ways to express width of left fringe plus left margin minus one pixel:
19151 '(space :width (- (+ left-fringe left-margin) (1)))
19152 '(space :width (+ left-fringe left-margin (- (1))))
19153 '(space :width (+ left-fringe left-margin (-1)))
19154
19155 */
19156
19157 #define NUMVAL(X) \
19158 ((INTEGERP (X) || FLOATP (X)) \
19159 ? XFLOATINT (X) \
19160 : - 1)
19161
19162 int
19163 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
19164 double *res;
19165 struct it *it;
19166 Lisp_Object prop;
19167 struct font *font;
19168 int width_p, *align_to;
19169 {
19170 double pixels;
19171
19172 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
19173 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
19174
19175 if (NILP (prop))
19176 return OK_PIXELS (0);
19177
19178 xassert (FRAME_LIVE_P (it->f));
19179
19180 if (SYMBOLP (prop))
19181 {
19182 if (SCHARS (SYMBOL_NAME (prop)) == 2)
19183 {
19184 char *unit = SDATA (SYMBOL_NAME (prop));
19185
19186 if (unit[0] == 'i' && unit[1] == 'n')
19187 pixels = 1.0;
19188 else if (unit[0] == 'm' && unit[1] == 'm')
19189 pixels = 25.4;
19190 else if (unit[0] == 'c' && unit[1] == 'm')
19191 pixels = 2.54;
19192 else
19193 pixels = 0;
19194 if (pixels > 0)
19195 {
19196 double ppi;
19197 #ifdef HAVE_WINDOW_SYSTEM
19198 if (FRAME_WINDOW_P (it->f)
19199 && (ppi = (width_p
19200 ? FRAME_X_DISPLAY_INFO (it->f)->resx
19201 : FRAME_X_DISPLAY_INFO (it->f)->resy),
19202 ppi > 0))
19203 return OK_PIXELS (ppi / pixels);
19204 #endif
19205
19206 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
19207 || (CONSP (Vdisplay_pixels_per_inch)
19208 && (ppi = (width_p
19209 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
19210 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
19211 ppi > 0)))
19212 return OK_PIXELS (ppi / pixels);
19213
19214 return 0;
19215 }
19216 }
19217
19218 #ifdef HAVE_WINDOW_SYSTEM
19219 if (EQ (prop, Qheight))
19220 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
19221 if (EQ (prop, Qwidth))
19222 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
19223 #else
19224 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
19225 return OK_PIXELS (1);
19226 #endif
19227
19228 if (EQ (prop, Qtext))
19229 return OK_PIXELS (width_p
19230 ? window_box_width (it->w, TEXT_AREA)
19231 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
19232
19233 if (align_to && *align_to < 0)
19234 {
19235 *res = 0;
19236 if (EQ (prop, Qleft))
19237 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
19238 if (EQ (prop, Qright))
19239 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
19240 if (EQ (prop, Qcenter))
19241 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
19242 + window_box_width (it->w, TEXT_AREA) / 2);
19243 if (EQ (prop, Qleft_fringe))
19244 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19245 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
19246 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
19247 if (EQ (prop, Qright_fringe))
19248 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19249 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
19250 : window_box_right_offset (it->w, TEXT_AREA));
19251 if (EQ (prop, Qleft_margin))
19252 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
19253 if (EQ (prop, Qright_margin))
19254 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
19255 if (EQ (prop, Qscroll_bar))
19256 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
19257 ? 0
19258 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
19259 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
19260 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19261 : 0)));
19262 }
19263 else
19264 {
19265 if (EQ (prop, Qleft_fringe))
19266 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
19267 if (EQ (prop, Qright_fringe))
19268 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
19269 if (EQ (prop, Qleft_margin))
19270 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
19271 if (EQ (prop, Qright_margin))
19272 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
19273 if (EQ (prop, Qscroll_bar))
19274 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
19275 }
19276
19277 prop = Fbuffer_local_value (prop, it->w->buffer);
19278 }
19279
19280 if (INTEGERP (prop) || FLOATP (prop))
19281 {
19282 int base_unit = (width_p
19283 ? FRAME_COLUMN_WIDTH (it->f)
19284 : FRAME_LINE_HEIGHT (it->f));
19285 return OK_PIXELS (XFLOATINT (prop) * base_unit);
19286 }
19287
19288 if (CONSP (prop))
19289 {
19290 Lisp_Object car = XCAR (prop);
19291 Lisp_Object cdr = XCDR (prop);
19292
19293 if (SYMBOLP (car))
19294 {
19295 #ifdef HAVE_WINDOW_SYSTEM
19296 if (FRAME_WINDOW_P (it->f)
19297 && valid_image_p (prop))
19298 {
19299 int id = lookup_image (it->f, prop);
19300 struct image *img = IMAGE_FROM_ID (it->f, id);
19301
19302 return OK_PIXELS (width_p ? img->width : img->height);
19303 }
19304 #endif
19305 if (EQ (car, Qplus) || EQ (car, Qminus))
19306 {
19307 int first = 1;
19308 double px;
19309
19310 pixels = 0;
19311 while (CONSP (cdr))
19312 {
19313 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
19314 font, width_p, align_to))
19315 return 0;
19316 if (first)
19317 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
19318 else
19319 pixels += px;
19320 cdr = XCDR (cdr);
19321 }
19322 if (EQ (car, Qminus))
19323 pixels = -pixels;
19324 return OK_PIXELS (pixels);
19325 }
19326
19327 car = Fbuffer_local_value (car, it->w->buffer);
19328 }
19329
19330 if (INTEGERP (car) || FLOATP (car))
19331 {
19332 double fact;
19333 pixels = XFLOATINT (car);
19334 if (NILP (cdr))
19335 return OK_PIXELS (pixels);
19336 if (calc_pixel_width_or_height (&fact, it, cdr,
19337 font, width_p, align_to))
19338 return OK_PIXELS (pixels * fact);
19339 return 0;
19340 }
19341
19342 return 0;
19343 }
19344
19345 return 0;
19346 }
19347
19348 \f
19349 /***********************************************************************
19350 Glyph Display
19351 ***********************************************************************/
19352
19353 #ifdef HAVE_WINDOW_SYSTEM
19354
19355 #if GLYPH_DEBUG
19356
19357 void
19358 dump_glyph_string (s)
19359 struct glyph_string *s;
19360 {
19361 fprintf (stderr, "glyph string\n");
19362 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
19363 s->x, s->y, s->width, s->height);
19364 fprintf (stderr, " ybase = %d\n", s->ybase);
19365 fprintf (stderr, " hl = %d\n", s->hl);
19366 fprintf (stderr, " left overhang = %d, right = %d\n",
19367 s->left_overhang, s->right_overhang);
19368 fprintf (stderr, " nchars = %d\n", s->nchars);
19369 fprintf (stderr, " extends to end of line = %d\n",
19370 s->extends_to_end_of_line_p);
19371 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
19372 fprintf (stderr, " bg width = %d\n", s->background_width);
19373 }
19374
19375 #endif /* GLYPH_DEBUG */
19376
19377 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
19378 of XChar2b structures for S; it can't be allocated in
19379 init_glyph_string because it must be allocated via `alloca'. W
19380 is the window on which S is drawn. ROW and AREA are the glyph row
19381 and area within the row from which S is constructed. START is the
19382 index of the first glyph structure covered by S. HL is a
19383 face-override for drawing S. */
19384
19385 #ifdef HAVE_NTGUI
19386 #define OPTIONAL_HDC(hdc) hdc,
19387 #define DECLARE_HDC(hdc) HDC hdc;
19388 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
19389 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
19390 #endif
19391
19392 #ifndef OPTIONAL_HDC
19393 #define OPTIONAL_HDC(hdc)
19394 #define DECLARE_HDC(hdc)
19395 #define ALLOCATE_HDC(hdc, f)
19396 #define RELEASE_HDC(hdc, f)
19397 #endif
19398
19399 static void
19400 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
19401 struct glyph_string *s;
19402 DECLARE_HDC (hdc)
19403 XChar2b *char2b;
19404 struct window *w;
19405 struct glyph_row *row;
19406 enum glyph_row_area area;
19407 int start;
19408 enum draw_glyphs_face hl;
19409 {
19410 bzero (s, sizeof *s);
19411 s->w = w;
19412 s->f = XFRAME (w->frame);
19413 #ifdef HAVE_NTGUI
19414 s->hdc = hdc;
19415 #endif
19416 s->display = FRAME_X_DISPLAY (s->f);
19417 s->window = FRAME_X_WINDOW (s->f);
19418 s->char2b = char2b;
19419 s->hl = hl;
19420 s->row = row;
19421 s->area = area;
19422 s->first_glyph = row->glyphs[area] + start;
19423 s->height = row->height;
19424 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
19425
19426 /* Display the internal border below the tool-bar window. */
19427 if (WINDOWP (s->f->tool_bar_window)
19428 && s->w == XWINDOW (s->f->tool_bar_window))
19429 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
19430
19431 s->ybase = s->y + row->ascent;
19432 }
19433
19434
19435 /* Append the list of glyph strings with head H and tail T to the list
19436 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
19437
19438 static INLINE void
19439 append_glyph_string_lists (head, tail, h, t)
19440 struct glyph_string **head, **tail;
19441 struct glyph_string *h, *t;
19442 {
19443 if (h)
19444 {
19445 if (*head)
19446 (*tail)->next = h;
19447 else
19448 *head = h;
19449 h->prev = *tail;
19450 *tail = t;
19451 }
19452 }
19453
19454
19455 /* Prepend the list of glyph strings with head H and tail T to the
19456 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
19457 result. */
19458
19459 static INLINE void
19460 prepend_glyph_string_lists (head, tail, h, t)
19461 struct glyph_string **head, **tail;
19462 struct glyph_string *h, *t;
19463 {
19464 if (h)
19465 {
19466 if (*head)
19467 (*head)->prev = t;
19468 else
19469 *tail = t;
19470 t->next = *head;
19471 *head = h;
19472 }
19473 }
19474
19475
19476 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
19477 Set *HEAD and *TAIL to the resulting list. */
19478
19479 static INLINE void
19480 append_glyph_string (head, tail, s)
19481 struct glyph_string **head, **tail;
19482 struct glyph_string *s;
19483 {
19484 s->next = s->prev = NULL;
19485 append_glyph_string_lists (head, tail, s, s);
19486 }
19487
19488
19489 /* Get face and two-byte form of character C in face FACE_ID on frame
19490 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19491 means we want to display multibyte text. DISPLAY_P non-zero means
19492 make sure that X resources for the face returned are allocated.
19493 Value is a pointer to a realized face that is ready for display if
19494 DISPLAY_P is non-zero. */
19495
19496 static INLINE struct face *
19497 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19498 struct frame *f;
19499 int c, face_id;
19500 XChar2b *char2b;
19501 int multibyte_p, display_p;
19502 {
19503 struct face *face = FACE_FROM_ID (f, face_id);
19504
19505 if (face->font)
19506 {
19507 unsigned code = face->font->driver->encode_char (face->font, c);
19508
19509 if (code != FONT_INVALID_CODE)
19510 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19511 else
19512 STORE_XCHAR2B (char2b, 0, 0);
19513 }
19514
19515 /* Make sure X resources of the face are allocated. */
19516 #ifdef HAVE_X_WINDOWS
19517 if (display_p)
19518 #endif
19519 {
19520 xassert (face != NULL);
19521 PREPARE_FACE_FOR_DISPLAY (f, face);
19522 }
19523
19524 return face;
19525 }
19526
19527
19528 /* Get face and two-byte form of character glyph GLYPH on frame F.
19529 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
19530 a pointer to a realized face that is ready for display. */
19531
19532 static INLINE struct face *
19533 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19534 struct frame *f;
19535 struct glyph *glyph;
19536 XChar2b *char2b;
19537 int *two_byte_p;
19538 {
19539 struct face *face;
19540
19541 xassert (glyph->type == CHAR_GLYPH);
19542 face = FACE_FROM_ID (f, glyph->face_id);
19543
19544 if (two_byte_p)
19545 *two_byte_p = 0;
19546
19547 if (face->font)
19548 {
19549 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
19550
19551 if (code != FONT_INVALID_CODE)
19552 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19553 else
19554 STORE_XCHAR2B (char2b, 0, 0);
19555 }
19556
19557 /* Make sure X resources of the face are allocated. */
19558 xassert (face != NULL);
19559 PREPARE_FACE_FOR_DISPLAY (f, face);
19560 return face;
19561 }
19562
19563
19564 /* Fill glyph string S with composition components specified by S->cmp.
19565
19566 BASE_FACE is the base face of the composition.
19567 S->cmp_from is the index of the first component for S.
19568
19569 OVERLAPS non-zero means S should draw the foreground only, and use
19570 its physical height for clipping. See also draw_glyphs.
19571
19572 Value is the index of a component not in S. */
19573
19574 static int
19575 fill_composite_glyph_string (s, base_face, overlaps)
19576 struct glyph_string *s;
19577 struct face *base_face;
19578 int overlaps;
19579 {
19580 int i;
19581 /* For all glyphs of this composition, starting at the offset
19582 S->cmp_from, until we reach the end of the definition or encounter a
19583 glyph that requires the different face, add it to S. */
19584 struct face *face;
19585
19586 xassert (s);
19587
19588 s->for_overlaps = overlaps;
19589 s->face = NULL;
19590 s->font = NULL;
19591 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
19592 {
19593 int c = COMPOSITION_GLYPH (s->cmp, i);
19594
19595 if (c != '\t')
19596 {
19597 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
19598 -1, Qnil);
19599
19600 face = get_char_face_and_encoding (s->f, c, face_id,
19601 s->char2b + i, 1, 1);
19602 if (face)
19603 {
19604 if (! s->face)
19605 {
19606 s->face = face;
19607 s->font = s->face->font;
19608 }
19609 else if (s->face != face)
19610 break;
19611 }
19612 }
19613 ++s->nchars;
19614 }
19615 s->cmp_to = i;
19616
19617 /* All glyph strings for the same composition has the same width,
19618 i.e. the width set for the first component of the composition. */
19619 s->width = s->first_glyph->pixel_width;
19620
19621 /* If the specified font could not be loaded, use the frame's
19622 default font, but record the fact that we couldn't load it in
19623 the glyph string so that we can draw rectangles for the
19624 characters of the glyph string. */
19625 if (s->font == NULL)
19626 {
19627 s->font_not_found_p = 1;
19628 s->font = FRAME_FONT (s->f);
19629 }
19630
19631 /* Adjust base line for subscript/superscript text. */
19632 s->ybase += s->first_glyph->voffset;
19633
19634 /* This glyph string must always be drawn with 16-bit functions. */
19635 s->two_byte_p = 1;
19636
19637 return s->cmp_to;
19638 }
19639
19640 static int
19641 fill_gstring_glyph_string (s, face_id, start, end, overlaps)
19642 struct glyph_string *s;
19643 int face_id;
19644 int start, end, overlaps;
19645 {
19646 struct glyph *glyph, *last;
19647 Lisp_Object lgstring;
19648 int i;
19649
19650 s->for_overlaps = overlaps;
19651 glyph = s->row->glyphs[s->area] + start;
19652 last = s->row->glyphs[s->area] + end;
19653 s->cmp_id = glyph->u.cmp.id;
19654 s->cmp_from = glyph->u.cmp.from;
19655 s->cmp_to = glyph->u.cmp.to + 1;
19656 s->face = FACE_FROM_ID (s->f, face_id);
19657 lgstring = composition_gstring_from_id (s->cmp_id);
19658 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
19659 glyph++;
19660 while (glyph < last
19661 && glyph->u.cmp.automatic
19662 && glyph->u.cmp.id == s->cmp_id
19663 && s->cmp_to == glyph->u.cmp.from)
19664 s->cmp_to = (glyph++)->u.cmp.to + 1;
19665
19666 for (i = s->cmp_from; i < s->cmp_to; i++)
19667 {
19668 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
19669 unsigned code = LGLYPH_CODE (lglyph);
19670
19671 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
19672 }
19673 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
19674 return glyph - s->row->glyphs[s->area];
19675 }
19676
19677
19678 /* Fill glyph string S from a sequence of character glyphs.
19679
19680 FACE_ID is the face id of the string. START is the index of the
19681 first glyph to consider, END is the index of the last + 1.
19682 OVERLAPS non-zero means S should draw the foreground only, and use
19683 its physical height for clipping. See also draw_glyphs.
19684
19685 Value is the index of the first glyph not in S. */
19686
19687 static int
19688 fill_glyph_string (s, face_id, start, end, overlaps)
19689 struct glyph_string *s;
19690 int face_id;
19691 int start, end, overlaps;
19692 {
19693 struct glyph *glyph, *last;
19694 int voffset;
19695 int glyph_not_available_p;
19696
19697 xassert (s->f == XFRAME (s->w->frame));
19698 xassert (s->nchars == 0);
19699 xassert (start >= 0 && end > start);
19700
19701 s->for_overlaps = overlaps;
19702 glyph = s->row->glyphs[s->area] + start;
19703 last = s->row->glyphs[s->area] + end;
19704 voffset = glyph->voffset;
19705 s->padding_p = glyph->padding_p;
19706 glyph_not_available_p = glyph->glyph_not_available_p;
19707
19708 while (glyph < last
19709 && glyph->type == CHAR_GLYPH
19710 && glyph->voffset == voffset
19711 /* Same face id implies same font, nowadays. */
19712 && glyph->face_id == face_id
19713 && glyph->glyph_not_available_p == glyph_not_available_p)
19714 {
19715 int two_byte_p;
19716
19717 s->face = get_glyph_face_and_encoding (s->f, glyph,
19718 s->char2b + s->nchars,
19719 &two_byte_p);
19720 s->two_byte_p = two_byte_p;
19721 ++s->nchars;
19722 xassert (s->nchars <= end - start);
19723 s->width += glyph->pixel_width;
19724 if (glyph++->padding_p != s->padding_p)
19725 break;
19726 }
19727
19728 s->font = s->face->font;
19729
19730 /* If the specified font could not be loaded, use the frame's font,
19731 but record the fact that we couldn't load it in
19732 S->font_not_found_p so that we can draw rectangles for the
19733 characters of the glyph string. */
19734 if (s->font == NULL || glyph_not_available_p)
19735 {
19736 s->font_not_found_p = 1;
19737 s->font = FRAME_FONT (s->f);
19738 }
19739
19740 /* Adjust base line for subscript/superscript text. */
19741 s->ybase += voffset;
19742
19743 xassert (s->face && s->face->gc);
19744 return glyph - s->row->glyphs[s->area];
19745 }
19746
19747
19748 /* Fill glyph string S from image glyph S->first_glyph. */
19749
19750 static void
19751 fill_image_glyph_string (s)
19752 struct glyph_string *s;
19753 {
19754 xassert (s->first_glyph->type == IMAGE_GLYPH);
19755 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19756 xassert (s->img);
19757 s->slice = s->first_glyph->slice;
19758 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19759 s->font = s->face->font;
19760 s->width = s->first_glyph->pixel_width;
19761
19762 /* Adjust base line for subscript/superscript text. */
19763 s->ybase += s->first_glyph->voffset;
19764 }
19765
19766
19767 /* Fill glyph string S from a sequence of stretch glyphs.
19768
19769 ROW is the glyph row in which the glyphs are found, AREA is the
19770 area within the row. START is the index of the first glyph to
19771 consider, END is the index of the last + 1.
19772
19773 Value is the index of the first glyph not in S. */
19774
19775 static int
19776 fill_stretch_glyph_string (s, row, area, start, end)
19777 struct glyph_string *s;
19778 struct glyph_row *row;
19779 enum glyph_row_area area;
19780 int start, end;
19781 {
19782 struct glyph *glyph, *last;
19783 int voffset, face_id;
19784
19785 xassert (s->first_glyph->type == STRETCH_GLYPH);
19786
19787 glyph = s->row->glyphs[s->area] + start;
19788 last = s->row->glyphs[s->area] + end;
19789 face_id = glyph->face_id;
19790 s->face = FACE_FROM_ID (s->f, face_id);
19791 s->font = s->face->font;
19792 s->width = glyph->pixel_width;
19793 s->nchars = 1;
19794 voffset = glyph->voffset;
19795
19796 for (++glyph;
19797 (glyph < last
19798 && glyph->type == STRETCH_GLYPH
19799 && glyph->voffset == voffset
19800 && glyph->face_id == face_id);
19801 ++glyph)
19802 s->width += glyph->pixel_width;
19803
19804 /* Adjust base line for subscript/superscript text. */
19805 s->ybase += voffset;
19806
19807 /* The case that face->gc == 0 is handled when drawing the glyph
19808 string by calling PREPARE_FACE_FOR_DISPLAY. */
19809 xassert (s->face);
19810 return glyph - s->row->glyphs[s->area];
19811 }
19812
19813 static struct font_metrics *
19814 get_per_char_metric (f, font, char2b)
19815 struct frame *f;
19816 struct font *font;
19817 XChar2b *char2b;
19818 {
19819 static struct font_metrics metrics;
19820 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
19821
19822 if (! font || code == FONT_INVALID_CODE)
19823 return NULL;
19824 font->driver->text_extents (font, &code, 1, &metrics);
19825 return &metrics;
19826 }
19827
19828 /* EXPORT for RIF:
19829 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19830 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19831 assumed to be zero. */
19832
19833 void
19834 x_get_glyph_overhangs (glyph, f, left, right)
19835 struct glyph *glyph;
19836 struct frame *f;
19837 int *left, *right;
19838 {
19839 *left = *right = 0;
19840
19841 if (glyph->type == CHAR_GLYPH)
19842 {
19843 struct face *face;
19844 XChar2b char2b;
19845 struct font_metrics *pcm;
19846
19847 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19848 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
19849 {
19850 if (pcm->rbearing > pcm->width)
19851 *right = pcm->rbearing - pcm->width;
19852 if (pcm->lbearing < 0)
19853 *left = -pcm->lbearing;
19854 }
19855 }
19856 else if (glyph->type == COMPOSITE_GLYPH)
19857 {
19858 if (! glyph->u.cmp.automatic)
19859 {
19860 struct composition *cmp = composition_table[glyph->u.cmp.id];
19861
19862 if (cmp->rbearing > cmp->pixel_width)
19863 *right = cmp->rbearing - cmp->pixel_width;
19864 if (cmp->lbearing < 0)
19865 *left = - cmp->lbearing;
19866 }
19867 else
19868 {
19869 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
19870 struct font_metrics metrics;
19871
19872 composition_gstring_width (gstring, glyph->u.cmp.from,
19873 glyph->u.cmp.to + 1, &metrics);
19874 if (metrics.rbearing > metrics.width)
19875 *right = metrics.rbearing - metrics.width;
19876 if (metrics.lbearing < 0)
19877 *left = - metrics.lbearing;
19878 }
19879 }
19880 }
19881
19882
19883 /* Return the index of the first glyph preceding glyph string S that
19884 is overwritten by S because of S's left overhang. Value is -1
19885 if no glyphs are overwritten. */
19886
19887 static int
19888 left_overwritten (s)
19889 struct glyph_string *s;
19890 {
19891 int k;
19892
19893 if (s->left_overhang)
19894 {
19895 int x = 0, i;
19896 struct glyph *glyphs = s->row->glyphs[s->area];
19897 int first = s->first_glyph - glyphs;
19898
19899 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19900 x -= glyphs[i].pixel_width;
19901
19902 k = i + 1;
19903 }
19904 else
19905 k = -1;
19906
19907 return k;
19908 }
19909
19910
19911 /* Return the index of the first glyph preceding glyph string S that
19912 is overwriting S because of its right overhang. Value is -1 if no
19913 glyph in front of S overwrites S. */
19914
19915 static int
19916 left_overwriting (s)
19917 struct glyph_string *s;
19918 {
19919 int i, k, x;
19920 struct glyph *glyphs = s->row->glyphs[s->area];
19921 int first = s->first_glyph - glyphs;
19922
19923 k = -1;
19924 x = 0;
19925 for (i = first - 1; i >= 0; --i)
19926 {
19927 int left, right;
19928 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19929 if (x + right > 0)
19930 k = i;
19931 x -= glyphs[i].pixel_width;
19932 }
19933
19934 return k;
19935 }
19936
19937
19938 /* Return the index of the last glyph following glyph string S that is
19939 overwritten by S because of S's right overhang. Value is -1 if
19940 no such glyph is found. */
19941
19942 static int
19943 right_overwritten (s)
19944 struct glyph_string *s;
19945 {
19946 int k = -1;
19947
19948 if (s->right_overhang)
19949 {
19950 int x = 0, i;
19951 struct glyph *glyphs = s->row->glyphs[s->area];
19952 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19953 int end = s->row->used[s->area];
19954
19955 for (i = first; i < end && s->right_overhang > x; ++i)
19956 x += glyphs[i].pixel_width;
19957
19958 k = i;
19959 }
19960
19961 return k;
19962 }
19963
19964
19965 /* Return the index of the last glyph following glyph string S that
19966 overwrites S because of its left overhang. Value is negative
19967 if no such glyph is found. */
19968
19969 static int
19970 right_overwriting (s)
19971 struct glyph_string *s;
19972 {
19973 int i, k, x;
19974 int end = s->row->used[s->area];
19975 struct glyph *glyphs = s->row->glyphs[s->area];
19976 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19977
19978 k = -1;
19979 x = 0;
19980 for (i = first; i < end; ++i)
19981 {
19982 int left, right;
19983 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19984 if (x - left < 0)
19985 k = i;
19986 x += glyphs[i].pixel_width;
19987 }
19988
19989 return k;
19990 }
19991
19992
19993 /* Set background width of glyph string S. START is the index of the
19994 first glyph following S. LAST_X is the right-most x-position + 1
19995 in the drawing area. */
19996
19997 static INLINE void
19998 set_glyph_string_background_width (s, start, last_x)
19999 struct glyph_string *s;
20000 int start;
20001 int last_x;
20002 {
20003 /* If the face of this glyph string has to be drawn to the end of
20004 the drawing area, set S->extends_to_end_of_line_p. */
20005
20006 if (start == s->row->used[s->area]
20007 && s->area == TEXT_AREA
20008 && ((s->row->fill_line_p
20009 && (s->hl == DRAW_NORMAL_TEXT
20010 || s->hl == DRAW_IMAGE_RAISED
20011 || s->hl == DRAW_IMAGE_SUNKEN))
20012 || s->hl == DRAW_MOUSE_FACE))
20013 s->extends_to_end_of_line_p = 1;
20014
20015 /* If S extends its face to the end of the line, set its
20016 background_width to the distance to the right edge of the drawing
20017 area. */
20018 if (s->extends_to_end_of_line_p)
20019 s->background_width = last_x - s->x + 1;
20020 else
20021 s->background_width = s->width;
20022 }
20023
20024
20025 /* Compute overhangs and x-positions for glyph string S and its
20026 predecessors, or successors. X is the starting x-position for S.
20027 BACKWARD_P non-zero means process predecessors. */
20028
20029 static void
20030 compute_overhangs_and_x (s, x, backward_p)
20031 struct glyph_string *s;
20032 int x;
20033 int backward_p;
20034 {
20035 if (backward_p)
20036 {
20037 while (s)
20038 {
20039 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20040 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20041 x -= s->width;
20042 s->x = x;
20043 s = s->prev;
20044 }
20045 }
20046 else
20047 {
20048 while (s)
20049 {
20050 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20051 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20052 s->x = x;
20053 x += s->width;
20054 s = s->next;
20055 }
20056 }
20057 }
20058
20059
20060
20061 /* The following macros are only called from draw_glyphs below.
20062 They reference the following parameters of that function directly:
20063 `w', `row', `area', and `overlap_p'
20064 as well as the following local variables:
20065 `s', `f', and `hdc' (in W32) */
20066
20067 #ifdef HAVE_NTGUI
20068 /* On W32, silently add local `hdc' variable to argument list of
20069 init_glyph_string. */
20070 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20071 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20072 #else
20073 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20074 init_glyph_string (s, char2b, w, row, area, start, hl)
20075 #endif
20076
20077 /* Add a glyph string for a stretch glyph to the list of strings
20078 between HEAD and TAIL. START is the index of the stretch glyph in
20079 row area AREA of glyph row ROW. END is the index of the last glyph
20080 in that glyph row area. X is the current output position assigned
20081 to the new glyph string constructed. HL overrides that face of the
20082 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20083 is the right-most x-position of the drawing area. */
20084
20085 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
20086 and below -- keep them on one line. */
20087 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20088 do \
20089 { \
20090 s = (struct glyph_string *) alloca (sizeof *s); \
20091 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
20092 START = fill_stretch_glyph_string (s, row, area, START, END); \
20093 append_glyph_string (&HEAD, &TAIL, s); \
20094 s->x = (X); \
20095 } \
20096 while (0)
20097
20098
20099 /* Add a glyph string for an image glyph to the list of strings
20100 between HEAD and TAIL. START is the index of the image glyph in
20101 row area AREA of glyph row ROW. END is the index of the last glyph
20102 in that glyph row area. X is the current output position assigned
20103 to the new glyph string constructed. HL overrides that face of the
20104 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20105 is the right-most x-position of the drawing area. */
20106
20107 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20108 do \
20109 { \
20110 s = (struct glyph_string *) alloca (sizeof *s); \
20111 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
20112 fill_image_glyph_string (s); \
20113 append_glyph_string (&HEAD, &TAIL, s); \
20114 ++START; \
20115 s->x = (X); \
20116 } \
20117 while (0)
20118
20119
20120 /* Add a glyph string for a sequence of character glyphs to the list
20121 of strings between HEAD and TAIL. START is the index of the first
20122 glyph in row area AREA of glyph row ROW that is part of the new
20123 glyph string. END is the index of the last glyph in that glyph row
20124 area. X is the current output position assigned to the new glyph
20125 string constructed. HL overrides that face of the glyph; e.g. it
20126 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
20127 right-most x-position of the drawing area. */
20128
20129 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
20130 do \
20131 { \
20132 int face_id; \
20133 XChar2b *char2b; \
20134 \
20135 face_id = (row)->glyphs[area][START].face_id; \
20136 \
20137 s = (struct glyph_string *) alloca (sizeof *s); \
20138 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
20139 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20140 append_glyph_string (&HEAD, &TAIL, s); \
20141 s->x = (X); \
20142 START = fill_glyph_string (s, face_id, START, END, overlaps); \
20143 } \
20144 while (0)
20145
20146
20147 /* Add a glyph string for a composite sequence to the list of strings
20148 between HEAD and TAIL. START is the index of the first glyph in
20149 row area AREA of glyph row ROW that is part of the new glyph
20150 string. END is the index of the last glyph in that glyph row area.
20151 X is the current output position assigned to the new glyph string
20152 constructed. HL overrides that face of the glyph; e.g. it is
20153 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
20154 x-position of the drawing area. */
20155
20156 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20157 do { \
20158 int face_id = (row)->glyphs[area][START].face_id; \
20159 struct face *base_face = FACE_FROM_ID (f, face_id); \
20160 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
20161 struct composition *cmp = composition_table[cmp_id]; \
20162 XChar2b *char2b; \
20163 struct glyph_string *first_s; \
20164 int n; \
20165 \
20166 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
20167 \
20168 /* Make glyph_strings for each glyph sequence that is drawable by \
20169 the same face, and append them to HEAD/TAIL. */ \
20170 for (n = 0; n < cmp->glyph_len;) \
20171 { \
20172 s = (struct glyph_string *) alloca (sizeof *s); \
20173 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20174 append_glyph_string (&(HEAD), &(TAIL), s); \
20175 s->cmp = cmp; \
20176 s->cmp_from = n; \
20177 s->x = (X); \
20178 if (n == 0) \
20179 first_s = s; \
20180 n = fill_composite_glyph_string (s, base_face, overlaps); \
20181 } \
20182 \
20183 ++START; \
20184 s = first_s; \
20185 } while (0)
20186
20187
20188 /* Add a glyph string for a glyph-string sequence to the list of strings
20189 between HEAD and TAIL. */
20190
20191 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20192 do { \
20193 int face_id; \
20194 XChar2b *char2b; \
20195 Lisp_Object gstring; \
20196 \
20197 face_id = (row)->glyphs[area][START].face_id; \
20198 gstring = (composition_gstring_from_id \
20199 ((row)->glyphs[area][START].u.cmp.id)); \
20200 s = (struct glyph_string *) alloca (sizeof *s); \
20201 char2b = (XChar2b *) alloca ((sizeof *char2b) \
20202 * LGSTRING_GLYPH_LEN (gstring)); \
20203 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20204 append_glyph_string (&(HEAD), &(TAIL), s); \
20205 s->x = (X); \
20206 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
20207 } while (0)
20208
20209
20210 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
20211 of AREA of glyph row ROW on window W between indices START and END.
20212 HL overrides the face for drawing glyph strings, e.g. it is
20213 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
20214 x-positions of the drawing area.
20215
20216 This is an ugly monster macro construct because we must use alloca
20217 to allocate glyph strings (because draw_glyphs can be called
20218 asynchronously). */
20219
20220 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
20221 do \
20222 { \
20223 HEAD = TAIL = NULL; \
20224 while (START < END) \
20225 { \
20226 struct glyph *first_glyph = (row)->glyphs[area] + START; \
20227 switch (first_glyph->type) \
20228 { \
20229 case CHAR_GLYPH: \
20230 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
20231 HL, X, LAST_X); \
20232 break; \
20233 \
20234 case COMPOSITE_GLYPH: \
20235 if (first_glyph->u.cmp.automatic) \
20236 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
20237 HL, X, LAST_X); \
20238 else \
20239 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
20240 HL, X, LAST_X); \
20241 break; \
20242 \
20243 case STRETCH_GLYPH: \
20244 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
20245 HL, X, LAST_X); \
20246 break; \
20247 \
20248 case IMAGE_GLYPH: \
20249 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
20250 HL, X, LAST_X); \
20251 break; \
20252 \
20253 default: \
20254 abort (); \
20255 } \
20256 \
20257 if (s) \
20258 { \
20259 set_glyph_string_background_width (s, START, LAST_X); \
20260 (X) += s->width; \
20261 } \
20262 } \
20263 } while (0)
20264
20265
20266 /* Draw glyphs between START and END in AREA of ROW on window W,
20267 starting at x-position X. X is relative to AREA in W. HL is a
20268 face-override with the following meaning:
20269
20270 DRAW_NORMAL_TEXT draw normally
20271 DRAW_CURSOR draw in cursor face
20272 DRAW_MOUSE_FACE draw in mouse face.
20273 DRAW_INVERSE_VIDEO draw in mode line face
20274 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
20275 DRAW_IMAGE_RAISED draw an image with a raised relief around it
20276
20277 If OVERLAPS is non-zero, draw only the foreground of characters and
20278 clip to the physical height of ROW. Non-zero value also defines
20279 the overlapping part to be drawn:
20280
20281 OVERLAPS_PRED overlap with preceding rows
20282 OVERLAPS_SUCC overlap with succeeding rows
20283 OVERLAPS_BOTH overlap with both preceding/succeeding rows
20284 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
20285
20286 Value is the x-position reached, relative to AREA of W. */
20287
20288 static int
20289 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
20290 struct window *w;
20291 int x;
20292 struct glyph_row *row;
20293 enum glyph_row_area area;
20294 EMACS_INT start, end;
20295 enum draw_glyphs_face hl;
20296 int overlaps;
20297 {
20298 struct glyph_string *head, *tail;
20299 struct glyph_string *s;
20300 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
20301 int i, j, x_reached, last_x, area_left = 0;
20302 struct frame *f = XFRAME (WINDOW_FRAME (w));
20303 DECLARE_HDC (hdc);
20304
20305 ALLOCATE_HDC (hdc, f);
20306
20307 /* Let's rather be paranoid than getting a SEGV. */
20308 end = min (end, row->used[area]);
20309 start = max (0, start);
20310 start = min (end, start);
20311
20312 /* Translate X to frame coordinates. Set last_x to the right
20313 end of the drawing area. */
20314 if (row->full_width_p)
20315 {
20316 /* X is relative to the left edge of W, without scroll bars
20317 or fringes. */
20318 area_left = WINDOW_LEFT_EDGE_X (w);
20319 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
20320 }
20321 else
20322 {
20323 area_left = window_box_left (w, area);
20324 last_x = area_left + window_box_width (w, area);
20325 }
20326 x += area_left;
20327
20328 /* Build a doubly-linked list of glyph_string structures between
20329 head and tail from what we have to draw. Note that the macro
20330 BUILD_GLYPH_STRINGS will modify its start parameter. That's
20331 the reason we use a separate variable `i'. */
20332 i = start;
20333 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
20334 if (tail)
20335 x_reached = tail->x + tail->background_width;
20336 else
20337 x_reached = x;
20338
20339 /* If there are any glyphs with lbearing < 0 or rbearing > width in
20340 the row, redraw some glyphs in front or following the glyph
20341 strings built above. */
20342 if (head && !overlaps && row->contains_overlapping_glyphs_p)
20343 {
20344 struct glyph_string *h, *t;
20345 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20346 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
20347 int dummy_x = 0;
20348
20349 /* If mouse highlighting is on, we may need to draw adjacent
20350 glyphs using mouse-face highlighting. */
20351 if (area == TEXT_AREA && row->mouse_face_p)
20352 {
20353 struct glyph_row *mouse_beg_row, *mouse_end_row;
20354
20355 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20356 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20357
20358 if (row >= mouse_beg_row && row <= mouse_end_row)
20359 {
20360 check_mouse_face = 1;
20361 mouse_beg_col = (row == mouse_beg_row)
20362 ? dpyinfo->mouse_face_beg_col : 0;
20363 mouse_end_col = (row == mouse_end_row)
20364 ? dpyinfo->mouse_face_end_col
20365 : row->used[TEXT_AREA];
20366 }
20367 }
20368
20369 /* Compute overhangs for all glyph strings. */
20370 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
20371 for (s = head; s; s = s->next)
20372 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
20373
20374 /* Prepend glyph strings for glyphs in front of the first glyph
20375 string that are overwritten because of the first glyph
20376 string's left overhang. The background of all strings
20377 prepended must be drawn because the first glyph string
20378 draws over it. */
20379 i = left_overwritten (head);
20380 if (i >= 0)
20381 {
20382 enum draw_glyphs_face overlap_hl;
20383
20384 /* If this row contains mouse highlighting, attempt to draw
20385 the overlapped glyphs with the correct highlight. This
20386 code fails if the overlap encompasses more than one glyph
20387 and mouse-highlight spans only some of these glyphs.
20388 However, making it work perfectly involves a lot more
20389 code, and I don't know if the pathological case occurs in
20390 practice, so we'll stick to this for now. --- cyd */
20391 if (check_mouse_face
20392 && mouse_beg_col < start && mouse_end_col > i)
20393 overlap_hl = DRAW_MOUSE_FACE;
20394 else
20395 overlap_hl = DRAW_NORMAL_TEXT;
20396
20397 j = i;
20398 BUILD_GLYPH_STRINGS (j, start, h, t,
20399 overlap_hl, dummy_x, last_x);
20400 compute_overhangs_and_x (t, head->x, 1);
20401 prepend_glyph_string_lists (&head, &tail, h, t);
20402 clip_head = head;
20403 }
20404
20405 /* Prepend glyph strings for glyphs in front of the first glyph
20406 string that overwrite that glyph string because of their
20407 right overhang. For these strings, only the foreground must
20408 be drawn, because it draws over the glyph string at `head'.
20409 The background must not be drawn because this would overwrite
20410 right overhangs of preceding glyphs for which no glyph
20411 strings exist. */
20412 i = left_overwriting (head);
20413 if (i >= 0)
20414 {
20415 enum draw_glyphs_face overlap_hl;
20416
20417 if (check_mouse_face
20418 && mouse_beg_col < start && mouse_end_col > i)
20419 overlap_hl = DRAW_MOUSE_FACE;
20420 else
20421 overlap_hl = DRAW_NORMAL_TEXT;
20422
20423 clip_head = head;
20424 BUILD_GLYPH_STRINGS (i, start, h, t,
20425 overlap_hl, dummy_x, last_x);
20426 for (s = h; s; s = s->next)
20427 s->background_filled_p = 1;
20428 compute_overhangs_and_x (t, head->x, 1);
20429 prepend_glyph_string_lists (&head, &tail, h, t);
20430 }
20431
20432 /* Append glyphs strings for glyphs following the last glyph
20433 string tail that are overwritten by tail. The background of
20434 these strings has to be drawn because tail's foreground draws
20435 over it. */
20436 i = right_overwritten (tail);
20437 if (i >= 0)
20438 {
20439 enum draw_glyphs_face overlap_hl;
20440
20441 if (check_mouse_face
20442 && mouse_beg_col < i && mouse_end_col > end)
20443 overlap_hl = DRAW_MOUSE_FACE;
20444 else
20445 overlap_hl = DRAW_NORMAL_TEXT;
20446
20447 BUILD_GLYPH_STRINGS (end, i, h, t,
20448 overlap_hl, x, last_x);
20449 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20450 append_glyph_string_lists (&head, &tail, h, t);
20451 clip_tail = tail;
20452 }
20453
20454 /* Append glyph strings for glyphs following the last glyph
20455 string tail that overwrite tail. The foreground of such
20456 glyphs has to be drawn because it writes into the background
20457 of tail. The background must not be drawn because it could
20458 paint over the foreground of following glyphs. */
20459 i = right_overwriting (tail);
20460 if (i >= 0)
20461 {
20462 enum draw_glyphs_face overlap_hl;
20463 if (check_mouse_face
20464 && mouse_beg_col < i && mouse_end_col > end)
20465 overlap_hl = DRAW_MOUSE_FACE;
20466 else
20467 overlap_hl = DRAW_NORMAL_TEXT;
20468
20469 clip_tail = tail;
20470 i++; /* We must include the Ith glyph. */
20471 BUILD_GLYPH_STRINGS (end, i, h, t,
20472 overlap_hl, x, last_x);
20473 for (s = h; s; s = s->next)
20474 s->background_filled_p = 1;
20475 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20476 append_glyph_string_lists (&head, &tail, h, t);
20477 }
20478 if (clip_head || clip_tail)
20479 for (s = head; s; s = s->next)
20480 {
20481 s->clip_head = clip_head;
20482 s->clip_tail = clip_tail;
20483 }
20484 }
20485
20486 /* Draw all strings. */
20487 for (s = head; s; s = s->next)
20488 FRAME_RIF (f)->draw_glyph_string (s);
20489
20490 #ifndef HAVE_NS
20491 /* When focus a sole frame and move horizontally, this sets on_p to 0
20492 causing a failure to erase prev cursor position. */
20493 if (area == TEXT_AREA
20494 && !row->full_width_p
20495 /* When drawing overlapping rows, only the glyph strings'
20496 foreground is drawn, which doesn't erase a cursor
20497 completely. */
20498 && !overlaps)
20499 {
20500 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
20501 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
20502 : (tail ? tail->x + tail->background_width : x));
20503 x0 -= area_left;
20504 x1 -= area_left;
20505
20506 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
20507 row->y, MATRIX_ROW_BOTTOM_Y (row));
20508 }
20509 #endif
20510
20511 /* Value is the x-position up to which drawn, relative to AREA of W.
20512 This doesn't include parts drawn because of overhangs. */
20513 if (row->full_width_p)
20514 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
20515 else
20516 x_reached -= area_left;
20517
20518 RELEASE_HDC (hdc, f);
20519
20520 return x_reached;
20521 }
20522
20523 /* Expand row matrix if too narrow. Don't expand if area
20524 is not present. */
20525
20526 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
20527 { \
20528 if (!fonts_changed_p \
20529 && (it->glyph_row->glyphs[area] \
20530 < it->glyph_row->glyphs[area + 1])) \
20531 { \
20532 it->w->ncols_scale_factor++; \
20533 fonts_changed_p = 1; \
20534 } \
20535 }
20536
20537 /* Store one glyph for IT->char_to_display in IT->glyph_row.
20538 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20539
20540 static INLINE void
20541 append_glyph (it)
20542 struct it *it;
20543 {
20544 struct glyph *glyph;
20545 enum glyph_row_area area = it->area;
20546
20547 xassert (it->glyph_row);
20548 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
20549
20550 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20551 if (glyph < it->glyph_row->glyphs[area + 1])
20552 {
20553 glyph->charpos = CHARPOS (it->position);
20554 glyph->object = it->object;
20555 if (it->pixel_width > 0)
20556 {
20557 glyph->pixel_width = it->pixel_width;
20558 glyph->padding_p = 0;
20559 }
20560 else
20561 {
20562 /* Assure at least 1-pixel width. Otherwise, cursor can't
20563 be displayed correctly. */
20564 glyph->pixel_width = 1;
20565 glyph->padding_p = 1;
20566 }
20567 glyph->ascent = it->ascent;
20568 glyph->descent = it->descent;
20569 glyph->voffset = it->voffset;
20570 glyph->type = CHAR_GLYPH;
20571 glyph->avoid_cursor_p = it->avoid_cursor_p;
20572 glyph->multibyte_p = it->multibyte_p;
20573 glyph->left_box_line_p = it->start_of_box_run_p;
20574 glyph->right_box_line_p = it->end_of_box_run_p;
20575 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20576 || it->phys_descent > it->descent);
20577 glyph->glyph_not_available_p = it->glyph_not_available_p;
20578 glyph->face_id = it->face_id;
20579 glyph->u.ch = it->char_to_display;
20580 glyph->slice = null_glyph_slice;
20581 glyph->font_type = FONT_TYPE_UNKNOWN;
20582 ++it->glyph_row->used[area];
20583 }
20584 else
20585 IT_EXPAND_MATRIX_WIDTH (it, area);
20586 }
20587
20588 /* Store one glyph for the composition IT->cmp_it.id in
20589 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
20590 non-null. */
20591
20592 static INLINE void
20593 append_composite_glyph (it)
20594 struct it *it;
20595 {
20596 struct glyph *glyph;
20597 enum glyph_row_area area = it->area;
20598
20599 xassert (it->glyph_row);
20600
20601 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20602 if (glyph < it->glyph_row->glyphs[area + 1])
20603 {
20604 glyph->charpos = CHARPOS (it->position);
20605 glyph->object = it->object;
20606 glyph->pixel_width = it->pixel_width;
20607 glyph->ascent = it->ascent;
20608 glyph->descent = it->descent;
20609 glyph->voffset = it->voffset;
20610 glyph->type = COMPOSITE_GLYPH;
20611 if (it->cmp_it.ch < 0)
20612 {
20613 glyph->u.cmp.automatic = 0;
20614 glyph->u.cmp.id = it->cmp_it.id;
20615 }
20616 else
20617 {
20618 glyph->u.cmp.automatic = 1;
20619 glyph->u.cmp.id = it->cmp_it.id;
20620 glyph->u.cmp.from = it->cmp_it.from;
20621 glyph->u.cmp.to = it->cmp_it.to - 1;
20622 }
20623 glyph->avoid_cursor_p = it->avoid_cursor_p;
20624 glyph->multibyte_p = it->multibyte_p;
20625 glyph->left_box_line_p = it->start_of_box_run_p;
20626 glyph->right_box_line_p = it->end_of_box_run_p;
20627 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20628 || it->phys_descent > it->descent);
20629 glyph->padding_p = 0;
20630 glyph->glyph_not_available_p = 0;
20631 glyph->face_id = it->face_id;
20632 glyph->slice = null_glyph_slice;
20633 glyph->font_type = FONT_TYPE_UNKNOWN;
20634 ++it->glyph_row->used[area];
20635 }
20636 else
20637 IT_EXPAND_MATRIX_WIDTH (it, area);
20638 }
20639
20640
20641 /* Change IT->ascent and IT->height according to the setting of
20642 IT->voffset. */
20643
20644 static INLINE void
20645 take_vertical_position_into_account (it)
20646 struct it *it;
20647 {
20648 if (it->voffset)
20649 {
20650 if (it->voffset < 0)
20651 /* Increase the ascent so that we can display the text higher
20652 in the line. */
20653 it->ascent -= it->voffset;
20654 else
20655 /* Increase the descent so that we can display the text lower
20656 in the line. */
20657 it->descent += it->voffset;
20658 }
20659 }
20660
20661
20662 /* Produce glyphs/get display metrics for the image IT is loaded with.
20663 See the description of struct display_iterator in dispextern.h for
20664 an overview of struct display_iterator. */
20665
20666 static void
20667 produce_image_glyph (it)
20668 struct it *it;
20669 {
20670 struct image *img;
20671 struct face *face;
20672 int glyph_ascent, crop;
20673 struct glyph_slice slice;
20674
20675 xassert (it->what == IT_IMAGE);
20676
20677 face = FACE_FROM_ID (it->f, it->face_id);
20678 xassert (face);
20679 /* Make sure X resources of the face is loaded. */
20680 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20681
20682 if (it->image_id < 0)
20683 {
20684 /* Fringe bitmap. */
20685 it->ascent = it->phys_ascent = 0;
20686 it->descent = it->phys_descent = 0;
20687 it->pixel_width = 0;
20688 it->nglyphs = 0;
20689 return;
20690 }
20691
20692 img = IMAGE_FROM_ID (it->f, it->image_id);
20693 xassert (img);
20694 /* Make sure X resources of the image is loaded. */
20695 prepare_image_for_display (it->f, img);
20696
20697 slice.x = slice.y = 0;
20698 slice.width = img->width;
20699 slice.height = img->height;
20700
20701 if (INTEGERP (it->slice.x))
20702 slice.x = XINT (it->slice.x);
20703 else if (FLOATP (it->slice.x))
20704 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
20705
20706 if (INTEGERP (it->slice.y))
20707 slice.y = XINT (it->slice.y);
20708 else if (FLOATP (it->slice.y))
20709 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
20710
20711 if (INTEGERP (it->slice.width))
20712 slice.width = XINT (it->slice.width);
20713 else if (FLOATP (it->slice.width))
20714 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
20715
20716 if (INTEGERP (it->slice.height))
20717 slice.height = XINT (it->slice.height);
20718 else if (FLOATP (it->slice.height))
20719 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
20720
20721 if (slice.x >= img->width)
20722 slice.x = img->width;
20723 if (slice.y >= img->height)
20724 slice.y = img->height;
20725 if (slice.x + slice.width >= img->width)
20726 slice.width = img->width - slice.x;
20727 if (slice.y + slice.height > img->height)
20728 slice.height = img->height - slice.y;
20729
20730 if (slice.width == 0 || slice.height == 0)
20731 return;
20732
20733 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20734
20735 it->descent = slice.height - glyph_ascent;
20736 if (slice.y == 0)
20737 it->descent += img->vmargin;
20738 if (slice.y + slice.height == img->height)
20739 it->descent += img->vmargin;
20740 it->phys_descent = it->descent;
20741
20742 it->pixel_width = slice.width;
20743 if (slice.x == 0)
20744 it->pixel_width += img->hmargin;
20745 if (slice.x + slice.width == img->width)
20746 it->pixel_width += img->hmargin;
20747
20748 /* It's quite possible for images to have an ascent greater than
20749 their height, so don't get confused in that case. */
20750 if (it->descent < 0)
20751 it->descent = 0;
20752
20753 it->nglyphs = 1;
20754
20755 if (face->box != FACE_NO_BOX)
20756 {
20757 if (face->box_line_width > 0)
20758 {
20759 if (slice.y == 0)
20760 it->ascent += face->box_line_width;
20761 if (slice.y + slice.height == img->height)
20762 it->descent += face->box_line_width;
20763 }
20764
20765 if (it->start_of_box_run_p && slice.x == 0)
20766 it->pixel_width += eabs (face->box_line_width);
20767 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20768 it->pixel_width += eabs (face->box_line_width);
20769 }
20770
20771 take_vertical_position_into_account (it);
20772
20773 /* Automatically crop wide image glyphs at right edge so we can
20774 draw the cursor on same display row. */
20775 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20776 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20777 {
20778 it->pixel_width -= crop;
20779 slice.width -= crop;
20780 }
20781
20782 if (it->glyph_row)
20783 {
20784 struct glyph *glyph;
20785 enum glyph_row_area area = it->area;
20786
20787 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20788 if (glyph < it->glyph_row->glyphs[area + 1])
20789 {
20790 glyph->charpos = CHARPOS (it->position);
20791 glyph->object = it->object;
20792 glyph->pixel_width = it->pixel_width;
20793 glyph->ascent = glyph_ascent;
20794 glyph->descent = it->descent;
20795 glyph->voffset = it->voffset;
20796 glyph->type = IMAGE_GLYPH;
20797 glyph->avoid_cursor_p = it->avoid_cursor_p;
20798 glyph->multibyte_p = it->multibyte_p;
20799 glyph->left_box_line_p = it->start_of_box_run_p;
20800 glyph->right_box_line_p = it->end_of_box_run_p;
20801 glyph->overlaps_vertically_p = 0;
20802 glyph->padding_p = 0;
20803 glyph->glyph_not_available_p = 0;
20804 glyph->face_id = it->face_id;
20805 glyph->u.img_id = img->id;
20806 glyph->slice = slice;
20807 glyph->font_type = FONT_TYPE_UNKNOWN;
20808 ++it->glyph_row->used[area];
20809 }
20810 else
20811 IT_EXPAND_MATRIX_WIDTH (it, area);
20812 }
20813 }
20814
20815
20816 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20817 of the glyph, WIDTH and HEIGHT are the width and height of the
20818 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20819
20820 static void
20821 append_stretch_glyph (it, object, width, height, ascent)
20822 struct it *it;
20823 Lisp_Object object;
20824 int width, height;
20825 int ascent;
20826 {
20827 struct glyph *glyph;
20828 enum glyph_row_area area = it->area;
20829
20830 xassert (ascent >= 0 && ascent <= height);
20831
20832 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20833 if (glyph < it->glyph_row->glyphs[area + 1])
20834 {
20835 glyph->charpos = CHARPOS (it->position);
20836 glyph->object = object;
20837 glyph->pixel_width = width;
20838 glyph->ascent = ascent;
20839 glyph->descent = height - ascent;
20840 glyph->voffset = it->voffset;
20841 glyph->type = STRETCH_GLYPH;
20842 glyph->avoid_cursor_p = it->avoid_cursor_p;
20843 glyph->multibyte_p = it->multibyte_p;
20844 glyph->left_box_line_p = it->start_of_box_run_p;
20845 glyph->right_box_line_p = it->end_of_box_run_p;
20846 glyph->overlaps_vertically_p = 0;
20847 glyph->padding_p = 0;
20848 glyph->glyph_not_available_p = 0;
20849 glyph->face_id = it->face_id;
20850 glyph->u.stretch.ascent = ascent;
20851 glyph->u.stretch.height = height;
20852 glyph->slice = null_glyph_slice;
20853 glyph->font_type = FONT_TYPE_UNKNOWN;
20854 ++it->glyph_row->used[area];
20855 }
20856 else
20857 IT_EXPAND_MATRIX_WIDTH (it, area);
20858 }
20859
20860
20861 /* Produce a stretch glyph for iterator IT. IT->object is the value
20862 of the glyph property displayed. The value must be a list
20863 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20864 being recognized:
20865
20866 1. `:width WIDTH' specifies that the space should be WIDTH *
20867 canonical char width wide. WIDTH may be an integer or floating
20868 point number.
20869
20870 2. `:relative-width FACTOR' specifies that the width of the stretch
20871 should be computed from the width of the first character having the
20872 `glyph' property, and should be FACTOR times that width.
20873
20874 3. `:align-to HPOS' specifies that the space should be wide enough
20875 to reach HPOS, a value in canonical character units.
20876
20877 Exactly one of the above pairs must be present.
20878
20879 4. `:height HEIGHT' specifies that the height of the stretch produced
20880 should be HEIGHT, measured in canonical character units.
20881
20882 5. `:relative-height FACTOR' specifies that the height of the
20883 stretch should be FACTOR times the height of the characters having
20884 the glyph property.
20885
20886 Either none or exactly one of 4 or 5 must be present.
20887
20888 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20889 of the stretch should be used for the ascent of the stretch.
20890 ASCENT must be in the range 0 <= ASCENT <= 100. */
20891
20892 static void
20893 produce_stretch_glyph (it)
20894 struct it *it;
20895 {
20896 /* (space :width WIDTH :height HEIGHT ...) */
20897 Lisp_Object prop, plist;
20898 int width = 0, height = 0, align_to = -1;
20899 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20900 int ascent = 0;
20901 double tem;
20902 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20903 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20904
20905 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20906
20907 /* List should start with `space'. */
20908 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20909 plist = XCDR (it->object);
20910
20911 /* Compute the width of the stretch. */
20912 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20913 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20914 {
20915 /* Absolute width `:width WIDTH' specified and valid. */
20916 zero_width_ok_p = 1;
20917 width = (int)tem;
20918 }
20919 else if (prop = Fplist_get (plist, QCrelative_width),
20920 NUMVAL (prop) > 0)
20921 {
20922 /* Relative width `:relative-width FACTOR' specified and valid.
20923 Compute the width of the characters having the `glyph'
20924 property. */
20925 struct it it2;
20926 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20927
20928 it2 = *it;
20929 if (it->multibyte_p)
20930 {
20931 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20932 - IT_BYTEPOS (*it));
20933 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20934 }
20935 else
20936 it2.c = *p, it2.len = 1;
20937
20938 it2.glyph_row = NULL;
20939 it2.what = IT_CHARACTER;
20940 x_produce_glyphs (&it2);
20941 width = NUMVAL (prop) * it2.pixel_width;
20942 }
20943 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20944 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20945 {
20946 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20947 align_to = (align_to < 0
20948 ? 0
20949 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20950 else if (align_to < 0)
20951 align_to = window_box_left_offset (it->w, TEXT_AREA);
20952 width = max (0, (int)tem + align_to - it->current_x);
20953 zero_width_ok_p = 1;
20954 }
20955 else
20956 /* Nothing specified -> width defaults to canonical char width. */
20957 width = FRAME_COLUMN_WIDTH (it->f);
20958
20959 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20960 width = 1;
20961
20962 /* Compute height. */
20963 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20964 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20965 {
20966 height = (int)tem;
20967 zero_height_ok_p = 1;
20968 }
20969 else if (prop = Fplist_get (plist, QCrelative_height),
20970 NUMVAL (prop) > 0)
20971 height = FONT_HEIGHT (font) * NUMVAL (prop);
20972 else
20973 height = FONT_HEIGHT (font);
20974
20975 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20976 height = 1;
20977
20978 /* Compute percentage of height used for ascent. If
20979 `:ascent ASCENT' is present and valid, use that. Otherwise,
20980 derive the ascent from the font in use. */
20981 if (prop = Fplist_get (plist, QCascent),
20982 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20983 ascent = height * NUMVAL (prop) / 100.0;
20984 else if (!NILP (prop)
20985 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20986 ascent = min (max (0, (int)tem), height);
20987 else
20988 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20989
20990 if (width > 0 && it->line_wrap != TRUNCATE
20991 && it->current_x + width > it->last_visible_x)
20992 width = it->last_visible_x - it->current_x - 1;
20993
20994 if (width > 0 && height > 0 && it->glyph_row)
20995 {
20996 Lisp_Object object = it->stack[it->sp - 1].string;
20997 if (!STRINGP (object))
20998 object = it->w->buffer;
20999 append_stretch_glyph (it, object, width, height, ascent);
21000 }
21001
21002 it->pixel_width = width;
21003 it->ascent = it->phys_ascent = ascent;
21004 it->descent = it->phys_descent = height - it->ascent;
21005 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
21006
21007 take_vertical_position_into_account (it);
21008 }
21009
21010 /* Calculate line-height and line-spacing properties.
21011 An integer value specifies explicit pixel value.
21012 A float value specifies relative value to current face height.
21013 A cons (float . face-name) specifies relative value to
21014 height of specified face font.
21015
21016 Returns height in pixels, or nil. */
21017
21018
21019 static Lisp_Object
21020 calc_line_height_property (it, val, font, boff, override)
21021 struct it *it;
21022 Lisp_Object val;
21023 struct font *font;
21024 int boff, override;
21025 {
21026 Lisp_Object face_name = Qnil;
21027 int ascent, descent, height;
21028
21029 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
21030 return val;
21031
21032 if (CONSP (val))
21033 {
21034 face_name = XCAR (val);
21035 val = XCDR (val);
21036 if (!NUMBERP (val))
21037 val = make_number (1);
21038 if (NILP (face_name))
21039 {
21040 height = it->ascent + it->descent;
21041 goto scale;
21042 }
21043 }
21044
21045 if (NILP (face_name))
21046 {
21047 font = FRAME_FONT (it->f);
21048 boff = FRAME_BASELINE_OFFSET (it->f);
21049 }
21050 else if (EQ (face_name, Qt))
21051 {
21052 override = 0;
21053 }
21054 else
21055 {
21056 int face_id;
21057 struct face *face;
21058
21059 face_id = lookup_named_face (it->f, face_name, 0);
21060 if (face_id < 0)
21061 return make_number (-1);
21062
21063 face = FACE_FROM_ID (it->f, face_id);
21064 font = face->font;
21065 if (font == NULL)
21066 return make_number (-1);
21067 boff = font->baseline_offset;
21068 if (font->vertical_centering)
21069 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21070 }
21071
21072 ascent = FONT_BASE (font) + boff;
21073 descent = FONT_DESCENT (font) - boff;
21074
21075 if (override)
21076 {
21077 it->override_ascent = ascent;
21078 it->override_descent = descent;
21079 it->override_boff = boff;
21080 }
21081
21082 height = ascent + descent;
21083
21084 scale:
21085 if (FLOATP (val))
21086 height = (int)(XFLOAT_DATA (val) * height);
21087 else if (INTEGERP (val))
21088 height *= XINT (val);
21089
21090 return make_number (height);
21091 }
21092
21093
21094 /* RIF:
21095 Produce glyphs/get display metrics for the display element IT is
21096 loaded with. See the description of struct it in dispextern.h
21097 for an overview of struct it. */
21098
21099 void
21100 x_produce_glyphs (it)
21101 struct it *it;
21102 {
21103 int extra_line_spacing = it->extra_line_spacing;
21104
21105 it->glyph_not_available_p = 0;
21106
21107 if (it->what == IT_CHARACTER)
21108 {
21109 XChar2b char2b;
21110 struct font *font;
21111 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21112 struct font_metrics *pcm;
21113 int font_not_found_p;
21114 int boff; /* baseline offset */
21115 /* We may change it->multibyte_p upon unibyte<->multibyte
21116 conversion. So, save the current value now and restore it
21117 later.
21118
21119 Note: It seems that we don't have to record multibyte_p in
21120 struct glyph because the character code itself tells whether
21121 or not the character is multibyte. Thus, in the future, we
21122 must consider eliminating the field `multibyte_p' in the
21123 struct glyph. */
21124 int saved_multibyte_p = it->multibyte_p;
21125
21126 /* Maybe translate single-byte characters to multibyte, or the
21127 other way. */
21128 it->char_to_display = it->c;
21129 if (!ASCII_BYTE_P (it->c)
21130 && ! it->multibyte_p)
21131 {
21132 if (SINGLE_BYTE_CHAR_P (it->c)
21133 && unibyte_display_via_language_environment)
21134 {
21135 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
21136
21137 /* get_next_display_element assures that this decoding
21138 never fails. */
21139 it->char_to_display = DECODE_CHAR (unibyte, it->c);
21140 it->multibyte_p = 1;
21141 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
21142 -1, Qnil);
21143 face = FACE_FROM_ID (it->f, it->face_id);
21144 }
21145 }
21146
21147 /* Get font to use. Encode IT->char_to_display. */
21148 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
21149 &char2b, it->multibyte_p, 0);
21150 font = face->font;
21151
21152 /* When no suitable font found, use the default font. */
21153 font_not_found_p = font == NULL;
21154 if (font_not_found_p)
21155 {
21156 font = FRAME_FONT (it->f);
21157 boff = FRAME_BASELINE_OFFSET (it->f);
21158 }
21159 else
21160 {
21161 boff = font->baseline_offset;
21162 if (font->vertical_centering)
21163 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21164 }
21165
21166 if (it->char_to_display >= ' '
21167 && (!it->multibyte_p || it->char_to_display < 128))
21168 {
21169 /* Either unibyte or ASCII. */
21170 int stretched_p;
21171
21172 it->nglyphs = 1;
21173
21174 pcm = get_per_char_metric (it->f, font, &char2b);
21175
21176 if (it->override_ascent >= 0)
21177 {
21178 it->ascent = it->override_ascent;
21179 it->descent = it->override_descent;
21180 boff = it->override_boff;
21181 }
21182 else
21183 {
21184 it->ascent = FONT_BASE (font) + boff;
21185 it->descent = FONT_DESCENT (font) - boff;
21186 }
21187
21188 if (pcm)
21189 {
21190 it->phys_ascent = pcm->ascent + boff;
21191 it->phys_descent = pcm->descent - boff;
21192 it->pixel_width = pcm->width;
21193 }
21194 else
21195 {
21196 it->glyph_not_available_p = 1;
21197 it->phys_ascent = it->ascent;
21198 it->phys_descent = it->descent;
21199 it->pixel_width = FONT_WIDTH (font);
21200 }
21201
21202 if (it->constrain_row_ascent_descent_p)
21203 {
21204 if (it->descent > it->max_descent)
21205 {
21206 it->ascent += it->descent - it->max_descent;
21207 it->descent = it->max_descent;
21208 }
21209 if (it->ascent > it->max_ascent)
21210 {
21211 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
21212 it->ascent = it->max_ascent;
21213 }
21214 it->phys_ascent = min (it->phys_ascent, it->ascent);
21215 it->phys_descent = min (it->phys_descent, it->descent);
21216 extra_line_spacing = 0;
21217 }
21218
21219 /* If this is a space inside a region of text with
21220 `space-width' property, change its width. */
21221 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
21222 if (stretched_p)
21223 it->pixel_width *= XFLOATINT (it->space_width);
21224
21225 /* If face has a box, add the box thickness to the character
21226 height. If character has a box line to the left and/or
21227 right, add the box line width to the character's width. */
21228 if (face->box != FACE_NO_BOX)
21229 {
21230 int thick = face->box_line_width;
21231
21232 if (thick > 0)
21233 {
21234 it->ascent += thick;
21235 it->descent += thick;
21236 }
21237 else
21238 thick = -thick;
21239
21240 if (it->start_of_box_run_p)
21241 it->pixel_width += thick;
21242 if (it->end_of_box_run_p)
21243 it->pixel_width += thick;
21244 }
21245
21246 /* If face has an overline, add the height of the overline
21247 (1 pixel) and a 1 pixel margin to the character height. */
21248 if (face->overline_p)
21249 it->ascent += overline_margin;
21250
21251 if (it->constrain_row_ascent_descent_p)
21252 {
21253 if (it->ascent > it->max_ascent)
21254 it->ascent = it->max_ascent;
21255 if (it->descent > it->max_descent)
21256 it->descent = it->max_descent;
21257 }
21258
21259 take_vertical_position_into_account (it);
21260
21261 /* If we have to actually produce glyphs, do it. */
21262 if (it->glyph_row)
21263 {
21264 if (stretched_p)
21265 {
21266 /* Translate a space with a `space-width' property
21267 into a stretch glyph. */
21268 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
21269 / FONT_HEIGHT (font));
21270 append_stretch_glyph (it, it->object, it->pixel_width,
21271 it->ascent + it->descent, ascent);
21272 }
21273 else
21274 append_glyph (it);
21275
21276 /* If characters with lbearing or rbearing are displayed
21277 in this line, record that fact in a flag of the
21278 glyph row. This is used to optimize X output code. */
21279 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
21280 it->glyph_row->contains_overlapping_glyphs_p = 1;
21281 }
21282 if (! stretched_p && it->pixel_width == 0)
21283 /* We assure that all visible glyphs have at least 1-pixel
21284 width. */
21285 it->pixel_width = 1;
21286 }
21287 else if (it->char_to_display == '\n')
21288 {
21289 /* A newline has no width, but we need the height of the
21290 line. But if previous part of the line sets a height,
21291 don't increase that height */
21292
21293 Lisp_Object height;
21294 Lisp_Object total_height = Qnil;
21295
21296 it->override_ascent = -1;
21297 it->pixel_width = 0;
21298 it->nglyphs = 0;
21299
21300 height = get_it_property(it, Qline_height);
21301 /* Split (line-height total-height) list */
21302 if (CONSP (height)
21303 && CONSP (XCDR (height))
21304 && NILP (XCDR (XCDR (height))))
21305 {
21306 total_height = XCAR (XCDR (height));
21307 height = XCAR (height);
21308 }
21309 height = calc_line_height_property(it, height, font, boff, 1);
21310
21311 if (it->override_ascent >= 0)
21312 {
21313 it->ascent = it->override_ascent;
21314 it->descent = it->override_descent;
21315 boff = it->override_boff;
21316 }
21317 else
21318 {
21319 it->ascent = FONT_BASE (font) + boff;
21320 it->descent = FONT_DESCENT (font) - boff;
21321 }
21322
21323 if (EQ (height, Qt))
21324 {
21325 if (it->descent > it->max_descent)
21326 {
21327 it->ascent += it->descent - it->max_descent;
21328 it->descent = it->max_descent;
21329 }
21330 if (it->ascent > it->max_ascent)
21331 {
21332 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
21333 it->ascent = it->max_ascent;
21334 }
21335 it->phys_ascent = min (it->phys_ascent, it->ascent);
21336 it->phys_descent = min (it->phys_descent, it->descent);
21337 it->constrain_row_ascent_descent_p = 1;
21338 extra_line_spacing = 0;
21339 }
21340 else
21341 {
21342 Lisp_Object spacing;
21343
21344 it->phys_ascent = it->ascent;
21345 it->phys_descent = it->descent;
21346
21347 if ((it->max_ascent > 0 || it->max_descent > 0)
21348 && face->box != FACE_NO_BOX
21349 && face->box_line_width > 0)
21350 {
21351 it->ascent += face->box_line_width;
21352 it->descent += face->box_line_width;
21353 }
21354 if (!NILP (height)
21355 && XINT (height) > it->ascent + it->descent)
21356 it->ascent = XINT (height) - it->descent;
21357
21358 if (!NILP (total_height))
21359 spacing = calc_line_height_property(it, total_height, font, boff, 0);
21360 else
21361 {
21362 spacing = get_it_property(it, Qline_spacing);
21363 spacing = calc_line_height_property(it, spacing, font, boff, 0);
21364 }
21365 if (INTEGERP (spacing))
21366 {
21367 extra_line_spacing = XINT (spacing);
21368 if (!NILP (total_height))
21369 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
21370 }
21371 }
21372 }
21373 else if (it->char_to_display == '\t')
21374 {
21375 if (font->space_width > 0)
21376 {
21377 int tab_width = it->tab_width * font->space_width;
21378 int x = it->current_x + it->continuation_lines_width;
21379 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
21380
21381 /* If the distance from the current position to the next tab
21382 stop is less than a space character width, use the
21383 tab stop after that. */
21384 if (next_tab_x - x < font->space_width)
21385 next_tab_x += tab_width;
21386
21387 it->pixel_width = next_tab_x - x;
21388 it->nglyphs = 1;
21389 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
21390 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
21391
21392 if (it->glyph_row)
21393 {
21394 append_stretch_glyph (it, it->object, it->pixel_width,
21395 it->ascent + it->descent, it->ascent);
21396 }
21397 }
21398 else
21399 {
21400 it->pixel_width = 0;
21401 it->nglyphs = 1;
21402 }
21403 }
21404 else
21405 {
21406 /* A multi-byte character. Assume that the display width of the
21407 character is the width of the character multiplied by the
21408 width of the font. */
21409
21410 /* If we found a font, this font should give us the right
21411 metrics. If we didn't find a font, use the frame's
21412 default font and calculate the width of the character by
21413 multiplying the width of font by the width of the
21414 character. */
21415
21416 pcm = get_per_char_metric (it->f, font, &char2b);
21417
21418 if (font_not_found_p || !pcm)
21419 {
21420 int char_width = CHAR_WIDTH (it->char_to_display);
21421
21422 if (char_width == 0)
21423 /* This is a non spacing character. But, as we are
21424 going to display an empty box, the box must occupy
21425 at least one column. */
21426 char_width = 1;
21427 it->glyph_not_available_p = 1;
21428 it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
21429 it->phys_ascent = FONT_BASE (font) + boff;
21430 it->phys_descent = FONT_DESCENT (font) - boff;
21431 }
21432 else
21433 {
21434 it->pixel_width = pcm->width;
21435 it->phys_ascent = pcm->ascent + boff;
21436 it->phys_descent = pcm->descent - boff;
21437 if (it->glyph_row
21438 && (pcm->lbearing < 0
21439 || pcm->rbearing > pcm->width))
21440 it->glyph_row->contains_overlapping_glyphs_p = 1;
21441 }
21442 it->nglyphs = 1;
21443 it->ascent = FONT_BASE (font) + boff;
21444 it->descent = FONT_DESCENT (font) - boff;
21445 if (face->box != FACE_NO_BOX)
21446 {
21447 int thick = face->box_line_width;
21448
21449 if (thick > 0)
21450 {
21451 it->ascent += thick;
21452 it->descent += thick;
21453 }
21454 else
21455 thick = - thick;
21456
21457 if (it->start_of_box_run_p)
21458 it->pixel_width += thick;
21459 if (it->end_of_box_run_p)
21460 it->pixel_width += thick;
21461 }
21462
21463 /* If face has an overline, add the height of the overline
21464 (1 pixel) and a 1 pixel margin to the character height. */
21465 if (face->overline_p)
21466 it->ascent += overline_margin;
21467
21468 take_vertical_position_into_account (it);
21469
21470 if (it->ascent < 0)
21471 it->ascent = 0;
21472 if (it->descent < 0)
21473 it->descent = 0;
21474
21475 if (it->glyph_row)
21476 append_glyph (it);
21477 if (it->pixel_width == 0)
21478 /* We assure that all visible glyphs have at least 1-pixel
21479 width. */
21480 it->pixel_width = 1;
21481 }
21482 it->multibyte_p = saved_multibyte_p;
21483 }
21484 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
21485 {
21486 /* A static composition.
21487
21488 Note: A composition is represented as one glyph in the
21489 glyph matrix. There are no padding glyphs.
21490
21491 Important note: pixel_width, ascent, and descent are the
21492 values of what is drawn by draw_glyphs (i.e. the values of
21493 the overall glyphs composed). */
21494 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21495 int boff; /* baseline offset */
21496 struct composition *cmp = composition_table[it->cmp_it.id];
21497 int glyph_len = cmp->glyph_len;
21498 struct font *font = face->font;
21499
21500 it->nglyphs = 1;
21501
21502 /* If we have not yet calculated pixel size data of glyphs of
21503 the composition for the current face font, calculate them
21504 now. Theoretically, we have to check all fonts for the
21505 glyphs, but that requires much time and memory space. So,
21506 here we check only the font of the first glyph. This may
21507 lead to incorrect display, but it's very rare, and C-l
21508 (recenter-top-bottom) can correct the display anyway. */
21509 if (! cmp->font || cmp->font != font)
21510 {
21511 /* Ascent and descent of the font of the first character
21512 of this composition (adjusted by baseline offset).
21513 Ascent and descent of overall glyphs should not be less
21514 than these, respectively. */
21515 int font_ascent, font_descent, font_height;
21516 /* Bounding box of the overall glyphs. */
21517 int leftmost, rightmost, lowest, highest;
21518 int lbearing, rbearing;
21519 int i, width, ascent, descent;
21520 int left_padded = 0, right_padded = 0;
21521 int c;
21522 XChar2b char2b;
21523 struct font_metrics *pcm;
21524 int font_not_found_p;
21525 int pos;
21526
21527 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
21528 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
21529 break;
21530 if (glyph_len < cmp->glyph_len)
21531 right_padded = 1;
21532 for (i = 0; i < glyph_len; i++)
21533 {
21534 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
21535 break;
21536 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21537 }
21538 if (i > 0)
21539 left_padded = 1;
21540
21541 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
21542 : IT_CHARPOS (*it));
21543 /* If no suitable font is found, use the default font. */
21544 font_not_found_p = font == NULL;
21545 if (font_not_found_p)
21546 {
21547 face = face->ascii_face;
21548 font = face->font;
21549 }
21550 boff = font->baseline_offset;
21551 if (font->vertical_centering)
21552 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21553 font_ascent = FONT_BASE (font) + boff;
21554 font_descent = FONT_DESCENT (font) - boff;
21555 font_height = FONT_HEIGHT (font);
21556
21557 cmp->font = (void *) font;
21558
21559 pcm = NULL;
21560 if (! font_not_found_p)
21561 {
21562 get_char_face_and_encoding (it->f, c, it->face_id,
21563 &char2b, it->multibyte_p, 0);
21564 pcm = get_per_char_metric (it->f, font, &char2b);
21565 }
21566
21567 /* Initialize the bounding box. */
21568 if (pcm)
21569 {
21570 width = pcm->width;
21571 ascent = pcm->ascent;
21572 descent = pcm->descent;
21573 lbearing = pcm->lbearing;
21574 rbearing = pcm->rbearing;
21575 }
21576 else
21577 {
21578 width = FONT_WIDTH (font);
21579 ascent = FONT_BASE (font);
21580 descent = FONT_DESCENT (font);
21581 lbearing = 0;
21582 rbearing = width;
21583 }
21584
21585 rightmost = width;
21586 leftmost = 0;
21587 lowest = - descent + boff;
21588 highest = ascent + boff;
21589
21590 if (! font_not_found_p
21591 && font->default_ascent
21592 && CHAR_TABLE_P (Vuse_default_ascent)
21593 && !NILP (Faref (Vuse_default_ascent,
21594 make_number (it->char_to_display))))
21595 highest = font->default_ascent + boff;
21596
21597 /* Draw the first glyph at the normal position. It may be
21598 shifted to right later if some other glyphs are drawn
21599 at the left. */
21600 cmp->offsets[i * 2] = 0;
21601 cmp->offsets[i * 2 + 1] = boff;
21602 cmp->lbearing = lbearing;
21603 cmp->rbearing = rbearing;
21604
21605 /* Set cmp->offsets for the remaining glyphs. */
21606 for (i++; i < glyph_len; i++)
21607 {
21608 int left, right, btm, top;
21609 int ch = COMPOSITION_GLYPH (cmp, i);
21610 int face_id;
21611 struct face *this_face;
21612 int this_boff;
21613
21614 if (ch == '\t')
21615 ch = ' ';
21616 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
21617 this_face = FACE_FROM_ID (it->f, face_id);
21618 font = this_face->font;
21619
21620 if (font == NULL)
21621 pcm = NULL;
21622 else
21623 {
21624 this_boff = font->baseline_offset;
21625 if (font->vertical_centering)
21626 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21627 get_char_face_and_encoding (it->f, ch, face_id,
21628 &char2b, it->multibyte_p, 0);
21629 pcm = get_per_char_metric (it->f, font, &char2b);
21630 }
21631 if (! pcm)
21632 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21633 else
21634 {
21635 width = pcm->width;
21636 ascent = pcm->ascent;
21637 descent = pcm->descent;
21638 lbearing = pcm->lbearing;
21639 rbearing = pcm->rbearing;
21640 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21641 {
21642 /* Relative composition with or without
21643 alternate chars. */
21644 left = (leftmost + rightmost - width) / 2;
21645 btm = - descent + boff;
21646 if (font->relative_compose
21647 && (! CHAR_TABLE_P (Vignore_relative_composition)
21648 || NILP (Faref (Vignore_relative_composition,
21649 make_number (ch)))))
21650 {
21651
21652 if (- descent >= font->relative_compose)
21653 /* One extra pixel between two glyphs. */
21654 btm = highest + 1;
21655 else if (ascent <= 0)
21656 /* One extra pixel between two glyphs. */
21657 btm = lowest - 1 - ascent - descent;
21658 }
21659 }
21660 else
21661 {
21662 /* A composition rule is specified by an integer
21663 value that encodes global and new reference
21664 points (GREF and NREF). GREF and NREF are
21665 specified by numbers as below:
21666
21667 0---1---2 -- ascent
21668 | |
21669 | |
21670 | |
21671 9--10--11 -- center
21672 | |
21673 ---3---4---5--- baseline
21674 | |
21675 6---7---8 -- descent
21676 */
21677 int rule = COMPOSITION_RULE (cmp, i);
21678 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
21679
21680 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
21681 grefx = gref % 3, nrefx = nref % 3;
21682 grefy = gref / 3, nrefy = nref / 3;
21683 if (xoff)
21684 xoff = font_height * (xoff - 128) / 256;
21685 if (yoff)
21686 yoff = font_height * (yoff - 128) / 256;
21687
21688 left = (leftmost
21689 + grefx * (rightmost - leftmost) / 2
21690 - nrefx * width / 2
21691 + xoff);
21692
21693 btm = ((grefy == 0 ? highest
21694 : grefy == 1 ? 0
21695 : grefy == 2 ? lowest
21696 : (highest + lowest) / 2)
21697 - (nrefy == 0 ? ascent + descent
21698 : nrefy == 1 ? descent - boff
21699 : nrefy == 2 ? 0
21700 : (ascent + descent) / 2)
21701 + yoff);
21702 }
21703
21704 cmp->offsets[i * 2] = left;
21705 cmp->offsets[i * 2 + 1] = btm + descent;
21706
21707 /* Update the bounding box of the overall glyphs. */
21708 if (width > 0)
21709 {
21710 right = left + width;
21711 if (left < leftmost)
21712 leftmost = left;
21713 if (right > rightmost)
21714 rightmost = right;
21715 }
21716 top = btm + descent + ascent;
21717 if (top > highest)
21718 highest = top;
21719 if (btm < lowest)
21720 lowest = btm;
21721
21722 if (cmp->lbearing > left + lbearing)
21723 cmp->lbearing = left + lbearing;
21724 if (cmp->rbearing < left + rbearing)
21725 cmp->rbearing = left + rbearing;
21726 }
21727 }
21728
21729 /* If there are glyphs whose x-offsets are negative,
21730 shift all glyphs to the right and make all x-offsets
21731 non-negative. */
21732 if (leftmost < 0)
21733 {
21734 for (i = 0; i < cmp->glyph_len; i++)
21735 cmp->offsets[i * 2] -= leftmost;
21736 rightmost -= leftmost;
21737 cmp->lbearing -= leftmost;
21738 cmp->rbearing -= leftmost;
21739 }
21740
21741 if (left_padded && cmp->lbearing < 0)
21742 {
21743 for (i = 0; i < cmp->glyph_len; i++)
21744 cmp->offsets[i * 2] -= cmp->lbearing;
21745 rightmost -= cmp->lbearing;
21746 cmp->rbearing -= cmp->lbearing;
21747 cmp->lbearing = 0;
21748 }
21749 if (right_padded && rightmost < cmp->rbearing)
21750 {
21751 rightmost = cmp->rbearing;
21752 }
21753
21754 cmp->pixel_width = rightmost;
21755 cmp->ascent = highest;
21756 cmp->descent = - lowest;
21757 if (cmp->ascent < font_ascent)
21758 cmp->ascent = font_ascent;
21759 if (cmp->descent < font_descent)
21760 cmp->descent = font_descent;
21761 }
21762
21763 if (it->glyph_row
21764 && (cmp->lbearing < 0
21765 || cmp->rbearing > cmp->pixel_width))
21766 it->glyph_row->contains_overlapping_glyphs_p = 1;
21767
21768 it->pixel_width = cmp->pixel_width;
21769 it->ascent = it->phys_ascent = cmp->ascent;
21770 it->descent = it->phys_descent = cmp->descent;
21771 if (face->box != FACE_NO_BOX)
21772 {
21773 int thick = face->box_line_width;
21774
21775 if (thick > 0)
21776 {
21777 it->ascent += thick;
21778 it->descent += thick;
21779 }
21780 else
21781 thick = - thick;
21782
21783 if (it->start_of_box_run_p)
21784 it->pixel_width += thick;
21785 if (it->end_of_box_run_p)
21786 it->pixel_width += thick;
21787 }
21788
21789 /* If face has an overline, add the height of the overline
21790 (1 pixel) and a 1 pixel margin to the character height. */
21791 if (face->overline_p)
21792 it->ascent += overline_margin;
21793
21794 take_vertical_position_into_account (it);
21795 if (it->ascent < 0)
21796 it->ascent = 0;
21797 if (it->descent < 0)
21798 it->descent = 0;
21799
21800 if (it->glyph_row)
21801 append_composite_glyph (it);
21802 }
21803 else if (it->what == IT_COMPOSITION)
21804 {
21805 /* A dynamic (automatic) composition. */
21806 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21807 Lisp_Object gstring;
21808 struct font_metrics metrics;
21809
21810 gstring = composition_gstring_from_id (it->cmp_it.id);
21811 it->pixel_width
21812 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
21813 &metrics);
21814 if (it->glyph_row
21815 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
21816 it->glyph_row->contains_overlapping_glyphs_p = 1;
21817 it->ascent = it->phys_ascent = metrics.ascent;
21818 it->descent = it->phys_descent = metrics.descent;
21819 if (face->box != FACE_NO_BOX)
21820 {
21821 int thick = face->box_line_width;
21822
21823 if (thick > 0)
21824 {
21825 it->ascent += thick;
21826 it->descent += thick;
21827 }
21828 else
21829 thick = - thick;
21830
21831 if (it->start_of_box_run_p)
21832 it->pixel_width += thick;
21833 if (it->end_of_box_run_p)
21834 it->pixel_width += thick;
21835 }
21836 /* If face has an overline, add the height of the overline
21837 (1 pixel) and a 1 pixel margin to the character height. */
21838 if (face->overline_p)
21839 it->ascent += overline_margin;
21840 take_vertical_position_into_account (it);
21841 if (it->ascent < 0)
21842 it->ascent = 0;
21843 if (it->descent < 0)
21844 it->descent = 0;
21845
21846 if (it->glyph_row)
21847 append_composite_glyph (it);
21848 }
21849 else if (it->what == IT_IMAGE)
21850 produce_image_glyph (it);
21851 else if (it->what == IT_STRETCH)
21852 produce_stretch_glyph (it);
21853
21854 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21855 because this isn't true for images with `:ascent 100'. */
21856 xassert (it->ascent >= 0 && it->descent >= 0);
21857 if (it->area == TEXT_AREA)
21858 it->current_x += it->pixel_width;
21859
21860 if (extra_line_spacing > 0)
21861 {
21862 it->descent += extra_line_spacing;
21863 if (extra_line_spacing > it->max_extra_line_spacing)
21864 it->max_extra_line_spacing = extra_line_spacing;
21865 }
21866
21867 it->max_ascent = max (it->max_ascent, it->ascent);
21868 it->max_descent = max (it->max_descent, it->descent);
21869 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21870 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21871 }
21872
21873 /* EXPORT for RIF:
21874 Output LEN glyphs starting at START at the nominal cursor position.
21875 Advance the nominal cursor over the text. The global variable
21876 updated_window contains the window being updated, updated_row is
21877 the glyph row being updated, and updated_area is the area of that
21878 row being updated. */
21879
21880 void
21881 x_write_glyphs (start, len)
21882 struct glyph *start;
21883 int len;
21884 {
21885 int x, hpos;
21886
21887 xassert (updated_window && updated_row);
21888 BLOCK_INPUT;
21889
21890 /* Write glyphs. */
21891
21892 hpos = start - updated_row->glyphs[updated_area];
21893 x = draw_glyphs (updated_window, output_cursor.x,
21894 updated_row, updated_area,
21895 hpos, hpos + len,
21896 DRAW_NORMAL_TEXT, 0);
21897
21898 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21899 if (updated_area == TEXT_AREA
21900 && updated_window->phys_cursor_on_p
21901 && updated_window->phys_cursor.vpos == output_cursor.vpos
21902 && updated_window->phys_cursor.hpos >= hpos
21903 && updated_window->phys_cursor.hpos < hpos + len)
21904 updated_window->phys_cursor_on_p = 0;
21905
21906 UNBLOCK_INPUT;
21907
21908 /* Advance the output cursor. */
21909 output_cursor.hpos += len;
21910 output_cursor.x = x;
21911 }
21912
21913
21914 /* EXPORT for RIF:
21915 Insert LEN glyphs from START at the nominal cursor position. */
21916
21917 void
21918 x_insert_glyphs (start, len)
21919 struct glyph *start;
21920 int len;
21921 {
21922 struct frame *f;
21923 struct window *w;
21924 int line_height, shift_by_width, shifted_region_width;
21925 struct glyph_row *row;
21926 struct glyph *glyph;
21927 int frame_x, frame_y;
21928 EMACS_INT hpos;
21929
21930 xassert (updated_window && updated_row);
21931 BLOCK_INPUT;
21932 w = updated_window;
21933 f = XFRAME (WINDOW_FRAME (w));
21934
21935 /* Get the height of the line we are in. */
21936 row = updated_row;
21937 line_height = row->height;
21938
21939 /* Get the width of the glyphs to insert. */
21940 shift_by_width = 0;
21941 for (glyph = start; glyph < start + len; ++glyph)
21942 shift_by_width += glyph->pixel_width;
21943
21944 /* Get the width of the region to shift right. */
21945 shifted_region_width = (window_box_width (w, updated_area)
21946 - output_cursor.x
21947 - shift_by_width);
21948
21949 /* Shift right. */
21950 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21951 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21952
21953 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21954 line_height, shift_by_width);
21955
21956 /* Write the glyphs. */
21957 hpos = start - row->glyphs[updated_area];
21958 draw_glyphs (w, output_cursor.x, row, updated_area,
21959 hpos, hpos + len,
21960 DRAW_NORMAL_TEXT, 0);
21961
21962 /* Advance the output cursor. */
21963 output_cursor.hpos += len;
21964 output_cursor.x += shift_by_width;
21965 UNBLOCK_INPUT;
21966 }
21967
21968
21969 /* EXPORT for RIF:
21970 Erase the current text line from the nominal cursor position
21971 (inclusive) to pixel column TO_X (exclusive). The idea is that
21972 everything from TO_X onward is already erased.
21973
21974 TO_X is a pixel position relative to updated_area of
21975 updated_window. TO_X == -1 means clear to the end of this area. */
21976
21977 void
21978 x_clear_end_of_line (to_x)
21979 int to_x;
21980 {
21981 struct frame *f;
21982 struct window *w = updated_window;
21983 int max_x, min_y, max_y;
21984 int from_x, from_y, to_y;
21985
21986 xassert (updated_window && updated_row);
21987 f = XFRAME (w->frame);
21988
21989 if (updated_row->full_width_p)
21990 max_x = WINDOW_TOTAL_WIDTH (w);
21991 else
21992 max_x = window_box_width (w, updated_area);
21993 max_y = window_text_bottom_y (w);
21994
21995 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21996 of window. For TO_X > 0, truncate to end of drawing area. */
21997 if (to_x == 0)
21998 return;
21999 else if (to_x < 0)
22000 to_x = max_x;
22001 else
22002 to_x = min (to_x, max_x);
22003
22004 to_y = min (max_y, output_cursor.y + updated_row->height);
22005
22006 /* Notice if the cursor will be cleared by this operation. */
22007 if (!updated_row->full_width_p)
22008 notice_overwritten_cursor (w, updated_area,
22009 output_cursor.x, -1,
22010 updated_row->y,
22011 MATRIX_ROW_BOTTOM_Y (updated_row));
22012
22013 from_x = output_cursor.x;
22014
22015 /* Translate to frame coordinates. */
22016 if (updated_row->full_width_p)
22017 {
22018 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
22019 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
22020 }
22021 else
22022 {
22023 int area_left = window_box_left (w, updated_area);
22024 from_x += area_left;
22025 to_x += area_left;
22026 }
22027
22028 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
22029 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
22030 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
22031
22032 /* Prevent inadvertently clearing to end of the X window. */
22033 if (to_x > from_x && to_y > from_y)
22034 {
22035 BLOCK_INPUT;
22036 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
22037 to_x - from_x, to_y - from_y);
22038 UNBLOCK_INPUT;
22039 }
22040 }
22041
22042 #endif /* HAVE_WINDOW_SYSTEM */
22043
22044
22045 \f
22046 /***********************************************************************
22047 Cursor types
22048 ***********************************************************************/
22049
22050 /* Value is the internal representation of the specified cursor type
22051 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
22052 of the bar cursor. */
22053
22054 static enum text_cursor_kinds
22055 get_specified_cursor_type (arg, width)
22056 Lisp_Object arg;
22057 int *width;
22058 {
22059 enum text_cursor_kinds type;
22060
22061 if (NILP (arg))
22062 return NO_CURSOR;
22063
22064 if (EQ (arg, Qbox))
22065 return FILLED_BOX_CURSOR;
22066
22067 if (EQ (arg, Qhollow))
22068 return HOLLOW_BOX_CURSOR;
22069
22070 if (EQ (arg, Qbar))
22071 {
22072 *width = 2;
22073 return BAR_CURSOR;
22074 }
22075
22076 if (CONSP (arg)
22077 && EQ (XCAR (arg), Qbar)
22078 && INTEGERP (XCDR (arg))
22079 && XINT (XCDR (arg)) >= 0)
22080 {
22081 *width = XINT (XCDR (arg));
22082 return BAR_CURSOR;
22083 }
22084
22085 if (EQ (arg, Qhbar))
22086 {
22087 *width = 2;
22088 return HBAR_CURSOR;
22089 }
22090
22091 if (CONSP (arg)
22092 && EQ (XCAR (arg), Qhbar)
22093 && INTEGERP (XCDR (arg))
22094 && XINT (XCDR (arg)) >= 0)
22095 {
22096 *width = XINT (XCDR (arg));
22097 return HBAR_CURSOR;
22098 }
22099
22100 /* Treat anything unknown as "hollow box cursor".
22101 It was bad to signal an error; people have trouble fixing
22102 .Xdefaults with Emacs, when it has something bad in it. */
22103 type = HOLLOW_BOX_CURSOR;
22104
22105 return type;
22106 }
22107
22108 /* Set the default cursor types for specified frame. */
22109 void
22110 set_frame_cursor_types (f, arg)
22111 struct frame *f;
22112 Lisp_Object arg;
22113 {
22114 int width;
22115 Lisp_Object tem;
22116
22117 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
22118 FRAME_CURSOR_WIDTH (f) = width;
22119
22120 /* By default, set up the blink-off state depending on the on-state. */
22121
22122 tem = Fassoc (arg, Vblink_cursor_alist);
22123 if (!NILP (tem))
22124 {
22125 FRAME_BLINK_OFF_CURSOR (f)
22126 = get_specified_cursor_type (XCDR (tem), &width);
22127 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
22128 }
22129 else
22130 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
22131 }
22132
22133
22134 /* Return the cursor we want to be displayed in window W. Return
22135 width of bar/hbar cursor through WIDTH arg. Return with
22136 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
22137 (i.e. if the `system caret' should track this cursor).
22138
22139 In a mini-buffer window, we want the cursor only to appear if we
22140 are reading input from this window. For the selected window, we
22141 want the cursor type given by the frame parameter or buffer local
22142 setting of cursor-type. If explicitly marked off, draw no cursor.
22143 In all other cases, we want a hollow box cursor. */
22144
22145 static enum text_cursor_kinds
22146 get_window_cursor_type (w, glyph, width, active_cursor)
22147 struct window *w;
22148 struct glyph *glyph;
22149 int *width;
22150 int *active_cursor;
22151 {
22152 struct frame *f = XFRAME (w->frame);
22153 struct buffer *b = XBUFFER (w->buffer);
22154 int cursor_type = DEFAULT_CURSOR;
22155 Lisp_Object alt_cursor;
22156 int non_selected = 0;
22157
22158 *active_cursor = 1;
22159
22160 /* Echo area */
22161 if (cursor_in_echo_area
22162 && FRAME_HAS_MINIBUF_P (f)
22163 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
22164 {
22165 if (w == XWINDOW (echo_area_window))
22166 {
22167 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
22168 {
22169 *width = FRAME_CURSOR_WIDTH (f);
22170 return FRAME_DESIRED_CURSOR (f);
22171 }
22172 else
22173 return get_specified_cursor_type (b->cursor_type, width);
22174 }
22175
22176 *active_cursor = 0;
22177 non_selected = 1;
22178 }
22179
22180 /* Detect a nonselected window or nonselected frame. */
22181 else if (w != XWINDOW (f->selected_window)
22182 #ifdef HAVE_WINDOW_SYSTEM
22183 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
22184 #endif
22185 )
22186 {
22187 *active_cursor = 0;
22188
22189 if (MINI_WINDOW_P (w) && minibuf_level == 0)
22190 return NO_CURSOR;
22191
22192 non_selected = 1;
22193 }
22194
22195 /* Never display a cursor in a window in which cursor-type is nil. */
22196 if (NILP (b->cursor_type))
22197 return NO_CURSOR;
22198
22199 /* Get the normal cursor type for this window. */
22200 if (EQ (b->cursor_type, Qt))
22201 {
22202 cursor_type = FRAME_DESIRED_CURSOR (f);
22203 *width = FRAME_CURSOR_WIDTH (f);
22204 }
22205 else
22206 cursor_type = get_specified_cursor_type (b->cursor_type, width);
22207
22208 /* Use cursor-in-non-selected-windows instead
22209 for non-selected window or frame. */
22210 if (non_selected)
22211 {
22212 alt_cursor = b->cursor_in_non_selected_windows;
22213 if (!EQ (Qt, alt_cursor))
22214 return get_specified_cursor_type (alt_cursor, width);
22215 /* t means modify the normal cursor type. */
22216 if (cursor_type == FILLED_BOX_CURSOR)
22217 cursor_type = HOLLOW_BOX_CURSOR;
22218 else if (cursor_type == BAR_CURSOR && *width > 1)
22219 --*width;
22220 return cursor_type;
22221 }
22222
22223 /* Use normal cursor if not blinked off. */
22224 if (!w->cursor_off_p)
22225 {
22226 #ifdef HAVE_WINDOW_SYSTEM
22227 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22228 {
22229 if (cursor_type == FILLED_BOX_CURSOR)
22230 {
22231 /* Using a block cursor on large images can be very annoying.
22232 So use a hollow cursor for "large" images.
22233 If image is not transparent (no mask), also use hollow cursor. */
22234 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22235 if (img != NULL && IMAGEP (img->spec))
22236 {
22237 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
22238 where N = size of default frame font size.
22239 This should cover most of the "tiny" icons people may use. */
22240 if (!img->mask
22241 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
22242 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
22243 cursor_type = HOLLOW_BOX_CURSOR;
22244 }
22245 }
22246 else if (cursor_type != NO_CURSOR)
22247 {
22248 /* Display current only supports BOX and HOLLOW cursors for images.
22249 So for now, unconditionally use a HOLLOW cursor when cursor is
22250 not a solid box cursor. */
22251 cursor_type = HOLLOW_BOX_CURSOR;
22252 }
22253 }
22254 #endif
22255 return cursor_type;
22256 }
22257
22258 /* Cursor is blinked off, so determine how to "toggle" it. */
22259
22260 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
22261 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
22262 return get_specified_cursor_type (XCDR (alt_cursor), width);
22263
22264 /* Then see if frame has specified a specific blink off cursor type. */
22265 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
22266 {
22267 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
22268 return FRAME_BLINK_OFF_CURSOR (f);
22269 }
22270
22271 #if 0
22272 /* Some people liked having a permanently visible blinking cursor,
22273 while others had very strong opinions against it. So it was
22274 decided to remove it. KFS 2003-09-03 */
22275
22276 /* Finally perform built-in cursor blinking:
22277 filled box <-> hollow box
22278 wide [h]bar <-> narrow [h]bar
22279 narrow [h]bar <-> no cursor
22280 other type <-> no cursor */
22281
22282 if (cursor_type == FILLED_BOX_CURSOR)
22283 return HOLLOW_BOX_CURSOR;
22284
22285 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
22286 {
22287 *width = 1;
22288 return cursor_type;
22289 }
22290 #endif
22291
22292 return NO_CURSOR;
22293 }
22294
22295
22296 #ifdef HAVE_WINDOW_SYSTEM
22297
22298 /* Notice when the text cursor of window W has been completely
22299 overwritten by a drawing operation that outputs glyphs in AREA
22300 starting at X0 and ending at X1 in the line starting at Y0 and
22301 ending at Y1. X coordinates are area-relative. X1 < 0 means all
22302 the rest of the line after X0 has been written. Y coordinates
22303 are window-relative. */
22304
22305 static void
22306 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
22307 struct window *w;
22308 enum glyph_row_area area;
22309 int x0, y0, x1, y1;
22310 {
22311 int cx0, cx1, cy0, cy1;
22312 struct glyph_row *row;
22313
22314 if (!w->phys_cursor_on_p)
22315 return;
22316 if (area != TEXT_AREA)
22317 return;
22318
22319 if (w->phys_cursor.vpos < 0
22320 || w->phys_cursor.vpos >= w->current_matrix->nrows
22321 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
22322 !(row->enabled_p && row->displays_text_p)))
22323 return;
22324
22325 if (row->cursor_in_fringe_p)
22326 {
22327 row->cursor_in_fringe_p = 0;
22328 draw_fringe_bitmap (w, row, 0);
22329 w->phys_cursor_on_p = 0;
22330 return;
22331 }
22332
22333 cx0 = w->phys_cursor.x;
22334 cx1 = cx0 + w->phys_cursor_width;
22335 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
22336 return;
22337
22338 /* The cursor image will be completely removed from the
22339 screen if the output area intersects the cursor area in
22340 y-direction. When we draw in [y0 y1[, and some part of
22341 the cursor is at y < y0, that part must have been drawn
22342 before. When scrolling, the cursor is erased before
22343 actually scrolling, so we don't come here. When not
22344 scrolling, the rows above the old cursor row must have
22345 changed, and in this case these rows must have written
22346 over the cursor image.
22347
22348 Likewise if part of the cursor is below y1, with the
22349 exception of the cursor being in the first blank row at
22350 the buffer and window end because update_text_area
22351 doesn't draw that row. (Except when it does, but
22352 that's handled in update_text_area.) */
22353
22354 cy0 = w->phys_cursor.y;
22355 cy1 = cy0 + w->phys_cursor_height;
22356 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
22357 return;
22358
22359 w->phys_cursor_on_p = 0;
22360 }
22361
22362 #endif /* HAVE_WINDOW_SYSTEM */
22363
22364 \f
22365 /************************************************************************
22366 Mouse Face
22367 ************************************************************************/
22368
22369 #ifdef HAVE_WINDOW_SYSTEM
22370
22371 /* EXPORT for RIF:
22372 Fix the display of area AREA of overlapping row ROW in window W
22373 with respect to the overlapping part OVERLAPS. */
22374
22375 void
22376 x_fix_overlapping_area (w, row, area, overlaps)
22377 struct window *w;
22378 struct glyph_row *row;
22379 enum glyph_row_area area;
22380 int overlaps;
22381 {
22382 int i, x;
22383
22384 BLOCK_INPUT;
22385
22386 x = 0;
22387 for (i = 0; i < row->used[area];)
22388 {
22389 if (row->glyphs[area][i].overlaps_vertically_p)
22390 {
22391 int start = i, start_x = x;
22392
22393 do
22394 {
22395 x += row->glyphs[area][i].pixel_width;
22396 ++i;
22397 }
22398 while (i < row->used[area]
22399 && row->glyphs[area][i].overlaps_vertically_p);
22400
22401 draw_glyphs (w, start_x, row, area,
22402 start, i,
22403 DRAW_NORMAL_TEXT, overlaps);
22404 }
22405 else
22406 {
22407 x += row->glyphs[area][i].pixel_width;
22408 ++i;
22409 }
22410 }
22411
22412 UNBLOCK_INPUT;
22413 }
22414
22415
22416 /* EXPORT:
22417 Draw the cursor glyph of window W in glyph row ROW. See the
22418 comment of draw_glyphs for the meaning of HL. */
22419
22420 void
22421 draw_phys_cursor_glyph (w, row, hl)
22422 struct window *w;
22423 struct glyph_row *row;
22424 enum draw_glyphs_face hl;
22425 {
22426 /* If cursor hpos is out of bounds, don't draw garbage. This can
22427 happen in mini-buffer windows when switching between echo area
22428 glyphs and mini-buffer. */
22429 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
22430 {
22431 int on_p = w->phys_cursor_on_p;
22432 int x1;
22433 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
22434 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
22435 hl, 0);
22436 w->phys_cursor_on_p = on_p;
22437
22438 if (hl == DRAW_CURSOR)
22439 w->phys_cursor_width = x1 - w->phys_cursor.x;
22440 /* When we erase the cursor, and ROW is overlapped by other
22441 rows, make sure that these overlapping parts of other rows
22442 are redrawn. */
22443 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
22444 {
22445 w->phys_cursor_width = x1 - w->phys_cursor.x;
22446
22447 if (row > w->current_matrix->rows
22448 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
22449 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
22450 OVERLAPS_ERASED_CURSOR);
22451
22452 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
22453 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
22454 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
22455 OVERLAPS_ERASED_CURSOR);
22456 }
22457 }
22458 }
22459
22460
22461 /* EXPORT:
22462 Erase the image of a cursor of window W from the screen. */
22463
22464 void
22465 erase_phys_cursor (w)
22466 struct window *w;
22467 {
22468 struct frame *f = XFRAME (w->frame);
22469 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22470 int hpos = w->phys_cursor.hpos;
22471 int vpos = w->phys_cursor.vpos;
22472 int mouse_face_here_p = 0;
22473 struct glyph_matrix *active_glyphs = w->current_matrix;
22474 struct glyph_row *cursor_row;
22475 struct glyph *cursor_glyph;
22476 enum draw_glyphs_face hl;
22477
22478 /* No cursor displayed or row invalidated => nothing to do on the
22479 screen. */
22480 if (w->phys_cursor_type == NO_CURSOR)
22481 goto mark_cursor_off;
22482
22483 /* VPOS >= active_glyphs->nrows means that window has been resized.
22484 Don't bother to erase the cursor. */
22485 if (vpos >= active_glyphs->nrows)
22486 goto mark_cursor_off;
22487
22488 /* If row containing cursor is marked invalid, there is nothing we
22489 can do. */
22490 cursor_row = MATRIX_ROW (active_glyphs, vpos);
22491 if (!cursor_row->enabled_p)
22492 goto mark_cursor_off;
22493
22494 /* If line spacing is > 0, old cursor may only be partially visible in
22495 window after split-window. So adjust visible height. */
22496 cursor_row->visible_height = min (cursor_row->visible_height,
22497 window_text_bottom_y (w) - cursor_row->y);
22498
22499 /* If row is completely invisible, don't attempt to delete a cursor which
22500 isn't there. This can happen if cursor is at top of a window, and
22501 we switch to a buffer with a header line in that window. */
22502 if (cursor_row->visible_height <= 0)
22503 goto mark_cursor_off;
22504
22505 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
22506 if (cursor_row->cursor_in_fringe_p)
22507 {
22508 cursor_row->cursor_in_fringe_p = 0;
22509 draw_fringe_bitmap (w, cursor_row, 0);
22510 goto mark_cursor_off;
22511 }
22512
22513 /* This can happen when the new row is shorter than the old one.
22514 In this case, either draw_glyphs or clear_end_of_line
22515 should have cleared the cursor. Note that we wouldn't be
22516 able to erase the cursor in this case because we don't have a
22517 cursor glyph at hand. */
22518 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
22519 goto mark_cursor_off;
22520
22521 /* If the cursor is in the mouse face area, redisplay that when
22522 we clear the cursor. */
22523 if (! NILP (dpyinfo->mouse_face_window)
22524 && w == XWINDOW (dpyinfo->mouse_face_window)
22525 && (vpos > dpyinfo->mouse_face_beg_row
22526 || (vpos == dpyinfo->mouse_face_beg_row
22527 && hpos >= dpyinfo->mouse_face_beg_col))
22528 && (vpos < dpyinfo->mouse_face_end_row
22529 || (vpos == dpyinfo->mouse_face_end_row
22530 && hpos < dpyinfo->mouse_face_end_col))
22531 /* Don't redraw the cursor's spot in mouse face if it is at the
22532 end of a line (on a newline). The cursor appears there, but
22533 mouse highlighting does not. */
22534 && cursor_row->used[TEXT_AREA] > hpos)
22535 mouse_face_here_p = 1;
22536
22537 /* Maybe clear the display under the cursor. */
22538 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
22539 {
22540 int x, y, left_x;
22541 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
22542 int width;
22543
22544 cursor_glyph = get_phys_cursor_glyph (w);
22545 if (cursor_glyph == NULL)
22546 goto mark_cursor_off;
22547
22548 width = cursor_glyph->pixel_width;
22549 left_x = window_box_left_offset (w, TEXT_AREA);
22550 x = w->phys_cursor.x;
22551 if (x < left_x)
22552 width -= left_x - x;
22553 width = min (width, window_box_width (w, TEXT_AREA) - x);
22554 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
22555 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
22556
22557 if (width > 0)
22558 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
22559 }
22560
22561 /* Erase the cursor by redrawing the character underneath it. */
22562 if (mouse_face_here_p)
22563 hl = DRAW_MOUSE_FACE;
22564 else
22565 hl = DRAW_NORMAL_TEXT;
22566 draw_phys_cursor_glyph (w, cursor_row, hl);
22567
22568 mark_cursor_off:
22569 w->phys_cursor_on_p = 0;
22570 w->phys_cursor_type = NO_CURSOR;
22571 }
22572
22573
22574 /* EXPORT:
22575 Display or clear cursor of window W. If ON is zero, clear the
22576 cursor. If it is non-zero, display the cursor. If ON is nonzero,
22577 where to put the cursor is specified by HPOS, VPOS, X and Y. */
22578
22579 void
22580 display_and_set_cursor (w, on, hpos, vpos, x, y)
22581 struct window *w;
22582 int on, hpos, vpos, x, y;
22583 {
22584 struct frame *f = XFRAME (w->frame);
22585 int new_cursor_type;
22586 int new_cursor_width;
22587 int active_cursor;
22588 struct glyph_row *glyph_row;
22589 struct glyph *glyph;
22590
22591 /* This is pointless on invisible frames, and dangerous on garbaged
22592 windows and frames; in the latter case, the frame or window may
22593 be in the midst of changing its size, and x and y may be off the
22594 window. */
22595 if (! FRAME_VISIBLE_P (f)
22596 || FRAME_GARBAGED_P (f)
22597 || vpos >= w->current_matrix->nrows
22598 || hpos >= w->current_matrix->matrix_w)
22599 return;
22600
22601 /* If cursor is off and we want it off, return quickly. */
22602 if (!on && !w->phys_cursor_on_p)
22603 return;
22604
22605 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
22606 /* If cursor row is not enabled, we don't really know where to
22607 display the cursor. */
22608 if (!glyph_row->enabled_p)
22609 {
22610 w->phys_cursor_on_p = 0;
22611 return;
22612 }
22613
22614 glyph = NULL;
22615 if (!glyph_row->exact_window_width_line_p
22616 || hpos < glyph_row->used[TEXT_AREA])
22617 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
22618
22619 xassert (interrupt_input_blocked);
22620
22621 /* Set new_cursor_type to the cursor we want to be displayed. */
22622 new_cursor_type = get_window_cursor_type (w, glyph,
22623 &new_cursor_width, &active_cursor);
22624
22625 /* If cursor is currently being shown and we don't want it to be or
22626 it is in the wrong place, or the cursor type is not what we want,
22627 erase it. */
22628 if (w->phys_cursor_on_p
22629 && (!on
22630 || w->phys_cursor.x != x
22631 || w->phys_cursor.y != y
22632 || new_cursor_type != w->phys_cursor_type
22633 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
22634 && new_cursor_width != w->phys_cursor_width)))
22635 erase_phys_cursor (w);
22636
22637 /* Don't check phys_cursor_on_p here because that flag is only set
22638 to zero in some cases where we know that the cursor has been
22639 completely erased, to avoid the extra work of erasing the cursor
22640 twice. In other words, phys_cursor_on_p can be 1 and the cursor
22641 still not be visible, or it has only been partly erased. */
22642 if (on)
22643 {
22644 w->phys_cursor_ascent = glyph_row->ascent;
22645 w->phys_cursor_height = glyph_row->height;
22646
22647 /* Set phys_cursor_.* before x_draw_.* is called because some
22648 of them may need the information. */
22649 w->phys_cursor.x = x;
22650 w->phys_cursor.y = glyph_row->y;
22651 w->phys_cursor.hpos = hpos;
22652 w->phys_cursor.vpos = vpos;
22653 }
22654
22655 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
22656 new_cursor_type, new_cursor_width,
22657 on, active_cursor);
22658 }
22659
22660
22661 /* Switch the display of W's cursor on or off, according to the value
22662 of ON. */
22663
22664 #ifndef HAVE_NS
22665 static
22666 #endif
22667 void
22668 update_window_cursor (w, on)
22669 struct window *w;
22670 int on;
22671 {
22672 /* Don't update cursor in windows whose frame is in the process
22673 of being deleted. */
22674 if (w->current_matrix)
22675 {
22676 BLOCK_INPUT;
22677 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
22678 w->phys_cursor.x, w->phys_cursor.y);
22679 UNBLOCK_INPUT;
22680 }
22681 }
22682
22683
22684 /* Call update_window_cursor with parameter ON_P on all leaf windows
22685 in the window tree rooted at W. */
22686
22687 static void
22688 update_cursor_in_window_tree (w, on_p)
22689 struct window *w;
22690 int on_p;
22691 {
22692 while (w)
22693 {
22694 if (!NILP (w->hchild))
22695 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
22696 else if (!NILP (w->vchild))
22697 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
22698 else
22699 update_window_cursor (w, on_p);
22700
22701 w = NILP (w->next) ? 0 : XWINDOW (w->next);
22702 }
22703 }
22704
22705
22706 /* EXPORT:
22707 Display the cursor on window W, or clear it, according to ON_P.
22708 Don't change the cursor's position. */
22709
22710 void
22711 x_update_cursor (f, on_p)
22712 struct frame *f;
22713 int on_p;
22714 {
22715 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
22716 }
22717
22718
22719 /* EXPORT:
22720 Clear the cursor of window W to background color, and mark the
22721 cursor as not shown. This is used when the text where the cursor
22722 is about to be rewritten. */
22723
22724 void
22725 x_clear_cursor (w)
22726 struct window *w;
22727 {
22728 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
22729 update_window_cursor (w, 0);
22730 }
22731
22732
22733 /* EXPORT:
22734 Display the active region described by mouse_face_* according to DRAW. */
22735
22736 void
22737 show_mouse_face (dpyinfo, draw)
22738 Display_Info *dpyinfo;
22739 enum draw_glyphs_face draw;
22740 {
22741 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
22742 struct frame *f = XFRAME (WINDOW_FRAME (w));
22743
22744 if (/* If window is in the process of being destroyed, don't bother
22745 to do anything. */
22746 w->current_matrix != NULL
22747 /* Don't update mouse highlight if hidden */
22748 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
22749 /* Recognize when we are called to operate on rows that don't exist
22750 anymore. This can happen when a window is split. */
22751 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
22752 {
22753 int phys_cursor_on_p = w->phys_cursor_on_p;
22754 struct glyph_row *row, *first, *last;
22755
22756 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
22757 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
22758
22759 for (row = first; row <= last && row->enabled_p; ++row)
22760 {
22761 int start_hpos, end_hpos, start_x;
22762
22763 /* For all but the first row, the highlight starts at column 0. */
22764 if (row == first)
22765 {
22766 start_hpos = dpyinfo->mouse_face_beg_col;
22767 start_x = dpyinfo->mouse_face_beg_x;
22768 }
22769 else
22770 {
22771 start_hpos = 0;
22772 start_x = 0;
22773 }
22774
22775 if (row == last)
22776 end_hpos = dpyinfo->mouse_face_end_col;
22777 else
22778 {
22779 end_hpos = row->used[TEXT_AREA];
22780 if (draw == DRAW_NORMAL_TEXT)
22781 row->fill_line_p = 1; /* Clear to end of line */
22782 }
22783
22784 if (end_hpos > start_hpos)
22785 {
22786 draw_glyphs (w, start_x, row, TEXT_AREA,
22787 start_hpos, end_hpos,
22788 draw, 0);
22789
22790 row->mouse_face_p
22791 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
22792 }
22793 }
22794
22795 /* When we've written over the cursor, arrange for it to
22796 be displayed again. */
22797 if (phys_cursor_on_p && !w->phys_cursor_on_p)
22798 {
22799 BLOCK_INPUT;
22800 display_and_set_cursor (w, 1,
22801 w->phys_cursor.hpos, w->phys_cursor.vpos,
22802 w->phys_cursor.x, w->phys_cursor.y);
22803 UNBLOCK_INPUT;
22804 }
22805 }
22806
22807 /* Change the mouse cursor. */
22808 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22809 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22810 else if (draw == DRAW_MOUSE_FACE)
22811 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22812 else
22813 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22814 }
22815
22816 /* EXPORT:
22817 Clear out the mouse-highlighted active region.
22818 Redraw it un-highlighted first. Value is non-zero if mouse
22819 face was actually drawn unhighlighted. */
22820
22821 int
22822 clear_mouse_face (dpyinfo)
22823 Display_Info *dpyinfo;
22824 {
22825 int cleared = 0;
22826
22827 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22828 {
22829 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22830 cleared = 1;
22831 }
22832
22833 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22834 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22835 dpyinfo->mouse_face_window = Qnil;
22836 dpyinfo->mouse_face_overlay = Qnil;
22837 return cleared;
22838 }
22839
22840
22841 /* EXPORT:
22842 Non-zero if physical cursor of window W is within mouse face. */
22843
22844 int
22845 cursor_in_mouse_face_p (w)
22846 struct window *w;
22847 {
22848 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22849 int in_mouse_face = 0;
22850
22851 if (WINDOWP (dpyinfo->mouse_face_window)
22852 && XWINDOW (dpyinfo->mouse_face_window) == w)
22853 {
22854 int hpos = w->phys_cursor.hpos;
22855 int vpos = w->phys_cursor.vpos;
22856
22857 if (vpos >= dpyinfo->mouse_face_beg_row
22858 && vpos <= dpyinfo->mouse_face_end_row
22859 && (vpos > dpyinfo->mouse_face_beg_row
22860 || hpos >= dpyinfo->mouse_face_beg_col)
22861 && (vpos < dpyinfo->mouse_face_end_row
22862 || hpos < dpyinfo->mouse_face_end_col
22863 || dpyinfo->mouse_face_past_end))
22864 in_mouse_face = 1;
22865 }
22866
22867 return in_mouse_face;
22868 }
22869
22870
22871
22872 \f
22873 /* This function sets the mouse_face_* elements of DPYINFO, assuming
22874 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
22875 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
22876 for the overlay or run of text properties specifying the mouse
22877 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
22878 before-string and after-string that must also be highlighted.
22879 DISPLAY_STRING, if non-nil, is a display string that may cover some
22880 or all of the highlighted text. */
22881
22882 static void
22883 mouse_face_from_buffer_pos (Lisp_Object window,
22884 Display_Info *dpyinfo,
22885 EMACS_INT mouse_charpos,
22886 EMACS_INT start_charpos,
22887 EMACS_INT end_charpos,
22888 Lisp_Object before_string,
22889 Lisp_Object after_string,
22890 Lisp_Object display_string)
22891 {
22892 struct window *w = XWINDOW (window);
22893 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22894 struct glyph_row *row;
22895 struct glyph *glyph, *end;
22896 EMACS_INT ignore;
22897 int x;
22898
22899 xassert (NILP (display_string) || STRINGP (display_string));
22900 xassert (NILP (before_string) || STRINGP (before_string));
22901 xassert (NILP (after_string) || STRINGP (after_string));
22902
22903 /* Find the first highlighted glyph. */
22904 if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
22905 {
22906 dpyinfo->mouse_face_beg_col = 0;
22907 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
22908 dpyinfo->mouse_face_beg_x = first->x;
22909 dpyinfo->mouse_face_beg_y = first->y;
22910 }
22911 else
22912 {
22913 row = row_containing_pos (w, start_charpos, first, NULL, 0);
22914 if (row == NULL)
22915 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22916
22917 /* If the before-string or display-string contains newlines,
22918 row_containing_pos skips to its last row. Move back. */
22919 if (!NILP (before_string) || !NILP (display_string))
22920 {
22921 struct glyph_row *prev;
22922 while ((prev = row - 1, prev >= first)
22923 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
22924 && prev->used[TEXT_AREA] > 0)
22925 {
22926 struct glyph *beg = prev->glyphs[TEXT_AREA];
22927 glyph = beg + prev->used[TEXT_AREA];
22928 while (--glyph >= beg && INTEGERP (glyph->object));
22929 if (glyph < beg
22930 || !(EQ (glyph->object, before_string)
22931 || EQ (glyph->object, display_string)))
22932 break;
22933 row = prev;
22934 }
22935 }
22936
22937 glyph = row->glyphs[TEXT_AREA];
22938 end = glyph + row->used[TEXT_AREA];
22939 x = row->x;
22940 dpyinfo->mouse_face_beg_y = row->y;
22941 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
22942
22943 /* Skip truncation glyphs at the start of the glyph row. */
22944 if (row->displays_text_p)
22945 for (; glyph < end
22946 && INTEGERP (glyph->object)
22947 && glyph->charpos < 0;
22948 ++glyph)
22949 x += glyph->pixel_width;
22950
22951 /* Scan the glyph row, stopping before BEFORE_STRING or
22952 DISPLAY_STRING or START_CHARPOS. */
22953 for (; glyph < end
22954 && !INTEGERP (glyph->object)
22955 && !EQ (glyph->object, before_string)
22956 && !EQ (glyph->object, display_string)
22957 && !(BUFFERP (glyph->object)
22958 && glyph->charpos >= start_charpos);
22959 ++glyph)
22960 x += glyph->pixel_width;
22961
22962 dpyinfo->mouse_face_beg_x = x;
22963 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
22964 }
22965
22966 /* Find the last highlighted glyph. */
22967 row = row_containing_pos (w, end_charpos, first, NULL, 0);
22968 if (row == NULL)
22969 {
22970 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22971 dpyinfo->mouse_face_past_end = 1;
22972 }
22973 else if (!NILP (after_string))
22974 {
22975 /* If the after-string has newlines, advance to its last row. */
22976 struct glyph_row *next;
22977 struct glyph_row *last
22978 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22979
22980 for (next = row + 1;
22981 next <= last
22982 && next->used[TEXT_AREA] > 0
22983 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
22984 ++next)
22985 row = next;
22986 }
22987
22988 glyph = row->glyphs[TEXT_AREA];
22989 end = glyph + row->used[TEXT_AREA];
22990 x = row->x;
22991 dpyinfo->mouse_face_end_y = row->y;
22992 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
22993
22994 /* Skip truncation glyphs at the start of the row. */
22995 if (row->displays_text_p)
22996 for (; glyph < end
22997 && INTEGERP (glyph->object)
22998 && glyph->charpos < 0;
22999 ++glyph)
23000 x += glyph->pixel_width;
23001
23002 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
23003 AFTER_STRING. */
23004 for (; glyph < end
23005 && !INTEGERP (glyph->object)
23006 && !EQ (glyph->object, after_string)
23007 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
23008 ++glyph)
23009 x += glyph->pixel_width;
23010
23011 /* If we found AFTER_STRING, consume it and stop. */
23012 if (EQ (glyph->object, after_string))
23013 {
23014 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
23015 x += glyph->pixel_width;
23016 }
23017 else
23018 {
23019 /* If there's no after-string, we must check if we overshot,
23020 which might be the case if we stopped after a string glyph.
23021 That glyph may belong to a before-string or display-string
23022 associated with the end position, which must not be
23023 highlighted. */
23024 Lisp_Object prev_object;
23025 int pos;
23026
23027 while (glyph > row->glyphs[TEXT_AREA])
23028 {
23029 prev_object = (glyph - 1)->object;
23030 if (!STRINGP (prev_object) || EQ (prev_object, display_string))
23031 break;
23032
23033 pos = string_buffer_position (w, prev_object, end_charpos);
23034 if (pos && pos < end_charpos)
23035 break;
23036
23037 for (; glyph > row->glyphs[TEXT_AREA]
23038 && EQ ((glyph - 1)->object, prev_object);
23039 --glyph)
23040 x -= (glyph - 1)->pixel_width;
23041 }
23042 }
23043
23044 dpyinfo->mouse_face_end_x = x;
23045 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
23046 dpyinfo->mouse_face_window = window;
23047 dpyinfo->mouse_face_face_id
23048 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
23049 mouse_charpos + 1,
23050 !dpyinfo->mouse_face_hidden, -1);
23051 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23052 }
23053
23054
23055 /* Find the position of the glyph for position POS in OBJECT in
23056 window W's current matrix, and return in *X, *Y the pixel
23057 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
23058
23059 RIGHT_P non-zero means return the position of the right edge of the
23060 glyph, RIGHT_P zero means return the left edge position.
23061
23062 If no glyph for POS exists in the matrix, return the position of
23063 the glyph with the next smaller position that is in the matrix, if
23064 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
23065 exists in the matrix, return the position of the glyph with the
23066 next larger position in OBJECT.
23067
23068 Value is non-zero if a glyph was found. */
23069
23070 static int
23071 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
23072 struct window *w;
23073 EMACS_INT pos;
23074 Lisp_Object object;
23075 int *hpos, *vpos, *x, *y;
23076 int right_p;
23077 {
23078 int yb = window_text_bottom_y (w);
23079 struct glyph_row *r;
23080 struct glyph *best_glyph = NULL;
23081 struct glyph_row *best_row = NULL;
23082 int best_x = 0;
23083
23084 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23085 r->enabled_p && r->y < yb;
23086 ++r)
23087 {
23088 struct glyph *g = r->glyphs[TEXT_AREA];
23089 struct glyph *e = g + r->used[TEXT_AREA];
23090 int gx;
23091
23092 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
23093 if (EQ (g->object, object))
23094 {
23095 if (g->charpos == pos)
23096 {
23097 best_glyph = g;
23098 best_x = gx;
23099 best_row = r;
23100 goto found;
23101 }
23102 else if (best_glyph == NULL
23103 || ((eabs (g->charpos - pos)
23104 < eabs (best_glyph->charpos - pos))
23105 && (right_p
23106 ? g->charpos < pos
23107 : g->charpos > pos)))
23108 {
23109 best_glyph = g;
23110 best_x = gx;
23111 best_row = r;
23112 }
23113 }
23114 }
23115
23116 found:
23117
23118 if (best_glyph)
23119 {
23120 *x = best_x;
23121 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
23122
23123 if (right_p)
23124 {
23125 *x += best_glyph->pixel_width;
23126 ++*hpos;
23127 }
23128
23129 *y = best_row->y;
23130 *vpos = best_row - w->current_matrix->rows;
23131 }
23132
23133 return best_glyph != NULL;
23134 }
23135
23136
23137 /* See if position X, Y is within a hot-spot of an image. */
23138
23139 static int
23140 on_hot_spot_p (hot_spot, x, y)
23141 Lisp_Object hot_spot;
23142 int x, y;
23143 {
23144 if (!CONSP (hot_spot))
23145 return 0;
23146
23147 if (EQ (XCAR (hot_spot), Qrect))
23148 {
23149 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
23150 Lisp_Object rect = XCDR (hot_spot);
23151 Lisp_Object tem;
23152 if (!CONSP (rect))
23153 return 0;
23154 if (!CONSP (XCAR (rect)))
23155 return 0;
23156 if (!CONSP (XCDR (rect)))
23157 return 0;
23158 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
23159 return 0;
23160 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
23161 return 0;
23162 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
23163 return 0;
23164 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
23165 return 0;
23166 return 1;
23167 }
23168 else if (EQ (XCAR (hot_spot), Qcircle))
23169 {
23170 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
23171 Lisp_Object circ = XCDR (hot_spot);
23172 Lisp_Object lr, lx0, ly0;
23173 if (CONSP (circ)
23174 && CONSP (XCAR (circ))
23175 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
23176 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
23177 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
23178 {
23179 double r = XFLOATINT (lr);
23180 double dx = XINT (lx0) - x;
23181 double dy = XINT (ly0) - y;
23182 return (dx * dx + dy * dy <= r * r);
23183 }
23184 }
23185 else if (EQ (XCAR (hot_spot), Qpoly))
23186 {
23187 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
23188 if (VECTORP (XCDR (hot_spot)))
23189 {
23190 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
23191 Lisp_Object *poly = v->contents;
23192 int n = v->size;
23193 int i;
23194 int inside = 0;
23195 Lisp_Object lx, ly;
23196 int x0, y0;
23197
23198 /* Need an even number of coordinates, and at least 3 edges. */
23199 if (n < 6 || n & 1)
23200 return 0;
23201
23202 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
23203 If count is odd, we are inside polygon. Pixels on edges
23204 may or may not be included depending on actual geometry of the
23205 polygon. */
23206 if ((lx = poly[n-2], !INTEGERP (lx))
23207 || (ly = poly[n-1], !INTEGERP (lx)))
23208 return 0;
23209 x0 = XINT (lx), y0 = XINT (ly);
23210 for (i = 0; i < n; i += 2)
23211 {
23212 int x1 = x0, y1 = y0;
23213 if ((lx = poly[i], !INTEGERP (lx))
23214 || (ly = poly[i+1], !INTEGERP (ly)))
23215 return 0;
23216 x0 = XINT (lx), y0 = XINT (ly);
23217
23218 /* Does this segment cross the X line? */
23219 if (x0 >= x)
23220 {
23221 if (x1 >= x)
23222 continue;
23223 }
23224 else if (x1 < x)
23225 continue;
23226 if (y > y0 && y > y1)
23227 continue;
23228 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
23229 inside = !inside;
23230 }
23231 return inside;
23232 }
23233 }
23234 return 0;
23235 }
23236
23237 Lisp_Object
23238 find_hot_spot (map, x, y)
23239 Lisp_Object map;
23240 int x, y;
23241 {
23242 while (CONSP (map))
23243 {
23244 if (CONSP (XCAR (map))
23245 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
23246 return XCAR (map);
23247 map = XCDR (map);
23248 }
23249
23250 return Qnil;
23251 }
23252
23253 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
23254 3, 3, 0,
23255 doc: /* Lookup in image map MAP coordinates X and Y.
23256 An image map is an alist where each element has the format (AREA ID PLIST).
23257 An AREA is specified as either a rectangle, a circle, or a polygon:
23258 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
23259 pixel coordinates of the upper left and bottom right corners.
23260 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
23261 and the radius of the circle; r may be a float or integer.
23262 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
23263 vector describes one corner in the polygon.
23264 Returns the alist element for the first matching AREA in MAP. */)
23265 (map, x, y)
23266 Lisp_Object map;
23267 Lisp_Object x, y;
23268 {
23269 if (NILP (map))
23270 return Qnil;
23271
23272 CHECK_NUMBER (x);
23273 CHECK_NUMBER (y);
23274
23275 return find_hot_spot (map, XINT (x), XINT (y));
23276 }
23277
23278
23279 /* Display frame CURSOR, optionally using shape defined by POINTER. */
23280 static void
23281 define_frame_cursor1 (f, cursor, pointer)
23282 struct frame *f;
23283 Cursor cursor;
23284 Lisp_Object pointer;
23285 {
23286 /* Do not change cursor shape while dragging mouse. */
23287 if (!NILP (do_mouse_tracking))
23288 return;
23289
23290 if (!NILP (pointer))
23291 {
23292 if (EQ (pointer, Qarrow))
23293 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23294 else if (EQ (pointer, Qhand))
23295 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
23296 else if (EQ (pointer, Qtext))
23297 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23298 else if (EQ (pointer, intern ("hdrag")))
23299 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23300 #ifdef HAVE_X_WINDOWS
23301 else if (EQ (pointer, intern ("vdrag")))
23302 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
23303 #endif
23304 else if (EQ (pointer, intern ("hourglass")))
23305 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
23306 else if (EQ (pointer, Qmodeline))
23307 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
23308 else
23309 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23310 }
23311
23312 if (cursor != No_Cursor)
23313 FRAME_RIF (f)->define_frame_cursor (f, cursor);
23314 }
23315
23316 /* Take proper action when mouse has moved to the mode or header line
23317 or marginal area AREA of window W, x-position X and y-position Y.
23318 X is relative to the start of the text display area of W, so the
23319 width of bitmap areas and scroll bars must be subtracted to get a
23320 position relative to the start of the mode line. */
23321
23322 static void
23323 note_mode_line_or_margin_highlight (window, x, y, area)
23324 Lisp_Object window;
23325 int x, y;
23326 enum window_part area;
23327 {
23328 struct window *w = XWINDOW (window);
23329 struct frame *f = XFRAME (w->frame);
23330 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23331 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23332 Lisp_Object pointer = Qnil;
23333 int charpos, dx, dy, width, height;
23334 Lisp_Object string, object = Qnil;
23335 Lisp_Object pos, help;
23336
23337 Lisp_Object mouse_face;
23338 int original_x_pixel = x;
23339 struct glyph * glyph = NULL, * row_start_glyph = NULL;
23340 struct glyph_row *row;
23341
23342 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
23343 {
23344 int x0;
23345 struct glyph *end;
23346
23347 string = mode_line_string (w, area, &x, &y, &charpos,
23348 &object, &dx, &dy, &width, &height);
23349
23350 row = (area == ON_MODE_LINE
23351 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
23352 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
23353
23354 /* Find glyph */
23355 if (row->mode_line_p && row->enabled_p)
23356 {
23357 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
23358 end = glyph + row->used[TEXT_AREA];
23359
23360 for (x0 = original_x_pixel;
23361 glyph < end && x0 >= glyph->pixel_width;
23362 ++glyph)
23363 x0 -= glyph->pixel_width;
23364
23365 if (glyph >= end)
23366 glyph = NULL;
23367 }
23368 }
23369 else
23370 {
23371 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
23372 string = marginal_area_string (w, area, &x, &y, &charpos,
23373 &object, &dx, &dy, &width, &height);
23374 }
23375
23376 help = Qnil;
23377
23378 if (IMAGEP (object))
23379 {
23380 Lisp_Object image_map, hotspot;
23381 if ((image_map = Fplist_get (XCDR (object), QCmap),
23382 !NILP (image_map))
23383 && (hotspot = find_hot_spot (image_map, dx, dy),
23384 CONSP (hotspot))
23385 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23386 {
23387 Lisp_Object area_id, plist;
23388
23389 area_id = XCAR (hotspot);
23390 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23391 If so, we could look for mouse-enter, mouse-leave
23392 properties in PLIST (and do something...). */
23393 hotspot = XCDR (hotspot);
23394 if (CONSP (hotspot)
23395 && (plist = XCAR (hotspot), CONSP (plist)))
23396 {
23397 pointer = Fplist_get (plist, Qpointer);
23398 if (NILP (pointer))
23399 pointer = Qhand;
23400 help = Fplist_get (plist, Qhelp_echo);
23401 if (!NILP (help))
23402 {
23403 help_echo_string = help;
23404 /* Is this correct? ++kfs */
23405 XSETWINDOW (help_echo_window, w);
23406 help_echo_object = w->buffer;
23407 help_echo_pos = charpos;
23408 }
23409 }
23410 }
23411 if (NILP (pointer))
23412 pointer = Fplist_get (XCDR (object), QCpointer);
23413 }
23414
23415 if (STRINGP (string))
23416 {
23417 pos = make_number (charpos);
23418 /* If we're on a string with `help-echo' text property, arrange
23419 for the help to be displayed. This is done by setting the
23420 global variable help_echo_string to the help string. */
23421 if (NILP (help))
23422 {
23423 help = Fget_text_property (pos, Qhelp_echo, string);
23424 if (!NILP (help))
23425 {
23426 help_echo_string = help;
23427 XSETWINDOW (help_echo_window, w);
23428 help_echo_object = string;
23429 help_echo_pos = charpos;
23430 }
23431 }
23432
23433 if (NILP (pointer))
23434 pointer = Fget_text_property (pos, Qpointer, string);
23435
23436 /* Change the mouse pointer according to what is under X/Y. */
23437 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
23438 {
23439 Lisp_Object map;
23440 map = Fget_text_property (pos, Qlocal_map, string);
23441 if (!KEYMAPP (map))
23442 map = Fget_text_property (pos, Qkeymap, string);
23443 if (!KEYMAPP (map))
23444 cursor = dpyinfo->vertical_scroll_bar_cursor;
23445 }
23446
23447 /* Change the mouse face according to what is under X/Y. */
23448 mouse_face = Fget_text_property (pos, Qmouse_face, string);
23449 if (!NILP (mouse_face)
23450 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23451 && glyph)
23452 {
23453 Lisp_Object b, e;
23454
23455 struct glyph * tmp_glyph;
23456
23457 int gpos;
23458 int gseq_length;
23459 int total_pixel_width;
23460 EMACS_INT ignore;
23461
23462 int vpos, hpos;
23463
23464 b = Fprevious_single_property_change (make_number (charpos + 1),
23465 Qmouse_face, string, Qnil);
23466 if (NILP (b))
23467 b = make_number (0);
23468
23469 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
23470 if (NILP (e))
23471 e = make_number (SCHARS (string));
23472
23473 /* Calculate the position(glyph position: GPOS) of GLYPH in
23474 displayed string. GPOS is different from CHARPOS.
23475
23476 CHARPOS is the position of glyph in internal string
23477 object. A mode line string format has structures which
23478 is converted to a flatten by emacs lisp interpreter.
23479 The internal string is an element of the structures.
23480 The displayed string is the flatten string. */
23481 gpos = 0;
23482 if (glyph > row_start_glyph)
23483 {
23484 tmp_glyph = glyph - 1;
23485 while (tmp_glyph >= row_start_glyph
23486 && tmp_glyph->charpos >= XINT (b)
23487 && EQ (tmp_glyph->object, glyph->object))
23488 {
23489 tmp_glyph--;
23490 gpos++;
23491 }
23492 }
23493
23494 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
23495 displayed string holding GLYPH.
23496
23497 GSEQ_LENGTH is different from SCHARS (STRING).
23498 SCHARS (STRING) returns the length of the internal string. */
23499 for (tmp_glyph = glyph, gseq_length = gpos;
23500 tmp_glyph->charpos < XINT (e);
23501 tmp_glyph++, gseq_length++)
23502 {
23503 if (!EQ (tmp_glyph->object, glyph->object))
23504 break;
23505 }
23506
23507 total_pixel_width = 0;
23508 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
23509 total_pixel_width += tmp_glyph->pixel_width;
23510
23511 /* Pre calculation of re-rendering position */
23512 vpos = (x - gpos);
23513 hpos = (area == ON_MODE_LINE
23514 ? (w->current_matrix)->nrows - 1
23515 : 0);
23516
23517 /* If the re-rendering position is included in the last
23518 re-rendering area, we should do nothing. */
23519 if ( EQ (window, dpyinfo->mouse_face_window)
23520 && dpyinfo->mouse_face_beg_col <= vpos
23521 && vpos < dpyinfo->mouse_face_end_col
23522 && dpyinfo->mouse_face_beg_row == hpos )
23523 return;
23524
23525 if (clear_mouse_face (dpyinfo))
23526 cursor = No_Cursor;
23527
23528 dpyinfo->mouse_face_beg_col = vpos;
23529 dpyinfo->mouse_face_beg_row = hpos;
23530
23531 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
23532 dpyinfo->mouse_face_beg_y = 0;
23533
23534 dpyinfo->mouse_face_end_col = vpos + gseq_length;
23535 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
23536
23537 dpyinfo->mouse_face_end_x = 0;
23538 dpyinfo->mouse_face_end_y = 0;
23539
23540 dpyinfo->mouse_face_past_end = 0;
23541 dpyinfo->mouse_face_window = window;
23542
23543 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
23544 charpos,
23545 0, 0, 0, &ignore,
23546 glyph->face_id, 1);
23547 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23548
23549 if (NILP (pointer))
23550 pointer = Qhand;
23551 }
23552 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23553 clear_mouse_face (dpyinfo);
23554 }
23555 define_frame_cursor1 (f, cursor, pointer);
23556 }
23557
23558
23559 /* EXPORT:
23560 Take proper action when the mouse has moved to position X, Y on
23561 frame F as regards highlighting characters that have mouse-face
23562 properties. Also de-highlighting chars where the mouse was before.
23563 X and Y can be negative or out of range. */
23564
23565 void
23566 note_mouse_highlight (f, x, y)
23567 struct frame *f;
23568 int x, y;
23569 {
23570 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23571 enum window_part part;
23572 Lisp_Object window;
23573 struct window *w;
23574 Cursor cursor = No_Cursor;
23575 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
23576 struct buffer *b;
23577
23578 /* When a menu is active, don't highlight because this looks odd. */
23579 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
23580 if (popup_activated ())
23581 return;
23582 #endif
23583
23584 if (NILP (Vmouse_highlight)
23585 || !f->glyphs_initialized_p)
23586 return;
23587
23588 dpyinfo->mouse_face_mouse_x = x;
23589 dpyinfo->mouse_face_mouse_y = y;
23590 dpyinfo->mouse_face_mouse_frame = f;
23591
23592 if (dpyinfo->mouse_face_defer)
23593 return;
23594
23595 if (gc_in_progress)
23596 {
23597 dpyinfo->mouse_face_deferred_gc = 1;
23598 return;
23599 }
23600
23601 /* Which window is that in? */
23602 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
23603
23604 /* If we were displaying active text in another window, clear that.
23605 Also clear if we move out of text area in same window. */
23606 if (! EQ (window, dpyinfo->mouse_face_window)
23607 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
23608 && !NILP (dpyinfo->mouse_face_window)))
23609 clear_mouse_face (dpyinfo);
23610
23611 /* Not on a window -> return. */
23612 if (!WINDOWP (window))
23613 return;
23614
23615 /* Reset help_echo_string. It will get recomputed below. */
23616 help_echo_string = Qnil;
23617
23618 /* Convert to window-relative pixel coordinates. */
23619 w = XWINDOW (window);
23620 frame_to_window_pixel_xy (w, &x, &y);
23621
23622 /* Handle tool-bar window differently since it doesn't display a
23623 buffer. */
23624 if (EQ (window, f->tool_bar_window))
23625 {
23626 note_tool_bar_highlight (f, x, y);
23627 return;
23628 }
23629
23630 /* Mouse is on the mode, header line or margin? */
23631 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
23632 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
23633 {
23634 note_mode_line_or_margin_highlight (window, x, y, part);
23635 return;
23636 }
23637
23638 if (part == ON_VERTICAL_BORDER)
23639 {
23640 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23641 help_echo_string = build_string ("drag-mouse-1: resize");
23642 }
23643 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
23644 || part == ON_SCROLL_BAR)
23645 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23646 else
23647 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23648
23649 /* Are we in a window whose display is up to date?
23650 And verify the buffer's text has not changed. */
23651 b = XBUFFER (w->buffer);
23652 if (part == ON_TEXT
23653 && EQ (w->window_end_valid, w->buffer)
23654 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
23655 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
23656 {
23657 int hpos, vpos, pos, i, dx, dy, area;
23658 struct glyph *glyph;
23659 Lisp_Object object;
23660 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
23661 Lisp_Object *overlay_vec = NULL;
23662 int noverlays;
23663 struct buffer *obuf;
23664 int obegv, ozv, same_region;
23665
23666 /* Find the glyph under X/Y. */
23667 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
23668
23669 /* Look for :pointer property on image. */
23670 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23671 {
23672 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23673 if (img != NULL && IMAGEP (img->spec))
23674 {
23675 Lisp_Object image_map, hotspot;
23676 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
23677 !NILP (image_map))
23678 && (hotspot = find_hot_spot (image_map,
23679 glyph->slice.x + dx,
23680 glyph->slice.y + dy),
23681 CONSP (hotspot))
23682 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23683 {
23684 Lisp_Object area_id, plist;
23685
23686 area_id = XCAR (hotspot);
23687 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23688 If so, we could look for mouse-enter, mouse-leave
23689 properties in PLIST (and do something...). */
23690 hotspot = XCDR (hotspot);
23691 if (CONSP (hotspot)
23692 && (plist = XCAR (hotspot), CONSP (plist)))
23693 {
23694 pointer = Fplist_get (plist, Qpointer);
23695 if (NILP (pointer))
23696 pointer = Qhand;
23697 help_echo_string = Fplist_get (plist, Qhelp_echo);
23698 if (!NILP (help_echo_string))
23699 {
23700 help_echo_window = window;
23701 help_echo_object = glyph->object;
23702 help_echo_pos = glyph->charpos;
23703 }
23704 }
23705 }
23706 if (NILP (pointer))
23707 pointer = Fplist_get (XCDR (img->spec), QCpointer);
23708 }
23709 }
23710
23711 /* Clear mouse face if X/Y not over text. */
23712 if (glyph == NULL
23713 || area != TEXT_AREA
23714 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
23715 {
23716 if (clear_mouse_face (dpyinfo))
23717 cursor = No_Cursor;
23718 if (NILP (pointer))
23719 {
23720 if (area != TEXT_AREA)
23721 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23722 else
23723 pointer = Vvoid_text_area_pointer;
23724 }
23725 goto set_cursor;
23726 }
23727
23728 pos = glyph->charpos;
23729 object = glyph->object;
23730 if (!STRINGP (object) && !BUFFERP (object))
23731 goto set_cursor;
23732
23733 /* If we get an out-of-range value, return now; avoid an error. */
23734 if (BUFFERP (object) && pos > BUF_Z (b))
23735 goto set_cursor;
23736
23737 /* Make the window's buffer temporarily current for
23738 overlays_at and compute_char_face. */
23739 obuf = current_buffer;
23740 current_buffer = b;
23741 obegv = BEGV;
23742 ozv = ZV;
23743 BEGV = BEG;
23744 ZV = Z;
23745
23746 /* Is this char mouse-active or does it have help-echo? */
23747 position = make_number (pos);
23748
23749 if (BUFFERP (object))
23750 {
23751 /* Put all the overlays we want in a vector in overlay_vec. */
23752 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
23753 /* Sort overlays into increasing priority order. */
23754 noverlays = sort_overlays (overlay_vec, noverlays, w);
23755 }
23756 else
23757 noverlays = 0;
23758
23759 same_region = (EQ (window, dpyinfo->mouse_face_window)
23760 && vpos >= dpyinfo->mouse_face_beg_row
23761 && vpos <= dpyinfo->mouse_face_end_row
23762 && (vpos > dpyinfo->mouse_face_beg_row
23763 || hpos >= dpyinfo->mouse_face_beg_col)
23764 && (vpos < dpyinfo->mouse_face_end_row
23765 || hpos < dpyinfo->mouse_face_end_col
23766 || dpyinfo->mouse_face_past_end));
23767
23768 if (same_region)
23769 cursor = No_Cursor;
23770
23771 /* Check mouse-face highlighting. */
23772 if (! same_region
23773 /* If there exists an overlay with mouse-face overlapping
23774 the one we are currently highlighting, we have to
23775 check if we enter the overlapping overlay, and then
23776 highlight only that. */
23777 || (OVERLAYP (dpyinfo->mouse_face_overlay)
23778 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
23779 {
23780 /* Find the highest priority overlay with a mouse-face. */
23781 overlay = Qnil;
23782 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
23783 {
23784 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
23785 if (!NILP (mouse_face))
23786 overlay = overlay_vec[i];
23787 }
23788
23789 /* If we're highlighting the same overlay as before, there's
23790 no need to do that again. */
23791 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
23792 goto check_help_echo;
23793 dpyinfo->mouse_face_overlay = overlay;
23794
23795 /* Clear the display of the old active region, if any. */
23796 if (clear_mouse_face (dpyinfo))
23797 cursor = No_Cursor;
23798
23799 /* If no overlay applies, get a text property. */
23800 if (NILP (overlay))
23801 mouse_face = Fget_text_property (position, Qmouse_face, object);
23802
23803 /* Next, compute the bounds of the mouse highlighting and
23804 display it. */
23805 if (!NILP (mouse_face) && STRINGP (object))
23806 {
23807 /* The mouse-highlighting comes from a display string
23808 with a mouse-face. */
23809 Lisp_Object b, e;
23810 EMACS_INT ignore;
23811
23812 b = Fprevious_single_property_change
23813 (make_number (pos + 1), Qmouse_face, object, Qnil);
23814 e = Fnext_single_property_change
23815 (position, Qmouse_face, object, Qnil);
23816 if (NILP (b))
23817 b = make_number (0);
23818 if (NILP (e))
23819 e = make_number (SCHARS (object) - 1);
23820
23821 fast_find_string_pos (w, XINT (b), object,
23822 &dpyinfo->mouse_face_beg_col,
23823 &dpyinfo->mouse_face_beg_row,
23824 &dpyinfo->mouse_face_beg_x,
23825 &dpyinfo->mouse_face_beg_y, 0);
23826 fast_find_string_pos (w, XINT (e), object,
23827 &dpyinfo->mouse_face_end_col,
23828 &dpyinfo->mouse_face_end_row,
23829 &dpyinfo->mouse_face_end_x,
23830 &dpyinfo->mouse_face_end_y, 1);
23831 dpyinfo->mouse_face_past_end = 0;
23832 dpyinfo->mouse_face_window = window;
23833 dpyinfo->mouse_face_face_id
23834 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23835 glyph->face_id, 1);
23836 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23837 cursor = No_Cursor;
23838 }
23839 else
23840 {
23841 /* The mouse-highlighting, if any, comes from an overlay
23842 or text property in the buffer. */
23843 Lisp_Object buffer, display_string;
23844
23845 if (STRINGP (object))
23846 {
23847 /* If we are on a display string with no mouse-face,
23848 check if the text under it has one. */
23849 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23850 int start = MATRIX_ROW_START_CHARPOS (r);
23851 pos = string_buffer_position (w, object, start);
23852 if (pos > 0)
23853 {
23854 mouse_face = get_char_property_and_overlay
23855 (make_number (pos), Qmouse_face, w->buffer, &overlay);
23856 buffer = w->buffer;
23857 display_string = object;
23858 }
23859 }
23860 else
23861 {
23862 buffer = object;
23863 display_string = Qnil;
23864 }
23865
23866 if (!NILP (mouse_face))
23867 {
23868 Lisp_Object before, after;
23869 Lisp_Object before_string, after_string;
23870
23871 if (NILP (overlay))
23872 {
23873 /* Handle the text property case. */
23874 before = Fprevious_single_property_change
23875 (make_number (pos + 1), Qmouse_face, buffer,
23876 Fmarker_position (w->start));
23877 after = Fnext_single_property_change
23878 (make_number (pos), Qmouse_face, buffer,
23879 make_number (BUF_Z (XBUFFER (buffer))
23880 - XFASTINT (w->window_end_pos)));
23881 before_string = after_string = Qnil;
23882 }
23883 else
23884 {
23885 /* Handle the overlay case. */
23886 before = Foverlay_start (overlay);
23887 after = Foverlay_end (overlay);
23888 before_string = Foverlay_get (overlay, Qbefore_string);
23889 after_string = Foverlay_get (overlay, Qafter_string);
23890
23891 if (!STRINGP (before_string)) before_string = Qnil;
23892 if (!STRINGP (after_string)) after_string = Qnil;
23893 }
23894
23895 mouse_face_from_buffer_pos (window, dpyinfo, pos,
23896 XFASTINT (before),
23897 XFASTINT (after),
23898 before_string, after_string,
23899 display_string);
23900 cursor = No_Cursor;
23901 }
23902 }
23903 }
23904
23905 check_help_echo:
23906
23907 /* Look for a `help-echo' property. */
23908 if (NILP (help_echo_string)) {
23909 Lisp_Object help, overlay;
23910
23911 /* Check overlays first. */
23912 help = overlay = Qnil;
23913 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23914 {
23915 overlay = overlay_vec[i];
23916 help = Foverlay_get (overlay, Qhelp_echo);
23917 }
23918
23919 if (!NILP (help))
23920 {
23921 help_echo_string = help;
23922 help_echo_window = window;
23923 help_echo_object = overlay;
23924 help_echo_pos = pos;
23925 }
23926 else
23927 {
23928 Lisp_Object object = glyph->object;
23929 int charpos = glyph->charpos;
23930
23931 /* Try text properties. */
23932 if (STRINGP (object)
23933 && charpos >= 0
23934 && charpos < SCHARS (object))
23935 {
23936 help = Fget_text_property (make_number (charpos),
23937 Qhelp_echo, object);
23938 if (NILP (help))
23939 {
23940 /* If the string itself doesn't specify a help-echo,
23941 see if the buffer text ``under'' it does. */
23942 struct glyph_row *r
23943 = MATRIX_ROW (w->current_matrix, vpos);
23944 int start = MATRIX_ROW_START_CHARPOS (r);
23945 int pos = string_buffer_position (w, object, start);
23946 if (pos > 0)
23947 {
23948 help = Fget_char_property (make_number (pos),
23949 Qhelp_echo, w->buffer);
23950 if (!NILP (help))
23951 {
23952 charpos = pos;
23953 object = w->buffer;
23954 }
23955 }
23956 }
23957 }
23958 else if (BUFFERP (object)
23959 && charpos >= BEGV
23960 && charpos < ZV)
23961 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23962 object);
23963
23964 if (!NILP (help))
23965 {
23966 help_echo_string = help;
23967 help_echo_window = window;
23968 help_echo_object = object;
23969 help_echo_pos = charpos;
23970 }
23971 }
23972 }
23973
23974 /* Look for a `pointer' property. */
23975 if (NILP (pointer))
23976 {
23977 /* Check overlays first. */
23978 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23979 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23980
23981 if (NILP (pointer))
23982 {
23983 Lisp_Object object = glyph->object;
23984 int charpos = glyph->charpos;
23985
23986 /* Try text properties. */
23987 if (STRINGP (object)
23988 && charpos >= 0
23989 && charpos < SCHARS (object))
23990 {
23991 pointer = Fget_text_property (make_number (charpos),
23992 Qpointer, object);
23993 if (NILP (pointer))
23994 {
23995 /* If the string itself doesn't specify a pointer,
23996 see if the buffer text ``under'' it does. */
23997 struct glyph_row *r
23998 = MATRIX_ROW (w->current_matrix, vpos);
23999 int start = MATRIX_ROW_START_CHARPOS (r);
24000 int pos = string_buffer_position (w, object, start);
24001 if (pos > 0)
24002 pointer = Fget_char_property (make_number (pos),
24003 Qpointer, w->buffer);
24004 }
24005 }
24006 else if (BUFFERP (object)
24007 && charpos >= BEGV
24008 && charpos < ZV)
24009 pointer = Fget_text_property (make_number (charpos),
24010 Qpointer, object);
24011 }
24012 }
24013
24014 BEGV = obegv;
24015 ZV = ozv;
24016 current_buffer = obuf;
24017 }
24018
24019 set_cursor:
24020
24021 define_frame_cursor1 (f, cursor, pointer);
24022 }
24023
24024
24025 /* EXPORT for RIF:
24026 Clear any mouse-face on window W. This function is part of the
24027 redisplay interface, and is called from try_window_id and similar
24028 functions to ensure the mouse-highlight is off. */
24029
24030 void
24031 x_clear_window_mouse_face (w)
24032 struct window *w;
24033 {
24034 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
24035 Lisp_Object window;
24036
24037 BLOCK_INPUT;
24038 XSETWINDOW (window, w);
24039 if (EQ (window, dpyinfo->mouse_face_window))
24040 clear_mouse_face (dpyinfo);
24041 UNBLOCK_INPUT;
24042 }
24043
24044
24045 /* EXPORT:
24046 Just discard the mouse face information for frame F, if any.
24047 This is used when the size of F is changed. */
24048
24049 void
24050 cancel_mouse_face (f)
24051 struct frame *f;
24052 {
24053 Lisp_Object window;
24054 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24055
24056 window = dpyinfo->mouse_face_window;
24057 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
24058 {
24059 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
24060 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
24061 dpyinfo->mouse_face_window = Qnil;
24062 }
24063 }
24064
24065
24066 #endif /* HAVE_WINDOW_SYSTEM */
24067
24068 \f
24069 /***********************************************************************
24070 Exposure Events
24071 ***********************************************************************/
24072
24073 #ifdef HAVE_WINDOW_SYSTEM
24074
24075 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
24076 which intersects rectangle R. R is in window-relative coordinates. */
24077
24078 static void
24079 expose_area (w, row, r, area)
24080 struct window *w;
24081 struct glyph_row *row;
24082 XRectangle *r;
24083 enum glyph_row_area area;
24084 {
24085 struct glyph *first = row->glyphs[area];
24086 struct glyph *end = row->glyphs[area] + row->used[area];
24087 struct glyph *last;
24088 int first_x, start_x, x;
24089
24090 if (area == TEXT_AREA && row->fill_line_p)
24091 /* If row extends face to end of line write the whole line. */
24092 draw_glyphs (w, 0, row, area,
24093 0, row->used[area],
24094 DRAW_NORMAL_TEXT, 0);
24095 else
24096 {
24097 /* Set START_X to the window-relative start position for drawing glyphs of
24098 AREA. The first glyph of the text area can be partially visible.
24099 The first glyphs of other areas cannot. */
24100 start_x = window_box_left_offset (w, area);
24101 x = start_x;
24102 if (area == TEXT_AREA)
24103 x += row->x;
24104
24105 /* Find the first glyph that must be redrawn. */
24106 while (first < end
24107 && x + first->pixel_width < r->x)
24108 {
24109 x += first->pixel_width;
24110 ++first;
24111 }
24112
24113 /* Find the last one. */
24114 last = first;
24115 first_x = x;
24116 while (last < end
24117 && x < r->x + r->width)
24118 {
24119 x += last->pixel_width;
24120 ++last;
24121 }
24122
24123 /* Repaint. */
24124 if (last > first)
24125 draw_glyphs (w, first_x - start_x, row, area,
24126 first - row->glyphs[area], last - row->glyphs[area],
24127 DRAW_NORMAL_TEXT, 0);
24128 }
24129 }
24130
24131
24132 /* Redraw the parts of the glyph row ROW on window W intersecting
24133 rectangle R. R is in window-relative coordinates. Value is
24134 non-zero if mouse-face was overwritten. */
24135
24136 static int
24137 expose_line (w, row, r)
24138 struct window *w;
24139 struct glyph_row *row;
24140 XRectangle *r;
24141 {
24142 xassert (row->enabled_p);
24143
24144 if (row->mode_line_p || w->pseudo_window_p)
24145 draw_glyphs (w, 0, row, TEXT_AREA,
24146 0, row->used[TEXT_AREA],
24147 DRAW_NORMAL_TEXT, 0);
24148 else
24149 {
24150 if (row->used[LEFT_MARGIN_AREA])
24151 expose_area (w, row, r, LEFT_MARGIN_AREA);
24152 if (row->used[TEXT_AREA])
24153 expose_area (w, row, r, TEXT_AREA);
24154 if (row->used[RIGHT_MARGIN_AREA])
24155 expose_area (w, row, r, RIGHT_MARGIN_AREA);
24156 draw_row_fringe_bitmaps (w, row);
24157 }
24158
24159 return row->mouse_face_p;
24160 }
24161
24162
24163 /* Redraw those parts of glyphs rows during expose event handling that
24164 overlap other rows. Redrawing of an exposed line writes over parts
24165 of lines overlapping that exposed line; this function fixes that.
24166
24167 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
24168 row in W's current matrix that is exposed and overlaps other rows.
24169 LAST_OVERLAPPING_ROW is the last such row. */
24170
24171 static void
24172 expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
24173 struct window *w;
24174 struct glyph_row *first_overlapping_row;
24175 struct glyph_row *last_overlapping_row;
24176 XRectangle *r;
24177 {
24178 struct glyph_row *row;
24179
24180 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
24181 if (row->overlapping_p)
24182 {
24183 xassert (row->enabled_p && !row->mode_line_p);
24184
24185 row->clip = r;
24186 if (row->used[LEFT_MARGIN_AREA])
24187 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
24188
24189 if (row->used[TEXT_AREA])
24190 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
24191
24192 if (row->used[RIGHT_MARGIN_AREA])
24193 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
24194 row->clip = NULL;
24195 }
24196 }
24197
24198
24199 /* Return non-zero if W's cursor intersects rectangle R. */
24200
24201 static int
24202 phys_cursor_in_rect_p (w, r)
24203 struct window *w;
24204 XRectangle *r;
24205 {
24206 XRectangle cr, result;
24207 struct glyph *cursor_glyph;
24208 struct glyph_row *row;
24209
24210 if (w->phys_cursor.vpos >= 0
24211 && w->phys_cursor.vpos < w->current_matrix->nrows
24212 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
24213 row->enabled_p)
24214 && row->cursor_in_fringe_p)
24215 {
24216 /* Cursor is in the fringe. */
24217 cr.x = window_box_right_offset (w,
24218 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
24219 ? RIGHT_MARGIN_AREA
24220 : TEXT_AREA));
24221 cr.y = row->y;
24222 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
24223 cr.height = row->height;
24224 return x_intersect_rectangles (&cr, r, &result);
24225 }
24226
24227 cursor_glyph = get_phys_cursor_glyph (w);
24228 if (cursor_glyph)
24229 {
24230 /* r is relative to W's box, but w->phys_cursor.x is relative
24231 to left edge of W's TEXT area. Adjust it. */
24232 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
24233 cr.y = w->phys_cursor.y;
24234 cr.width = cursor_glyph->pixel_width;
24235 cr.height = w->phys_cursor_height;
24236 /* ++KFS: W32 version used W32-specific IntersectRect here, but
24237 I assume the effect is the same -- and this is portable. */
24238 return x_intersect_rectangles (&cr, r, &result);
24239 }
24240 /* If we don't understand the format, pretend we're not in the hot-spot. */
24241 return 0;
24242 }
24243
24244
24245 /* EXPORT:
24246 Draw a vertical window border to the right of window W if W doesn't
24247 have vertical scroll bars. */
24248
24249 void
24250 x_draw_vertical_border (w)
24251 struct window *w;
24252 {
24253 struct frame *f = XFRAME (WINDOW_FRAME (w));
24254
24255 /* We could do better, if we knew what type of scroll-bar the adjacent
24256 windows (on either side) have... But we don't :-(
24257 However, I think this works ok. ++KFS 2003-04-25 */
24258
24259 /* Redraw borders between horizontally adjacent windows. Don't
24260 do it for frames with vertical scroll bars because either the
24261 right scroll bar of a window, or the left scroll bar of its
24262 neighbor will suffice as a border. */
24263 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
24264 return;
24265
24266 if (!WINDOW_RIGHTMOST_P (w)
24267 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
24268 {
24269 int x0, x1, y0, y1;
24270
24271 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
24272 y1 -= 1;
24273
24274 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
24275 x1 -= 1;
24276
24277 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
24278 }
24279 else if (!WINDOW_LEFTMOST_P (w)
24280 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
24281 {
24282 int x0, x1, y0, y1;
24283
24284 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
24285 y1 -= 1;
24286
24287 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
24288 x0 -= 1;
24289
24290 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
24291 }
24292 }
24293
24294
24295 /* Redraw the part of window W intersection rectangle FR. Pixel
24296 coordinates in FR are frame-relative. Call this function with
24297 input blocked. Value is non-zero if the exposure overwrites
24298 mouse-face. */
24299
24300 static int
24301 expose_window (w, fr)
24302 struct window *w;
24303 XRectangle *fr;
24304 {
24305 struct frame *f = XFRAME (w->frame);
24306 XRectangle wr, r;
24307 int mouse_face_overwritten_p = 0;
24308
24309 /* If window is not yet fully initialized, do nothing. This can
24310 happen when toolkit scroll bars are used and a window is split.
24311 Reconfiguring the scroll bar will generate an expose for a newly
24312 created window. */
24313 if (w->current_matrix == NULL)
24314 return 0;
24315
24316 /* When we're currently updating the window, display and current
24317 matrix usually don't agree. Arrange for a thorough display
24318 later. */
24319 if (w == updated_window)
24320 {
24321 SET_FRAME_GARBAGED (f);
24322 return 0;
24323 }
24324
24325 /* Frame-relative pixel rectangle of W. */
24326 wr.x = WINDOW_LEFT_EDGE_X (w);
24327 wr.y = WINDOW_TOP_EDGE_Y (w);
24328 wr.width = WINDOW_TOTAL_WIDTH (w);
24329 wr.height = WINDOW_TOTAL_HEIGHT (w);
24330
24331 if (x_intersect_rectangles (fr, &wr, &r))
24332 {
24333 int yb = window_text_bottom_y (w);
24334 struct glyph_row *row;
24335 int cursor_cleared_p;
24336 struct glyph_row *first_overlapping_row, *last_overlapping_row;
24337
24338 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
24339 r.x, r.y, r.width, r.height));
24340
24341 /* Convert to window coordinates. */
24342 r.x -= WINDOW_LEFT_EDGE_X (w);
24343 r.y -= WINDOW_TOP_EDGE_Y (w);
24344
24345 /* Turn off the cursor. */
24346 if (!w->pseudo_window_p
24347 && phys_cursor_in_rect_p (w, &r))
24348 {
24349 x_clear_cursor (w);
24350 cursor_cleared_p = 1;
24351 }
24352 else
24353 cursor_cleared_p = 0;
24354
24355 /* Update lines intersecting rectangle R. */
24356 first_overlapping_row = last_overlapping_row = NULL;
24357 for (row = w->current_matrix->rows;
24358 row->enabled_p;
24359 ++row)
24360 {
24361 int y0 = row->y;
24362 int y1 = MATRIX_ROW_BOTTOM_Y (row);
24363
24364 if ((y0 >= r.y && y0 < r.y + r.height)
24365 || (y1 > r.y && y1 < r.y + r.height)
24366 || (r.y >= y0 && r.y < y1)
24367 || (r.y + r.height > y0 && r.y + r.height < y1))
24368 {
24369 /* A header line may be overlapping, but there is no need
24370 to fix overlapping areas for them. KFS 2005-02-12 */
24371 if (row->overlapping_p && !row->mode_line_p)
24372 {
24373 if (first_overlapping_row == NULL)
24374 first_overlapping_row = row;
24375 last_overlapping_row = row;
24376 }
24377
24378 row->clip = fr;
24379 if (expose_line (w, row, &r))
24380 mouse_face_overwritten_p = 1;
24381 row->clip = NULL;
24382 }
24383 else if (row->overlapping_p)
24384 {
24385 /* We must redraw a row overlapping the exposed area. */
24386 if (y0 < r.y
24387 ? y0 + row->phys_height > r.y
24388 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
24389 {
24390 if (first_overlapping_row == NULL)
24391 first_overlapping_row = row;
24392 last_overlapping_row = row;
24393 }
24394 }
24395
24396 if (y1 >= yb)
24397 break;
24398 }
24399
24400 /* Display the mode line if there is one. */
24401 if (WINDOW_WANTS_MODELINE_P (w)
24402 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
24403 row->enabled_p)
24404 && row->y < r.y + r.height)
24405 {
24406 if (expose_line (w, row, &r))
24407 mouse_face_overwritten_p = 1;
24408 }
24409
24410 if (!w->pseudo_window_p)
24411 {
24412 /* Fix the display of overlapping rows. */
24413 if (first_overlapping_row)
24414 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
24415 fr);
24416
24417 /* Draw border between windows. */
24418 x_draw_vertical_border (w);
24419
24420 /* Turn the cursor on again. */
24421 if (cursor_cleared_p)
24422 update_window_cursor (w, 1);
24423 }
24424 }
24425
24426 return mouse_face_overwritten_p;
24427 }
24428
24429
24430
24431 /* Redraw (parts) of all windows in the window tree rooted at W that
24432 intersect R. R contains frame pixel coordinates. Value is
24433 non-zero if the exposure overwrites mouse-face. */
24434
24435 static int
24436 expose_window_tree (w, r)
24437 struct window *w;
24438 XRectangle *r;
24439 {
24440 struct frame *f = XFRAME (w->frame);
24441 int mouse_face_overwritten_p = 0;
24442
24443 while (w && !FRAME_GARBAGED_P (f))
24444 {
24445 if (!NILP (w->hchild))
24446 mouse_face_overwritten_p
24447 |= expose_window_tree (XWINDOW (w->hchild), r);
24448 else if (!NILP (w->vchild))
24449 mouse_face_overwritten_p
24450 |= expose_window_tree (XWINDOW (w->vchild), r);
24451 else
24452 mouse_face_overwritten_p |= expose_window (w, r);
24453
24454 w = NILP (w->next) ? NULL : XWINDOW (w->next);
24455 }
24456
24457 return mouse_face_overwritten_p;
24458 }
24459
24460
24461 /* EXPORT:
24462 Redisplay an exposed area of frame F. X and Y are the upper-left
24463 corner of the exposed rectangle. W and H are width and height of
24464 the exposed area. All are pixel values. W or H zero means redraw
24465 the entire frame. */
24466
24467 void
24468 expose_frame (f, x, y, w, h)
24469 struct frame *f;
24470 int x, y, w, h;
24471 {
24472 XRectangle r;
24473 int mouse_face_overwritten_p = 0;
24474
24475 TRACE ((stderr, "expose_frame "));
24476
24477 /* No need to redraw if frame will be redrawn soon. */
24478 if (FRAME_GARBAGED_P (f))
24479 {
24480 TRACE ((stderr, " garbaged\n"));
24481 return;
24482 }
24483
24484 /* If basic faces haven't been realized yet, there is no point in
24485 trying to redraw anything. This can happen when we get an expose
24486 event while Emacs is starting, e.g. by moving another window. */
24487 if (FRAME_FACE_CACHE (f) == NULL
24488 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
24489 {
24490 TRACE ((stderr, " no faces\n"));
24491 return;
24492 }
24493
24494 if (w == 0 || h == 0)
24495 {
24496 r.x = r.y = 0;
24497 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
24498 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
24499 }
24500 else
24501 {
24502 r.x = x;
24503 r.y = y;
24504 r.width = w;
24505 r.height = h;
24506 }
24507
24508 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
24509 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
24510
24511 if (WINDOWP (f->tool_bar_window))
24512 mouse_face_overwritten_p
24513 |= expose_window (XWINDOW (f->tool_bar_window), &r);
24514
24515 #ifdef HAVE_X_WINDOWS
24516 #ifndef MSDOS
24517 #ifndef USE_X_TOOLKIT
24518 if (WINDOWP (f->menu_bar_window))
24519 mouse_face_overwritten_p
24520 |= expose_window (XWINDOW (f->menu_bar_window), &r);
24521 #endif /* not USE_X_TOOLKIT */
24522 #endif
24523 #endif
24524
24525 /* Some window managers support a focus-follows-mouse style with
24526 delayed raising of frames. Imagine a partially obscured frame,
24527 and moving the mouse into partially obscured mouse-face on that
24528 frame. The visible part of the mouse-face will be highlighted,
24529 then the WM raises the obscured frame. With at least one WM, KDE
24530 2.1, Emacs is not getting any event for the raising of the frame
24531 (even tried with SubstructureRedirectMask), only Expose events.
24532 These expose events will draw text normally, i.e. not
24533 highlighted. Which means we must redo the highlight here.
24534 Subsume it under ``we love X''. --gerd 2001-08-15 */
24535 /* Included in Windows version because Windows most likely does not
24536 do the right thing if any third party tool offers
24537 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
24538 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
24539 {
24540 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24541 if (f == dpyinfo->mouse_face_mouse_frame)
24542 {
24543 int x = dpyinfo->mouse_face_mouse_x;
24544 int y = dpyinfo->mouse_face_mouse_y;
24545 clear_mouse_face (dpyinfo);
24546 note_mouse_highlight (f, x, y);
24547 }
24548 }
24549 }
24550
24551
24552 /* EXPORT:
24553 Determine the intersection of two rectangles R1 and R2. Return
24554 the intersection in *RESULT. Value is non-zero if RESULT is not
24555 empty. */
24556
24557 int
24558 x_intersect_rectangles (r1, r2, result)
24559 XRectangle *r1, *r2, *result;
24560 {
24561 XRectangle *left, *right;
24562 XRectangle *upper, *lower;
24563 int intersection_p = 0;
24564
24565 /* Rearrange so that R1 is the left-most rectangle. */
24566 if (r1->x < r2->x)
24567 left = r1, right = r2;
24568 else
24569 left = r2, right = r1;
24570
24571 /* X0 of the intersection is right.x0, if this is inside R1,
24572 otherwise there is no intersection. */
24573 if (right->x <= left->x + left->width)
24574 {
24575 result->x = right->x;
24576
24577 /* The right end of the intersection is the minimum of the
24578 the right ends of left and right. */
24579 result->width = (min (left->x + left->width, right->x + right->width)
24580 - result->x);
24581
24582 /* Same game for Y. */
24583 if (r1->y < r2->y)
24584 upper = r1, lower = r2;
24585 else
24586 upper = r2, lower = r1;
24587
24588 /* The upper end of the intersection is lower.y0, if this is inside
24589 of upper. Otherwise, there is no intersection. */
24590 if (lower->y <= upper->y + upper->height)
24591 {
24592 result->y = lower->y;
24593
24594 /* The lower end of the intersection is the minimum of the lower
24595 ends of upper and lower. */
24596 result->height = (min (lower->y + lower->height,
24597 upper->y + upper->height)
24598 - result->y);
24599 intersection_p = 1;
24600 }
24601 }
24602
24603 return intersection_p;
24604 }
24605
24606 #endif /* HAVE_WINDOW_SYSTEM */
24607
24608 \f
24609 /***********************************************************************
24610 Initialization
24611 ***********************************************************************/
24612
24613 void
24614 syms_of_xdisp ()
24615 {
24616 Vwith_echo_area_save_vector = Qnil;
24617 staticpro (&Vwith_echo_area_save_vector);
24618
24619 Vmessage_stack = Qnil;
24620 staticpro (&Vmessage_stack);
24621
24622 Qinhibit_redisplay = intern ("inhibit-redisplay");
24623 staticpro (&Qinhibit_redisplay);
24624
24625 message_dolog_marker1 = Fmake_marker ();
24626 staticpro (&message_dolog_marker1);
24627 message_dolog_marker2 = Fmake_marker ();
24628 staticpro (&message_dolog_marker2);
24629 message_dolog_marker3 = Fmake_marker ();
24630 staticpro (&message_dolog_marker3);
24631
24632 #if GLYPH_DEBUG
24633 defsubr (&Sdump_frame_glyph_matrix);
24634 defsubr (&Sdump_glyph_matrix);
24635 defsubr (&Sdump_glyph_row);
24636 defsubr (&Sdump_tool_bar_row);
24637 defsubr (&Strace_redisplay);
24638 defsubr (&Strace_to_stderr);
24639 #endif
24640 #ifdef HAVE_WINDOW_SYSTEM
24641 defsubr (&Stool_bar_lines_needed);
24642 defsubr (&Slookup_image_map);
24643 #endif
24644 defsubr (&Sformat_mode_line);
24645 defsubr (&Sinvisible_p);
24646
24647 staticpro (&Qmenu_bar_update_hook);
24648 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
24649
24650 staticpro (&Qoverriding_terminal_local_map);
24651 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
24652
24653 staticpro (&Qoverriding_local_map);
24654 Qoverriding_local_map = intern ("overriding-local-map");
24655
24656 staticpro (&Qwindow_scroll_functions);
24657 Qwindow_scroll_functions = intern ("window-scroll-functions");
24658
24659 staticpro (&Qwindow_text_change_functions);
24660 Qwindow_text_change_functions = intern ("window-text-change-functions");
24661
24662 staticpro (&Qredisplay_end_trigger_functions);
24663 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
24664
24665 staticpro (&Qinhibit_point_motion_hooks);
24666 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24667
24668 Qeval = intern ("eval");
24669 staticpro (&Qeval);
24670
24671 QCdata = intern (":data");
24672 staticpro (&QCdata);
24673 Qdisplay = intern ("display");
24674 staticpro (&Qdisplay);
24675 Qspace_width = intern ("space-width");
24676 staticpro (&Qspace_width);
24677 Qraise = intern ("raise");
24678 staticpro (&Qraise);
24679 Qslice = intern ("slice");
24680 staticpro (&Qslice);
24681 Qspace = intern ("space");
24682 staticpro (&Qspace);
24683 Qmargin = intern ("margin");
24684 staticpro (&Qmargin);
24685 Qpointer = intern ("pointer");
24686 staticpro (&Qpointer);
24687 Qleft_margin = intern ("left-margin");
24688 staticpro (&Qleft_margin);
24689 Qright_margin = intern ("right-margin");
24690 staticpro (&Qright_margin);
24691 Qcenter = intern ("center");
24692 staticpro (&Qcenter);
24693 Qline_height = intern ("line-height");
24694 staticpro (&Qline_height);
24695 QCalign_to = intern (":align-to");
24696 staticpro (&QCalign_to);
24697 QCrelative_width = intern (":relative-width");
24698 staticpro (&QCrelative_width);
24699 QCrelative_height = intern (":relative-height");
24700 staticpro (&QCrelative_height);
24701 QCeval = intern (":eval");
24702 staticpro (&QCeval);
24703 QCpropertize = intern (":propertize");
24704 staticpro (&QCpropertize);
24705 QCfile = intern (":file");
24706 staticpro (&QCfile);
24707 Qfontified = intern ("fontified");
24708 staticpro (&Qfontified);
24709 Qfontification_functions = intern ("fontification-functions");
24710 staticpro (&Qfontification_functions);
24711 Qtrailing_whitespace = intern ("trailing-whitespace");
24712 staticpro (&Qtrailing_whitespace);
24713 Qescape_glyph = intern ("escape-glyph");
24714 staticpro (&Qescape_glyph);
24715 Qnobreak_space = intern ("nobreak-space");
24716 staticpro (&Qnobreak_space);
24717 Qimage = intern ("image");
24718 staticpro (&Qimage);
24719 QCmap = intern (":map");
24720 staticpro (&QCmap);
24721 QCpointer = intern (":pointer");
24722 staticpro (&QCpointer);
24723 Qrect = intern ("rect");
24724 staticpro (&Qrect);
24725 Qcircle = intern ("circle");
24726 staticpro (&Qcircle);
24727 Qpoly = intern ("poly");
24728 staticpro (&Qpoly);
24729 Qmessage_truncate_lines = intern ("message-truncate-lines");
24730 staticpro (&Qmessage_truncate_lines);
24731 Qgrow_only = intern ("grow-only");
24732 staticpro (&Qgrow_only);
24733 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
24734 staticpro (&Qinhibit_menubar_update);
24735 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
24736 staticpro (&Qinhibit_eval_during_redisplay);
24737 Qposition = intern ("position");
24738 staticpro (&Qposition);
24739 Qbuffer_position = intern ("buffer-position");
24740 staticpro (&Qbuffer_position);
24741 Qobject = intern ("object");
24742 staticpro (&Qobject);
24743 Qbar = intern ("bar");
24744 staticpro (&Qbar);
24745 Qhbar = intern ("hbar");
24746 staticpro (&Qhbar);
24747 Qbox = intern ("box");
24748 staticpro (&Qbox);
24749 Qhollow = intern ("hollow");
24750 staticpro (&Qhollow);
24751 Qhand = intern ("hand");
24752 staticpro (&Qhand);
24753 Qarrow = intern ("arrow");
24754 staticpro (&Qarrow);
24755 Qtext = intern ("text");
24756 staticpro (&Qtext);
24757 Qrisky_local_variable = intern ("risky-local-variable");
24758 staticpro (&Qrisky_local_variable);
24759 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
24760 staticpro (&Qinhibit_free_realized_faces);
24761
24762 list_of_error = Fcons (Fcons (intern ("error"),
24763 Fcons (intern ("void-variable"), Qnil)),
24764 Qnil);
24765 staticpro (&list_of_error);
24766
24767 Qlast_arrow_position = intern ("last-arrow-position");
24768 staticpro (&Qlast_arrow_position);
24769 Qlast_arrow_string = intern ("last-arrow-string");
24770 staticpro (&Qlast_arrow_string);
24771
24772 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24773 staticpro (&Qoverlay_arrow_string);
24774 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24775 staticpro (&Qoverlay_arrow_bitmap);
24776
24777 echo_buffer[0] = echo_buffer[1] = Qnil;
24778 staticpro (&echo_buffer[0]);
24779 staticpro (&echo_buffer[1]);
24780
24781 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24782 staticpro (&echo_area_buffer[0]);
24783 staticpro (&echo_area_buffer[1]);
24784
24785 Vmessages_buffer_name = build_string ("*Messages*");
24786 staticpro (&Vmessages_buffer_name);
24787
24788 mode_line_proptrans_alist = Qnil;
24789 staticpro (&mode_line_proptrans_alist);
24790 mode_line_string_list = Qnil;
24791 staticpro (&mode_line_string_list);
24792 mode_line_string_face = Qnil;
24793 staticpro (&mode_line_string_face);
24794 mode_line_string_face_prop = Qnil;
24795 staticpro (&mode_line_string_face_prop);
24796 Vmode_line_unwind_vector = Qnil;
24797 staticpro (&Vmode_line_unwind_vector);
24798
24799 help_echo_string = Qnil;
24800 staticpro (&help_echo_string);
24801 help_echo_object = Qnil;
24802 staticpro (&help_echo_object);
24803 help_echo_window = Qnil;
24804 staticpro (&help_echo_window);
24805 previous_help_echo_string = Qnil;
24806 staticpro (&previous_help_echo_string);
24807 help_echo_pos = -1;
24808
24809 #ifdef HAVE_WINDOW_SYSTEM
24810 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24811 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24812 For example, if a block cursor is over a tab, it will be drawn as
24813 wide as that tab on the display. */);
24814 x_stretch_cursor_p = 0;
24815 #endif
24816
24817 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24818 doc: /* *Non-nil means highlight trailing whitespace.
24819 The face used for trailing whitespace is `trailing-whitespace'. */);
24820 Vshow_trailing_whitespace = Qnil;
24821
24822 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24823 doc: /* *Control highlighting of nobreak space and soft hyphen.
24824 A value of t means highlight the character itself (for nobreak space,
24825 use face `nobreak-space').
24826 A value of nil means no highlighting.
24827 Other values mean display the escape glyph followed by an ordinary
24828 space or ordinary hyphen. */);
24829 Vnobreak_char_display = Qt;
24830
24831 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24832 doc: /* *The pointer shape to show in void text areas.
24833 A value of nil means to show the text pointer. Other options are `arrow',
24834 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24835 Vvoid_text_area_pointer = Qarrow;
24836
24837 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24838 doc: /* Non-nil means don't actually do any redisplay.
24839 This is used for internal purposes. */);
24840 Vinhibit_redisplay = Qnil;
24841
24842 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24843 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24844 Vglobal_mode_string = Qnil;
24845
24846 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24847 doc: /* Marker for where to display an arrow on top of the buffer text.
24848 This must be the beginning of a line in order to work.
24849 See also `overlay-arrow-string'. */);
24850 Voverlay_arrow_position = Qnil;
24851
24852 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24853 doc: /* String to display as an arrow in non-window frames.
24854 See also `overlay-arrow-position'. */);
24855 Voverlay_arrow_string = build_string ("=>");
24856
24857 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24858 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24859 The symbols on this list are examined during redisplay to determine
24860 where to display overlay arrows. */);
24861 Voverlay_arrow_variable_list
24862 = Fcons (intern ("overlay-arrow-position"), Qnil);
24863
24864 DEFVAR_INT ("scroll-step", &scroll_step,
24865 doc: /* *The number of lines to try scrolling a window by when point moves out.
24866 If that fails to bring point back on frame, point is centered instead.
24867 If this is zero, point is always centered after it moves off frame.
24868 If you want scrolling to always be a line at a time, you should set
24869 `scroll-conservatively' to a large value rather than set this to 1. */);
24870
24871 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24872 doc: /* *Scroll up to this many lines, to bring point back on screen.
24873 If point moves off-screen, redisplay will scroll by up to
24874 `scroll-conservatively' lines in order to bring point just barely
24875 onto the screen again. If that cannot be done, then redisplay
24876 recenters point as usual.
24877
24878 A value of zero means always recenter point if it moves off screen. */);
24879 scroll_conservatively = 0;
24880
24881 DEFVAR_INT ("scroll-margin", &scroll_margin,
24882 doc: /* *Number of lines of margin at the top and bottom of a window.
24883 Recenter the window whenever point gets within this many lines
24884 of the top or bottom of the window. */);
24885 scroll_margin = 0;
24886
24887 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24888 doc: /* Pixels per inch value for non-window system displays.
24889 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24890 Vdisplay_pixels_per_inch = make_float (72.0);
24891
24892 #if GLYPH_DEBUG
24893 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24894 #endif
24895
24896 DEFVAR_LISP ("truncate-partial-width-windows",
24897 &Vtruncate_partial_width_windows,
24898 doc: /* Non-nil means truncate lines in windows narrower than the frame.
24899 For an integer value, truncate lines in each window narrower than the
24900 full frame width, provided the window width is less than that integer;
24901 otherwise, respect the value of `truncate-lines'.
24902
24903 For any other non-nil value, truncate lines in all windows that do
24904 not span the full frame width.
24905
24906 A value of nil means to respect the value of `truncate-lines'.
24907
24908 If `word-wrap' is enabled, you might want to reduce this. */);
24909 Vtruncate_partial_width_windows = make_number (50);
24910
24911 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24912 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24913 Any other value means to use the appropriate face, `mode-line',
24914 `header-line', or `menu' respectively. */);
24915 mode_line_inverse_video = 1;
24916
24917 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24918 doc: /* *Maximum buffer size for which line number should be displayed.
24919 If the buffer is bigger than this, the line number does not appear
24920 in the mode line. A value of nil means no limit. */);
24921 Vline_number_display_limit = Qnil;
24922
24923 DEFVAR_INT ("line-number-display-limit-width",
24924 &line_number_display_limit_width,
24925 doc: /* *Maximum line width (in characters) for line number display.
24926 If the average length of the lines near point is bigger than this, then the
24927 line number may be omitted from the mode line. */);
24928 line_number_display_limit_width = 200;
24929
24930 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24931 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24932 highlight_nonselected_windows = 0;
24933
24934 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24935 doc: /* Non-nil if more than one frame is visible on this display.
24936 Minibuffer-only frames don't count, but iconified frames do.
24937 This variable is not guaranteed to be accurate except while processing
24938 `frame-title-format' and `icon-title-format'. */);
24939
24940 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24941 doc: /* Template for displaying the title bar of visible frames.
24942 \(Assuming the window manager supports this feature.)
24943
24944 This variable has the same structure as `mode-line-format', except that
24945 the %c and %l constructs are ignored. It is used only on frames for
24946 which no explicit name has been set \(see `modify-frame-parameters'). */);
24947
24948 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24949 doc: /* Template for displaying the title bar of an iconified frame.
24950 \(Assuming the window manager supports this feature.)
24951 This variable has the same structure as `mode-line-format' (which see),
24952 and is used only on frames for which no explicit name has been set
24953 \(see `modify-frame-parameters'). */);
24954 Vicon_title_format
24955 = Vframe_title_format
24956 = Fcons (intern ("multiple-frames"),
24957 Fcons (build_string ("%b"),
24958 Fcons (Fcons (empty_unibyte_string,
24959 Fcons (intern ("invocation-name"),
24960 Fcons (build_string ("@"),
24961 Fcons (intern ("system-name"),
24962 Qnil)))),
24963 Qnil)));
24964
24965 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24966 doc: /* Maximum number of lines to keep in the message log buffer.
24967 If nil, disable message logging. If t, log messages but don't truncate
24968 the buffer when it becomes large. */);
24969 Vmessage_log_max = make_number (100);
24970
24971 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24972 doc: /* Functions called before redisplay, if window sizes have changed.
24973 The value should be a list of functions that take one argument.
24974 Just before redisplay, for each frame, if any of its windows have changed
24975 size since the last redisplay, or have been split or deleted,
24976 all the functions in the list are called, with the frame as argument. */);
24977 Vwindow_size_change_functions = Qnil;
24978
24979 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24980 doc: /* List of functions to call before redisplaying a window with scrolling.
24981 Each function is called with two arguments, the window and its new
24982 display-start position. Note that these functions are also called by
24983 `set-window-buffer'. Also note that the value of `window-end' is not
24984 valid when these functions are called. */);
24985 Vwindow_scroll_functions = Qnil;
24986
24987 DEFVAR_LISP ("window-text-change-functions",
24988 &Vwindow_text_change_functions,
24989 doc: /* Functions to call in redisplay when text in the window might change. */);
24990 Vwindow_text_change_functions = Qnil;
24991
24992 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24993 doc: /* Functions called when redisplay of a window reaches the end trigger.
24994 Each function is called with two arguments, the window and the end trigger value.
24995 See `set-window-redisplay-end-trigger'. */);
24996 Vredisplay_end_trigger_functions = Qnil;
24997
24998 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24999 doc: /* *Non-nil means autoselect window with mouse pointer.
25000 If nil, do not autoselect windows.
25001 A positive number means delay autoselection by that many seconds: a
25002 window is autoselected only after the mouse has remained in that
25003 window for the duration of the delay.
25004 A negative number has a similar effect, but causes windows to be
25005 autoselected only after the mouse has stopped moving. \(Because of
25006 the way Emacs compares mouse events, you will occasionally wait twice
25007 that time before the window gets selected.\)
25008 Any other value means to autoselect window instantaneously when the
25009 mouse pointer enters it.
25010
25011 Autoselection selects the minibuffer only if it is active, and never
25012 unselects the minibuffer if it is active.
25013
25014 When customizing this variable make sure that the actual value of
25015 `focus-follows-mouse' matches the behavior of your window manager. */);
25016 Vmouse_autoselect_window = Qnil;
25017
25018 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
25019 doc: /* *Non-nil means automatically resize tool-bars.
25020 This dynamically changes the tool-bar's height to the minimum height
25021 that is needed to make all tool-bar items visible.
25022 If value is `grow-only', the tool-bar's height is only increased
25023 automatically; to decrease the tool-bar height, use \\[recenter]. */);
25024 Vauto_resize_tool_bars = Qt;
25025
25026 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
25027 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
25028 auto_raise_tool_bar_buttons_p = 1;
25029
25030 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
25031 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
25032 make_cursor_line_fully_visible_p = 1;
25033
25034 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
25035 doc: /* *Border below tool-bar in pixels.
25036 If an integer, use it as the height of the border.
25037 If it is one of `internal-border-width' or `border-width', use the
25038 value of the corresponding frame parameter.
25039 Otherwise, no border is added below the tool-bar. */);
25040 Vtool_bar_border = Qinternal_border_width;
25041
25042 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
25043 doc: /* *Margin around tool-bar buttons in pixels.
25044 If an integer, use that for both horizontal and vertical margins.
25045 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
25046 HORZ specifying the horizontal margin, and VERT specifying the
25047 vertical margin. */);
25048 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
25049
25050 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
25051 doc: /* *Relief thickness of tool-bar buttons. */);
25052 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
25053
25054 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
25055 doc: /* List of functions to call to fontify regions of text.
25056 Each function is called with one argument POS. Functions must
25057 fontify a region starting at POS in the current buffer, and give
25058 fontified regions the property `fontified'. */);
25059 Vfontification_functions = Qnil;
25060 Fmake_variable_buffer_local (Qfontification_functions);
25061
25062 DEFVAR_BOOL ("unibyte-display-via-language-environment",
25063 &unibyte_display_via_language_environment,
25064 doc: /* *Non-nil means display unibyte text according to language environment.
25065 Specifically, this means that raw bytes in the range 160-255 decimal
25066 are displayed by converting them to the equivalent multibyte characters
25067 according to the current language environment. As a result, they are
25068 displayed according to the current fontset.
25069
25070 Note that this variable affects only how these bytes are displayed,
25071 but does not change the fact they are interpreted as raw bytes. */);
25072 unibyte_display_via_language_environment = 0;
25073
25074 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
25075 doc: /* *Maximum height for resizing mini-windows.
25076 If a float, it specifies a fraction of the mini-window frame's height.
25077 If an integer, it specifies a number of lines. */);
25078 Vmax_mini_window_height = make_float (0.25);
25079
25080 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
25081 doc: /* *How to resize mini-windows.
25082 A value of nil means don't automatically resize mini-windows.
25083 A value of t means resize them to fit the text displayed in them.
25084 A value of `grow-only', the default, means let mini-windows grow
25085 only, until their display becomes empty, at which point the windows
25086 go back to their normal size. */);
25087 Vresize_mini_windows = Qgrow_only;
25088
25089 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
25090 doc: /* Alist specifying how to blink the cursor off.
25091 Each element has the form (ON-STATE . OFF-STATE). Whenever the
25092 `cursor-type' frame-parameter or variable equals ON-STATE,
25093 comparing using `equal', Emacs uses OFF-STATE to specify
25094 how to blink it off. ON-STATE and OFF-STATE are values for
25095 the `cursor-type' frame parameter.
25096
25097 If a frame's ON-STATE has no entry in this list,
25098 the frame's other specifications determine how to blink the cursor off. */);
25099 Vblink_cursor_alist = Qnil;
25100
25101 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
25102 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
25103 automatic_hscrolling_p = 1;
25104 Qauto_hscroll_mode = intern ("auto-hscroll-mode");
25105 staticpro (&Qauto_hscroll_mode);
25106
25107 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
25108 doc: /* *How many columns away from the window edge point is allowed to get
25109 before automatic hscrolling will horizontally scroll the window. */);
25110 hscroll_margin = 5;
25111
25112 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
25113 doc: /* *How many columns to scroll the window when point gets too close to the edge.
25114 When point is less than `hscroll-margin' columns from the window
25115 edge, automatic hscrolling will scroll the window by the amount of columns
25116 determined by this variable. If its value is a positive integer, scroll that
25117 many columns. If it's a positive floating-point number, it specifies the
25118 fraction of the window's width to scroll. If it's nil or zero, point will be
25119 centered horizontally after the scroll. Any other value, including negative
25120 numbers, are treated as if the value were zero.
25121
25122 Automatic hscrolling always moves point outside the scroll margin, so if
25123 point was more than scroll step columns inside the margin, the window will
25124 scroll more than the value given by the scroll step.
25125
25126 Note that the lower bound for automatic hscrolling specified by `scroll-left'
25127 and `scroll-right' overrides this variable's effect. */);
25128 Vhscroll_step = make_number (0);
25129
25130 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
25131 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
25132 Bind this around calls to `message' to let it take effect. */);
25133 message_truncate_lines = 0;
25134
25135 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
25136 doc: /* Normal hook run to update the menu bar definitions.
25137 Redisplay runs this hook before it redisplays the menu bar.
25138 This is used to update submenus such as Buffers,
25139 whose contents depend on various data. */);
25140 Vmenu_bar_update_hook = Qnil;
25141
25142 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
25143 doc: /* Frame for which we are updating a menu.
25144 The enable predicate for a menu binding should check this variable. */);
25145 Vmenu_updating_frame = Qnil;
25146
25147 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
25148 doc: /* Non-nil means don't update menu bars. Internal use only. */);
25149 inhibit_menubar_update = 0;
25150
25151 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
25152 doc: /* Prefix prepended to all continuation lines at display time.
25153 The value may be a string, an image, or a stretch-glyph; it is
25154 interpreted in the same way as the value of a `display' text property.
25155
25156 This variable is overridden by any `wrap-prefix' text or overlay
25157 property.
25158
25159 To add a prefix to non-continuation lines, use `line-prefix'. */);
25160 Vwrap_prefix = Qnil;
25161 staticpro (&Qwrap_prefix);
25162 Qwrap_prefix = intern ("wrap-prefix");
25163 Fmake_variable_buffer_local (Qwrap_prefix);
25164
25165 DEFVAR_LISP ("line-prefix", &Vline_prefix,
25166 doc: /* Prefix prepended to all non-continuation lines at display time.
25167 The value may be a string, an image, or a stretch-glyph; it is
25168 interpreted in the same way as the value of a `display' text property.
25169
25170 This variable is overridden by any `line-prefix' text or overlay
25171 property.
25172
25173 To add a prefix to continuation lines, use `wrap-prefix'. */);
25174 Vline_prefix = Qnil;
25175 staticpro (&Qline_prefix);
25176 Qline_prefix = intern ("line-prefix");
25177 Fmake_variable_buffer_local (Qline_prefix);
25178
25179 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
25180 doc: /* Non-nil means don't eval Lisp during redisplay. */);
25181 inhibit_eval_during_redisplay = 0;
25182
25183 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
25184 doc: /* Non-nil means don't free realized faces. Internal use only. */);
25185 inhibit_free_realized_faces = 0;
25186
25187 #if GLYPH_DEBUG
25188 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
25189 doc: /* Inhibit try_window_id display optimization. */);
25190 inhibit_try_window_id = 0;
25191
25192 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
25193 doc: /* Inhibit try_window_reusing display optimization. */);
25194 inhibit_try_window_reusing = 0;
25195
25196 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
25197 doc: /* Inhibit try_cursor_movement display optimization. */);
25198 inhibit_try_cursor_movement = 0;
25199 #endif /* GLYPH_DEBUG */
25200
25201 DEFVAR_INT ("overline-margin", &overline_margin,
25202 doc: /* *Space between overline and text, in pixels.
25203 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
25204 margin to the caracter height. */);
25205 overline_margin = 2;
25206
25207 DEFVAR_INT ("underline-minimum-offset",
25208 &underline_minimum_offset,
25209 doc: /* Minimum distance between baseline and underline.
25210 This can improve legibility of underlined text at small font sizes,
25211 particularly when using variable `x-use-underline-position-properties'
25212 with fonts that specify an UNDERLINE_POSITION relatively close to the
25213 baseline. The default value is 1. */);
25214 underline_minimum_offset = 1;
25215
25216 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
25217 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
25218 display_hourglass_p = 1;
25219
25220 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
25221 doc: /* *Seconds to wait before displaying an hourglass pointer.
25222 Value must be an integer or float. */);
25223 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
25224
25225 hourglass_atimer = NULL;
25226 hourglass_shown_p = 0;
25227 }
25228
25229
25230 /* Initialize this module when Emacs starts. */
25231
25232 void
25233 init_xdisp ()
25234 {
25235 Lisp_Object root_window;
25236 struct window *mini_w;
25237
25238 current_header_line_height = current_mode_line_height = -1;
25239
25240 CHARPOS (this_line_start_pos) = 0;
25241
25242 mini_w = XWINDOW (minibuf_window);
25243 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
25244
25245 if (!noninteractive)
25246 {
25247 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
25248 int i;
25249
25250 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
25251 set_window_height (root_window,
25252 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
25253 0);
25254 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
25255 set_window_height (minibuf_window, 1, 0);
25256
25257 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
25258 mini_w->total_cols = make_number (FRAME_COLS (f));
25259
25260 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
25261 scratch_glyph_row.glyphs[TEXT_AREA + 1]
25262 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
25263
25264 /* The default ellipsis glyphs `...'. */
25265 for (i = 0; i < 3; ++i)
25266 default_invis_vector[i] = make_number ('.');
25267 }
25268
25269 {
25270 /* Allocate the buffer for frame titles.
25271 Also used for `format-mode-line'. */
25272 int size = 100;
25273 mode_line_noprop_buf = (char *) xmalloc (size);
25274 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
25275 mode_line_noprop_ptr = mode_line_noprop_buf;
25276 mode_line_target = MODE_LINE_DISPLAY;
25277 }
25278
25279 help_echo_showing_p = 0;
25280 }
25281
25282 /* Since w32 does not support atimers, it defines its own implementation of
25283 the following three functions in w32fns.c. */
25284 #ifndef WINDOWSNT
25285
25286 /* Platform-independent portion of hourglass implementation. */
25287
25288 /* Return non-zero if houglass timer has been started or hourglass is shown. */
25289 int
25290 hourglass_started ()
25291 {
25292 return hourglass_shown_p || hourglass_atimer != NULL;
25293 }
25294
25295 /* Cancel a currently active hourglass timer, and start a new one. */
25296 void
25297 start_hourglass ()
25298 {
25299 #if defined (HAVE_WINDOW_SYSTEM)
25300 EMACS_TIME delay;
25301 int secs, usecs = 0;
25302
25303 cancel_hourglass ();
25304
25305 if (INTEGERP (Vhourglass_delay)
25306 && XINT (Vhourglass_delay) > 0)
25307 secs = XFASTINT (Vhourglass_delay);
25308 else if (FLOATP (Vhourglass_delay)
25309 && XFLOAT_DATA (Vhourglass_delay) > 0)
25310 {
25311 Lisp_Object tem;
25312 tem = Ftruncate (Vhourglass_delay, Qnil);
25313 secs = XFASTINT (tem);
25314 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
25315 }
25316 else
25317 secs = DEFAULT_HOURGLASS_DELAY;
25318
25319 EMACS_SET_SECS_USECS (delay, secs, usecs);
25320 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
25321 show_hourglass, NULL);
25322 #endif
25323 }
25324
25325
25326 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
25327 shown. */
25328 void
25329 cancel_hourglass ()
25330 {
25331 #if defined (HAVE_WINDOW_SYSTEM)
25332 if (hourglass_atimer)
25333 {
25334 cancel_atimer (hourglass_atimer);
25335 hourglass_atimer = NULL;
25336 }
25337
25338 if (hourglass_shown_p)
25339 hide_hourglass ();
25340 #endif
25341 }
25342 #endif /* ! WINDOWSNT */
25343
25344 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
25345 (do not change this comment) */