1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1997
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
25 /*#include <ctype.h>*/
31 #include "dispextern.h"
38 #include "termhooks.h"
39 #include "intervals.h"
44 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
45 extern void set_frame_menubar ();
46 extern int pending_menu_activation
;
49 extern int interrupt_input
;
50 extern int command_loop_level
;
52 extern int minibuffer_auto_raise
;
54 extern Lisp_Object Qface
;
56 extern Lisp_Object Voverriding_local_map
;
57 extern Lisp_Object Voverriding_local_map_menu_flag
;
59 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
60 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
61 Lisp_Object Qredisplay_end_trigger_functions
;
63 /* Nonzero means print newline to stdout before next minibuffer message. */
65 int noninteractive_need_newline
;
67 /* Nonzero means print newline to message log before next message. */
69 static int message_log_need_newline
;
71 #define min(a, b) ((a) < (b) ? (a) : (b))
72 #define max(a, b) ((a) > (b) ? (a) : (b))
73 #define minmax(floor, val, ceil) \
74 ((val) < (floor) ? (floor) : (val) > (ceil) ? (ceil) : (val))
76 /* The buffer position of the first character appearing
77 entirely or partially on the current frame line.
78 Or zero, which disables the optimization for the current frame line. */
79 static int this_line_bufpos
;
81 /* Number of characters past the end of this line,
82 including the terminating newline */
83 static int this_line_endpos
;
85 /* The vertical position of this frame line. */
86 static int this_line_vpos
;
88 /* Hpos value for start of display on this frame line.
89 Usually zero, but negative if first character really began
91 static int this_line_start_hpos
;
93 /* Buffer that this_line variables are describing. */
94 static struct buffer
*this_line_buffer
;
96 /* Value of echo_area_glyphs when it was last acted on.
97 If this is nonzero, there is a message on the frame
98 in the minibuffer and it should be erased as soon
99 as it is no longer requested to appear. */
100 char *previous_echo_glyphs
;
102 /* Nonzero means truncate lines in all windows less wide than the frame */
103 int truncate_partial_width_windows
;
105 /* Nonzero means we have more than one non-minibuffer-only frame.
106 Not guaranteed to be accurate except while parsing frame-title-format. */
109 Lisp_Object Vglobal_mode_string
;
111 /* Marker for where to display an arrow on top of the buffer text. */
112 Lisp_Object Voverlay_arrow_position
;
114 /* String to display for the arrow. */
115 Lisp_Object Voverlay_arrow_string
;
117 /* Like mode-line-format, but for the titlebar on a visible frame. */
118 Lisp_Object Vframe_title_format
;
120 /* Like mode-line-format, but for the titlebar on an iconified frame. */
121 Lisp_Object Vicon_title_format
;
123 /* List of functions to call when a window's size changes. These
124 functions get one arg, a frame on which one or more windows' sizes
126 static Lisp_Object Vwindow_size_change_functions
;
128 /* Values of those variables at last redisplay. */
129 static Lisp_Object last_arrow_position
, last_arrow_string
;
131 Lisp_Object Qmenu_bar_update_hook
;
133 /* Nonzero if overlay arrow has been displayed once in this window. */
134 static int overlay_arrow_seen
;
136 /* Nonzero if visible end of buffer has already been displayed once
137 in this window. (We need this variable in case there are overlay
138 strings that get displayed there.) */
139 static int zv_strings_seen
;
141 /* Nonzero means highlight the region even in nonselected windows. */
142 static int highlight_nonselected_windows
;
144 /* If cursor motion alone moves point off frame,
145 Try scrolling this many lines up or down if that will bring it back. */
146 static int scroll_step
;
148 /* Non-0 means scroll just far enough to bring point back on the screen,
150 static int scroll_conservatively
;
152 /* Recenter the window whenever point gets within this many lines
153 of the top or bottom of the window. */
156 /* Nonzero if try_window_id has made blank lines at window bottom
157 since the last redisplay that paused */
158 static int blank_end_of_window
;
160 /* Number of windows showing the buffer of the selected window
161 (or another buffer with the same base buffer).
162 keyboard.c refers to this. */
165 /* display_text_line sets these to the frame position (origin 0) of point,
166 whether the window is selected or not.
167 Set one to -1 first to determine whether point was found afterwards. */
169 static int cursor_vpos
;
170 static int cursor_hpos
;
172 static int debug_end_pos
;
174 /* Nonzero means display mode line highlighted */
175 int mode_line_inverse_video
;
177 static void redisplay_internal ();
178 static int message_log_check_duplicate ();
179 static void echo_area_display ();
180 void mark_window_display_accurate ();
181 static void redisplay_windows ();
182 static void redisplay_window ();
183 static void update_menu_bar ();
184 static void try_window ();
185 static int try_window_id ();
186 static struct position
*display_text_line ();
187 static void display_mode_line ();
188 static int display_mode_element ();
189 static char *decode_mode_spec ();
190 static int display_string ();
191 static void display_menu_bar ();
192 static int display_count_lines ();
194 /* Prompt to display in front of the minibuffer contents */
195 Lisp_Object minibuf_prompt
;
197 /* Width in columns of current minibuffer prompt. */
198 int minibuf_prompt_width
;
200 /* Message to display instead of minibuffer contents
201 This is what the functions error and message make,
202 and command echoing uses it as well.
203 It overrides the minibuf_prompt as well as the buffer. */
204 char *echo_area_glyphs
;
206 /* This is the length of the message in echo_area_glyphs. */
207 int echo_area_glyphs_length
;
209 /* This is the window where the echo area message was displayed.
210 It is always a minibuffer window, but it may not be the
211 same window currently active as a minibuffer. */
212 Lisp_Object echo_area_window
;
214 /* true iff we should redraw the mode lines on the next redisplay */
215 int update_mode_lines
;
217 /* Smallest number of characters before the gap
218 at any time since last redisplay that finished.
219 Valid for current buffer when try_window_id can be called. */
222 /* Smallest number of characters after the gap
223 at any time since last redisplay that finished.
224 Valid for current buffer when try_window_id can be called. */
227 /* MODIFF as of last redisplay that finished;
228 if it matches MODIFF, and overlay_unchanged_modified
229 matches OVERLAY_MODIFF, that means beg_unchanged and end_unchanged
230 contain no useful information */
231 int unchanged_modified
;
233 /* OVERLAY_MODIFF as of last redisplay that finished. */
234 int overlay_unchanged_modified
;
236 /* Nonzero if window sizes or contents have changed
237 since last redisplay that finished */
238 int windows_or_buffers_changed
;
240 /* Nonzero after display_mode_line if %l was used
241 and it displayed a line number. */
242 int line_number_displayed
;
244 /* Maximum buffer size for which to display line numbers. */
245 static int line_number_display_limit
;
247 /* Number of lines to keep in the message log buffer.
248 t means infinite. nil means don't log at all. */
249 Lisp_Object Vmessage_log_max
;
251 /* Output a newline in the *Messages* buffer if "needs" one. */
254 message_log_maybe_newline ()
256 if (message_log_need_newline
)
257 message_dolog ("", 0, 1);
261 /* Add a string to the message log, optionally terminated with a newline.
262 This function calls low-level routines in order to bypass text property
263 hooks, etc. which might not be safe to run. */
266 message_dolog (m
, len
, nlflag
)
270 if (!NILP (Vmessage_log_max
))
272 struct buffer
*oldbuf
;
273 int oldpoint
, oldbegv
, oldzv
;
274 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
276 oldbuf
= current_buffer
;
277 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
278 current_buffer
->undo_list
= Qt
;
285 oldpoint
+= len
+ nlflag
;
287 oldzv
+= len
+ nlflag
;
290 insert_1 (m
, len
, 1, 0);
293 int this_bol
, prev_bol
, dup
;
294 insert_1 ("\n", 1, 1, 0);
296 this_bol
= scan_buffer ('\n', Z
, 0, -2, 0, 0);
299 prev_bol
= scan_buffer ('\n', this_bol
, 0, -2, 0, 0);
300 dup
= message_log_check_duplicate (prev_bol
, this_bol
);
303 if (oldpoint
> prev_bol
)
304 oldpoint
-= min (this_bol
, oldpoint
) - prev_bol
;
305 if (oldbegv
> prev_bol
)
306 oldbegv
-= min (this_bol
, oldbegv
) - prev_bol
;
307 if (oldzv
> prev_bol
)
308 oldzv
-= min (this_bol
, oldzv
) - prev_bol
;
309 del_range_1 (prev_bol
, this_bol
, 0);
315 /* If you change this format, don't forget to also
316 change message_log_check_duplicate. */
317 sprintf (dupstr
, " [%d times]", dup
);
318 duplen
= strlen (dupstr
);
324 insert_1 (dupstr
, duplen
, 1, 0);
329 if (NATNUMP (Vmessage_log_max
))
331 int pos
= scan_buffer ('\n', Z
, 0,
332 -XFASTINT (Vmessage_log_max
) - 1, 0, 0);
333 oldpoint
-= min (pos
, oldpoint
) - BEG
;
334 oldbegv
-= min (pos
, oldbegv
) - BEG
;
335 oldzv
-= min (pos
, oldzv
) - BEG
;
336 del_range_1 (BEG
, pos
, 0);
341 TEMP_SET_PT (oldpoint
);
342 set_buffer_internal (oldbuf
);
343 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
344 message_log_need_newline
= !nlflag
;
348 /* We are at the end of the buffer after just having inserted a newline.
349 (Note: We depend on the fact we won't be crossing the gap.)
350 Check to see if the most recent message looks a lot like the previous one.
351 Return 0 if different, 1 if the new one should just replace it, or a
352 value N > 1 if we should also append " [N times]". */
355 message_log_check_duplicate (prev_bol
, this_bol
)
356 int prev_bol
, this_bol
;
359 int len
= Z
- 1 - this_bol
;
361 unsigned char *p1
= BUF_CHAR_ADDRESS (current_buffer
, prev_bol
);
362 unsigned char *p2
= BUF_CHAR_ADDRESS (current_buffer
, this_bol
);
364 for (i
= 0; i
< len
; i
++)
366 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.'
375 if (*p1
++ == ' ' && *p1
++ == '[')
378 while (*p1
>= '0' && *p1
<= '9')
379 n
= n
* 10 + *p1
++ - '0';
380 if (strncmp (p1
, " times]\n", 8) == 0)
386 /* Display an echo area message M with a specified length of LEN chars.
387 The string may include null characters. If M is 0, clear out any
388 existing message, and let the minibuffer text show through.
390 The buffer M must continue to exist until after the echo area
391 gets cleared or some other message gets displayed there.
393 Do not pass text that is stored in a Lisp string.
394 Do not pass text in a buffer that was alloca'd. */
401 /* First flush out any partial line written with print. */
402 message_log_maybe_newline ();
404 message_dolog (m
, len
, 1);
405 message2_nolog (m
, len
);
409 /* The non-logging counterpart of message2. */
412 message2_nolog (m
, len
)
418 if (noninteractive_need_newline
)
420 noninteractive_need_newline
= 0;
422 fwrite (m
, len
, 1, stderr
);
423 if (cursor_in_echo_area
== 0)
424 fprintf (stderr
, "\n");
427 /* A null message buffer means that the frame hasn't really been
428 initialized yet. Error messages get reported properly by
429 cmd_error, so this must be just an informative message; toss it. */
430 else if (INTERACTIVE
&& FRAME_MESSAGE_BUF (selected_frame
))
432 Lisp_Object mini_window
;
435 /* Get the frame containing the minibuffer
436 that the selected frame is using. */
437 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
438 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
440 FRAME_SAMPLE_VISIBILITY (f
);
441 if (FRAME_VISIBLE_P (selected_frame
)
442 && ! FRAME_VISIBLE_P (f
))
443 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
447 echo_area_glyphs
= m
;
448 echo_area_glyphs_length
= len
;
450 if (minibuffer_auto_raise
)
451 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
454 echo_area_glyphs
= previous_echo_glyphs
= 0;
456 do_pending_window_change ();
457 echo_area_display ();
458 update_frame (f
, 1, 1);
459 do_pending_window_change ();
460 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
461 (*frame_up_to_date_hook
) (f
);
465 /* Display a null-terminated echo area message M. If M is 0, clear out any
466 existing message, and let the minibuffer text show through.
468 The buffer M must continue to exist until after the echo area
469 gets cleared or some other message gets displayed there.
471 Do not pass text that is stored in a Lisp string.
472 Do not pass text in a buffer that was alloca'd. */
478 message2 (m
, (m
? strlen (m
) : 0));
485 message2_nolog (m
, (m
? strlen (m
) : 0));
488 /* Truncate what will be displayed in the echo area
489 the next time we display it--but don't redisplay it now. */
492 truncate_echo_area (len
)
495 /* A null message buffer means that the frame hasn't really been
496 initialized yet. Error messages get reported properly by
497 cmd_error, so this must be just an informative message; toss it. */
498 if (!noninteractive
&& INTERACTIVE
&& FRAME_MESSAGE_BUF (selected_frame
))
499 echo_area_glyphs_length
= len
;
502 /* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by print;
503 zero if being used by message. */
504 int message_buf_print
;
506 /* Dump an informative message to the minibuf. If M is 0, clear out
507 any existing message, and let the minibuffer text show through. */
511 message (m
, a1
, a2
, a3
)
513 EMACS_INT a1
, a2
, a3
;
519 if (noninteractive_need_newline
)
521 noninteractive_need_newline
= 0;
522 fprintf (stderr
, m
, a1
, a2
, a3
);
523 if (cursor_in_echo_area
== 0)
524 fprintf (stderr
, "\n");
528 else if (INTERACTIVE
)
530 /* The frame whose minibuffer we're going to display the message on.
531 It may be larger than the selected frame, so we need
532 to use its buffer, not the selected frame's buffer. */
533 Lisp_Object mini_window
;
536 /* Get the frame containing the minibuffer
537 that the selected frame is using. */
538 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
539 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
541 /* A null message buffer means that the frame hasn't really been
542 initialized yet. Error messages get reported properly by
543 cmd_error, so this must be just an informative message; toss it. */
544 if (FRAME_MESSAGE_BUF (f
))
555 len
= doprnt (FRAME_MESSAGE_BUF (f
),
556 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
558 len
= doprnt (FRAME_MESSAGE_BUF (f
),
559 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, &a1
);
560 #endif /* NO_ARG_ARRAY */
562 message2 (FRAME_MESSAGE_BUF (f
), len
);
567 /* Print should start at the beginning of the message
569 message_buf_print
= 0;
574 /* The non-logging version of message. */
576 message_nolog (m
, a1
, a2
, a3
)
578 EMACS_INT a1
, a2
, a3
;
580 Lisp_Object old_log_max
;
581 old_log_max
= Vmessage_log_max
;
582 Vmessage_log_max
= Qnil
;
583 message (m
, a1
, a2
, a3
);
584 Vmessage_log_max
= old_log_max
;
590 message2 (echo_area_glyphs
, echo_area_glyphs_length
);
598 Lisp_Object mini_window
;
600 /* Choose the minibuffer window for this display.
601 It is the minibuffer window used by the selected frame. */
602 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
603 /* This is the frame that window is in. */
604 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
606 if (! FRAME_VISIBLE_P (f
))
611 redraw_garbaged_frames ();
615 if (echo_area_glyphs
|| minibuf_level
== 0)
619 echo_area_window
= mini_window
;
621 vpos
= XFASTINT (XWINDOW (mini_window
)->top
);
622 get_display_line (f
, vpos
, 0);
624 /* Make sure the columns that overlap a left-hand scroll bar
626 for (i
= 0; i
< FRAME_LEFT_SCROLL_BAR_WIDTH (f
); i
++)
627 f
->desired_glyphs
->glyphs
[vpos
][i
] = SPACEGLYPH
;
629 display_string (XWINDOW (mini_window
), vpos
,
630 echo_area_glyphs
? echo_area_glyphs
: "",
631 echo_area_glyphs
? echo_area_glyphs_length
: -1,
632 FRAME_LEFT_SCROLL_BAR_WIDTH (f
),
634 FRAME_WIDTH (f
) + FRAME_LEFT_SCROLL_BAR_WIDTH (f
));
636 #if 0 /* This just gets in the way. update_frame does the job. */
637 /* If desired cursor location is on this line, put it at end of text */
638 if (cursor_in_echo_area
)
639 FRAME_CURSOR_Y (f
) = vpos
;
640 if (FRAME_CURSOR_Y (f
) == vpos
)
641 FRAME_CURSOR_X (f
) = FRAME_DESIRED_GLYPHS (f
)->used
[vpos
];
644 /* Fill the rest of the minibuffer window with blank lines. */
649 i
< vpos
+ XFASTINT (XWINDOW (mini_window
)->height
); i
++)
651 get_display_line (f
, i
, 0);
652 /* We don't use FRAME_SCROLL_BAR_WIDTH (f) as the starting
653 hpos, because it is good to clear whatever is behind the
654 scroll bar. This does not affect the scroll bar itself. */
655 display_string (XWINDOW (mini_window
), i
,
658 0, FRAME_WIDTH (f
) + FRAME_SCROLL_BAR_WIDTH (f
));
662 else if (!EQ (mini_window
, selected_window
))
663 windows_or_buffers_changed
++;
665 if (EQ (mini_window
, selected_window
))
666 this_line_bufpos
= 0;
668 previous_echo_glyphs
= echo_area_glyphs
;
671 /* Update frame titles. */
673 #ifdef HAVE_WINDOW_SYSTEM
674 static char frame_title_buf
[512];
675 static char *frame_title_ptr
;
678 store_frame_title (str
, mincol
, maxcol
)
683 if (maxcol
< 0 || maxcol
>= sizeof(frame_title_buf
))
684 maxcol
= sizeof (frame_title_buf
);
685 limit
= &frame_title_buf
[maxcol
];
686 while (*str
!= '\0' && frame_title_ptr
< limit
)
687 *frame_title_ptr
++ = *str
++;
688 while (frame_title_ptr
< &frame_title_buf
[mincol
])
689 *frame_title_ptr
++ = ' ';
690 return frame_title_ptr
- frame_title_buf
;
694 x_consider_frame_title (frame
)
700 FRAME_PTR f
= XFRAME (frame
);
702 if (!(FRAME_WINDOW_P (f
) || FRAME_MINIBUF_ONLY_P (f
) || f
->explicit_name
))
705 /* Do we have more than one visible frame on this X display? */
709 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
711 FRAME_PTR tf
= XFRAME (XCONS (tail
)->car
);
713 if (tf
!= f
&& FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
714 && !FRAME_MINIBUF_ONLY_P (tf
)
715 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
719 multiple_frames
= CONSP (tail
);
722 obuf
= current_buffer
;
723 Fset_buffer (XWINDOW (f
->selected_window
)->buffer
);
724 fmt
= (FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
);
725 frame_title_ptr
= frame_title_buf
;
726 len
= display_mode_element (XWINDOW (f
->selected_window
), 0, 0, 0,
727 0, sizeof (frame_title_buf
), fmt
);
729 set_buffer_internal (obuf
);
730 /* Set the name only if it's changed. This avoids consing
731 in the common case where it hasn't. (If it turns out that we've
732 already wasted too much time by walking through the list with
733 display_mode_element, then we might need to optimize at a higher
735 if (! STRINGP (f
->name
) || XSTRING (f
->name
)->size
!= len
736 || bcmp (frame_title_buf
, XSTRING (f
->name
)->data
, len
) != 0)
737 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
740 #define frame_title_ptr ((char *)0)
741 #define store_frame_title(str, mincol, maxcol) 0
744 /* Prepare for redisplay by updating menu-bar item lists when appropriate.
745 This can call eval. */
750 register struct window
*w
= XWINDOW (selected_window
);
752 struct gcpro gcpro1
, gcpro2
;
754 all_windows
= (update_mode_lines
|| buffer_shared
> 1
755 || windows_or_buffers_changed
);
757 /* Update all frame titles based on their buffer names, etc.
758 We do this before the menu bars so that the buffer-menu
759 will show the up-to-date frame titles.
761 This used to be done after the menu bars, for a reason that
762 was stated as follows but which I do not understand:
763 "We do this after the menu bars so that the frame will first
764 create its menu bar using the name `emacs' if no other name
765 has yet been specified."
766 I think that is no longer a concern. */
767 #ifdef HAVE_WINDOW_SYSTEM
768 if (windows_or_buffers_changed
|| update_mode_lines
)
770 Lisp_Object tail
, frame
;
772 FOR_EACH_FRAME (tail
, frame
)
773 if (FRAME_VISIBLE_P (XFRAME (frame
))
774 || FRAME_ICONIFIED_P (XFRAME (frame
)))
775 x_consider_frame_title (frame
);
779 /* Update the menu bar item lists, if appropriate.
780 This has to be done before any actual redisplay
781 or generation of display lines. */
784 Lisp_Object tail
, frame
;
785 int count
= specpdl_ptr
- specpdl
;
787 record_unwind_protect (Fstore_match_data
, Fmatch_data (Qnil
, Qnil
));
789 FOR_EACH_FRAME (tail
, frame
)
791 /* If a window on this frame changed size,
792 report that to the user and clear the size-change flag. */
793 if (FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame
)))
795 Lisp_Object functions
;
796 /* Clear flag first in case we get error below. */
797 FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame
)) = 0;
798 functions
= Vwindow_size_change_functions
;
799 GCPRO2 (tail
, functions
);
800 while (CONSP (functions
))
802 call1 (XCONS (functions
)->car
, frame
);
803 functions
= XCONS (functions
)->cdr
;
808 update_menu_bar (XFRAME (frame
), 0);
812 unbind_to (count
, Qnil
);
815 update_menu_bar (selected_frame
, 1);
817 /* Motif needs this. See comment in xmenu.c.
818 Turn it off when pending_menu_activation is not defined. */
820 pending_menu_activation
= 0;
824 /* Do a frame update, taking possible shortcuts into account.
825 This is the main external entry point for redisplay.
827 If the last redisplay displayed an echo area message and that
828 message is no longer requested, we clear the echo area
829 or bring back the minibuffer if that is in use.
831 Do not call eval from within this function.
832 Calls to eval after the call to echo_area_display would confuse
833 the display_line mechanism and would cause a crash.
834 Calls to eval before that point will work most of the time,
835 but can still lose, because this function
836 can be called from signal handlers; with alarms set up;
837 or with synchronous processes running.
839 See Fcall_process; if you called it from here, it could be
840 entered recursively. */
842 static int do_verify_charstarts
;
844 /* Counter is used to clear the face cache
845 no more than once ever 1000 redisplays. */
846 static int clear_face_cache_count
;
848 /* Record the previous terminal frame we displayed. */
849 static FRAME_PTR previous_terminal_frame
;
854 redisplay_internal (0);
857 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay
858 is not in response to any user action; therefore, we should
859 preserve the echo area. (Actually, our caller does that job.)
860 Perhaps in the future avoid recentering windows
861 if it is not necessary; currently that causes some problems. */
864 redisplay_internal (preserve_echo_area
)
865 int preserve_echo_area
;
867 register struct window
*w
= XWINDOW (selected_window
);
871 register int tlbufpos
, tlendpos
;
873 int number_of_frames_redisplayed
;
879 if (popup_activated ())
885 if (! FRAME_WINDOW_P (selected_frame
)
886 && previous_terminal_frame
!= selected_frame
)
888 /* Since frames on an ASCII terminal share the same display area,
889 displaying a different frame means redisplay the whole thing. */
890 windows_or_buffers_changed
++;
891 SET_FRAME_GARBAGED (selected_frame
);
892 XSETFRAME (Vterminal_frame
, selected_frame
);
894 previous_terminal_frame
= selected_frame
;
896 /* Set the visible flags for all frames.
897 Do this before checking for resized or garbaged frames; they want
898 to know if their frames are visible.
899 See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
901 Lisp_Object tail
, frame
;
903 FOR_EACH_FRAME (tail
, frame
)
905 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
907 /* Clear out all the display lines in which we will generate the
908 glyphs to display. */
909 init_desired_glyphs (XFRAME (frame
));
913 /* Notice any pending interrupt request to change frame size. */
914 do_pending_window_change ();
918 redraw_garbaged_frames ();
922 prepare_menu_bars ();
924 if (windows_or_buffers_changed
)
927 /* Detect case that we need to write or remove a star in the mode line. */
928 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
930 w
->update_mode_line
= Qt
;
931 if (buffer_shared
> 1)
935 /* If %c is in use, update it if needed. */
936 if (!NILP (w
->column_number_displayed
)
937 /* This alternative quickly identifies a common case
938 where no change is needed. */
939 && !(PT
== XFASTINT (w
->last_point
)
940 && XFASTINT (w
->last_modified
) >= MODIFF
941 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
942 && XFASTINT (w
->column_number_displayed
) != current_column ())
943 w
->update_mode_line
= Qt
;
945 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
947 all_windows
= update_mode_lines
|| buffer_shared
> 1;
949 /* If specs for an arrow have changed, do thorough redisplay
950 to ensure we remove any arrow that should no longer exist. */
951 if (! EQ (Voverlay_arrow_position
, last_arrow_position
)
952 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
955 /* Normally the message* functions will have already displayed and
956 updated the echo area, but the frame may have been trashed, or
957 the update may have been preempted, so display the echo area
959 if (echo_area_glyphs
|| previous_echo_glyphs
)
961 echo_area_display ();
965 /* If showing region, and mark has changed, must redisplay whole window. */
966 if (((!NILP (Vtransient_mark_mode
)
967 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
968 != !NILP (w
->region_showing
))
969 || (!NILP (w
->region_showing
)
970 && !EQ (w
->region_showing
,
971 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
972 this_line_bufpos
= -1;
974 /* This is in case we goto update, below. */
975 number_of_frames_redisplayed
= 1;
977 tlbufpos
= this_line_bufpos
;
978 tlendpos
= this_line_endpos
;
979 if (!all_windows
&& tlbufpos
> 0 && NILP (w
->update_mode_line
)
980 && !current_buffer
->clip_changed
981 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
982 /* Make sure recorded data applies to current buffer, etc */
983 && this_line_buffer
== current_buffer
984 && current_buffer
== XBUFFER (w
->buffer
)
985 && NILP (w
->force_start
)
986 /* Point must be on the line that we have info recorded about */
988 && PT
<= Z
- tlendpos
989 /* All text outside that line, including its final newline,
991 && ((XFASTINT (w
->last_modified
) >= MODIFF
992 && (XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
))
993 || (beg_unchanged
>= tlbufpos
- 1
995 /* If selective display, can't optimize
996 if the changes start at the beginning of the line. */
997 && ((INTEGERP (current_buffer
->selective_display
)
998 && XINT (current_buffer
->selective_display
) > 0
999 ? (beg_unchanged
>= tlbufpos
1002 && end_unchanged
>= tlendpos
1003 && Z
- GPT
>= tlendpos
)))
1005 if (tlbufpos
> BEGV
&& FETCH_BYTE (tlbufpos
- 1) != '\n'
1007 || FETCH_BYTE (tlbufpos
) == '\n'))
1008 /* Former continuation line has disappeared by becoming empty */
1010 else if (XFASTINT (w
->last_modified
) < MODIFF
1011 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
1012 || MINI_WINDOW_P (w
))
1014 /* We have to handle the case of continuation around a
1015 wide-column character (See the comment in indent.c around
1018 For instance, in the following case:
1020 -------- Insert --------
1021 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
1022 J_I_ ==> J_I_ `^^' are cursors.
1026 As we have to redraw the line above, we should goto cancel. */
1028 struct position val
;
1031 prevline
= find_next_newline (tlbufpos
, -1);
1032 val
= *compute_motion (prevline
, 0,
1033 XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0,
1036 1 << (BITS_PER_SHORT
- 1),
1037 1 << (BITS_PER_SHORT
- 1),
1038 window_internal_width (w
) - 1,
1039 XINT (w
->hscroll
), 0, w
);
1040 if (val
.hpos
!= this_line_start_hpos
)
1044 overlay_arrow_seen
= 0;
1045 zv_strings_seen
= 0;
1046 display_text_line (w
, tlbufpos
, this_line_vpos
, this_line_start_hpos
,
1047 pos_tab_offset (w
, tlbufpos
), 0);
1048 /* If line contains point, is not continued,
1049 and ends at same distance from eob as before, we win */
1050 if (cursor_vpos
>= 0 && this_line_bufpos
1051 && this_line_endpos
== tlendpos
)
1053 /* If this is not the window's last line,
1054 we must adjust the charstarts of the lines below. */
1055 if (this_line_vpos
+ 1
1056 < XFASTINT (w
->top
) + window_internal_height (w
))
1058 int left
= WINDOW_LEFT_MARGIN (w
);
1059 int *charstart_next_line
1060 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[this_line_vpos
+ 1];
1063 if (Z
- tlendpos
== ZV
)
1064 /* This line ends at end of (accessible part of) buffer.
1065 There is no newline to count. */
1066 adjust
= Z
- tlendpos
- charstart_next_line
[left
];
1068 /* This line ends in a newline.
1069 Must take account of the newline and the rest of the
1070 text that follows. */
1071 adjust
= Z
- tlendpos
+ 1 - charstart_next_line
[left
];
1073 adjust_window_charstarts (w
, this_line_vpos
, adjust
);
1076 if (!WINDOW_FULL_WIDTH_P (w
))
1077 preserve_other_columns (w
);
1083 else if (PT
== XFASTINT (w
->last_point
)
1084 /* Make sure the cursor was last displayed
1085 in this window. Otherwise we have to reposition it. */
1086 && XINT (w
->top
) <= FRAME_CURSOR_Y (selected_frame
)
1087 && (XINT (w
->top
) + XINT (w
->height
)
1088 > FRAME_CURSOR_Y (selected_frame
)))
1092 do_pending_window_change ();
1097 /* If highlighting the region, or if the cursor is in the echo area,
1098 then we can't just move the cursor. */
1099 else if (! (!NILP (Vtransient_mark_mode
)
1100 && !NILP (current_buffer
->mark_active
))
1101 && (w
== XWINDOW (current_buffer
->last_selected_window
)
1102 || highlight_nonselected_windows
)
1103 && NILP (w
->region_showing
)
1104 && !cursor_in_echo_area
)
1106 pos
= *compute_motion (tlbufpos
, 0,
1107 XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0,
1109 PT
, 2, - (1 << (BITS_PER_SHORT
- 1)),
1110 window_internal_width (w
) - 1,
1112 pos_tab_offset (w
, tlbufpos
), w
);
1115 int width
= window_internal_width (w
) - 1;
1116 FRAME_CURSOR_X (selected_frame
)
1117 = WINDOW_LEFT_MARGIN (w
) + minmax (0, pos
.hpos
, width
);
1118 FRAME_CURSOR_Y (selected_frame
) = this_line_vpos
;
1125 /* Text changed drastically or point moved off of line */
1126 cancel_line (this_line_vpos
, selected_frame
);
1129 this_line_bufpos
= 0;
1130 all_windows
|= buffer_shared
> 1;
1132 clear_face_cache_count
++;
1136 Lisp_Object tail
, frame
;
1139 /* Clear the face cache, only when we do a full redisplay
1140 and not too often either. */
1141 if (clear_face_cache_count
> 1000)
1143 clear_face_cache ();
1144 clear_face_cache_count
= 0;
1148 /* Recompute # windows showing selected buffer.
1149 This will be incremented each time such a window is displayed. */
1151 number_of_frames_redisplayed
= 0;
1153 FOR_EACH_FRAME (tail
, frame
)
1155 FRAME_PTR f
= XFRAME (frame
);
1156 if (FRAME_WINDOW_P (f
) || f
== selected_frame
)
1159 /* Mark all the scroll bars to be removed; we'll redeem the ones
1160 we want when we redisplay their windows. */
1161 if (condemn_scroll_bars_hook
)
1162 (*condemn_scroll_bars_hook
) (f
);
1164 if (FRAME_VISIBLE_P (f
))
1166 redisplay_windows (FRAME_ROOT_WINDOW (f
), preserve_echo_area
);
1167 number_of_frames_redisplayed
++;
1170 /* Any scroll bars which redisplay_windows should have nuked
1171 should now go away. */
1172 if (judge_scroll_bars_hook
)
1173 (*judge_scroll_bars_hook
) (f
);
1177 else if (FRAME_VISIBLE_P (selected_frame
))
1179 redisplay_window (selected_window
, 1, preserve_echo_area
);
1180 if (!WINDOW_FULL_WIDTH_P (w
))
1181 preserve_other_columns (w
);
1182 number_of_frames_redisplayed
= 1;
1186 /* Prevent various kinds of signals during display update.
1187 stdio is not robust about handling signals,
1188 which can cause an apparent I/O error. */
1189 if (interrupt_input
)
1199 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1203 if (!FRAMEP (XCONS (tail
)->car
))
1206 f
= XFRAME (XCONS (tail
)->car
);
1208 if ((FRAME_WINDOW_P (f
) || f
== selected_frame
)
1209 && FRAME_VISIBLE_P (f
))
1211 pause
|= update_frame (f
, 0, 0);
1214 mark_window_display_accurate (f
->root_window
, 1);
1215 if (frame_up_to_date_hook
!= 0)
1216 (*frame_up_to_date_hook
) (f
);
1223 if (FRAME_VISIBLE_P (selected_frame
))
1224 pause
= update_frame (selected_frame
, 0, 0);
1228 /* We may have called echo_area_display at the top of this
1229 function. If the echo area is on another frame, that may
1230 have put text on a frame other than the selected one, so the
1231 above call to update_frame would not have caught it. Catch
1234 Lisp_Object mini_window
;
1235 FRAME_PTR mini_frame
;
1237 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
1238 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
1240 if (mini_frame
!= selected_frame
&& FRAME_WINDOW_P (mini_frame
))
1241 pause
|= update_frame (mini_frame
, 0, 0);
1245 /* If frame does not match, prevent doing single-line-update next time.
1246 Also, don't forget to check every line to update the arrow. */
1249 this_line_bufpos
= 0;
1250 if (!NILP (last_arrow_position
))
1252 last_arrow_position
= Qt
;
1253 last_arrow_string
= Qt
;
1255 /* If we pause after scrolling, some lines in current_frame
1256 may be null, so preserve_other_columns won't be able to
1257 preserve all the vertical-bar separators. So, avoid using it
1259 if (!WINDOW_FULL_WIDTH_P (w
))
1260 update_mode_lines
= 1;
1263 /* Now text on frame agrees with windows, so
1264 put info into the windows for partial redisplay to follow */
1268 register struct buffer
*b
= XBUFFER (w
->buffer
);
1270 blank_end_of_window
= 0;
1271 unchanged_modified
= BUF_MODIFF (b
);
1272 overlay_unchanged_modified
= BUF_OVERLAY_MODIFF (b
);
1273 beg_unchanged
= BUF_GPT (b
) - BUF_BEG (b
);
1274 end_unchanged
= BUF_Z (b
) - BUF_GPT (b
);
1276 XSETFASTINT (w
->last_point
, BUF_PT (b
));
1277 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (selected_frame
));
1278 XSETFASTINT (w
->last_point_y
, FRAME_CURSOR_Y (selected_frame
));
1281 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame
), 1);
1284 b
->clip_changed
= 0;
1285 w
->update_mode_line
= Qnil
;
1286 XSETFASTINT (w
->last_modified
, BUF_MODIFF (b
));
1287 XSETFASTINT (w
->last_overlay_modified
, BUF_OVERLAY_MODIFF (b
));
1289 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1292 /* Record if we are showing a region, so can make sure to
1293 update it fully at next redisplay. */
1294 w
->region_showing
= (!NILP (Vtransient_mark_mode
)
1295 && (w
== XWINDOW (current_buffer
->last_selected_window
)
1296 || highlight_nonselected_windows
)
1297 && !NILP (XBUFFER (w
->buffer
)->mark_active
)
1298 ? Fmarker_position (XBUFFER (w
->buffer
)->mark
)
1301 w
->window_end_valid
= w
->buffer
;
1302 last_arrow_position
= Voverlay_arrow_position
;
1303 last_arrow_string
= Voverlay_arrow_string
;
1304 if (do_verify_charstarts
)
1305 verify_charstarts (w
);
1306 if (frame_up_to_date_hook
!= 0)
1307 (*frame_up_to_date_hook
) (selected_frame
);
1309 update_mode_lines
= 0;
1310 windows_or_buffers_changed
= 0;
1313 /* Start SIGIO interrupts coming again.
1314 Having them off during the code above
1315 makes it less likely one will discard output,
1316 but not impossible, since there might be stuff
1317 in the system buffer here.
1318 But it is much hairier to try to do anything about that. */
1320 if (interrupt_input
)
1324 /* If something has become visible now which was not before,
1325 redisplay again, so that we get them. */
1328 Lisp_Object tail
, frame
;
1331 FOR_EACH_FRAME (tail
, frame
)
1333 int this_is_visible
= 0;
1334 if (XFRAME (frame
)->visible
)
1335 this_is_visible
= 1;
1336 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
1337 if (XFRAME (frame
)->visible
)
1338 this_is_visible
= 1;
1340 if (this_is_visible
)
1344 if (new_count
!= number_of_frames_redisplayed
)
1345 windows_or_buffers_changed
++;
1348 /* Change frame size now if a change is pending. */
1349 do_pending_window_change ();
1351 /* If we just did a pending size change, or have additional
1352 visible frames, redisplay again. */
1353 if (windows_or_buffers_changed
&& !pause
)
1357 /* Redisplay, but leave alone any recent echo area message
1358 unless another message has been requested in its place.
1360 This is useful in situations where you need to redisplay but no
1361 user action has occurred, making it inappropriate for the message
1362 area to be cleared. See tracking_off and
1363 wait_reading_process_input for examples of these situations. */
1365 redisplay_preserve_echo_area ()
1367 if (echo_area_glyphs
== 0 && previous_echo_glyphs
!= 0)
1369 echo_area_glyphs
= previous_echo_glyphs
;
1370 redisplay_internal (1);
1371 echo_area_glyphs
= 0;
1374 redisplay_internal (1);
1378 mark_window_display_accurate (window
, flag
)
1382 register struct window
*w
;
1384 for (;!NILP (window
); window
= w
->next
)
1386 if (!WINDOWP (window
)) abort ();
1387 w
= XWINDOW (window
);
1389 if (!NILP (w
->buffer
))
1391 XSETFASTINT (w
->last_modified
,
1392 !flag
? 0 : BUF_MODIFF (XBUFFER (w
->buffer
)));
1393 XSETFASTINT (w
->last_overlay_modified
,
1394 !flag
? 0 : BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
)));
1396 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1399 /* Record if we are showing a region, so can make sure to
1400 update it fully at next redisplay. */
1401 w
->region_showing
= (!NILP (Vtransient_mark_mode
)
1402 && (w
== XWINDOW (current_buffer
->last_selected_window
)
1403 || highlight_nonselected_windows
)
1404 && !NILP (XBUFFER (w
->buffer
)->mark_active
)
1405 ? Fmarker_position (XBUFFER (w
->buffer
)->mark
)
1409 w
->window_end_valid
= w
->buffer
;
1410 w
->update_mode_line
= Qnil
;
1411 if (!NILP (w
->buffer
) && flag
)
1412 XBUFFER (w
->buffer
)->clip_changed
= 0;
1414 if (!NILP (w
->vchild
))
1415 mark_window_display_accurate (w
->vchild
, flag
);
1416 if (!NILP (w
->hchild
))
1417 mark_window_display_accurate (w
->hchild
, flag
);
1422 last_arrow_position
= Voverlay_arrow_position
;
1423 last_arrow_string
= Voverlay_arrow_string
;
1427 /* t is unequal to any useful value of Voverlay_arrow_... */
1428 last_arrow_position
= Qt
;
1429 last_arrow_string
= Qt
;
1433 /* Update the menu bar item list for frame F.
1434 This has to be done before we start to fill in any display lines,
1435 because it can call eval.
1437 If SAVE_MATCH_DATA is 1, we must save and restore it here. */
1440 update_menu_bar (f
, save_match_data
)
1442 int save_match_data
;
1444 struct buffer
*old
= current_buffer
;
1446 register struct window
*w
;
1448 window
= FRAME_SELECTED_WINDOW (f
);
1449 w
= XWINDOW (window
);
1451 if (update_mode_lines
)
1452 w
->update_mode_line
= Qt
;
1454 if (FRAME_WINDOW_P (f
)
1456 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1457 FRAME_EXTERNAL_MENU_BAR (f
)
1459 FRAME_MENU_BAR_LINES (f
) > 0
1461 : FRAME_MENU_BAR_LINES (f
) > 0)
1463 /* If the user has switched buffers or windows, we need to
1464 recompute to reflect the new bindings. But we'll
1465 recompute when update_mode_lines is set too; that means
1466 that people can use force-mode-line-update to request
1467 that the menu bar be recomputed. The adverse effect on
1468 the rest of the redisplay algorithm is about the same as
1469 windows_or_buffers_changed anyway. */
1470 if (windows_or_buffers_changed
1471 || !NILP (w
->update_mode_line
)
1472 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1473 < BUF_MODIFF (XBUFFER (w
->buffer
)))
1474 != !NILP (w
->last_had_star
))
1475 || ((!NILP (Vtransient_mark_mode
)
1476 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
1477 != !NILP (w
->region_showing
)))
1479 struct buffer
*prev
= current_buffer
;
1480 int count
= specpdl_ptr
- specpdl
;
1482 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1483 if (save_match_data
)
1484 record_unwind_protect (Fstore_match_data
, Fmatch_data (Qnil
, Qnil
));
1485 if (NILP (Voverriding_local_map_menu_flag
))
1487 specbind (Qoverriding_terminal_local_map
, Qnil
);
1488 specbind (Qoverriding_local_map
, Qnil
);
1491 /* Run the Lucid hook. */
1492 call1 (Vrun_hooks
, Qactivate_menubar_hook
);
1493 /* If it has changed current-menubar from previous value,
1494 really recompute the menubar from the value. */
1495 if (! NILP (Vlucid_menu_bar_dirty_flag
))
1496 call0 (Qrecompute_lucid_menubar
);
1497 safe_run_hooks (Qmenu_bar_update_hook
);
1498 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
1499 /* Redisplay the menu bar in case we changed it. */
1500 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1501 if (FRAME_WINDOW_P (f
))
1502 set_frame_menubar (f
, 0, 0);
1504 /* On a terminal screen, the menu bar is an ordinary screen
1505 line, and this makes it get updated. */
1506 w
->update_mode_line
= Qt
;
1507 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
1508 /* In the non-toolkit version, the menu bar is an ordinary screen
1509 line, and this makes it get updated. */
1510 w
->update_mode_line
= Qt
;
1511 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
1513 unbind_to (count
, Qnil
);
1514 set_buffer_internal_1 (prev
);
1521 /* Redisplay WINDOW and its subwindows and siblings. */
1524 redisplay_windows (window
, preserve_echo_area
)
1526 int preserve_echo_area
;
1528 for (; !NILP (window
); window
= XWINDOW (window
)->next
)
1529 redisplay_window (window
, 0, preserve_echo_area
);
1532 /* Return value in display table DP (Lisp_Char_Table *) for character
1533 C. Since a display table doesn't have any parent, we don't have to
1534 follow parent. Do not call this function directly but use the
1535 macro DISP_CHAR_VECTOR. */
1537 disp_char_vector (dp
, c
)
1538 struct Lisp_Char_Table
*dp
;
1544 if (SINGLE_BYTE_CHAR_P (c
)) return (dp
->contents
[c
]);
1546 SPLIT_NON_ASCII_CHAR (c
, code
[0], code
[1], code
[2]);
1547 if (code
[0] != CHARSET_COMPOSITION
)
1549 if (code
[1] < 32) code
[1] = -1;
1550 else if (code
[2] < 32) code
[2] = -1;
1552 /* Here, the possible range of CODE[0] (== charset ID) is
1553 128..MAX_CHARSET. Since the top level char table contains data
1554 for multibyte characters after 256th element, we must increment
1555 CODE[0] by 128 to get a correct index. */
1557 code
[3] = -1; /* anchor */
1559 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
1561 val
= dp
->contents
[code
[i
]];
1562 if (!SUB_CHAR_TABLE_P (val
))
1563 return (NILP (val
) ? dp
->defalt
: val
);
1565 /* Here, VAL is a sub char table. We return the default value of it. */
1566 return (dp
->defalt
);
1569 /* Redisplay window WINDOW and its subwindows. */
1572 redisplay_window (window
, just_this_one
, preserve_echo_area
)
1574 int just_this_one
, preserve_echo_area
;
1576 register struct window
*w
= XWINDOW (window
);
1577 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
1579 register int lpoint
= PT
;
1580 struct buffer
*old
= current_buffer
;
1581 register int width
= window_internal_width (w
) - 1;
1582 register int startp
;
1583 register int hscroll
= XINT (w
->hscroll
);
1584 struct position pos
;
1587 int update_mode_line
;
1588 struct Lisp_Char_Table
*dp
= window_display_table (w
);
1590 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1592 /* If this is a combination window, do its children; that's all. */
1594 if (!NILP (w
->vchild
))
1596 redisplay_windows (w
->vchild
, preserve_echo_area
);
1599 if (!NILP (w
->hchild
))
1601 redisplay_windows (w
->hchild
, preserve_echo_area
);
1604 if (NILP (w
->buffer
))
1607 height
= window_internal_height (w
);
1608 update_mode_line
= (!NILP (w
->update_mode_line
) || update_mode_lines
);
1609 if (XBUFFER (w
->buffer
)->clip_changed
)
1610 update_mode_line
= 1;
1612 if (MINI_WINDOW_P (w
))
1614 if (w
== XWINDOW (echo_area_window
) && echo_area_glyphs
)
1615 /* We've already displayed the echo area glyphs in this window. */
1616 goto finish_scroll_bars
;
1617 else if (w
!= XWINDOW (minibuf_window
))
1619 /* This is a minibuffer, but it's not the currently active one,
1621 int vpos
= XFASTINT (w
->top
);
1624 for (i
= 0; i
< height
; i
++)
1626 get_display_line (f
, vpos
+ i
, 0);
1627 display_string (w
, vpos
+ i
, "", 0,
1628 FRAME_LEFT_SCROLL_BAR_WIDTH (f
),
1632 goto finish_scroll_bars
;
1636 /* Otherwise set up data on this window; select its buffer and point value */
1638 if (update_mode_line
)
1639 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1641 set_buffer_temp (XBUFFER (w
->buffer
));
1645 /* If %c is in mode line, update it if needed. */
1646 if (!NILP (w
->column_number_displayed
)
1647 /* This alternative quickly identifies a common case
1648 where no change is needed. */
1649 && !(PT
== XFASTINT (w
->last_point
)
1650 && XFASTINT (w
->last_modified
) >= MODIFF
1651 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
1652 && XFASTINT (w
->column_number_displayed
) != current_column ())
1653 update_mode_line
= 1;
1655 /* Count number of windows showing the selected buffer.
1656 An indirect buffer counts as its base buffer. */
1660 struct buffer
*current_base
, *window_base
;
1661 current_base
= current_buffer
;
1662 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
1663 if (current_base
->base_buffer
)
1664 current_base
= current_base
->base_buffer
;
1665 if (window_base
->base_buffer
)
1666 window_base
= window_base
->base_buffer
;
1667 if (current_base
== window_base
)
1671 /* POINT refers normally to the selected window.
1672 For any other window, set up appropriate value. */
1674 if (!EQ (window
, selected_window
))
1676 int new_pt
= marker_position (w
->pointm
);
1680 Fset_marker (w
->pointm
, make_number (new_pt
), Qnil
);
1682 else if (new_pt
> (ZV
- 1))
1685 Fset_marker (w
->pointm
, make_number (new_pt
), Qnil
);
1687 /* We don't use SET_PT so that the point-motion hooks don't run. */
1688 BUF_PT (current_buffer
) = new_pt
;
1691 /* If any of the character widths specified in the display table
1692 have changed, invalidate the width run cache. It's true that this
1693 may be a bit late to catch such changes, but the rest of
1694 redisplay goes (non-fatally) haywire when the display table is
1695 changed, so why should we worry about doing any better? */
1696 if (current_buffer
->width_run_cache
)
1698 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
1700 if (! disptab_matches_widthtab (disptab
,
1701 XVECTOR (current_buffer
->width_table
)))
1703 invalidate_region_cache (current_buffer
,
1704 current_buffer
->width_run_cache
,
1706 recompute_width_table (current_buffer
, disptab
);
1710 /* If window-start is screwed up, choose a new one. */
1711 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
1714 startp
= marker_position (w
->start
);
1716 /* If someone specified a new starting point but did not insist,
1717 check whether it can be used. */
1718 if (!NILP (w
->optional_new_start
))
1720 w
->optional_new_start
= Qnil
;
1721 /* Check whether this start pos is usable given where point is. */
1723 pos
= *compute_motion (startp
, 0,
1724 (((EQ (window
, minibuf_window
)
1726 ? minibuf_prompt_width
: 0)
1727 + (hscroll
? 1 - hscroll
: 0)),
1730 /* BUG FIX: See the comment of
1731 Fpos_visible_in_window_p (window.c). */
1732 - (1 << (BITS_PER_SHORT
- 1)),
1733 width
, hscroll
, pos_tab_offset (w
, startp
), w
);
1734 /* If PT does fit on the screen, we will use this start pos,
1735 so do so by setting force_start. */
1736 if (pos
.bufpos
== PT
)
1737 w
->force_start
= Qt
;
1740 /* Handle case where place to start displaying has been specified,
1741 unless the specified location is outside the accessible range. */
1742 if (!NILP (w
->force_start
))
1744 w
->force_start
= Qnil
;
1745 /* Forget any recorded base line for line number display. */
1746 w
->base_line_number
= Qnil
;
1747 /* Redisplay the mode line. Select the buffer properly for that.
1748 Also, run the hook window-scroll-functions
1749 because we have scrolled. */
1750 /* Note, we do this after clearing force_start because
1751 if there's an error, it is better to forget about force_start
1752 than to get into an infinite loop calling the hook functions
1753 and having them get more errors. */
1754 if (!update_mode_line
1755 || ! NILP (Vwindow_scroll_functions
))
1757 Lisp_Object temp
[3];
1759 set_buffer_temp (old
);
1760 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1761 update_mode_line
= 1;
1762 w
->update_mode_line
= Qt
;
1763 if (! NILP (Vwindow_scroll_functions
))
1765 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
1766 make_number (startp
));
1767 startp
= marker_position (w
->start
);
1770 XSETFASTINT (w
->last_modified
, 0);
1771 XSETFASTINT (w
->last_overlay_modified
, 0);
1772 if (startp
< BEGV
) startp
= BEGV
;
1773 if (startp
> ZV
) startp
= ZV
;
1774 try_window (window
, startp
);
1775 if (cursor_vpos
< 0)
1777 /* If point does not appear, move point so it does appear */
1778 pos
= *compute_motion (startp
, 0,
1779 (((EQ (window
, minibuf_window
)
1781 ? minibuf_prompt_width
: 0)
1782 + (hscroll
? 1 - hscroll
: 0)),
1785 - (1 << (BITS_PER_SHORT
- 1)),
1786 width
, hscroll
, pos_tab_offset (w
, startp
), w
);
1787 BUF_PT (current_buffer
) = pos
.bufpos
;
1788 if (w
!= XWINDOW (selected_window
))
1789 Fset_marker (w
->pointm
, make_number (PT
), Qnil
);
1792 if (current_buffer
== old
)
1794 FRAME_CURSOR_X (f
) = (WINDOW_LEFT_MARGIN (w
)
1795 + minmax (0, pos
.hpos
, width
));
1796 FRAME_CURSOR_Y (f
) = pos
.vpos
+ XFASTINT (w
->top
);
1798 /* If we are highlighting the region,
1799 then we just changed the region, so redisplay to show it. */
1800 if (!NILP (Vtransient_mark_mode
)
1801 && !NILP (current_buffer
->mark_active
))
1803 cancel_my_columns (XWINDOW (window
));
1804 try_window (window
, startp
);
1810 /* Handle case where text has not changed, only point,
1811 and it has not moved off the frame. */
1813 /* This code is not used for minibuffer for the sake of
1814 the case of redisplaying to replace an echo area message;
1815 since in that case the minibuffer contents per se are usually unchanged.
1816 This code is of no real use in the minibuffer since
1817 the handling of this_line_bufpos, etc.,
1818 in redisplay handles the same cases. */
1820 if (XFASTINT (w
->last_modified
) >= MODIFF
1821 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
1822 && PT
>= startp
&& !current_buffer
->clip_changed
1823 && (just_this_one
|| WINDOW_FULL_WIDTH_P (w
))
1824 /* If force-mode-line-update was called, really redisplay;
1825 that's how redisplay is forced after e.g. changing
1826 buffer-invisibility-spec. */
1827 && NILP (w
->update_mode_line
)
1828 /* Can't use this case if highlighting a region. */
1829 && !(!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1830 && NILP (w
->region_showing
)
1831 /* If end pos is out of date, scroll bar and percentage will be wrong */
1832 && INTEGERP (w
->window_end_vpos
)
1833 && XFASTINT (w
->window_end_vpos
) < XFASTINT (w
->height
)
1834 && !EQ (window
, minibuf_window
))
1836 int this_scroll_margin
= scroll_margin
;
1838 pos
= *compute_motion (startp
, 0, (hscroll
? 1 - hscroll
: 0), 0,
1840 /* BUG FIX: See the comment of
1841 Fpos_visible_in_window_p (window.c). */
1842 - (1 << (BITS_PER_SHORT
- 1)),
1844 pos_tab_offset (w
, startp
), w
);
1846 /* Don't use a scroll margin that is negative or too large. */
1847 if (this_scroll_margin
< 0)
1848 this_scroll_margin
= 0;
1850 if (XINT (w
->height
) < 4 * scroll_margin
)
1851 this_scroll_margin
= XINT (w
->height
) / 4;
1853 /* If point fits on the screen, and not within the scroll margin,
1855 if (pos
.vpos
< height
- this_scroll_margin
1856 && (pos
.vpos
>= this_scroll_margin
|| startp
== BEGV
))
1858 /* Ok, point is still on frame */
1859 if (w
== XWINDOW (FRAME_SELECTED_WINDOW (f
)))
1861 /* These variables are supposed to be origin 1 */
1862 FRAME_CURSOR_X (f
) = (WINDOW_LEFT_MARGIN (w
)
1863 + minmax (0, pos
.hpos
, width
));
1864 FRAME_CURSOR_Y (f
) = pos
.vpos
+ XFASTINT (w
->top
);
1866 /* This doesn't do the trick, because if a window to the right of
1867 this one must be redisplayed, this does nothing because there
1868 is nothing in DesiredFrame yet, and then the other window is
1869 redisplayed, making likes that are empty in this window's columns.
1870 if (WINDOW_FULL_WIDTH_P (w))
1871 preserve_my_columns (w);
1875 /* Don't bother trying redisplay with same start;
1876 we already know it will lose */
1878 /* If current starting point was originally the beginning of a line
1879 but no longer is, find a new starting point. */
1880 else if (!NILP (w
->start_at_line_beg
)
1882 || FETCH_BYTE (startp
- 1) == '\n'))
1886 else if (just_this_one
&& !MINI_WINDOW_P (w
)
1888 && XFASTINT (w
->last_modified
)
1889 /* or else vmotion on first line won't work. */
1890 && ! NILP (w
->start_at_line_beg
)
1891 && ! EQ (w
->window_end_valid
, Qnil
)
1892 && do_id
&& !current_buffer
->clip_changed
1893 && !blank_end_of_window
1894 && WINDOW_FULL_WIDTH_P (w
)
1895 /* Can't use this case if highlighting a region. */
1896 && !(!NILP (Vtransient_mark_mode
)
1897 && !NILP (current_buffer
->mark_active
))
1898 /* Don't use try_window_id if newline
1899 doesn't display as the end of a line. */
1900 && !(dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, '\n')))
1901 && NILP (w
->region_showing
)
1902 && EQ (last_arrow_position
, Voverlay_arrow_position
)
1903 && EQ (last_arrow_string
, Voverlay_arrow_string
)
1904 && (tem
= try_window_id (FRAME_SELECTED_WINDOW (f
)))
1907 /* tem > 0 means success. tem == -1 means choose new start.
1908 tem == -2 means try again with same start,
1909 and nothing but whitespace follows the changed stuff.
1910 tem == 0 means try again with same start. */
1914 else if (startp
>= BEGV
&& startp
<= ZV
1916 /* Avoid starting at end of buffer. */
1917 #if 0 /* This change causes trouble for M-! finger & RET.
1918 It will have to be considered later. */
1919 || ! EQ (window
, selected_window
)
1920 /* Don't do the recentering if redisplay
1921 is not for no user action. */
1922 || preserve_echo_area
1925 || (XFASTINT (w
->last_modified
) >= MODIFF
1926 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
1928 /* Try to redisplay starting at same place as before */
1929 /* If point has not moved off frame, accept the results */
1930 try_window (window
, startp
);
1931 if (cursor_vpos
>= 0)
1933 if (!just_this_one
|| current_buffer
->clip_changed
1934 || beg_unchanged
< startp
)
1935 /* Forget any recorded base line for line number display. */
1936 w
->base_line_number
= Qnil
;
1940 cancel_my_columns (w
);
1943 XSETFASTINT (w
->last_modified
, 0);
1944 XSETFASTINT (w
->last_overlay_modified
, 0);
1945 /* Redisplay the mode line. Select the buffer properly for that. */
1946 if (!update_mode_line
)
1948 set_buffer_temp (old
);
1949 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1950 update_mode_line
= 1;
1951 w
->update_mode_line
= Qt
;
1954 /* Try to scroll by specified few lines */
1956 if (scroll_conservatively
&& !current_buffer
->clip_changed
1957 && startp
>= BEGV
&& startp
<= ZV
)
1959 int this_scroll_margin
= scroll_margin
;
1961 /* Don't use a scroll margin that is negative or too large. */
1962 if (this_scroll_margin
< 0)
1963 this_scroll_margin
= 0;
1965 if (XINT (w
->height
) < 4 * scroll_margin
)
1966 this_scroll_margin
= XINT (w
->height
) / 4;
1968 if (PT
>= Z
- XFASTINT (w
->window_end_pos
))
1970 struct position pos
;
1971 pos
= *compute_motion (Z
- XFASTINT (w
->window_end_pos
), 0, 0, 0,
1972 PT
, XFASTINT (w
->height
), 0,
1973 XFASTINT (w
->width
), XFASTINT (w
->hscroll
),
1974 pos_tab_offset (w
, startp
), w
);
1975 if (pos
.vpos
> scroll_conservatively
)
1978 pos
= *vmotion (startp
, pos
.vpos
+ 1 + this_scroll_margin
, w
);
1980 if (! NILP (Vwindow_scroll_functions
))
1982 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
1983 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
1984 make_number (pos
.bufpos
));
1985 pos
.bufpos
= marker_position (w
->start
);
1987 try_window (window
, pos
.bufpos
);
1988 if (cursor_vpos
>= 0)
1990 if (!just_this_one
|| current_buffer
->clip_changed
1991 || beg_unchanged
< startp
)
1992 /* Forget any recorded base line for line number display. */
1993 w
->base_line_number
= Qnil
;
1997 cancel_my_columns (w
);
2001 struct position pos
;
2002 pos
= *compute_motion (PT
, 0, 0, 0,
2003 startp
, XFASTINT (w
->height
), 0,
2004 XFASTINT (w
->width
), XFASTINT (w
->hscroll
),
2005 pos_tab_offset (w
, startp
), w
);
2006 if (pos
.vpos
>= scroll_conservatively
)
2009 pos
= *vmotion (startp
, - pos
.vpos
- this_scroll_margin
, w
);
2011 if (! NILP (Vwindow_scroll_functions
))
2013 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
2014 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2015 make_number (pos
.bufpos
));
2016 pos
.bufpos
= marker_position (w
->start
);
2018 try_window (window
, pos
.bufpos
);
2019 if (cursor_vpos
>= 0)
2021 if (!just_this_one
|| current_buffer
->clip_changed
2022 || beg_unchanged
< startp
)
2023 /* Forget any recorded base line for line number display. */
2024 w
->base_line_number
= Qnil
;
2028 cancel_my_columns (w
);
2033 if (scroll_step
&& !current_buffer
->clip_changed
2034 && startp
>= BEGV
&& startp
<= ZV
)
2038 pos
= *vmotion (Z
- XFASTINT (w
->window_end_pos
), scroll_step
, w
);
2039 if (pos
.vpos
>= height
)
2043 pos
= *vmotion (startp
, (PT
< startp
? - scroll_step
: scroll_step
), w
);
2045 if (PT
>= pos
.bufpos
)
2047 if (! NILP (Vwindow_scroll_functions
))
2049 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
2050 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2051 make_number (pos
.bufpos
));
2052 pos
.bufpos
= marker_position (w
->start
);
2054 try_window (window
, pos
.bufpos
);
2055 if (cursor_vpos
>= 0)
2057 if (!just_this_one
|| current_buffer
->clip_changed
2058 || beg_unchanged
< startp
)
2059 /* Forget any recorded base line for line number display. */
2060 w
->base_line_number
= Qnil
;
2064 cancel_my_columns (w
);
2069 /* Finally, just choose place to start which centers point */
2072 /* Forget any previously recorded base line for line number display. */
2073 w
->base_line_number
= Qnil
;
2075 pos
= *vmotion (PT
, - (height
/ 2), w
);
2076 /* Set startp here explicitly in case that helps avoid an infinite loop
2077 in case the window-scroll-functions functions get errors. */
2078 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
2079 if (! NILP (Vwindow_scroll_functions
))
2081 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2082 make_number (pos
.bufpos
));
2083 pos
.bufpos
= marker_position (w
->start
);
2085 try_window (window
, pos
.bufpos
);
2087 startp
= marker_position (w
->start
);
2088 w
->start_at_line_beg
2089 = (startp
== BEGV
|| FETCH_BYTE (startp
- 1) == '\n') ? Qt
: Qnil
;
2092 if ((update_mode_line
2093 /* If window not full width, must redo its mode line
2094 if the window to its side is being redone */
2095 || (!just_this_one
&& !WINDOW_FULL_WIDTH_P (w
))
2096 || INTEGERP (w
->base_line_pos
)
2097 || (!NILP (w
->column_number_displayed
)
2098 && XFASTINT (w
->column_number_displayed
) != current_column ()))
2099 && height
!= XFASTINT (w
->height
))
2100 display_mode_line (w
);
2101 if (! line_number_displayed
2102 && ! BUFFERP (w
->base_line_pos
))
2104 w
->base_line_pos
= Qnil
;
2105 w
->base_line_number
= Qnil
;
2108 /* When we reach a frame's selected window, redo the frame's menu bar. */
2109 if (update_mode_line
2110 && (FRAME_WINDOW_P (f
)
2112 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
2113 FRAME_EXTERNAL_MENU_BAR (f
)
2115 FRAME_MENU_BAR_LINES (f
) > 0
2117 : FRAME_MENU_BAR_LINES (f
) > 0)
2118 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
2119 display_menu_bar (w
);
2122 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2124 int start
, end
, whole
;
2126 /* Calculate the start and end positions for the current window.
2127 At some point, it would be nice to choose between scrollbars
2128 which reflect the whole buffer size, with special markers
2129 indicating narrowing, and scrollbars which reflect only the
2132 Note that minibuffers sometimes aren't displaying any text. */
2133 if (! MINI_WINDOW_P (w
)
2134 || (w
== XWINDOW (minibuf_window
) && ! echo_area_glyphs
))
2137 start
= marker_position (w
->start
) - BEGV
;
2138 /* I don't think this is guaranteed to be right. For the
2139 moment, we'll pretend it is. */
2140 end
= (Z
- XINT (w
->window_end_pos
)) - BEGV
;
2142 if (end
< start
) end
= start
;
2143 if (whole
< (end
- start
)) whole
= end
- start
;
2146 start
= end
= whole
= 0;
2148 /* Indicate what this scroll bar ought to be displaying now. */
2149 (*set_vertical_scroll_bar_hook
) (w
, end
- start
, whole
, start
);
2151 /* Note that we actually used the scroll bar attached to this window,
2152 so it shouldn't be deleted at the end of redisplay. */
2153 (*redeem_scroll_bar_hook
) (w
);
2156 BUF_PT (current_buffer
) = opoint
;
2157 if (update_mode_line
)
2158 set_buffer_internal_1 (old
);
2160 set_buffer_temp (old
);
2161 BUF_PT (current_buffer
) = lpoint
;
2164 /* Do full redisplay on one window, starting at position `pos'. */
2167 try_window (window
, pos
)
2171 register struct window
*w
= XWINDOW (window
);
2172 register int height
= window_internal_height (w
);
2173 register int vpos
= XFASTINT (w
->top
);
2174 register int last_text_vpos
= vpos
;
2175 FRAME_PTR f
= XFRAME (w
->frame
);
2176 int width
= window_internal_width (w
) - 1;
2177 struct position val
;
2179 /* POS should never be out of range! */
2180 if (pos
< XBUFFER (w
->buffer
)->begv
2181 || pos
> XBUFFER (w
->buffer
)->zv
)
2184 Fset_marker (w
->start
, make_number (pos
), Qnil
);
2186 overlay_arrow_seen
= 0;
2187 zv_strings_seen
= 0;
2188 val
.hpos
= XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0;
2189 val
.ovstring_chars_done
= 0;
2190 val
.tab_offset
= pos_tab_offset (w
, pos
);
2192 while (--height
>= 0)
2194 val
= *display_text_line (w
, pos
, vpos
, val
.hpos
, val
.tab_offset
,
2195 val
.ovstring_chars_done
);
2196 /* The following code is omitted because we maintain tab_offset
2199 tab_offset
+= width
;
2200 if (val
.vpos
) tab_offset
= 0;
2203 if (pos
!= val
.bufpos
)
2206 #ifdef USE_TEXT_PROPERTIES
2207 Lisp_Object invis_prop
;
2208 invis_prop
= Fget_char_property (val
.bufpos
-1, Qinvisible
, window
);
2209 invis
= TEXT_PROP_MEANS_INVISIBLE (invis_prop
);
2213 /* Next line, unless prev line ended in end of buffer with no cr */
2215 && (FETCH_BYTE (val
.bufpos
- 1) != '\n' || invis
));
2220 /* If last line is continued in middle of character,
2221 include the split character in the text considered on the frame */
2222 if (val
.hpos
< (XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0))
2225 /* If bottom just moved off end of frame, change mode line percentage. */
2226 if (XFASTINT (w
->window_end_pos
) == 0
2228 w
->update_mode_line
= Qt
;
2230 /* Say where last char on frame will be, once redisplay is finished. */
2231 XSETFASTINT (w
->window_end_pos
, Z
- pos
);
2232 XSETFASTINT (w
->window_end_vpos
, last_text_vpos
- XFASTINT (w
->top
));
2233 /* But that is not valid info until redisplay finishes. */
2234 w
->window_end_valid
= Qnil
;
2237 /* Try to redisplay when buffer is modified locally,
2238 computing insert/delete line to preserve text outside
2239 the bounds of the changes.
2240 Return 1 if successful, 0 if if cannot tell what to do,
2241 or -1 to tell caller to find a new window start,
2242 or -2 to tell caller to do normal redisplay with same window start. */
2245 try_window_id (window
)
2249 register struct window
*w
= XWINDOW (window
);
2250 register int height
= window_internal_height (w
);
2251 FRAME_PTR f
= XFRAME (w
->frame
);
2252 int top
= XFASTINT (w
->top
);
2253 int start
= marker_position (w
->start
);
2254 int width
= window_internal_width (w
) - 1;
2255 int hscroll
= XINT (w
->hscroll
);
2256 int lmargin
= hscroll
> 0 ? 1 - hscroll
: 0;
2259 register int i
, tem
;
2260 int last_text_vpos
= 0;
2262 int selective
= (INTEGERP (current_buffer
->selective_display
)
2263 ? XINT (current_buffer
->selective_display
)
2264 : !NILP (current_buffer
->selective_display
) ? -1 : 0);
2266 struct position val
, bp
, ep
, xp
, pp
;
2267 int scroll_amount
= 0;
2271 if (GPT
- BEG
< beg_unchanged
)
2272 beg_unchanged
= GPT
- BEG
;
2273 if (Z
- GPT
< end_unchanged
)
2274 end_unchanged
= Z
- GPT
;
2276 if (beg_unchanged
+ BEG
< start
)
2277 return 0; /* Give up if changes go above top of window */
2279 /* Find position before which nothing is changed. */
2280 bp
= *compute_motion (start
, 0, lmargin
, 0,
2281 min (ZV
, beg_unchanged
+ BEG
), height
,
2282 /* BUG FIX: See the comment of
2283 Fpos_visible_in_window_p() (window.c). */
2284 - (1 << (BITS_PER_SHORT
- 1)),
2285 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2286 if (bp
.vpos
>= height
)
2290 /* All changes are beyond the window end, and point is on the screen.
2291 We don't need to change the text at all.
2292 But we need to update window_end_pos to account for
2293 any change in buffer size. */
2294 bp
= *compute_motion (start
, 0, lmargin
, 0,
2296 /* BUG FIX: See the comment of
2297 Fpos_visible_in_window_p() (window.c). */
2298 - (1 << (BITS_PER_SHORT
- 1)),
2299 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2300 XSETFASTINT (w
->window_end_vpos
, height
);
2301 XSETFASTINT (w
->window_end_pos
, Z
- bp
.bufpos
);
2309 /* Find beginning of that frame line. Must display from there. */
2310 bp
= *vmotion (bp
.bufpos
, 0, w
);
2318 /* If about to start displaying at the beginning of a continuation line,
2319 really start with previous frame line, in case it was not
2320 continued when last redisplayed */
2321 if ((bp
.contin
&& bp
.bufpos
- 1 == beg_unchanged
&& vpos
> 0)
2323 /* Likewise if we have to worry about selective display. */
2324 (selective
> 0 && bp
.bufpos
- 1 == beg_unchanged
&& vpos
> 0))
2326 bp
= *vmotion (bp
.bufpos
, -1, w
);
2330 val
.tab_offset
= bp
.tab_offset
; /* Update tab offset. */
2332 if (bp
.contin
&& bp
.hpos
!= lmargin
)
2334 val
.hpos
= bp
.prevhpos
- width
+ lmargin
;
2335 val
.tab_offset
= bp
.tab_offset
+ bp
.prevhpos
- width
;
2342 /* Find first visible newline after which no more is changed. */
2343 tem
= find_next_newline (Z
- max (end_unchanged
, Z
- ZV
), 1);
2345 while (tem
< ZV
- 1 && (indented_beyond_p (tem
, selective
)))
2346 tem
= find_next_newline (tem
, 1);
2348 /* Compute the cursor position after that newline. */
2349 ep
= *compute_motion (pos
, vpos
, val
.hpos
, did_motion
, tem
,
2350 height
, - (1 << (BITS_PER_SHORT
- 1)),
2352 /* We have tab offset in VAL, use it. */
2355 /* If changes reach past the text available on the frame,
2356 just display rest of frame. */
2357 if (ep
.bufpos
> Z
- XFASTINT (w
->window_end_pos
))
2360 stop_vpos
= ep
.vpos
;
2362 /* If no newline before ep, the line ep is on includes some changes
2363 that must be displayed. Make sure we don't stop before it. */
2364 /* Also, if changes reach all the way until ep.bufpos,
2365 it is possible that something was deleted after the
2366 newline before it, so the following line must be redrawn. */
2367 if (stop_vpos
== ep
.vpos
2368 && (ep
.bufpos
== BEGV
2369 || FETCH_BYTE (ep
.bufpos
- 1) != '\n'
2370 || ep
.bufpos
== Z
- end_unchanged
))
2371 stop_vpos
= ep
.vpos
+ 1;
2374 overlay_arrow_seen
= 0;
2375 zv_strings_seen
= 0;
2377 /* If changes do not reach to bottom of window,
2378 figure out how much to scroll the rest of the window */
2379 if (stop_vpos
< height
)
2381 /* Now determine how far up or down the rest of the window has moved */
2382 xp
= *compute_motion (ep
.bufpos
, ep
.vpos
, ep
.hpos
, 1,
2383 Z
- XFASTINT (w
->window_end_pos
),
2384 /* Don't care for VPOS... */
2385 1 << (BITS_PER_SHORT
- 1),
2387 1 << (BITS_PER_SHORT
- 1),
2388 width
, hscroll
, ep
.tab_offset
, w
);
2389 scroll_amount
= xp
.vpos
- XFASTINT (w
->window_end_vpos
);
2391 /* Is everything on frame below the changes whitespace?
2392 If so, no scrolling is really necessary. */
2393 for (i
= ep
.bufpos
; i
< xp
.bufpos
; i
++)
2395 tem
= FETCH_BYTE (i
);
2396 if (tem
!= ' ' && tem
!= '\n' && tem
!= '\t')
2402 XSETFASTINT (w
->window_end_vpos
,
2403 XFASTINT (w
->window_end_vpos
) + scroll_amount
);
2405 /* Before doing any scrolling, verify that point will be on frame. */
2406 if (PT
> ep
.bufpos
&& !(PT
<= xp
.bufpos
&& xp
.vpos
< height
))
2408 if (PT
<= xp
.bufpos
)
2410 pp
= *compute_motion (ep
.bufpos
, ep
.vpos
, ep
.hpos
, 1,
2411 PT
, height
, - (1 << (BITS_PER_SHORT
- 1)),
2413 /* We have tab offset in EP, use it. */
2418 pp
= *compute_motion (xp
.bufpos
, xp
.vpos
, xp
.hpos
, 1,
2419 PT
, height
, - (1 << (BITS_PER_SHORT
- 1)),
2421 /* We have tab offset in XP, use it. */
2424 if (pp
.bufpos
< PT
|| pp
.vpos
== height
)
2426 cursor_vpos
= pp
.vpos
+ top
;
2427 cursor_hpos
= WINDOW_LEFT_MARGIN (w
) + minmax (0, pp
.hpos
, width
);
2430 if (stop_vpos
- scroll_amount
>= height
2431 || ep
.bufpos
== xp
.bufpos
)
2433 if (scroll_amount
< 0)
2434 stop_vpos
-= scroll_amount
;
2436 /* In this path, we have altered window_end_vpos
2437 and not left it negative.
2438 We must make sure that, in case display is preempted
2439 before the frame changes to reflect what we do here,
2440 further updates will not come to try_window_id
2441 and assume the frame and window_end_vpos match. */
2442 blank_end_of_window
= 1;
2444 else if (!scroll_amount
)
2446 /* Even if we don't need to scroll, we must adjust the
2447 charstarts of subsequent lines (that we won't redisplay)
2448 according to the amount of text inserted or deleted. */
2449 int oldpos
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[ep
.vpos
+ top
][0];
2450 int adjust
= ep
.bufpos
- oldpos
;
2451 adjust_window_charstarts (w
, ep
.vpos
+ top
- 1, adjust
);
2453 else if (bp
.bufpos
== Z
- end_unchanged
)
2455 /* If reprinting everything is nearly as fast as scrolling,
2456 don't bother scrolling. Can happen if lines are short. */
2457 if (scroll_cost (f
, bp
.vpos
+ top
- scroll_amount
,
2458 top
+ height
- max (0, scroll_amount
),
2460 > xp
.bufpos
- bp
.bufpos
- 20)
2461 /* Return "try normal display with same window-start."
2462 Too bad we can't prevent further scroll-thinking. */
2464 /* If pure deletion, scroll up as many lines as possible.
2465 In common case of killing a line, this can save the
2466 following line from being overwritten by scrolling
2467 and therefore having to be redrawn. */
2468 tem
= scroll_frame_lines (f
, bp
.vpos
+ top
- scroll_amount
,
2469 top
+ height
- max (0, scroll_amount
),
2470 scroll_amount
, bp
.bufpos
);
2475 /* scroll_frame_lines did not properly adjust subsequent
2476 lines' charstarts in the case where the text of the
2477 screen line at bp.vpos has changed.
2478 (This can happen in a deletion that ends in mid-line.)
2479 To adjust properly, we need to make things consistent
2481 So do a second adjust to make that happen.
2482 Note that stop_vpos >= ep.vpos, so it is sufficient
2483 to update the charstarts for lines at ep.vpos and below. */
2485 = FRAME_CURRENT_GLYPHS (f
)->charstarts
[ep
.vpos
+ top
][0];
2486 adjust_window_charstarts (w
, ep
.vpos
+ top
- 1,
2487 ep
.bufpos
- oldstart
);
2490 else if (scroll_amount
)
2492 /* If reprinting everything is nearly as fast as scrolling,
2493 don't bother scrolling. Can happen if lines are short. */
2494 /* Note that if scroll_amount > 0, xp.bufpos - bp.bufpos is an
2495 overestimate of cost of reprinting, since xp.bufpos
2496 would end up below the bottom of the window. */
2497 if (scroll_cost (f
, ep
.vpos
+ top
- scroll_amount
,
2498 top
+ height
- max (0, scroll_amount
),
2500 > xp
.bufpos
- ep
.bufpos
- 20)
2501 /* Return "try normal display with same window-start."
2502 Too bad we can't prevent further scroll-thinking. */
2504 tem
= scroll_frame_lines (f
, ep
.vpos
+ top
- scroll_amount
,
2505 top
+ height
- max (0, scroll_amount
),
2506 scroll_amount
, ep
.bufpos
);
2507 if (!tem
) stop_vpos
= height
;
2511 /* In any case, do not display past bottom of window */
2512 if (stop_vpos
>= height
)
2518 /* Handle case where pos is before w->start --
2519 can happen if part of line had been clipped and is not clipped now */
2520 if (vpos
== 0 && pos
< marker_position (w
->start
))
2521 Fset_marker (w
->start
, make_number (pos
), Qnil
);
2523 /* Redisplay the lines where the text was changed */
2524 last_text_vpos
= vpos
;
2525 /* The following code is omitted because we maintain tab offset in
2528 tab_offset
= pos_tab_offset (w
, pos
);
2529 /* If we are starting display in mid-character, correct tab_offset
2530 to account for passing the line that that character really starts in. */
2531 if (val
.hpos
< lmargin
)
2532 tab_offset
+= width
;
2535 while (vpos
< stop_vpos
)
2537 val
= *display_text_line (w
, pos
, top
+ vpos
++, val
.hpos
, val
.tab_offset
,
2538 val
.ovstring_chars_done
);
2539 /* If display_text_line ran a hook and changed some text,
2540 redisplay all the way to bottom of buffer
2541 So that we show the changes. */
2542 if (old_tick
!= MODIFF
)
2544 /* The following code is omitted because we maintain tab offset
2545 in val.tab_offset. */
2547 tab_offset
+= width
;
2548 if (val
.vpos
) tab_offset
= 0;
2550 if (pos
!= val
.bufpos
)
2552 /* Next line, unless prev line ended in end of buffer with no cr */
2553 = vpos
- (val
.vpos
&& FETCH_BYTE (val
.bufpos
- 1) != '\n');
2557 /* There are two cases:
2558 1) we have displayed down to the bottom of the window
2559 2) we have scrolled lines below stop_vpos by scroll_amount */
2563 /* If last line is continued in middle of character,
2564 include the split character in the text considered on the frame */
2565 if (val
.hpos
< lmargin
)
2567 XSETFASTINT (w
->window_end_vpos
, last_text_vpos
);
2568 XSETFASTINT (w
->window_end_pos
, Z
- val
.bufpos
);
2571 /* If scrolling made blank lines at window bottom,
2572 redisplay to fill those lines */
2573 if (scroll_amount
< 0)
2575 /* Don't consider these lines for general-purpose scrolling.
2576 That will save time in the scrolling computation. */
2577 FRAME_SCROLL_BOTTOM_VPOS (f
) = xp
.vpos
;
2581 val
.tab_offset
= xp
.tab_offset
;
2583 { /* Display from next line */
2584 vpos
= height
+ scroll_amount
;
2588 else if (xp
.contin
&& xp
.hpos
!= lmargin
)
2590 val
.hpos
= xp
.prevhpos
- width
+ lmargin
;
2591 val
.tab_offset
= xp
.tab_offset
+ bp
.prevhpos
- width
;
2595 blank_end_of_window
= 1;
2596 /* The following code is omitted because we maintain tab offset
2597 in val.tab_offset. */
2599 tab_offset
= pos_tab_offset (w
, pos
);
2600 /* If we are starting display in mid-character, correct tab_offset
2601 to account for passing the line that that character starts in. */
2602 if (val
.hpos
< lmargin
)
2603 tab_offset
+= width
;
2605 while (vpos
< height
)
2607 val
= *display_text_line (w
, pos
, top
+ vpos
++, val
.hpos
,
2608 val
.tab_offset
, val
.ovstring_chars_done
);
2609 /* The following code is omitted because we maintain tab
2610 offset in val.tab_offset. */
2612 tab_offset
+= width
;
2613 if (val
.vpos
) tab_offset
= 0;
2618 /* Here is a case where display_text_line sets cursor_vpos wrong.
2619 Make it be fixed up, below. */
2625 /* If bottom just moved off end of frame, change mode line percentage. */
2626 if (XFASTINT (w
->window_end_pos
) == 0
2628 w
->update_mode_line
= Qt
;
2630 /* Attempt to adjust end-of-text positions to new bottom line */
2633 delta
= height
- xp
.vpos
;
2635 || (delta
> 0 && xp
.bufpos
<= ZV
)
2636 || (delta
== 0 && xp
.hpos
))
2638 val
= *vmotion (Z
- XFASTINT (w
->window_end_pos
), delta
, w
);
2639 XSETFASTINT (w
->window_end_pos
, Z
- val
.bufpos
);
2640 XSETFASTINT (w
->window_end_vpos
,
2641 XFASTINT (w
->window_end_vpos
) + val
.vpos
);
2645 w
->window_end_valid
= Qnil
;
2647 /* If point was not in a line that was displayed, find it */
2648 if (cursor_vpos
< 0)
2651 val
= *compute_motion (start
, 0, lmargin
, 0, PT
,
2652 /* Don't care for VPOS... */
2653 1 << (BITS_PER_SHORT
- 1),
2655 1 << (BITS_PER_SHORT
- 1),
2656 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2657 /* Admit failure if point is off frame now */
2658 if (val
.vpos
>= height
)
2660 for (vpos
= 0; vpos
< height
; vpos
++)
2661 cancel_line (vpos
+ top
, f
);
2664 cursor_vpos
= val
.vpos
+ top
;
2665 cursor_hpos
= WINDOW_LEFT_MARGIN (w
) + minmax (0, val
.hpos
, width
);
2668 FRAME_CURSOR_X (f
) = cursor_hpos
;
2669 FRAME_CURSOR_Y (f
) = cursor_vpos
;
2673 val
= *compute_motion (start
, 0, lmargin
, 0, ZV
,
2674 height
, - (1 << (BITS_PER_SHORT
- 1)),
2675 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2676 if (val
.vpos
!= XFASTINT (w
->window_end_vpos
))
2678 if (XFASTINT (w
->window_end_pos
)
2686 /* Copy LEN glyphs starting address FROM to the rope TO.
2687 But don't actually copy the parts that would come in before S.
2688 Value is TO, advanced past the copied data.
2689 F is the frame we are displaying in. */
2692 copy_part_of_rope (f
, to
, s
, from
, len
, face
)
2694 register GLYPH
*to
; /* Copy to here. */
2695 register GLYPH
*s
; /* Starting point. */
2696 Lisp_Object
*from
; /* Data to copy. */
2698 int face
; /* Face to apply to glyphs which don't specify one. */
2701 register Lisp_Object
*fp
= from
;
2702 /* These cache the results of the last call to compute_glyph_face. */
2704 int last_merged
= 0;
2707 if (! FRAME_TERMCAP_P (f
))
2710 GLYPH glyph
= (INTEGERP (*fp
) ? XFASTINT (*fp
) : 0);
2712 unsigned int c
= FAST_GLYPH_CHAR (glyph
);
2715 /* For an invalid character code, use space. */
2718 if (FAST_GLYPH_FACE (glyph
) == 0)
2719 /* If GLYPH has no face code, use FACE. */
2721 else if (FAST_GLYPH_FACE (glyph
) == last_code
)
2722 /* If it's same as previous glyph, use same result. */
2723 facecode
= last_merged
;
2726 /* Merge this glyph's face and remember the result. */
2727 last_code
= FAST_GLYPH_FACE (glyph
);
2728 last_merged
= facecode
= compute_glyph_face (f
, last_code
, face
);
2732 *to
= FAST_MAKE_GLYPH (c
, facecode
);
2740 if (to
>= s
) *to
= (INTEGERP (*fp
) ? XFASTINT (*fp
) : 0);
2747 /* Correct a glyph by replacing its specified user-level face code
2748 with a displayable computed face code. */
2751 fix_glyph (f
, glyph
, cface
)
2757 if (! FRAME_TERMCAP_P (f
))
2759 if (FAST_GLYPH_FACE (glyph
) != 0)
2760 cface
= compute_glyph_face (f
, FAST_GLYPH_FACE (glyph
), cface
);
2761 glyph
= FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph
), cface
);
2767 /* Display one line of window W, starting at position START in W's buffer.
2769 Display starting at horizontal position HPOS, expressed relative to
2770 W's left edge. In situations where the text at START shouldn't
2771 start at the left margin (i.e. when the window is hscrolled, or
2772 we're continuing a line which left off in the midst of a
2773 multi-column character), HPOS should be negative; we throw away
2774 characters up 'til hpos = 0. So, HPOS must take hscrolling into
2777 TABOFFSET is an offset for ostensible hpos, used in tab stop calculations.
2779 OVSTR_DONE is the number of chars of overlay before/after strings
2780 at this position which have already been processed.
2782 Display on position VPOS on the frame. It is origin 0, relative to
2783 the top of the frame, not W.
2785 Returns a STRUCT POSITION giving character to start next line with
2786 and where to display it, including a zero or negative hpos.
2787 The vpos field is not really a vpos; it is 1 unless the line is continued */
2789 struct position val_display_text_line
;
2791 static struct position
*
2792 display_text_line (w
, start
, vpos
, hpos
, taboffset
, ovstr_done
)
2800 register int pos
= start
;
2804 register unsigned char *p
;
2806 register GLYPH
*leftmargin
;
2807 register GLYPH
*p1prev
;
2808 register GLYPH
*p1start
;
2811 FRAME_PTR f
= XFRAME (w
->frame
);
2812 int tab_width
= XINT (current_buffer
->tab_width
);
2813 int ctl_arrow
= !NILP (current_buffer
->ctl_arrow
);
2814 int width
= window_internal_width (w
) - 1;
2815 struct position val
;
2818 int last_invis_skip
= 0;
2819 Lisp_Object last_invis_prop
;
2820 int hscroll
= XINT (w
->hscroll
);
2821 int truncate
= (hscroll
2822 || (truncate_partial_width_windows
2823 && !WINDOW_FULL_WIDTH_P (w
))
2824 || !NILP (current_buffer
->truncate_lines
));
2826 /* 1 if we should highlight the region. */
2827 int highlight_region
2828 = (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
)
2829 && (XWINDOW (current_buffer
->last_selected_window
) == w
2830 || highlight_nonselected_windows
));
2831 int region_beg
, region_end
;
2833 int selective
= (INTEGERP (current_buffer
->selective_display
)
2834 ? XINT (current_buffer
->selective_display
)
2835 : !NILP (current_buffer
->selective_display
) ? -1 : 0);
2836 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (f
);
2837 register struct Lisp_Char_Table
*dp
= window_display_table (w
);
2839 Lisp_Object default_invis_vector
[3];
2840 /* Number of characters of ellipsis to display after an invisible line
2841 if it calls for an ellipsis.
2842 Note that this value can be nonzero regardless of whether
2843 selective display is enabled--you must check that separately. */
2845 = (dp
&& VECTORP (DISP_INVIS_VECTOR (dp
))
2846 ? XVECTOR (DISP_INVIS_VECTOR (dp
))->size
2847 : !NILP (current_buffer
->selective_display_ellipses
) ? 3 : 0);
2848 /* This is the sequence of Lisp objects to display
2849 when there are invisible lines. */
2850 Lisp_Object
*invis_vector_contents
2851 = (dp
&& VECTORP (DISP_INVIS_VECTOR (dp
))
2852 ? XVECTOR (DISP_INVIS_VECTOR (dp
))->contents
2853 : default_invis_vector
);
2855 GLYPH truncator
= (dp
== 0 || !INTEGERP (DISP_TRUNC_GLYPH (dp
))
2856 || !GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (dp
)))
2857 ? '$' : XINT (DISP_TRUNC_GLYPH (dp
)));
2858 GLYPH continuer
= (dp
== 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp
))
2859 || !GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (dp
)))
2860 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp
)));
2862 /* If 1, we must handle multibyte characters. */
2863 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
2864 /* Length of multibyte form of each character. */
2866 /* Glyphs generated should be set this bit mask if text must be
2867 displayed from right to left. */
2868 GLYPH rev_dir_bit
= (NILP (current_buffer
->direction_reversed
)
2869 ? 0 : GLYPH_MASK_REV_DIR
);
2871 /* The next buffer location at which the face should change, due
2872 to overlays or text property changes. */
2873 int next_face_change
;
2875 /* The next location where the `invisible' property changes, or an
2876 overlay starts or ends. */
2879 /* The face we're currently using. */
2880 int current_face
= 0;
2883 XSETFASTINT (default_invis_vector
[2], '.');
2884 default_invis_vector
[0] = default_invis_vector
[1] = default_invis_vector
[2];
2886 hpos
+= WINDOW_LEFT_MARGIN (w
);
2887 get_display_line (f
, vpos
, WINDOW_LEFT_MARGIN (w
));
2888 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
2890 /* Show where to highlight the region. */
2891 if (highlight_region
&& XMARKER (current_buffer
->mark
)->buffer
!= 0
2892 /* Maybe highlight only in selected window. */
2893 && (highlight_nonselected_windows
2894 || w
== XWINDOW (selected_window
)))
2896 region_beg
= marker_position (current_buffer
->mark
);
2897 if (PT
< region_beg
)
2899 region_end
= region_beg
;
2904 w
->region_showing
= Qt
;
2908 region_beg
= region_end
= -1;
2909 w
->region_showing
= Qnil
;
2912 if (MINI_WINDOW_P (w
)
2914 && vpos
== XFASTINT (w
->top
))
2916 if (! NILP (minibuf_prompt
))
2918 minibuf_prompt_width
2919 = (display_string (w
, vpos
, XSTRING (minibuf_prompt
)->data
,
2920 XSTRING (minibuf_prompt
)->size
, hpos
,
2921 /* Display a space if we truncate. */
2924 /* Truncate the prompt a little before the
2925 margin, so user input can at least start
2926 on the first line. */
2927 (XFASTINT (w
->width
) > 10
2928 ? XFASTINT (w
->width
) - 4 : -1))
2930 hpos
+= minibuf_prompt_width
;
2931 taboffset
-= minibuf_prompt_width
;
2934 minibuf_prompt_width
= 0;
2937 /* If we're hscrolled at all, use compute_motion to skip over any
2938 text off the left edge of the window. compute_motion may know
2939 tricks to do this faster than we can. */
2942 struct position
*left_edge
2943 = compute_motion (pos
, vpos
, hpos
, 0,
2945 width
, hscroll
, taboffset
, w
);
2947 /* Retrieve the buffer position and column provided by
2948 compute_motion. We can't assume that the column will be
2949 zero, because you may have multi-column characters crossing
2952 compute_motion may have moved us past the screen position we
2953 requested, if we hit a multi-column character, or the end of
2954 the line. If so, back up. */
2955 if (left_edge
->vpos
> vpos
2956 || left_edge
->hpos
> 0)
2958 pos
= left_edge
->bufpos
;
2959 /* Since this should not be a valid multibyte character, we
2960 can decrease POS by 1. */
2962 hpos
= left_edge
->prevhpos
;
2966 pos
= left_edge
->bufpos
;
2967 hpos
= left_edge
->hpos
;
2971 desired_glyphs
->bufp
[vpos
] = start
;
2972 p1
= desired_glyphs
->glyphs
[vpos
] + hpos
;
2974 charstart
= desired_glyphs
->charstarts
[vpos
] + hpos
;
2975 /* In case we don't ever write anything into it... */
2976 desired_glyphs
->charstarts
[vpos
][WINDOW_LEFT_MARGIN (w
)] = -1;
2977 leftmargin
= desired_glyphs
->glyphs
[vpos
] + WINDOW_LEFT_MARGIN (w
);
2978 endp
= leftmargin
+ width
;
2980 /* Arrange the overlays nicely for our purposes. Usually, we call
2981 display_text_line on only one line at a time, in which case this
2982 can't really hurt too much, or we call it on lines which appear
2983 one after another in the buffer, in which case all calls to
2984 recenter_overlay_lists but the first will be pretty cheap. */
2985 recenter_overlay_lists (current_buffer
, pos
);
2987 /* Loop generating characters.
2988 Stop at end of buffer, before newline,
2989 if reach or pass continuation column,
2990 or at face change. */
2992 next_face_change
= pos
;
2993 next_boundary
= pos
;
3002 while (pos
== next_boundary
)
3004 Lisp_Object position
, limit
, prop
, ww
;
3006 /* Display the overlay strings here, unless we're at ZV
3007 and have already displayed the appropriate strings
3008 on an earlier line. */
3009 if (pos
< ZV
|| !zv_strings_seen
++)
3012 unsigned char *ovstr
;
3013 ovlen
= overlay_strings (pos
, w
, &ovstr
);
3017 /* Skip the ones we did in a previous line. */
3018 ovstr
+= ovstr_done
;
3019 ovlen
-= ovstr_done
;
3028 c
= STRING_CHAR_AND_LENGTH (ovstr
, ovlen
, len
);
3029 ovstr
+= len
, ovlen
-= len
, ovstr_done
+= len
;
3030 charset
= CHAR_CHARSET (c
);
3031 cols
= (charset
== CHARSET_COMPOSITION
3032 ? cmpchar_table
[COMPOSITE_CHAR_ID (c
)]->width
3033 : CHARSET_WIDTH (charset
));
3037 c
= *ovstr
++, ovlen
--, ovstr_done
++;
3040 g
= MAKE_GLYPH (f
, c
, current_face
) | rev_dir_bit
;
3043 if (p1
>= leftmargin
&& p1
< endp
)
3044 *p1
= g
, g
|= GLYPH_MASK_PADDING
;
3048 /* If we did all the overlay strings
3049 and we have room for text, clear ovstr_done
3050 just for neatness' sake. */
3051 if (ovlen
== 0 && p1
< endp
)
3056 /* Did we reach point? Record the cursor location. */
3057 if (pos
== PT
&& cursor_vpos
< 0)
3060 cursor_hpos
= p1
- leftmargin
;
3066 XSETFASTINT (position
, pos
);
3067 limit
= Fnext_overlay_change (position
);
3068 #ifdef USE_TEXT_PROPERTIES
3069 /* This is just an estimate to give reasonable
3070 performance; nothing should go wrong if it is too small. */
3071 if (XFASTINT (limit
) > pos
+ 50)
3073 int limitpos
= pos
+ 50;
3075 INC_POS (limitpos
); /* Adjust to character boundary. */
3076 XSETFASTINT (limit
, limitpos
);
3078 limit
= Fnext_single_property_change (position
, Qinvisible
,
3079 Fcurrent_buffer (), limit
);
3081 next_boundary
= XFASTINT (limit
);
3082 /* if the `invisible' property is set, we can skip to
3083 the next property change. */
3085 prop
= Fget_char_property (position
, Qinvisible
, ww
);
3086 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
3088 if (pos
< PT
&& next_boundary
>= PT
)
3091 cursor_hpos
= p1
- leftmargin
;
3093 pos
= next_boundary
;
3094 last_invis_skip
= pos
;
3095 last_invis_prop
= prop
;
3099 /* Did we reach point? Record the cursor location. */
3100 if (pos
== PT
&& cursor_vpos
< 0)
3103 cursor_hpos
= p1
- leftmargin
;
3106 /* Did we hit the end of the visible region of the buffer?
3110 /* Update charstarts for the end of this line. */
3111 /* Do nothing if off the left edge or at the right edge. */
3112 if (p1
>= leftmargin
&& p1
+ 1 != endp
)
3114 int *p2x
= &charstart
[(p1
< leftmargin
3122 /* Figure out where (if at all) the
3123 redisplay_end_trigger-hook should run. */
3124 if (MARKERP (w
->redisplay_end_trigger
)
3125 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
3126 e_t_h
= marker_position (w
->redisplay_end_trigger
);
3127 else if (INTEGERP (w
->redisplay_end_trigger
))
3128 e_t_h
= XINT (w
->redisplay_end_trigger
);
3132 /* If we've gone past the place to run a hook,
3134 if (pos
>= e_t_h
&& e_t_h
!= ZV
)
3136 Lisp_Object args
[3];
3138 args
[0] = Qredisplay_end_trigger_functions
;
3139 XSETWINDOW (args
[1], w
);
3140 XSETINT (args
[2], e_t_h
);
3142 /* Since we are *trying* to run these functions,
3143 don't try to run them again, even if they get an error. */
3144 w
->redisplay_end_trigger
= Qnil
;
3145 Frun_hook_with_args (3, args
);
3148 /* Notice if it changed the face of this character. */
3149 next_face_change
= pos
;
3153 /* Did we hit a face change? Figure out what face we should
3154 use now. We also hit this the first time through the
3155 loop, to see what face we should start with. */
3156 if (pos
>= next_face_change
3157 && (FRAME_WINDOW_P (f
) || FRAME_MSDOS_P (f
)))
3159 int limit
= pos
+ 50;
3161 if (limit
< Z
&& !CHAR_HEAD_P (POS_ADDR (limit
)))
3162 INC_POS (limit
); /* Adjust to character boundary. */
3163 current_face
= compute_char_face (f
, w
, pos
,
3164 region_beg
, region_end
,
3165 &next_face_change
, limit
, 0);
3169 /* Compute the next place we need to stop
3170 and do something special; set PAUSE. */
3174 if (pos
< next_boundary
&& next_boundary
< pause
)
3175 pause
= next_boundary
;
3176 if (pos
< next_face_change
&& next_face_change
< pause
)
3177 pause
= next_face_change
;
3182 /* Wouldn't you hate to read the next line to someone over
3184 if (pos
< PT
&& PT
< pause
)
3186 if (pos
< GPT
&& GPT
< pause
)
3198 /* PAUSE is surely at character boundary. */
3199 c
= STRING_CHAR_AND_LENGTH (p
, pause
- pos
, len
), p
+= len
;
3202 /* Let a display table override all standard display methods. */
3203 if (dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
3205 p1
= copy_part_of_rope (f
, p1
, leftmargin
,
3206 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->contents
,
3207 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->size
,
3208 current_face
, rev_dir_bit
);
3210 else if (c
>= 040 && c
< 0177)
3212 if (p1
>= leftmargin
)
3213 *p1
= MAKE_GLYPH (f
, c
, current_face
) | rev_dir_bit
;
3219 /* Same as p1prev, but after the invis_vector_contents text
3220 (if we have that on this line). */
3221 GLYPH
*p1prev_modified
;
3225 if (last_invis_skip
== pos
3226 && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop
))
3230 && indented_beyond_p (pos
+ 1, selective
))
3233 pos
= find_next_newline (pos
+ 1, 1);
3234 if (FETCH_BYTE (pos
- 1) == '\n')
3237 if (invis
&& selective_rlen
> 0 && p1
>= leftmargin
)
3242 cs
= charstart
+ (p1
- p1start
);
3245 p1
+= selective_rlen
;
3246 if (p1
- leftmargin
> width
)
3249 #if 0 /* This needs more work; charstarts needs to record
3250 both whether a position ho;ds an ellipsis character
3251 and what buffer position it corresponds to. */
3252 csend
= charstart
+ (p1
- p1start
);
3255 /* The idea is to use p1prev_modified instead of p1prev
3256 in the loop below over p2x. */
3257 p1prev_modified
= p1
;
3260 copy_part_of_rope (f
, p1prev
, p1prev
, invis_vector_contents
,
3261 (p1
- p1prev
), current_face
, rev_dir_bit
);
3264 /* Update charstarts for the newline that ended this line. */
3265 /* Do nothing here for a char that's entirely off the left edge
3266 or if it starts at the right edge. */
3267 if (p1
>= leftmargin
&& p1prev
!= endp
)
3269 /* Store the newline's position into charstarts
3270 for the column where the newline starts.
3271 Store -1 for the rest of the glyphs it occupies. */
3272 int *p2x
= &charstart
[(p1prev
< leftmargin
3273 ? leftmargin
: p1prev
)
3275 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
3282 /* Draw the face of the newline character as extending all the
3283 way to the end of the frame line. */
3286 if (p1
< leftmargin
)
3289 *p1
++ = FAST_MAKE_GLYPH (' ', current_face
) | rev_dir_bit
;
3299 if (p1
>= leftmargin
&& p1
< endp
)
3300 *p1
= MAKE_GLYPH (f
, ' ', current_face
) | rev_dir_bit
;
3303 while ((p1
- leftmargin
+ taboffset
+ hscroll
- (hscroll
> 0))
3306 else if (c
== Ctl ('M') && selective
== -1)
3308 pos
= find_next_newline (pos
, 1);
3309 if (FETCH_BYTE (pos
- 1) == '\n')
3311 if (selective_rlen
> 0)
3313 p1
+= selective_rlen
;
3314 if (p1
- leftmargin
> width
)
3316 copy_part_of_rope (f
, p1prev
, p1prev
, invis_vector_contents
,
3317 (p1
- p1prev
), current_face
, rev_dir_bit
);
3320 /* Draw the face of the newline character as extending all the
3321 way to the end of the frame line. */
3324 if (p1
< leftmargin
)
3327 *p1
++ = FAST_MAKE_GLYPH (' ', current_face
) | rev_dir_bit
;
3331 /* Update charstarts for the ^M that ended this line. */
3332 /* Do nothing here for a char that's entirely off the left edge
3333 or if it starts at the right edge. */
3334 if (p1
>= leftmargin
&& p1prev
!= endp
)
3336 /* Store the newline's position into charstarts
3337 for the column where the newline starts.
3338 Store -1 for the rest of the glyphs it occupies. */
3339 int *p2x
= &charstart
[(p1prev
< leftmargin
3340 ? leftmargin
: p1prev
)
3342 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
3350 else if (c
< 0200 && ctl_arrow
)
3352 if (p1
>= leftmargin
)
3354 (f
, (dp
&& INTEGERP (DISP_CTRL_GLYPH (dp
))
3355 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (dp
)))
3356 ? XINT (DISP_CTRL_GLYPH (dp
)) : '^'),
3360 if (p1
>= leftmargin
&& p1
< endp
)
3361 *p1
= MAKE_GLYPH (f
, c
^ 0100, current_face
) | rev_dir_bit
;
3366 /* C is not a multibyte character. */
3367 if (p1
>= leftmargin
)
3369 (f
, (dp
&& INTEGERP (DISP_ESCAPE_GLYPH (dp
))
3370 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp
)))
3371 ? XINT (DISP_ESCAPE_GLYPH (dp
)) : '\\'),
3375 if (p1
>= leftmargin
&& p1
< endp
)
3376 *p1
= MAKE_GLYPH (f
, (c
>> 6) + '0', current_face
) | rev_dir_bit
;
3378 if (p1
>= leftmargin
&& p1
< endp
)
3379 *p1
= (MAKE_GLYPH (f
, (7 & (c
>> 3)) + '0', current_face
)
3382 if (p1
>= leftmargin
&& p1
< endp
)
3383 *p1
= MAKE_GLYPH (f
, (7 & c
) + '0', current_face
) | rev_dir_bit
;
3388 /* C is a multibyte character. */
3389 int charset
= CHAR_CHARSET (c
);
3390 int columns
= (charset
== CHARSET_COMPOSITION
3391 ? cmpchar_table
[COMPOSITE_CHAR_ID (c
)]->width
3392 : CHARSET_WIDTH (charset
));
3393 GLYPH g
= MAKE_GLYPH (f
, c
, current_face
) | rev_dir_bit
;
3397 if (p1
>= leftmargin
&& p1
< endp
)
3398 *p1
= g
, g
|= GLYPH_MASK_PADDING
;
3406 /* Update charstarts for the character just output. */
3408 /* Do nothing here for a char that's entirely off the left edge. */
3409 if (p1
>= leftmargin
)
3411 /* Store the char's position into charstarts
3412 for the first glyph occupied by this char.
3413 Store -1 for the rest of the glyphs it occupies. */
3416 int *p2x
= &charstart
[(p1prev
< leftmargin
3417 ? leftmargin
: p1prev
)
3419 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
3429 val
.hpos
= - XINT (w
->hscroll
);
3437 /* Store 0 in this charstart line for the positions where
3438 there is no character. But do leave what was recorded
3439 for the character that ended the line. */
3440 /* Add 1 in the endtest to compensate for the fact that ENDP was
3441 made from WIDTH, which is 1 less than the window's actual
3443 i
= p1
- p1start
+ 1;
3444 if (p1
< leftmargin
)
3445 i
+= leftmargin
- p1
;
3446 for (; i
< endp
- p1start
+ 1; i
++)
3449 /* Handle continuation in middle of a character */
3450 /* by backing up over it */
3453 /* Don't back up if we never actually displayed any text.
3454 This occurs when the minibuffer prompt takes up the whole line. */
3457 /* Start the next line with that same character whose
3458 character code is C and the length of multi-byte form is
3463 /* C is not a multi-byte character. We can break it and
3464 start from the middle column in the next line. So,
3465 adjust VAL.HPOS to skip the columns output on this
3467 val
.hpos
+= p1prev
- endp
;
3470 /* C is a multibyte character. Since we can't broke it
3471 in the middle, the whole character should be driven
3472 into the next line. */
3473 /* As the result, the actual columns occupied by the
3474 text on this line is less than WIDTH. VAL.TAB_OFFSET
3475 must be adjusted. */
3476 taboffset
= taboffset
+ (p1prev
- endp
);
3477 /* Let's fill unused columns with TRUNCATOR or CONTINUER. */
3479 GLYPH g
= fix_glyph (f
, truncate
? truncator
: continuer
, 0);
3480 while (p1prev
< endp
)
3483 /* If POINT is at POS, cursor should not on this line. */
3490 /* Keep in this line everything up to the continuation column. */
3494 /* Finish deciding which character to start the next line on,
3495 and what hpos to start it at.
3496 Also set `lastpos' to the last position which counts as "on this line"
3497 for cursor-positioning. */
3501 if (FETCH_BYTE (pos
) == '\n')
3503 /* If stopped due to a newline, start next line after it */
3506 /* Check again for hidden lines, in case the newline occurred exactly
3507 at the right margin. */
3508 while (pos
< ZV
&& selective
> 0
3509 && indented_beyond_p (pos
, selective
))
3510 pos
= find_next_newline (pos
, 1);
3513 /* Stopped due to right margin of window */
3517 *p1
++ = fix_glyph (f
, truncator
, 0);
3518 /* Truncating => start next line after next newline,
3519 and point is on this line if it is before the newline,
3520 and skip none of first char of next line */
3522 pos
= find_next_newline (pos
, 1);
3523 while (pos
< ZV
&& selective
> 0
3524 && indented_beyond_p (pos
, selective
));
3525 val
.hpos
= XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0;
3527 lastpos
= pos
- (FETCH_BYTE (pos
- 1) == '\n');
3532 *p1
++ = fix_glyph (f
, continuer
, 0);
3535 val
.tab_offset
= taboffset
+ width
;
3542 /* If point is at eol or in invisible text at eol,
3543 record its frame location now. */
3545 if (start
<= PT
&& PT
<= lastpos
&& cursor_vpos
< 0)
3548 cursor_hpos
= p1
- leftmargin
;
3551 if (cursor_vpos
== vpos
)
3553 if (cursor_hpos
< 0) cursor_hpos
= 0;
3554 if (cursor_hpos
> width
) cursor_hpos
= width
;
3555 cursor_hpos
+= WINDOW_LEFT_MARGIN (w
);
3556 if (w
== XWINDOW (FRAME_SELECTED_WINDOW (f
)))
3558 if (!(cursor_in_echo_area
&& FRAME_HAS_MINIBUF_P (f
)
3559 && EQ (FRAME_MINIBUF_WINDOW (f
), minibuf_window
)))
3561 FRAME_CURSOR_Y (f
) = cursor_vpos
;
3562 FRAME_CURSOR_X (f
) = cursor_hpos
;
3565 if (w
== XWINDOW (selected_window
))
3567 /* Line is not continued and did not start
3568 in middle of character */
3569 if ((hpos
- WINDOW_LEFT_MARGIN (w
)
3570 == (XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0))
3573 this_line_bufpos
= start
;
3574 this_line_buffer
= current_buffer
;
3575 this_line_vpos
= cursor_vpos
;
3576 this_line_start_hpos
= hpos
;
3577 this_line_endpos
= Z
- lastpos
;
3580 this_line_bufpos
= 0;
3585 /* If hscroll and line not empty, insert truncation-at-left marker */
3586 if (hscroll
&& lastpos
!= start
)
3588 GLYPH g
= fix_glyph (f
, truncator
, 0);
3590 if (p1
<= leftmargin
)
3591 p1
= leftmargin
+ 1;
3592 else /* MULE: it may be a wide-column character */
3594 p1prev
= leftmargin
+ 1;
3595 while (p1prev
< p1
&& *p1prev
& GLYPH_MASK_PADDING
)
3600 if (!WINDOW_RIGHTMOST_P (w
))
3603 if (p1
< leftmargin
) p1
= leftmargin
;
3604 while (p1
< endp
) *p1
++ = SPACEGLYPH
;
3606 /* Don't draw vertical bars if we're using scroll bars. They're
3607 covered up by the scroll bars, and it's distracting to see
3608 them when the scroll bar windows are flickering around to be
3610 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
3613 for (i
= 0; i
< FRAME_SCROLL_BAR_COLS (f
); i
++)
3616 else if (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3617 *p1
++ = (dp
&& INTEGERP (DISP_BORDER_GLYPH (dp
))
3618 ? XINT (DISP_BORDER_GLYPH (dp
))
3621 desired_glyphs
->used
[vpos
] = max (desired_glyphs
->used
[vpos
],
3622 p1
- desired_glyphs
->glyphs
[vpos
]);
3623 desired_glyphs
->glyphs
[vpos
][desired_glyphs
->used
[vpos
]] = 0;
3625 /* If the start of this line is the overlay arrow-position,
3626 then put the arrow string into the display-line. */
3628 if (MARKERP (Voverlay_arrow_position
)
3629 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
3630 && start
== marker_position (Voverlay_arrow_position
)
3631 && STRINGP (Voverlay_arrow_string
)
3632 && ! overlay_arrow_seen
)
3634 unsigned char *p
= XSTRING (Voverlay_arrow_string
)->data
;
3636 int len
= XSTRING (Voverlay_arrow_string
)->size
;
3642 if (!NULL_INTERVAL_P (XSTRING (Voverlay_arrow_string
)->intervals
))
3644 /* If the arrow string has text props, obey them when displaying. */
3645 for (i
= 0; i
< len
; i
++)
3648 Lisp_Object face
, ilisp
;
3651 XSETFASTINT (ilisp
, i
);
3652 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
3653 newface
= compute_glyph_face_1 (f
, face
, 0);
3654 leftmargin
[i
] = FAST_MAKE_GLYPH (c
, newface
);
3658 #endif /* HAVE_FACES */
3660 for (i
= 0; i
< len
; i
++)
3661 leftmargin
[i
] = p
[i
];
3664 /* Bug in SunOS 4.1.1 compiler requires this intermediate variable. */
3665 arrow_end
= (leftmargin
- desired_glyphs
->glyphs
[vpos
]) + len
;
3666 if (desired_glyphs
->used
[vpos
] < arrow_end
)
3667 desired_glyphs
->used
[vpos
] = arrow_end
;
3669 overlay_arrow_seen
= 1;
3673 val
.ovstring_chars_done
= ovstr_done
;
3674 val_display_text_line
= val
;
3675 return &val_display_text_line
;
3678 /* Redisplay the menu bar in the frame for window W. */
3681 display_menu_bar (w
)
3684 Lisp_Object items
, tail
;
3685 register int vpos
= 0;
3686 register FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
3687 int maxendcol
= FRAME_WIDTH (f
);
3692 if (!NILP (Vwindow_system
))
3696 #ifdef USE_X_TOOLKIT
3699 #endif /* USE_X_TOOLKIT */
3701 get_display_line (f
, vpos
, 0);
3703 items
= FRAME_MENU_BAR_ITEMS (f
);
3704 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
3706 Lisp_Object pos
, string
;
3707 string
= XVECTOR (items
)->contents
[i
+ 1];
3711 XSETFASTINT (XVECTOR (items
)->contents
[i
+ 3], hpos
);
3713 if (hpos
< maxendcol
)
3714 hpos
= display_string (w
, vpos
,
3715 XSTRING (string
)->data
,
3716 XSTRING (string
)->size
,
3717 hpos
, 0, 0, hpos
, maxendcol
);
3718 /* Put a space between items. */
3719 if (hpos
< maxendcol
)
3721 int hpos1
= hpos
+ 1;
3722 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 0,
3723 min (hpos1
, maxendcol
), maxendcol
);
3727 FRAME_DESIRED_GLYPHS (f
)->bufp
[vpos
] = 0;
3728 FRAME_DESIRED_GLYPHS (f
)->highlight
[vpos
] = mode_line_inverse_video
;
3730 /* Fill out the line with spaces. */
3731 if (maxendcol
> hpos
)
3732 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 0, maxendcol
, maxendcol
);
3734 /* Clear the rest of the lines allocated to the menu bar. */
3736 while (vpos
< FRAME_MENU_BAR_LINES (f
))
3737 get_display_line (f
, vpos
++, 0);
3740 /* Display the mode line for window w */
3743 display_mode_line (w
)
3746 register int vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
3747 register int left
= WINDOW_LEFT_MARGIN (w
);
3748 register int right
= WINDOW_RIGHT_MARGIN (w
);
3749 register FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
3751 line_number_displayed
= 0;
3752 w
->column_number_displayed
= Qnil
;
3754 get_display_line (f
, vpos
, left
);
3756 /* Temporarily make frame F's kboard the current kboard
3757 so that kboard-local variables in the mode_line_format
3758 will get the right values. */
3759 push_frame_kboard (f
);
3761 display_mode_element (w
, vpos
, left
, 0, right
, right
,
3762 current_buffer
->mode_line_format
);
3764 pop_frame_kboard ();
3766 FRAME_DESIRED_GLYPHS (f
)->bufp
[vpos
] = 0;
3768 /* Put the mode line in inverse video.
3769 Use faces if possible, since that lets us handle
3770 partial-width windows and avoid inverting the scroll bar columns. */
3772 if (! FRAME_TERMCAP_P (f
) && mode_line_inverse_video
)
3774 /* For a partial width window, explicitly set face of each glyph. */
3776 unsigned int padding
;
3777 GLYPH
*ptr
= FRAME_DESIRED_GLYPHS (f
)->glyphs
[vpos
];
3778 for (i
= left
; i
< right
; ++i
)
3780 padding
= ptr
[i
] & GLYPH_MASK_PADDING
;
3781 ptr
[i
] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr
[i
]), 1) | padding
;
3787 /* Make the mode line inverse video if the entire line
3788 is made of mode lines.
3789 I.e. if this window is full width,
3790 or if it is the child of a full width window
3791 (which implies that that window is split side-by-side
3792 and the rest of this line is mode lines of the sibling windows). */
3793 if (WINDOW_FULL_WIDTH_P (w
)
3794 || WINDOW_FULL_WIDTH_P (XWINDOW (w
->parent
)))
3795 FRAME_DESIRED_GLYPHS (f
)->highlight
[vpos
] = mode_line_inverse_video
;
3798 /* Contribute ELT to the mode line for window W.
3799 How it translates into text depends on its data type.
3801 VPOS is the position of the mode line being displayed.
3803 HPOS is the position (absolute on frame) where this element's text
3804 should start. The output is truncated automatically at the right
3807 DEPTH is the depth in recursion. It is used to prevent
3808 infinite recursion here.
3810 MINENDCOL is the hpos before which the element may not end.
3811 The element is padded at the right with spaces if nec
3812 to reach this column.
3814 MAXENDCOL is the hpos past which this element may not extend.
3815 If MINENDCOL is > MAXENDCOL, MINENDCOL takes priority.
3816 (This is necessary to make nested padding and truncation work.)
3818 Returns the hpos of the end of the text generated by ELT.
3819 The next element will receive that value as its HPOS arg,
3820 so as to concatenate the elements. */
3823 display_mode_element (w
, vpos
, hpos
, depth
, minendcol
, maxendcol
, elt
)
3825 register int vpos
, hpos
;
3828 register int maxendcol
;
3829 register Lisp_Object elt
;
3837 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
3841 /* A string: output it and check for %-constructs within it. */
3842 register unsigned char c
;
3843 register unsigned char *this = XSTRING (elt
)->data
;
3845 while (hpos
< maxendcol
&& *this)
3847 unsigned char *last
= this;
3848 while ((c
= *this++) != '\0' && c
!= '%')
3850 if (this - 1 != last
)
3852 register int lim
= --this - last
+ hpos
;
3853 if (frame_title_ptr
)
3854 hpos
= store_frame_title (last
, hpos
, min (lim
, maxendcol
));
3856 hpos
= display_string (w
, vpos
, last
, -1, hpos
, 0, 1,
3857 hpos
, min (lim
, maxendcol
));
3861 register int minendcol
;
3862 register int spec_width
= 0;
3864 /* We can't allow -ve args due to the "%-" construct */
3865 /* Argument specifies minwidth but not maxwidth
3866 (maxwidth can be specified by
3867 (<negative-number> . <stuff>) mode-line elements) */
3869 while ((c
= *this++) >= '0' && c
<= '9')
3871 spec_width
= spec_width
* 10 + (c
- '0');
3874 minendcol
= hpos
+ spec_width
;
3875 if (minendcol
> maxendcol
)
3877 spec_width
= maxendcol
- hpos
;
3878 minendcol
= maxendcol
;
3882 hpos
= display_mode_element (w
, vpos
, hpos
, depth
,
3883 spec_width
, maxendcol
,
3884 Vglobal_mode_string
);
3887 char *spec
= decode_mode_spec (w
, c
, spec_width
,
3889 if (frame_title_ptr
)
3890 hpos
= store_frame_title (spec
, minendcol
, maxendcol
);
3892 hpos
= display_string (w
, vpos
, spec
, -1,
3894 minendcol
, maxendcol
);
3902 /* A symbol: process the value of the symbol recursively
3903 as if it appeared here directly. Avoid error if symbol void.
3904 Special case: if value of symbol is a string, output the string
3907 register Lisp_Object tem
;
3908 tem
= Fboundp (elt
);
3911 tem
= Fsymbol_value (elt
);
3912 /* If value is a string, output that string literally:
3913 don't check for % within it. */
3916 if (frame_title_ptr
)
3917 hpos
= store_frame_title (XSTRING (tem
)->data
,
3918 minendcol
, maxendcol
);
3920 hpos
= display_string (w
, vpos
, XSTRING (tem
)->data
,
3921 XSTRING (tem
)->size
,
3922 hpos
, 0, 1, minendcol
, maxendcol
);
3924 /* Give up right away for nil or t. */
3925 else if (!EQ (tem
, elt
))
3926 { elt
= tem
; goto tail_recurse
; }
3933 register Lisp_Object car
, tem
;
3935 /* A cons cell: three distinct cases.
3936 If first element is a string or a cons, process all the elements
3937 and effectively concatenate them.
3938 If first element is a negative number, truncate displaying cdr to
3939 at most that many characters. If positive, pad (with spaces)
3940 to at least that many characters.
3941 If first element is a symbol, process the cadr or caddr recursively
3942 according to whether the symbol's value is non-nil or nil. */
3943 car
= XCONS (elt
)->car
;
3946 tem
= Fboundp (car
);
3947 elt
= XCONS (elt
)->cdr
;
3950 /* elt is now the cdr, and we know it is a cons cell.
3951 Use its car if CAR has a non-nil value. */
3954 tem
= Fsymbol_value (car
);
3956 { elt
= XCONS (elt
)->car
; goto tail_recurse
; }
3958 /* Symbol's value is nil (or symbol is unbound)
3959 Get the cddr of the original list
3960 and if possible find the caddr and use that. */
3961 elt
= XCONS (elt
)->cdr
;
3964 else if (!CONSP (elt
))
3966 elt
= XCONS (elt
)->car
;
3969 else if (INTEGERP (car
))
3971 register int lim
= XINT (car
);
3972 elt
= XCONS (elt
)->cdr
;
3974 /* Negative int means reduce maximum width.
3975 DO NOT change MINENDCOL here!
3976 (20 -10 . foo) should truncate foo to 10 col
3977 and then pad to 20. */
3978 maxendcol
= min (maxendcol
, hpos
- lim
);
3981 /* Padding specified. Don't let it be more than
3984 if (lim
> maxendcol
)
3986 /* If that's more padding than already wanted, queue it.
3987 But don't reduce padding already specified even if
3988 that is beyond the current truncation point. */
3989 if (lim
> minendcol
)
3994 else if (STRINGP (car
) || CONSP (car
))
3996 register int limit
= 50;
3997 /* LIMIT is to protect against circular lists. */
3998 while (CONSP (elt
) && --limit
> 0
3999 && hpos
< maxendcol
)
4001 hpos
= display_mode_element (w
, vpos
, hpos
, depth
,
4004 elt
= XCONS (elt
)->cdr
;
4012 if (frame_title_ptr
)
4013 hpos
= store_frame_title ("*invalid*", minendcol
, maxendcol
);
4015 hpos
= display_string (w
, vpos
, "*invalid*", -1, hpos
, 0, 1,
4016 minendcol
, maxendcol
);
4020 if (minendcol
> hpos
)
4021 if (frame_title_ptr
)
4022 hpos
= store_frame_title ("", minendcol
, maxendcol
);
4024 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 1, minendcol
, maxendcol
);
4028 /* Write a null-terminated, right justified decimal representation of
4029 the positive integer D to BUF using a minimal field width WIDTH. */
4032 pint2str (buf
, width
, d
)
4037 register char *p
= buf
;
4044 *p
++ = d
% 10 + '0';
4047 for (width
-= (int) (p
- buf
); width
> 0; --width
) *p
++ = ' ';
4057 /* Set a mnemonic character for CODING_SYSTEM (Lisp symbol) in BUF.
4058 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
4059 type of CODING_SYSTEM. Return updated pointer into BUF. */
4062 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
4063 Lisp_Object coding_system
;
4069 val
= coding_system
;
4071 if (NILP (val
)) /* Not yet decided. */
4075 *buf
++ = eol_mnemonic_undecided
;
4076 /* Don't mention EOL conversion if it isn't decided. */
4080 Lisp_Object eolvalue
;
4082 eolvalue
= Fget (coding_system
, Qeol_type
);
4084 while (!NILP (val
) && SYMBOLP (val
))
4086 val
= Fget (val
, Qcoding_system
);
4087 if (NILP (eolvalue
))
4088 eolvalue
= Fget (coding_system
, Qeol_type
);
4091 *buf
++ = XFASTINT (XVECTOR (val
)->contents
[1]);
4094 /* The EOL conversion we are using. */
4096 /* The EOL conversion that is normal on this system. */
4098 if (NILP (eolvalue
)) /* Not yet decided. */
4099 eoltype
= eol_mnemonic_undecided
;
4100 else if (VECTORP (eolvalue
)) /* Not yet decided. */
4101 eoltype
= eol_mnemonic_undecided
;
4102 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
4103 eoltype
= (XFASTINT (eolvalue
) == 0
4105 : (XFASTINT (eolvalue
) == 1
4106 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
4108 /* Mention the EOL conversion if it is not the usual one. */
4115 /* Return a string for the output of a mode line %-spec for window W,
4116 generated by character C. SPEC_WIDTH is the field width when
4117 padding to the left (%c, %l). The value returned from this
4118 function will later be truncated to width MAXWIDTH. */
4120 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
4123 decode_mode_spec (w
, c
, spec_width
, maxwidth
)
4126 register int spec_width
;
4127 register int maxwidth
;
4130 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
4131 char *decode_mode_spec_buf
= (char *) FRAME_TEMP_GLYPHS (f
)->total_contents
;
4132 struct buffer
*b
= XBUFFER (w
->buffer
);
4135 if (maxwidth
> FRAME_WIDTH (f
))
4136 maxwidth
= FRAME_WIDTH (f
);
4141 if (!NILP (b
->read_only
))
4143 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
4148 /* This differs from %* only for a modified read-only buffer. */
4149 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
4151 if (!NILP (b
->read_only
))
4156 /* This differs from %* in ignoring read-only-ness. */
4157 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
4169 if (command_loop_level
> 5)
4171 p
= decode_mode_spec_buf
;
4172 for (i
= 0; i
< command_loop_level
; i
++)
4175 return decode_mode_spec_buf
;
4183 if (command_loop_level
> 5)
4185 p
= decode_mode_spec_buf
;
4186 for (i
= 0; i
< command_loop_level
; i
++)
4189 return decode_mode_spec_buf
;
4197 if (maxwidth
< sizeof (lots_of_dashes
))
4198 return lots_of_dashes
;
4201 for (p
= decode_mode_spec_buf
, i
= maxwidth
; i
> 0; i
--)
4205 return decode_mode_spec_buf
;
4211 if (maxwidth
>= 3 && XSTRING (obj
)->size
> maxwidth
)
4213 bcopy (XSTRING (obj
)->data
, decode_mode_spec_buf
, maxwidth
- 1);
4214 decode_mode_spec_buf
[maxwidth
- 1] = '\\';
4215 decode_mode_spec_buf
[maxwidth
] = '\0';
4216 return decode_mode_spec_buf
;
4223 int col
= current_column ();
4224 XSETFASTINT (w
->column_number_displayed
, col
);
4225 pint2str (decode_mode_spec_buf
, spec_width
, col
);
4226 return decode_mode_spec_buf
;
4230 /* %F displays the frame name. */
4231 if (!NILP (f
->title
))
4232 return (char *) XSTRING (f
->title
)->data
;
4233 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
4234 return (char *) XSTRING (f
->name
)->data
;
4242 else if (STRINGP (obj
) && XSTRING (obj
)->size
> maxwidth
)
4244 bcopy ("...", decode_mode_spec_buf
, 3);
4245 bcopy (XSTRING (obj
)->data
+ XSTRING (obj
)->size
- maxwidth
+ 3,
4246 decode_mode_spec_buf
+ 3, maxwidth
- 3);
4247 return decode_mode_spec_buf
;
4254 int startpos
= marker_position (w
->start
);
4255 int line
, linepos
, topline
;
4258 int height
= XFASTINT (w
->height
);
4260 /* If we decided that this buffer isn't suitable for line numbers,
4261 don't forget that too fast. */
4262 if (EQ (w
->base_line_pos
, w
->buffer
))
4264 /* But do forget it, if the window shows a different buffer now. */
4265 else if (BUFFERP (w
->base_line_pos
))
4266 w
->base_line_pos
= Qnil
;
4268 /* If the buffer is very big, don't waste time. */
4269 if (BUF_ZV (b
) - BUF_BEGV (b
) > line_number_display_limit
)
4271 w
->base_line_pos
= Qnil
;
4272 w
->base_line_number
= Qnil
;
4276 if (!NILP (w
->base_line_number
)
4277 && !NILP (w
->base_line_pos
)
4278 && XFASTINT (w
->base_line_pos
) <= marker_position (w
->start
))
4280 line
= XFASTINT (w
->base_line_number
);
4281 linepos
= XFASTINT (w
->base_line_pos
);
4286 linepos
= BUF_BEGV (b
);
4289 /* Count lines from base line to window start position. */
4290 nlines
= display_count_lines (linepos
, startpos
, startpos
, &junk
);
4292 topline
= nlines
+ line
;
4294 /* Determine a new base line, if the old one is too close
4295 or too far away, or if we did not have one.
4296 "Too close" means it's plausible a scroll-down would
4298 if (startpos
== BUF_BEGV (b
))
4300 XSETFASTINT (w
->base_line_number
, topline
);
4301 XSETFASTINT (w
->base_line_pos
, BUF_BEGV (b
));
4303 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
4304 || linepos
== BUF_BEGV (b
))
4306 int limit
= BUF_BEGV (b
);
4308 int distance
= (height
* 2 + 30) * 200;
4310 if (startpos
- distance
> limit
)
4311 limit
= startpos
- distance
;
4313 nlines
= display_count_lines (startpos
, limit
,
4316 /* If we couldn't find the lines we wanted within
4318 give up on line numbers for this window. */
4319 if (position
== startpos
- distance
)
4321 w
->base_line_pos
= w
->buffer
;
4322 w
->base_line_number
= Qnil
;
4326 XSETFASTINT (w
->base_line_number
, topline
- nlines
);
4327 XSETFASTINT (w
->base_line_pos
, position
);
4330 /* Now count lines from the start pos to point. */
4331 nlines
= display_count_lines (startpos
, PT
, PT
, &junk
);
4333 /* Record that we did display the line number. */
4334 line_number_displayed
= 1;
4336 /* Make the string to show. */
4337 pint2str (decode_mode_spec_buf
, spec_width
, topline
+ nlines
);
4338 return decode_mode_spec_buf
;
4341 char* p
= decode_mode_spec_buf
;
4342 for (spec_width
-= 2; spec_width
> 0; --spec_width
) *p
++ = ' ';
4344 return decode_mode_spec_buf
;
4354 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
4360 int pos
= marker_position (w
->start
);
4361 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
4363 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
4365 if (pos
<= BUF_BEGV (b
))
4370 else if (pos
<= BUF_BEGV (b
))
4374 if (total
> 1000000)
4375 /* Do it differently for a large value, to avoid overflow. */
4376 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
4378 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
4379 /* We can't normally display a 3-digit number,
4380 so get us a 2-digit number that is close. */
4383 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
4384 return decode_mode_spec_buf
;
4388 /* Display percentage of size above the bottom of the screen. */
4391 int toppos
= marker_position (w
->start
);
4392 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
4393 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
4395 if (botpos
>= BUF_ZV (b
))
4397 if (toppos
<= BUF_BEGV (b
))
4404 if (total
> 1000000)
4405 /* Do it differently for a large value, to avoid overflow. */
4406 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
4408 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
4409 /* We can't normally display a 3-digit number,
4410 so get us a 2-digit number that is close. */
4413 if (toppos
<= BUF_BEGV (b
))
4414 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
4416 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
4417 return decode_mode_spec_buf
;
4422 /* status of process */
4423 obj
= Fget_buffer_process (w
->buffer
);
4425 return "no process";
4427 obj
= Fsymbol_name (Fprocess_status (obj
));
4431 case 't': /* indicate TEXT or BINARY */
4432 #ifdef MODE_LINE_BINARY_TEXT
4433 return MODE_LINE_BINARY_TEXT (b
);
4439 /* coding-system (not including end-of-line format) */
4441 /* coding-system (including end-of-line type) */
4443 int eol_flag
= (c
== 'Z');
4444 char *p
= decode_mode_spec_buf
;
4446 if (FRAME_TERMCAP_P (f
))
4448 /* No need to mention EOL here--the terminal never needs
4449 to do EOL conversion. */
4450 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
4451 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
4453 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
4456 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
4458 obj
= Fget_buffer_process (Fcurrent_buffer ());
4461 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
4463 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
4466 #endif /* subprocesses */
4469 return decode_mode_spec_buf
;
4474 return (char *) XSTRING (obj
)->data
;
4479 /* Search for COUNT instances of a line boundary, which means either a
4480 newline or (if selective display enabled) a carriage return.
4481 Start at START. If COUNT is negative, search backwards.
4483 If we find COUNT instances, set *SHORTAGE to zero, and return the
4484 position after the COUNTth match. Note that for reverse motion
4485 this is not the same as the usual convention for Emacs motion commands.
4487 If we don't find COUNT instances before reaching the end of the
4488 buffer (or the beginning, if scanning backwards), set *SHORTAGE to
4489 the number of line boundaries left unfound, and return the end of the
4490 buffer we bumped up against. */
4493 display_scan_buffer (start
, count
, shortage
)
4494 int *shortage
, start
;
4497 int limit
= ((count
> 0) ? ZV
- 1 : BEGV
);
4498 int direction
= ((count
> 0) ? 1 : -1);
4500 register unsigned char *cursor
;
4501 unsigned char *base
;
4503 register int ceiling
;
4504 register unsigned char *ceiling_addr
;
4506 /* If we are not in selective display mode,
4507 check only for newlines. */
4508 if (! (!NILP (current_buffer
->selective_display
)
4509 && !INTEGERP (current_buffer
->selective_display
)))
4510 return scan_buffer ('\n', start
, 0, count
, shortage
, 0);
4512 /* The code that follows is like scan_buffer
4513 but checks for either newline or carriage return. */
4519 while (start
!= limit
+ 1)
4521 ceiling
= BUFFER_CEILING_OF (start
);
4522 ceiling
= min (limit
, ceiling
);
4523 ceiling_addr
= POS_ADDR (ceiling
) + 1;
4524 base
= (cursor
= POS_ADDR (start
));
4527 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
4529 if (cursor
!= ceiling_addr
)
4534 return (start
+ cursor
- base
+ 1);
4537 if (++cursor
== ceiling_addr
)
4543 start
+= cursor
- base
;
4547 start
--; /* first character we scan */
4548 while (start
> limit
- 1)
4549 { /* we WILL scan under start */
4550 ceiling
= BUFFER_FLOOR_OF (start
);
4551 ceiling
= max (limit
, ceiling
);
4552 ceiling_addr
= POS_ADDR (ceiling
) - 1;
4553 base
= (cursor
= POS_ADDR (start
));
4557 while (--cursor
!= ceiling_addr
4558 && *cursor
!= '\n' && *cursor
!= 015)
4560 if (cursor
!= ceiling_addr
)
4565 return (start
+ cursor
- base
+ 1);
4571 start
+= cursor
- base
;
4576 *shortage
= count
* direction
;
4577 return (start
+ ((direction
== 1 ? 0 : 1)));
4580 /* Count up to N lines starting from FROM.
4581 But don't go beyond LIMIT.
4582 Return the number of lines thus found (always positive).
4583 Store the position after what was found into *POS_PTR. */
4586 display_count_lines (from
, limit
, n
, pos_ptr
)
4599 *pos_ptr
= display_scan_buffer (from
, n
, &shortage
);
4605 /* When scanning backwards, scan_buffer stops *after* the last newline
4606 it finds, but does count it. Compensate for that. */
4607 return - n
- shortage
- (*pos_ptr
!= limit
);
4608 return n
- shortage
;
4611 /* Display STRING on one line of window W, starting at HPOS.
4612 Display at position VPOS. Caller should have done get_display_line.
4613 If VPOS == -1, display it as the current frame's title.
4614 LENGTH is the length of STRING, or -1 meaning STRING is null-terminated.
4616 TRUNCATE is GLYPH to display at end if truncated. Zero for none.
4618 MINCOL is the first column ok to end at. (Pad with spaces to this col.)
4619 MAXCOL is the last column ok to end at. Truncate here.
4620 -1 for MINCOL or MAXCOL means no explicit minimum or maximum.
4621 Both count from the left edge of the frame, as does HPOS.
4622 The right edge of W is an implicit maximum.
4623 If TRUNCATE is nonzero, the implicit maximum is one column before the edge.
4625 OBEY_WINDOW_WIDTH says to put spaces or vertical bars
4626 at the place where the current window ends in this line
4627 and not display anything beyond there. Otherwise, only MAXCOL
4628 controls where to stop output.
4630 Returns ending hpos. */
4633 display_string (w
, vpos
, string
, length
, hpos
, truncate
,
4634 obey_window_width
, mincol
, maxcol
)
4636 unsigned char *string
;
4640 int obey_window_width
;
4646 int hscroll
= XINT (w
->hscroll
);
4647 int tab_width
= XINT (XBUFFER (w
->buffer
)->tab_width
);
4648 register GLYPH
*start
;
4649 register GLYPH
*end
;
4650 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
4651 struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (f
);
4652 GLYPH
*p1start
= desired_glyphs
->glyphs
[vpos
] + hpos
;
4653 int window_width
= XFASTINT (w
->width
);
4654 /* If 1, we must display multibyte characters. */
4655 int multibyte
= !NILP (XBUFFER (w
->buffer
)->enable_multibyte_characters
);
4657 /* Use the standard display table, not the window's display table.
4658 We don't want the mode line in rot13. */
4659 register struct Lisp_Char_Table
*dp
= 0;
4662 if (DISP_TABLE_P (Vstandard_display_table
))
4663 dp
= XCHAR_TABLE (Vstandard_display_table
);
4665 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
4668 start
= desired_glyphs
->glyphs
[vpos
] + XFASTINT (w
->left
);
4670 if (obey_window_width
)
4672 end
= start
+ window_width
- (truncate
!= 0);
4674 if (!WINDOW_RIGHTMOST_P (w
))
4676 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4680 for (i
= 0; i
< FRAME_SCROLL_BAR_COLS (f
); i
++)
4683 else if (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4688 if (! obey_window_width
4689 || (maxcol
>= 0 && end
- desired_glyphs
->glyphs
[vpos
] > maxcol
))
4690 end
= desired_glyphs
->glyphs
[vpos
] + maxcol
;
4692 /* Store 0 in charstart for these columns. */
4693 for (i
= (hpos
>= 0 ? hpos
: 0); i
< end
- p1start
+ hpos
; i
++)
4694 desired_glyphs
->charstarts
[vpos
][i
] = 0;
4696 if (maxcol
>= 0 && mincol
> maxcol
)
4700 /* We need this value for multibyte characters. */
4701 length
= strlen (string
);
4703 /* We set truncated to 1 if we get stopped by trying to pass END
4704 (that is, trying to pass MAXCOL.) */
4713 c
= STRING_CHAR_AND_LENGTH (string
, length
, len
);
4715 c
= *string
, len
= 1;
4717 string
+= len
, length
-= len
;
4725 if (dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
4727 p1
= copy_part_of_rope (f
, p1
, start
,
4728 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->contents
,
4729 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->size
,
4732 else if (c
>= 040 && c
< 0177)
4742 if (p1
>= start
&& p1
< end
)
4746 while ((p1
- start
+ hscroll
- (hscroll
> 0)) % tab_width
);
4748 else if (c
< 0200 && ! NILP (buffer_defaults
.ctl_arrow
))
4752 (f
, (dp
&& INTEGERP (DISP_CTRL_GLYPH (dp
))
4753 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (dp
)))
4754 ? XINT (DISP_CTRL_GLYPH (dp
)) : '^'),
4757 if (p1
>= start
&& p1
< end
)
4763 /* C is a control character or a binary byte data. */
4766 (f
, (dp
&& INTEGERP (DISP_ESCAPE_GLYPH (dp
))
4767 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp
)))
4768 ? XINT (DISP_ESCAPE_GLYPH (dp
)) : '\\'),
4771 if (p1
>= start
&& p1
< end
)
4772 *p1
= (c
>> 6) + '0';
4774 if (p1
>= start
&& p1
< end
)
4775 *p1
= (7 & (c
>> 3)) + '0';
4777 if (p1
>= start
&& p1
< end
)
4778 *p1
= (7 & c
) + '0';
4783 /* C is a multibyte character. */
4784 int charset
= CHAR_CHARSET (c
);
4785 int columns
= (charset
== CHARSET_COMPOSITION
4786 ? cmpchar_table
[COMPOSITE_CHAR_ID (c
)]->width
4787 : CHARSET_WIDTH (charset
));
4791 /* Since we can't show the left part of C, fill all
4792 columns with spaces. */
4793 columns
-= start
- p1
;
4802 else if (p1
+ columns
> end
)
4804 /* Since we can't show the right part of C, fill all
4805 columns with TRUNCATE if TRUNCATE is specified. */
4809 *p1
++ = fix_glyph (f
, truncate
, 0);
4810 /* And tell the line is truncated. */
4817 /* We can show the whole glyph of C. */
4820 *p1
++ = c
| GLYPH_MASK_PADDING
;
4828 if (truncate
) *p1
++ = fix_glyph (f
, truncate
, 0);
4830 else if (mincol
>= 0)
4832 end
= desired_glyphs
->glyphs
[vpos
] + mincol
;
4838 register int len
= p1
- desired_glyphs
->glyphs
[vpos
];
4840 if (len
> desired_glyphs
->used
[vpos
])
4841 desired_glyphs
->used
[vpos
] = len
;
4842 desired_glyphs
->glyphs
[vpos
][desired_glyphs
->used
[vpos
]] = 0;
4848 /* This is like a combination of memq and assq.
4849 Return 1 if PROPVAL appears as an element of LIST
4850 or as the car of an element of LIST.
4851 If PROPVAL is a list, compare each element against LIST
4852 in that way, and return 1 if any element of PROPVAL is found in LIST.
4854 This function cannot quit. */
4857 invisible_p (propval
, list
)
4858 register Lisp_Object propval
;
4861 register Lisp_Object tail
, proptail
;
4862 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4864 register Lisp_Object tem
;
4865 tem
= XCONS (tail
)->car
;
4866 if (EQ (propval
, tem
))
4868 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
4871 if (CONSP (propval
))
4872 for (proptail
= propval
; CONSP (proptail
);
4873 proptail
= XCONS (proptail
)->cdr
)
4875 Lisp_Object propelt
;
4876 propelt
= XCONS (proptail
)->car
;
4877 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4879 register Lisp_Object tem
;
4880 tem
= XCONS (tail
)->car
;
4881 if (EQ (propelt
, tem
))
4883 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
4890 /* Return 1 if PROPVAL appears as the car of an element of LIST
4891 and the cdr of that element is non-nil.
4892 If PROPVAL is a list, check each element of PROPVAL in that way,
4893 and the first time some element is found,
4894 return 1 if the cdr of that element is non-nil.
4896 This function cannot quit. */
4899 invisible_ellipsis_p (propval
, list
)
4900 register Lisp_Object propval
;
4903 register Lisp_Object tail
, proptail
;
4904 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4906 register Lisp_Object tem
;
4907 tem
= XCONS (tail
)->car
;
4908 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
4909 return ! NILP (XCONS (tem
)->cdr
);
4911 if (CONSP (propval
))
4912 for (proptail
= propval
; CONSP (proptail
);
4913 proptail
= XCONS (proptail
)->cdr
)
4915 Lisp_Object propelt
;
4916 propelt
= XCONS (proptail
)->car
;
4917 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4919 register Lisp_Object tem
;
4920 tem
= XCONS (tail
)->car
;
4921 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
4922 return ! NILP (XCONS (tem
)->cdr
);
4931 staticpro (&Qmenu_bar_update_hook
);
4932 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
4934 staticpro (&Qoverriding_terminal_local_map
);
4935 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
4937 staticpro (&Qoverriding_local_map
);
4938 Qoverriding_local_map
= intern ("overriding-local-map");
4940 staticpro (&Qwindow_scroll_functions
);
4941 Qwindow_scroll_functions
= intern ("window-scroll-functions");
4943 staticpro (&Qredisplay_end_trigger_functions
);
4944 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
4946 staticpro (&last_arrow_position
);
4947 staticpro (&last_arrow_string
);
4948 last_arrow_position
= Qnil
;
4949 last_arrow_string
= Qnil
;
4951 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
4952 "String (or mode line construct) included (normally) in `mode-line-format'.");
4953 Vglobal_mode_string
= Qnil
;
4955 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
4956 "Marker for where to display an arrow on top of the buffer text.\n\
4957 This must be the beginning of a line in order to work.\n\
4958 See also `overlay-arrow-string'.");
4959 Voverlay_arrow_position
= Qnil
;
4961 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
4962 "String to display as an arrow. See also `overlay-arrow-position'.");
4963 Voverlay_arrow_string
= Qnil
;
4965 DEFVAR_INT ("scroll-step", &scroll_step
,
4966 "*The number of lines to try scrolling a window by when point moves out.\n\
4967 If that fails to bring point back on frame, point is centered instead.\n\
4968 If this is zero, point is always centered after it moves off frame.");
4970 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
4971 "*Scroll up to this many lines, to bring point back on screen.");
4972 scroll_conservatively
= 0;
4974 DEFVAR_INT ("scroll-margin", &scroll_margin
,
4975 "*Number of lines of margin at the top and bottom of a window.\n\
4976 Recenter the window whenever point gets within this many lines\n\
4977 of the top or bottom of the window.");
4980 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, "Don't ask");
4982 DEFVAR_BOOL ("truncate-partial-width-windows",
4983 &truncate_partial_width_windows
,
4984 "*Non-nil means truncate lines in all windows less than full frame wide.");
4985 truncate_partial_width_windows
= 1;
4987 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
4988 "*Non-nil means use inverse video for the mode line.");
4989 mode_line_inverse_video
= 1;
4991 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit
,
4992 "*Maximum buffer size for which line number should be displayed.");
4993 line_number_display_limit
= 1000000;
4995 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
4996 "*Non-nil means highlight region even in nonselected windows.");
4997 highlight_nonselected_windows
= 0;
4999 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
5000 "Non-nil if more than one frame is visible on this display.\n\
5001 Minibuffer-only frames don't count, but iconified frames do.\n\
5002 This variable is not guaranteed to be accurate except while processing\n\
5003 `frame-title-format' and `icon-title-format'.");
5005 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
5006 "Template for displaying the titlebar of visible frames.\n\
5007 \(Assuming the window manager supports this feature.)\n\
5008 This variable has the same structure as `mode-line-format' (which see),\n\
5009 and is used only on frames for which no explicit name has been set\n\
5010 \(see `modify-frame-parameters').");
5011 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
5012 "Template for displaying the titlebar of an iconified frame.\n\
5013 \(Assuming the window manager supports this feature.)\n\
5014 This variable has the same structure as `mode-line-format' (which see),\n\
5015 and is used only on frames for which no explicit name has been set\n\
5016 \(see `modify-frame-parameters').");
5018 = Vframe_title_format
5019 = Fcons (intern ("multiple-frames"),
5020 Fcons (build_string ("%b"),
5021 Fcons (Fcons (build_string (""),
5022 Fcons (intern ("invocation-name"),
5023 Fcons (build_string ("@"),
5024 Fcons (intern ("system-name"),
5028 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
5029 "Maximum number of lines to keep in the message log buffer.\n\
5030 If nil, disable message logging. If t, log messages but don't truncate\n\
5031 the buffer when it becomes large.");
5032 XSETFASTINT (Vmessage_log_max
, 50);
5034 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
5035 "Functions called before redisplay, if window sizes have changed.\n\
5036 The value should be a list of functions that take one argument.\n\
5037 Just before redisplay, for each frame, if any of its windows have changed\n\
5038 size since the last redisplay, or have been split or deleted,\n\
5039 all the functions in the list are called, with the frame as argument.");
5040 Vwindow_size_change_functions
= Qnil
;
5042 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
5043 "List of Functions to call before redisplaying a window with scrolling.\n\
5044 Each function is called with two arguments, the window\n\
5045 and its new display-start position. Note that the value of `window-end'\n\
5046 is not valid when these functions are called.");
5047 Vwindow_scroll_functions
= Qnil
;
5050 /* initialize the window system */
5053 Lisp_Object root_window
;
5054 #ifndef COMPILER_REGISTER_BUG
5056 #endif /* COMPILER_REGISTER_BUG */
5057 struct window
*mini_w
;
5059 this_line_bufpos
= 0;
5061 mini_w
= XWINDOW (minibuf_window
);
5062 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
5064 echo_area_glyphs
= 0;
5065 previous_echo_glyphs
= 0;
5067 if (!noninteractive
)
5069 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
5070 XSETFASTINT (XWINDOW (root_window
)->top
, FRAME_MENU_BAR_LINES (f
));
5071 set_window_height (root_window
,
5072 FRAME_HEIGHT (f
) - 1 - FRAME_MENU_BAR_LINES (f
),
5074 XSETFASTINT (mini_w
->top
, FRAME_HEIGHT (f
) - 1);
5075 set_window_height (minibuf_window
, 1, 0);
5077 XSETFASTINT (XWINDOW (root_window
)->width
, FRAME_WIDTH (f
));
5078 XSETFASTINT (mini_w
->width
, FRAME_WIDTH (f
));