1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 /*#include <ctype.h>*/
30 #include "dispextern.h"
36 #include "termhooks.h"
37 #include "intervals.h"
40 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
41 extern void set_frame_menubar ();
42 extern int pending_menu_activation
;
45 extern int interrupt_input
;
46 extern int command_loop_level
;
48 extern Lisp_Object Qface
;
50 extern Lisp_Object Voverriding_local_map
;
51 extern Lisp_Object Voverriding_local_map_menu_flag
;
53 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
54 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
55 Lisp_Object Qredisplay_end_trigger_functions
;
57 /* Nonzero means print newline to stdout before next minibuffer message. */
59 int noninteractive_need_newline
;
61 /* Nonzero means print newline to message log before next message. */
63 static int message_log_need_newline
;
65 #define min(a, b) ((a) < (b) ? (a) : (b))
66 #define max(a, b) ((a) > (b) ? (a) : (b))
67 #define minmax(floor, val, ceil) \
68 ((val) < (floor) ? (floor) : (val) > (ceil) ? (ceil) : (val))
70 /* The buffer position of the first character appearing
71 entirely or partially on the current frame line.
72 Or zero, which disables the optimization for the current frame line. */
73 static int this_line_bufpos
;
75 /* Number of characters past the end of this line,
76 including the terminating newline */
77 static int this_line_endpos
;
79 /* The vertical position of this frame line. */
80 static int this_line_vpos
;
82 /* Hpos value for start of display on this frame line.
83 Usually zero, but negative if first character really began
85 static int this_line_start_hpos
;
87 /* Buffer that this_line variables are describing. */
88 static struct buffer
*this_line_buffer
;
90 /* Value of echo_area_glyphs when it was last acted on.
91 If this is nonzero, there is a message on the frame
92 in the minibuffer and it should be erased as soon
93 as it is no longer requested to appear. */
94 char *previous_echo_glyphs
;
96 /* Nonzero means truncate lines in all windows less wide than the frame */
97 int truncate_partial_width_windows
;
99 /* Nonzero means we have more than one non-minibuffer-only frame.
100 Not guaranteed to be accurate except while parsing frame-title-format. */
103 Lisp_Object Vglobal_mode_string
;
105 /* Marker for where to display an arrow on top of the buffer text. */
106 Lisp_Object Voverlay_arrow_position
;
108 /* String to display for the arrow. */
109 Lisp_Object Voverlay_arrow_string
;
111 /* Like mode-line-format, but for the titlebar on a visible frame. */
112 Lisp_Object Vframe_title_format
;
114 /* Like mode-line-format, but for the titlebar on an iconified frame. */
115 Lisp_Object Vicon_title_format
;
117 /* List of functions to call when a window's size changes. These
118 functions get one arg, a frame on which one or more windows' sizes
120 static Lisp_Object Vwindow_size_change_functions
;
122 /* Values of those variables at last redisplay. */
123 static Lisp_Object last_arrow_position
, last_arrow_string
;
125 Lisp_Object Qmenu_bar_update_hook
;
127 /* Nonzero if overlay arrow has been displayed once in this window. */
128 static int overlay_arrow_seen
;
130 /* Nonzero if visible end of buffer has already been displayed once
131 in this window. (We need this variable in case there are overlay
132 strings that get displayed there.) */
133 static int zv_strings_seen
;
135 /* Nonzero means highlight the region even in nonselected windows. */
136 static int highlight_nonselected_windows
;
138 /* If cursor motion alone moves point off frame,
139 Try scrolling this many lines up or down if that will bring it back. */
140 static int scroll_step
;
142 /* Nonzero if try_window_id has made blank lines at window bottom
143 since the last redisplay that paused */
144 static int blank_end_of_window
;
146 /* Number of windows showing the buffer of the selected window
147 (or another buffer with the same base buffer).
148 keyboard.c refers to this. */
151 /* display_text_line sets these to the frame position (origin 0) of point,
152 whether the window is selected or not.
153 Set one to -1 first to determine whether point was found afterwards. */
155 static int cursor_vpos
;
156 static int cursor_hpos
;
158 static int debug_end_pos
;
160 /* Nonzero means display mode line highlighted */
161 int mode_line_inverse_video
;
163 static void redisplay_internal ();
164 static int message_log_check_duplicate ();
165 static void echo_area_display ();
166 void mark_window_display_accurate ();
167 static void redisplay_windows ();
168 static void redisplay_window ();
169 static void update_menu_bar ();
170 static void try_window ();
171 static int try_window_id ();
172 static struct position
*display_text_line ();
173 static void display_mode_line ();
174 static int display_mode_element ();
175 static char *decode_mode_spec ();
176 static int display_string ();
177 static void display_menu_bar ();
178 static int display_count_lines ();
180 /* Prompt to display in front of the minibuffer contents */
181 Lisp_Object minibuf_prompt
;
183 /* Width in columns of current minibuffer prompt. */
184 int minibuf_prompt_width
;
186 /* Message to display instead of minibuffer contents
187 This is what the functions error and message make,
188 and command echoing uses it as well.
189 It overrides the minibuf_prompt as well as the buffer. */
190 char *echo_area_glyphs
;
192 /* This is the length of the message in echo_area_glyphs. */
193 int echo_area_glyphs_length
;
195 /* This is the window where the echo area message was displayed.
196 It is always a minibuffer window, but it may not be the
197 same window currently active as a minibuffer. */
198 Lisp_Object echo_area_window
;
200 /* true iff we should redraw the mode lines on the next redisplay */
201 int update_mode_lines
;
203 /* Smallest number of characters before the gap
204 at any time since last redisplay that finished.
205 Valid for current buffer when try_window_id can be called. */
208 /* Smallest number of characters after the gap
209 at any time since last redisplay that finished.
210 Valid for current buffer when try_window_id can be called. */
213 /* MODIFF as of last redisplay that finished;
214 if it matches MODIFF, and overlay_unchanged_modified
215 matches OVERLAY_MODIFF, that means beg_unchanged and end_unchanged
216 contain no useful information */
217 int unchanged_modified
;
219 /* OVERLAY_MODIFF as of last redisplay that finished. */
220 int overlay_unchanged_modified
;
222 /* Nonzero if window sizes or contents have changed
223 since last redisplay that finished */
224 int windows_or_buffers_changed
;
226 /* Nonzero after display_mode_line if %l was used
227 and it displayed a line number. */
228 int line_number_displayed
;
230 /* Maximum buffer size for which to display line numbers. */
231 static int line_number_display_limit
;
233 /* Number of lines to keep in the message log buffer.
234 t means infinite. nil means don't log at all. */
235 Lisp_Object Vmessage_log_max
;
237 /* Output a newline in the *Messages* buffer if "needs" one. */
240 message_log_maybe_newline ()
242 if (message_log_need_newline
)
243 message_dolog ("", 0, 1);
247 /* Add a string to the message log, optionally terminated with a newline.
248 This function calls low-level routines in order to bypass text property
249 hooks, etc. which might not be safe to run. */
252 message_dolog (m
, len
, nlflag
)
256 if (!NILP (Vmessage_log_max
))
258 struct buffer
*oldbuf
;
259 int oldpoint
, oldbegv
, oldzv
;
260 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
262 oldbuf
= current_buffer
;
263 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
264 current_buffer
->undo_list
= Qt
;
271 oldpoint
+= len
+ nlflag
;
273 oldzv
+= len
+ nlflag
;
276 insert_1 (m
, len
, 1, 0);
279 int this_bol
, prev_bol
, dup
;
280 insert_1 ("\n", 1, 1, 0);
282 this_bol
= scan_buffer ('\n', Z
, 0, -2, 0, 0);
285 prev_bol
= scan_buffer ('\n', this_bol
, 0, -2, 0, 0);
286 dup
= message_log_check_duplicate (prev_bol
, this_bol
);
289 if (oldpoint
> prev_bol
)
290 oldpoint
-= min (this_bol
, oldpoint
) - prev_bol
;
291 if (oldbegv
> prev_bol
)
292 oldbegv
-= min (this_bol
, oldbegv
) - prev_bol
;
293 if (oldzv
> prev_bol
)
294 oldzv
-= min (this_bol
, oldzv
) - prev_bol
;
295 del_range_1 (prev_bol
, this_bol
, 0);
301 /* If you change this format, don't forget to also
302 change message_log_check_duplicate. */
303 sprintf (dupstr
, " [%d times]", dup
);
304 duplen
= strlen (dupstr
);
310 insert_1 (dupstr
, duplen
, 1, 0);
315 if (NATNUMP (Vmessage_log_max
))
317 int pos
= scan_buffer ('\n', Z
, 0,
318 -XFASTINT (Vmessage_log_max
) - 1, 0, 0);
319 oldpoint
-= min (pos
, oldpoint
) - BEG
;
320 oldbegv
-= min (pos
, oldbegv
) - BEG
;
321 oldzv
-= min (pos
, oldzv
) - BEG
;
322 del_range_1 (BEG
, pos
, 0);
327 TEMP_SET_PT (oldpoint
);
328 set_buffer_internal (oldbuf
);
329 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
330 message_log_need_newline
= !nlflag
;
334 /* We are at the end of the buffer after just having inserted a newline.
335 (Note: We depend on the fact we won't be crossing the gap.)
336 Check to see if the most recent message looks a lot like the previous one.
337 Return 0 if different, 1 if the new one should just replace it, or a
338 value N > 1 if we should also append " [N times]". */
341 message_log_check_duplicate (prev_bol
, this_bol
)
342 int prev_bol
, this_bol
;
345 int len
= Z
- 1 - this_bol
;
347 unsigned char *p1
= BUF_CHAR_ADDRESS (current_buffer
, prev_bol
);
348 unsigned char *p2
= BUF_CHAR_ADDRESS (current_buffer
, this_bol
);
350 for (i
= 0; i
< len
; i
++)
352 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.'
361 if (*p1
++ == ' ' && *p1
++ == '[')
364 while (*p1
>= '0' && *p1
<= '9')
365 n
= n
* 10 + *p1
++ - '0';
366 if (strncmp (p1
, " times]\n", 8) == 0)
372 /* Display an echo area message M with a specified length of LEN chars.
373 The string may include null characters. If M is 0, clear out any
374 existing message, and let the minibuffer text show through.
376 The buffer M must continue to exist until after the echo area
377 gets cleared or some other message gets displayed there.
379 Do not pass text that is stored in a Lisp string.
380 Do not pass text in a buffer that was alloca'd. */
387 /* First flush out any partial line written with print. */
388 message_log_maybe_newline ();
390 message_dolog (m
, len
, 1);
391 message2_nolog (m
, len
);
395 /* The non-logging counterpart of message2. */
398 message2_nolog (m
, len
)
404 if (noninteractive_need_newline
)
406 noninteractive_need_newline
= 0;
407 fwrite (m
, len
, 1, stderr
);
408 if (cursor_in_echo_area
== 0)
409 fprintf (stderr
, "\n");
412 /* A null message buffer means that the frame hasn't really been
413 initialized yet. Error messages get reported properly by
414 cmd_error, so this must be just an informative message; toss it. */
415 else if (INTERACTIVE
&& FRAME_MESSAGE_BUF (selected_frame
))
417 Lisp_Object mini_window
;
420 /* Get the frame containing the minibuffer
421 that the selected frame is using. */
422 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
423 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
425 FRAME_SAMPLE_VISIBILITY (f
);
426 if (FRAME_VISIBLE_P (selected_frame
)
427 && ! FRAME_VISIBLE_P (f
))
428 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
432 echo_area_glyphs
= m
;
433 echo_area_glyphs_length
= len
;
436 echo_area_glyphs
= previous_echo_glyphs
= 0;
438 do_pending_window_change ();
439 echo_area_display ();
440 update_frame (f
, 1, 1);
441 do_pending_window_change ();
442 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
443 (*frame_up_to_date_hook
) (f
);
447 /* Display a null-terminated echo area message M. If M is 0, clear out any
448 existing message, and let the minibuffer text show through.
450 The buffer M must continue to exist until after the echo area
451 gets cleared or some other message gets displayed there.
453 Do not pass text that is stored in a Lisp string.
454 Do not pass text in a buffer that was alloca'd. */
460 message2 (m
, (m
? strlen (m
) : 0));
467 message2_nolog (m
, (m
? strlen (m
) : 0));
470 /* Truncate what will be displayed in the echo area
471 the next time we display it--but don't redisplay it now. */
474 truncate_echo_area (len
)
477 /* A null message buffer means that the frame hasn't really been
478 initialized yet. Error messages get reported properly by
479 cmd_error, so this must be just an informative message; toss it. */
480 if (!noninteractive
&& INTERACTIVE
&& FRAME_MESSAGE_BUF (selected_frame
))
481 echo_area_glyphs_length
= len
;
484 /* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by print;
485 zero if being used by message. */
486 int message_buf_print
;
488 /* Dump an informative message to the minibuf. If M is 0, clear out
489 any existing message, and let the minibuffer text show through. */
493 message (m
, a1
, a2
, a3
)
495 EMACS_INT a1
, a2
, a3
;
501 if (noninteractive_need_newline
)
503 noninteractive_need_newline
= 0;
504 fprintf (stderr
, m
, a1
, a2
, a3
);
505 if (cursor_in_echo_area
== 0)
506 fprintf (stderr
, "\n");
510 else if (INTERACTIVE
)
512 /* The frame whose minibuffer we're going to display the message on.
513 It may be larger than the selected frame, so we need
514 to use its buffer, not the selected frame's buffer. */
515 Lisp_Object mini_window
;
518 /* Get the frame containing the minibuffer
519 that the selected frame is using. */
520 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
521 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
523 /* A null message buffer means that the frame hasn't really been
524 initialized yet. Error messages get reported properly by
525 cmd_error, so this must be just an informative message; toss it. */
526 if (FRAME_MESSAGE_BUF (f
))
537 len
= doprnt (FRAME_MESSAGE_BUF (f
),
538 (int) FRAME_WIDTH (f
), m
, (char *)0, 3, a
);
540 len
= doprnt (FRAME_MESSAGE_BUF (f
),
541 (int) FRAME_WIDTH (f
), m
, (char *)0, 3, &a1
);
542 #endif /* NO_ARG_ARRAY */
544 message2 (FRAME_MESSAGE_BUF (f
), len
);
549 /* Print should start at the beginning of the message
551 message_buf_print
= 0;
556 /* The non-logging version of message. */
558 message_nolog (m
, a1
, a2
, a3
)
560 EMACS_INT a1
, a2
, a3
;
562 Lisp_Object old_log_max
;
563 old_log_max
= Vmessage_log_max
;
564 Vmessage_log_max
= Qnil
;
565 message (m
, a1
, a2
, a3
);
566 Vmessage_log_max
= old_log_max
;
572 message2 (echo_area_glyphs
, echo_area_glyphs_length
);
580 Lisp_Object mini_window
;
582 /* Choose the minibuffer window for this display.
583 It is the minibuffer window used by the selected frame. */
584 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
585 /* This is the frame that window is in. */
586 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
588 if (! FRAME_VISIBLE_P (f
))
593 redraw_garbaged_frames ();
597 if (echo_area_glyphs
|| minibuf_level
== 0)
599 echo_area_window
= mini_window
;
601 vpos
= XFASTINT (XWINDOW (mini_window
)->top
);
602 get_display_line (f
, vpos
, 0);
603 display_string (XWINDOW (mini_window
), vpos
,
604 echo_area_glyphs
? echo_area_glyphs
: "",
605 echo_area_glyphs
? echo_area_glyphs_length
: -1,
606 0, 0, 0, 0, FRAME_WIDTH (f
));
608 #if 0 /* This just gets in the way. update_frame does the job. */
609 /* If desired cursor location is on this line, put it at end of text */
610 if (cursor_in_echo_area
)
611 FRAME_CURSOR_Y (f
) = vpos
;
612 if (FRAME_CURSOR_Y (f
) == vpos
)
613 FRAME_CURSOR_X (f
) = FRAME_DESIRED_GLYPHS (f
)->used
[vpos
];
616 /* Fill the rest of the minibuffer window with blank lines. */
621 i
< vpos
+ XFASTINT (XWINDOW (mini_window
)->height
); i
++)
623 get_display_line (f
, i
, 0);
624 display_string (XWINDOW (mini_window
), vpos
,
625 "", 0, 0, 0, 0, 0, FRAME_WIDTH (f
));
629 else if (!EQ (mini_window
, selected_window
))
630 windows_or_buffers_changed
++;
632 if (EQ (mini_window
, selected_window
))
633 this_line_bufpos
= 0;
635 previous_echo_glyphs
= echo_area_glyphs
;
638 /* Update frame titles. */
640 #ifdef HAVE_WINDOW_SYSTEM
641 static char frame_title_buf
[512];
642 static char *frame_title_ptr
;
645 store_frame_title (str
, mincol
, maxcol
)
650 if (maxcol
< 0 || maxcol
>= sizeof(frame_title_buf
))
651 maxcol
= sizeof (frame_title_buf
);
652 limit
= &frame_title_buf
[maxcol
];
653 while (*str
!= '\0' && frame_title_ptr
< limit
)
654 *frame_title_ptr
++ = *str
++;
655 while (frame_title_ptr
< &frame_title_buf
[mincol
])
656 *frame_title_ptr
++ = ' ';
657 return frame_title_ptr
- frame_title_buf
;
661 x_consider_frame_title (frame
)
667 FRAME_PTR f
= XFRAME (frame
);
669 if (!(FRAME_WINDOW_P (f
) || FRAME_MINIBUF_ONLY_P (f
) || f
->explicit_name
))
672 /* Do we have more than one visible frame on this X display? */
676 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
678 FRAME_PTR tf
= XFRAME (XCONS (tail
)->car
);
680 if (tf
!= f
&& FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
681 && !FRAME_MINIBUF_ONLY_P (tf
)
682 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
686 multiple_frames
= CONSP (tail
);
689 obuf
= current_buffer
;
690 Fset_buffer (XWINDOW (f
->selected_window
)->buffer
);
691 fmt
= (FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
);
692 frame_title_ptr
= frame_title_buf
;
693 len
= display_mode_element (XWINDOW (f
->selected_window
), 0, 0, 0,
694 0, sizeof (frame_title_buf
), fmt
);
696 set_buffer_internal (obuf
);
697 /* Set the name only if it's changed. This avoids consing
698 in the common case where it hasn't. (If it turns out that we've
699 already wasted too much time by walking through the list with
700 display_mode_element, then we might need to optimize at a higher
702 if (! STRINGP (f
->name
) || XSTRING (f
->name
)->size
!= len
703 || bcmp (frame_title_buf
, XSTRING (f
->name
)->data
, len
) != 0)
704 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
707 #define frame_title_ptr ((char *)0)
708 #define store_frame_title(str, mincol, maxcol) 0
711 /* Prepare for redisplay by updating menu-bar item lists when appropriate.
712 This can call eval. */
717 register struct window
*w
= XWINDOW (selected_window
);
719 struct gcpro gcpro1
, gcpro2
;
721 all_windows
= (update_mode_lines
|| buffer_shared
> 1
722 || windows_or_buffers_changed
);
724 /* Update all frame titles based on their buffer names, etc.
725 We do this before the menu bars so that the buffer-menu
726 will show the up-to-date frame titles.
728 This used to be done after the menu bars, for a reason that
729 was stated as follows but which I do not understand:
730 "We do this after the menu bars so that the frame will first
731 create its menu bar using the name `emacs' if no other name
732 has yet been specified."
733 I think that is no longer a concern. */
734 #ifdef HAVE_WINDOW_SYSTEM
735 if (windows_or_buffers_changed
|| update_mode_lines
)
737 Lisp_Object tail
, frame
;
739 FOR_EACH_FRAME (tail
, frame
)
740 if (FRAME_VISIBLE_P (XFRAME (frame
))
741 || FRAME_ICONIFIED_P (XFRAME (frame
)))
742 x_consider_frame_title (frame
);
746 /* Update the menu bar item lists, if appropriate.
747 This has to be done before any actual redisplay
748 or generation of display lines. */
751 Lisp_Object tail
, frame
;
752 int count
= specpdl_ptr
- specpdl
;
754 record_unwind_protect (Fstore_match_data
, Fmatch_data ());
756 FOR_EACH_FRAME (tail
, frame
)
758 /* If a window on this frame changed size,
759 report that to the user and clear the size-change flag. */
760 if (FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame
)))
762 Lisp_Object functions
;
763 /* Clear flag first in case we get error below. */
764 FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame
)) = 0;
765 functions
= Vwindow_size_change_functions
;
766 GCPRO2 (tail
, functions
);
767 while (CONSP (functions
))
769 call1 (XCONS (functions
)->car
, frame
);
770 functions
= XCONS (functions
)->cdr
;
775 update_menu_bar (XFRAME (frame
), 0);
779 unbind_to (count
, Qnil
);
782 update_menu_bar (selected_frame
, 1);
784 /* Motif needs this. See comment in xmenu.c.
785 Turn it off when pending_menu_activation is not defined. */
787 pending_menu_activation
= 0;
791 /* Do a frame update, taking possible shortcuts into account.
792 This is the main external entry point for redisplay.
794 If the last redisplay displayed an echo area message and that
795 message is no longer requested, we clear the echo area
796 or bring back the minibuffer if that is in use.
798 Do not call eval from within this function.
799 Calls to eval after the call to echo_area_display would confuse
800 the display_line mechanism and would cause a crash.
801 Calls to eval before that point will work most of the time,
802 but can still lose, because this function
803 can be called from signal handlers; with alarms set up;
804 or with synchronous processes running.
806 See Fcall_process; if you called it from here, it could be
807 entered recursively. */
809 static int do_verify_charstarts
;
811 /* Counter is used to clear the face cache
812 no more than once ever 1000 redisplays. */
813 static int clear_face_cache_count
;
815 /* Record the previous terminal frame we displayed. */
816 static FRAME_PTR previous_terminal_frame
;
821 redisplay_internal (0);
824 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay
825 is not in response to any user action; therefore, we should
826 preserve the echo area. (Actually, our caller does that job.)
827 Perhaps in the future avoid recentering windows
828 if it is not necessary; currently that causes some problems. */
831 redisplay_internal (preserve_echo_area
)
832 int preserve_echo_area
;
834 register struct window
*w
= XWINDOW (selected_window
);
838 register int tlbufpos
, tlendpos
;
845 if (popup_activated ())
849 if (! FRAME_WINDOW_P (selected_frame
)
850 && previous_terminal_frame
!= selected_frame
)
852 /* Since frames on an ASCII terminal share the same display area,
853 displaying a different frame means redisplay the whole thing. */
854 windows_or_buffers_changed
++;
855 SET_FRAME_GARBAGED (selected_frame
);
856 XSETFRAME (Vterminal_frame
, selected_frame
);
858 previous_terminal_frame
= selected_frame
;
860 /* Set the visible flags for all frames.
861 Do this before checking for resized or garbaged frames; they want
862 to know if their frames are visible.
863 See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
865 Lisp_Object tail
, frame
;
867 FOR_EACH_FRAME (tail
, frame
)
869 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
871 /* Clear out all the display lines in which we will generate the
872 glyphs to display. */
873 init_desired_glyphs (XFRAME (frame
));
877 /* Notice any pending interrupt request to change frame size. */
878 do_pending_window_change ();
882 redraw_garbaged_frames ();
886 prepare_menu_bars ();
888 if (windows_or_buffers_changed
)
891 /* Detect case that we need to write or remove a star in the mode line. */
892 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
894 w
->update_mode_line
= Qt
;
895 if (buffer_shared
> 1)
899 /* If %c is in use, update it if needed. */
900 if (!NILP (w
->column_number_displayed
)
901 /* This alternative quickly identifies a common case
902 where no change is needed. */
903 && !(PT
== XFASTINT (w
->last_point
)
904 && XFASTINT (w
->last_modified
) >= MODIFF
905 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
906 && XFASTINT (w
->column_number_displayed
) != current_column ())
907 w
->update_mode_line
= Qt
;
909 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
911 all_windows
= update_mode_lines
|| buffer_shared
> 1;
913 /* If specs for an arrow have changed, do thorough redisplay
914 to ensure we remove any arrow that should no longer exist. */
915 if (! EQ (Voverlay_arrow_position
, last_arrow_position
)
916 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
919 /* Normally the message* functions will have already displayed and
920 updated the echo area, but the frame may have been trashed, or
921 the update may have been preempted, so display the echo area
923 if (echo_area_glyphs
|| previous_echo_glyphs
)
925 echo_area_display ();
929 /* If showing region, and mark has changed, must redisplay whole window. */
930 if (((!NILP (Vtransient_mark_mode
)
931 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
932 != !NILP (w
->region_showing
))
933 || (!NILP (w
->region_showing
)
934 && !EQ (w
->region_showing
,
935 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
936 this_line_bufpos
= -1;
938 tlbufpos
= this_line_bufpos
;
939 tlendpos
= this_line_endpos
;
940 if (!all_windows
&& tlbufpos
> 0 && NILP (w
->update_mode_line
)
941 && !current_buffer
->clip_changed
942 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
943 /* Make sure recorded data applies to current buffer, etc */
944 && this_line_buffer
== current_buffer
945 && current_buffer
== XBUFFER (w
->buffer
)
946 && NILP (w
->force_start
)
947 /* Point must be on the line that we have info recorded about */
949 && PT
<= Z
- tlendpos
950 /* All text outside that line, including its final newline,
952 && ((XFASTINT (w
->last_modified
) >= MODIFF
953 && (XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
))
954 || (beg_unchanged
>= tlbufpos
- 1
956 /* If selective display, can't optimize
957 if the changes start at the beginning of the line. */
958 && ((INTEGERP (current_buffer
->selective_display
)
959 && XINT (current_buffer
->selective_display
) > 0
960 ? (beg_unchanged
>= tlbufpos
963 && end_unchanged
>= tlendpos
964 && Z
- GPT
>= tlendpos
)))
966 if (tlbufpos
> BEGV
&& FETCH_CHAR (tlbufpos
- 1) != '\n'
968 || FETCH_CHAR (tlbufpos
) == '\n'))
969 /* Former continuation line has disappeared by becoming empty */
971 else if (XFASTINT (w
->last_modified
) < MODIFF
972 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
973 || MINI_WINDOW_P (w
))
976 overlay_arrow_seen
= 0;
978 display_text_line (w
, tlbufpos
, this_line_vpos
, this_line_start_hpos
,
979 pos_tab_offset (w
, tlbufpos
));
980 /* If line contains point, is not continued,
981 and ends at same distance from eob as before, we win */
982 if (cursor_vpos
>= 0 && this_line_bufpos
983 && this_line_endpos
== tlendpos
)
985 /* If this is not the window's last line,
986 we must adjust the charstarts of the lines below. */
987 if (this_line_vpos
+ 1
988 < XFASTINT (w
->top
) + window_internal_height (w
))
990 int left
= XFASTINT (w
->left
);
991 int *charstart_next_line
992 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[this_line_vpos
+ 1];
995 if (Z
- tlendpos
== ZV
)
996 /* This line ends at end of (accessible part of) buffer.
997 There is no newline to count. */
998 adjust
= Z
- tlendpos
- charstart_next_line
[left
];
1000 /* This line ends in a newline.
1001 Must take account of the newline and the rest of the
1002 text that follows. */
1003 adjust
= Z
- tlendpos
+ 1 - charstart_next_line
[left
];
1005 adjust_window_charstarts (w
, this_line_vpos
, adjust
);
1008 if (XFASTINT (w
->width
) != FRAME_WIDTH (XFRAME (WINDOW_FRAME (w
))))
1009 preserve_other_columns (w
);
1015 else if (PT
== XFASTINT (w
->last_point
)
1016 /* Make sure the cursor was last displayed
1017 in this window. Otherwise we have to reposition it. */
1018 && XINT (w
->top
) <= FRAME_CURSOR_Y (selected_frame
)
1019 && (XINT (w
->top
) + XINT (w
->height
)
1020 > FRAME_CURSOR_Y (selected_frame
)))
1024 do_pending_window_change ();
1029 /* If highlighting the region, or if the cursor is in the echo area,
1030 then we can't just move the cursor. */
1031 else if (! (!NILP (Vtransient_mark_mode
)
1032 && !NILP (current_buffer
->mark_active
))
1033 && w
== XWINDOW (current_buffer
->last_selected_window
)
1034 && NILP (w
->region_showing
)
1035 && !cursor_in_echo_area
)
1037 pos
= *compute_motion (tlbufpos
, 0,
1038 XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0,
1040 PT
, 2, - (1 << (BITS_PER_SHORT
- 1)),
1041 window_internal_width (w
) - 1,
1043 pos_tab_offset (w
, tlbufpos
), w
);
1046 int width
= window_internal_width (w
) - 1;
1047 FRAME_CURSOR_X (selected_frame
)
1048 = XFASTINT (w
->left
) + minmax (0, pos
.hpos
, width
);
1049 FRAME_CURSOR_Y (selected_frame
) = this_line_vpos
;
1056 /* Text changed drastically or point moved off of line */
1057 cancel_line (this_line_vpos
, selected_frame
);
1060 this_line_bufpos
= 0;
1061 all_windows
|= buffer_shared
> 1;
1063 clear_face_cache_count
++;
1067 Lisp_Object tail
, frame
;
1070 /* Clear the face cache, only when we do a full redisplay
1071 and not too often either. */
1072 if (clear_face_cache_count
> 1000)
1074 clear_face_cache ();
1075 clear_face_cache_count
= 0;
1079 /* Recompute # windows showing selected buffer.
1080 This will be incremented each time such a window is displayed. */
1083 FOR_EACH_FRAME (tail
, frame
)
1085 FRAME_PTR f
= XFRAME (frame
);
1086 if (FRAME_WINDOW_P (f
) || f
== selected_frame
)
1089 /* Mark all the scroll bars to be removed; we'll redeem the ones
1090 we want when we redisplay their windows. */
1091 if (condemn_scroll_bars_hook
)
1092 (*condemn_scroll_bars_hook
) (f
);
1094 if (FRAME_VISIBLE_P (f
))
1095 redisplay_windows (FRAME_ROOT_WINDOW (f
), preserve_echo_area
);
1097 /* Any scroll bars which redisplay_windows should have nuked
1098 should now go away. */
1099 if (judge_scroll_bars_hook
)
1100 (*judge_scroll_bars_hook
) (f
);
1104 else if (FRAME_VISIBLE_P (selected_frame
))
1106 redisplay_window (selected_window
, 1, preserve_echo_area
);
1107 if (XFASTINT (w
->width
) != FRAME_WIDTH (selected_frame
))
1108 preserve_other_columns (w
);
1112 /* Prevent various kinds of signals during display update.
1113 stdio is not robust about handling signals,
1114 which can cause an apparent I/O error. */
1115 if (interrupt_input
)
1125 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1129 if (!FRAMEP (XCONS (tail
)->car
))
1132 f
= XFRAME (XCONS (tail
)->car
);
1134 if ((FRAME_WINDOW_P (f
) || f
== selected_frame
)
1135 && FRAME_VISIBLE_P (f
))
1137 pause
|= update_frame (f
, 0, 0);
1140 mark_window_display_accurate (f
->root_window
, 1);
1141 if (frame_up_to_date_hook
!= 0)
1142 (*frame_up_to_date_hook
) (f
);
1149 if (FRAME_VISIBLE_P (selected_frame
))
1150 pause
= update_frame (selected_frame
, 0, 0);
1154 /* We may have called echo_area_display at the top of this
1155 function. If the echo area is on another frame, that may
1156 have put text on a frame other than the selected one, so the
1157 above call to update_frame would not have caught it. Catch
1160 Lisp_Object mini_window
;
1161 FRAME_PTR mini_frame
;
1163 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
1164 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
1166 if (mini_frame
!= selected_frame
&& FRAME_WINDOW_P (mini_frame
))
1167 pause
|= update_frame (mini_frame
, 0, 0);
1171 /* If frame does not match, prevent doing single-line-update next time.
1172 Also, don't forget to check every line to update the arrow. */
1175 this_line_bufpos
= 0;
1176 if (!NILP (last_arrow_position
))
1178 last_arrow_position
= Qt
;
1179 last_arrow_string
= Qt
;
1181 /* If we pause after scrolling, some lines in current_frame
1182 may be null, so preserve_other_columns won't be able to
1183 preserve all the vertical-bar separators. So, avoid using it
1185 if (XFASTINT (w
->width
) != FRAME_WIDTH (selected_frame
))
1186 update_mode_lines
= 1;
1189 /* Now text on frame agrees with windows, so
1190 put info into the windows for partial redisplay to follow */
1194 register struct buffer
*b
= XBUFFER (w
->buffer
);
1196 blank_end_of_window
= 0;
1197 unchanged_modified
= BUF_MODIFF (b
);
1198 overlay_unchanged_modified
= BUF_OVERLAY_MODIFF (b
);
1199 beg_unchanged
= BUF_GPT (b
) - BUF_BEG (b
);
1200 end_unchanged
= BUF_Z (b
) - BUF_GPT (b
);
1202 XSETFASTINT (w
->last_point
, BUF_PT (b
));
1203 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (selected_frame
));
1204 XSETFASTINT (w
->last_point_y
, FRAME_CURSOR_Y (selected_frame
));
1207 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame
), 1);
1210 b
->clip_changed
= 0;
1211 w
->update_mode_line
= Qnil
;
1212 XSETFASTINT (w
->last_modified
, BUF_MODIFF (b
));
1213 XSETFASTINT (w
->last_overlay_modified
, BUF_OVERLAY_MODIFF (b
));
1215 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1217 w
->window_end_valid
= w
->buffer
;
1218 last_arrow_position
= Voverlay_arrow_position
;
1219 last_arrow_string
= Voverlay_arrow_string
;
1220 if (do_verify_charstarts
)
1221 verify_charstarts (w
);
1222 if (frame_up_to_date_hook
!= 0)
1223 (*frame_up_to_date_hook
) (selected_frame
);
1225 update_mode_lines
= 0;
1226 windows_or_buffers_changed
= 0;
1229 /* Start SIGIO interrupts coming again.
1230 Having them off during the code above
1231 makes it less likely one will discard output,
1232 but not impossible, since there might be stuff
1233 in the system buffer here.
1234 But it is much hairier to try to do anything about that. */
1236 if (interrupt_input
)
1240 /* Change frame size now if a change is pending. */
1241 do_pending_window_change ();
1243 /* If we just did a pending size change, redisplay again
1244 for the new size. */
1245 if (windows_or_buffers_changed
&& !pause
)
1249 /* Redisplay, but leave alone any recent echo area message
1250 unless another message has been requested in its place.
1252 This is useful in situations where you need to redisplay but no
1253 user action has occurred, making it inappropriate for the message
1254 area to be cleared. See tracking_off and
1255 wait_reading_process_input for examples of these situations. */
1257 redisplay_preserve_echo_area ()
1259 if (echo_area_glyphs
== 0 && previous_echo_glyphs
!= 0)
1261 echo_area_glyphs
= previous_echo_glyphs
;
1262 redisplay_internal (1);
1263 echo_area_glyphs
= 0;
1266 redisplay_internal (1);
1270 mark_window_display_accurate (window
, flag
)
1274 register struct window
*w
;
1276 for (;!NILP (window
); window
= w
->next
)
1278 if (!WINDOWP (window
)) abort ();
1279 w
= XWINDOW (window
);
1281 if (!NILP (w
->buffer
))
1283 XSETFASTINT (w
->last_modified
,
1284 !flag
? 0 : BUF_MODIFF (XBUFFER (w
->buffer
)));
1285 XSETFASTINT (w
->last_overlay_modified
,
1286 !flag
? 0 : BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
)));
1288 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1291 /* Record if we are showing a region, so can make sure to
1292 update it fully at next redisplay. */
1293 w
->region_showing
= (!NILP (Vtransient_mark_mode
)
1294 && w
== XWINDOW (current_buffer
->last_selected_window
)
1295 && !NILP (XBUFFER (w
->buffer
)->mark_active
)
1296 ? Fmarker_position (XBUFFER (w
->buffer
)->mark
)
1300 w
->window_end_valid
= w
->buffer
;
1301 w
->update_mode_line
= Qnil
;
1302 if (!NILP (w
->buffer
) && flag
)
1303 XBUFFER (w
->buffer
)->clip_changed
= 0;
1305 if (!NILP (w
->vchild
))
1306 mark_window_display_accurate (w
->vchild
, flag
);
1307 if (!NILP (w
->hchild
))
1308 mark_window_display_accurate (w
->hchild
, flag
);
1313 last_arrow_position
= Voverlay_arrow_position
;
1314 last_arrow_string
= Voverlay_arrow_string
;
1318 /* t is unequal to any useful value of Voverlay_arrow_... */
1319 last_arrow_position
= Qt
;
1320 last_arrow_string
= Qt
;
1324 /* Update the menu bar item list for frame F.
1325 This has to be done before we start to fill in any display lines,
1326 because it can call eval.
1328 If SAVE_MATCH_DATA is 1, we must save and restore it here. */
1331 update_menu_bar (f
, save_match_data
)
1333 int save_match_data
;
1335 struct buffer
*old
= current_buffer
;
1337 register struct window
*w
;
1339 window
= FRAME_SELECTED_WINDOW (f
);
1340 w
= XWINDOW (window
);
1342 if (update_mode_lines
)
1343 w
->update_mode_line
= Qt
;
1345 if (FRAME_WINDOW_P (f
)
1347 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1348 FRAME_EXTERNAL_MENU_BAR (f
)
1350 FRAME_MENU_BAR_LINES (f
) > 0
1352 : FRAME_MENU_BAR_LINES (f
) > 0)
1354 /* If the user has switched buffers or windows, we need to
1355 recompute to reflect the new bindings. But we'll
1356 recompute when update_mode_lines is set too; that means
1357 that people can use force-mode-line-update to request
1358 that the menu bar be recomputed. The adverse effect on
1359 the rest of the redisplay algorithm is about the same as
1360 windows_or_buffers_changed anyway. */
1361 if (windows_or_buffers_changed
1362 || !NILP (w
->update_mode_line
)
1363 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
1364 < BUF_MODIFF (XBUFFER (w
->buffer
)))
1365 != !NILP (w
->last_had_star
))
1366 || ((!NILP (Vtransient_mark_mode
)
1367 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
1368 != !NILP (w
->region_showing
)))
1370 struct buffer
*prev
= current_buffer
;
1371 int count
= specpdl_ptr
- specpdl
;
1373 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1374 if (save_match_data
)
1375 record_unwind_protect (Fstore_match_data
, Fmatch_data ());
1376 if (NILP (Voverriding_local_map_menu_flag
))
1378 specbind (Qoverriding_terminal_local_map
, Qnil
);
1379 specbind (Qoverriding_local_map
, Qnil
);
1382 /* Run the Lucid hook. */
1383 call1 (Vrun_hooks
, Qactivate_menubar_hook
);
1384 /* If it has changed current-menubar from previous value,
1385 really recompute the menubar from the value. */
1386 if (! NILP (Vlucid_menu_bar_dirty_flag
))
1387 call0 (Qrecompute_lucid_menubar
);
1388 safe_run_hooks (Qmenu_bar_update_hook
);
1389 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
1390 /* Redisplay the menu bar in case we changed it. */
1391 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1392 if (FRAME_WINDOW_P (f
))
1393 set_frame_menubar (f
, 0, 0);
1395 /* On a terminal screen, the menu bar is an ordinary screen
1396 line, and this makes it get updated. */
1397 w
->update_mode_line
= Qt
;
1398 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
1399 /* In the non-toolkit version, the menu bar is an ordinary screen
1400 line, and this makes it get updated. */
1401 w
->update_mode_line
= Qt
;
1402 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
1404 unbind_to (count
, Qnil
);
1405 set_buffer_internal_1 (prev
);
1412 /* Redisplay WINDOW and its subwindows and siblings. */
1415 redisplay_windows (window
, preserve_echo_area
)
1417 int preserve_echo_area
;
1419 for (; !NILP (window
); window
= XWINDOW (window
)->next
)
1420 redisplay_window (window
, 0, preserve_echo_area
);
1423 /* Redisplay window WINDOW and its subwindows. */
1426 redisplay_window (window
, just_this_one
, preserve_echo_area
)
1428 int just_this_one
, preserve_echo_area
;
1430 register struct window
*w
= XWINDOW (window
);
1431 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
1433 register int lpoint
= PT
;
1434 struct buffer
*old
= current_buffer
;
1435 register int width
= window_internal_width (w
) - 1;
1436 register int startp
;
1437 register int hscroll
= XINT (w
->hscroll
);
1438 struct position pos
;
1441 int update_mode_line
;
1442 struct Lisp_Char_Table
*dp
= window_display_table (w
);
1444 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1446 /* If this is a combination window, do its children; that's all. */
1448 if (!NILP (w
->vchild
))
1450 redisplay_windows (w
->vchild
, preserve_echo_area
);
1453 if (!NILP (w
->hchild
))
1455 redisplay_windows (w
->hchild
, preserve_echo_area
);
1458 if (NILP (w
->buffer
))
1461 height
= window_internal_height (w
);
1462 update_mode_line
= (!NILP (w
->update_mode_line
) || update_mode_lines
);
1463 if (XBUFFER (w
->buffer
)->clip_changed
)
1464 update_mode_line
= 1;
1466 if (MINI_WINDOW_P (w
))
1468 if (w
== XWINDOW (echo_area_window
) && echo_area_glyphs
)
1469 /* We've already displayed the echo area glyphs in this window. */
1470 goto finish_scroll_bars
;
1471 else if (w
!= XWINDOW (minibuf_window
))
1473 /* This is a minibuffer, but it's not the currently active one,
1475 int vpos
= XFASTINT (w
->top
);
1478 for (i
= 0; i
< height
; i
++)
1480 get_display_line (f
, vpos
+ i
, 0);
1481 display_string (w
, vpos
+ i
, "", 0, 0, 0, 1, 0, width
);
1484 goto finish_scroll_bars
;
1488 /* Otherwise set up data on this window; select its buffer and point value */
1490 if (update_mode_line
)
1491 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1493 set_buffer_temp (XBUFFER (w
->buffer
));
1497 /* If %c is in mode line, update it if needed. */
1498 if (!NILP (w
->column_number_displayed
)
1499 /* This alternative quickly identifies a common case
1500 where no change is needed. */
1501 && !(PT
== XFASTINT (w
->last_point
)
1502 && XFASTINT (w
->last_modified
) >= MODIFF
1503 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
1504 && XFASTINT (w
->column_number_displayed
) != current_column ())
1505 update_mode_line
= 1;
1507 /* Count number of windows showing the selected buffer.
1508 An indirect buffer counts as its base buffer. */
1512 struct buffer
*current_base
, *window_base
;
1513 current_base
= current_buffer
;
1514 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
1515 if (current_base
->base_buffer
)
1516 current_base
= current_base
->base_buffer
;
1517 if (window_base
->base_buffer
)
1518 window_base
= window_base
->base_buffer
;
1519 if (current_base
== window_base
)
1523 /* POINT refers normally to the selected window.
1524 For any other window, set up appropriate value. */
1526 if (!EQ (window
, selected_window
))
1528 int new_pt
= marker_position (w
->pointm
);
1532 Fset_marker (w
->pointm
, make_number (new_pt
), Qnil
);
1534 else if (new_pt
> (ZV
- 1))
1537 Fset_marker (w
->pointm
, make_number (new_pt
), Qnil
);
1539 /* We don't use SET_PT so that the point-motion hooks don't run. */
1540 BUF_PT (current_buffer
) = new_pt
;
1543 /* If any of the character widths specified in the display table
1544 have changed, invalidate the width run cache. It's true that this
1545 may be a bit late to catch such changes, but the rest of
1546 redisplay goes (non-fatally) haywire when the display table is
1547 changed, so why should we worry about doing any better? */
1548 if (current_buffer
->width_run_cache
)
1550 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
1552 if (! disptab_matches_widthtab (disptab
,
1553 XVECTOR (current_buffer
->width_table
)))
1555 invalidate_region_cache (current_buffer
,
1556 current_buffer
->width_run_cache
,
1558 recompute_width_table (current_buffer
, disptab
);
1562 /* If window-start is screwed up, choose a new one. */
1563 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
1566 startp
= marker_position (w
->start
);
1568 /* Handle case where place to start displaying has been specified,
1569 unless the specified location is outside the accessible range. */
1570 if (!NILP (w
->force_start
))
1572 w
->force_start
= Qnil
;
1573 /* Forget any recorded base line for line number display. */
1574 w
->base_line_number
= Qnil
;
1575 /* Redisplay the mode line. Select the buffer properly for that.
1576 Also, run the hook window-scroll-functions
1577 because we have scrolled. */
1578 /* Note, we do this after clearing force_start because
1579 if there's an error, it is better to forget about force_start
1580 than to get into an infinite loop calling the hook functions
1581 and having them get more errors. */
1582 if (!update_mode_line
1583 || ! NILP (Vwindow_scroll_functions
))
1585 Lisp_Object temp
[3];
1587 set_buffer_temp (old
);
1588 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1589 update_mode_line
= 1;
1590 w
->update_mode_line
= Qt
;
1591 if (! NILP (Vwindow_scroll_functions
))
1593 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
1594 make_number (startp
));
1595 startp
= marker_position (w
->start
);
1598 XSETFASTINT (w
->last_modified
, 0);
1599 XSETFASTINT (w
->last_overlay_modified
, 0);
1600 if (startp
< BEGV
) startp
= BEGV
;
1601 if (startp
> ZV
) startp
= ZV
;
1602 try_window (window
, startp
);
1603 if (cursor_vpos
< 0)
1605 /* If point does not appear, move point so it does appear */
1606 pos
= *compute_motion (startp
, 0,
1607 (((EQ (window
, minibuf_window
)
1609 ? minibuf_prompt_width
: 0)
1610 + (hscroll
? 1 - hscroll
: 0)),
1613 - (1 << (BITS_PER_SHORT
- 1)),
1614 width
, hscroll
, pos_tab_offset (w
, startp
), w
);
1615 BUF_PT (current_buffer
) = pos
.bufpos
;
1616 if (w
!= XWINDOW (selected_window
))
1617 Fset_marker (w
->pointm
, make_number (PT
), Qnil
);
1620 if (current_buffer
== old
)
1622 FRAME_CURSOR_X (f
) = (XFASTINT (w
->left
)
1623 + minmax (0, pos
.hpos
, width
));
1624 FRAME_CURSOR_Y (f
) = pos
.vpos
+ XFASTINT (w
->top
);
1626 /* If we are highlighting the region,
1627 then we just changed the region, so redisplay to show it. */
1628 if (!NILP (Vtransient_mark_mode
)
1629 && !NILP (current_buffer
->mark_active
))
1631 cancel_my_columns (XWINDOW (window
));
1632 try_window (window
, startp
);
1638 /* Handle case where text has not changed, only point,
1639 and it has not moved off the frame. */
1641 /* This code is not used for minibuffer for the sake of
1642 the case of redisplaying to replace an echo area message;
1643 since in that case the minibuffer contents per se are usually unchanged.
1644 This code is of no real use in the minibuffer since
1645 the handling of this_line_bufpos, etc.,
1646 in redisplay handles the same cases. */
1648 if (XFASTINT (w
->last_modified
) >= MODIFF
1649 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
1650 && PT
>= startp
&& !current_buffer
->clip_changed
1651 && (just_this_one
|| XFASTINT (w
->width
) == FRAME_WIDTH (f
))
1652 /* If force-mode-line-update was called, really redisplay;
1653 that's how redisplay is forced after e.g. changing
1654 buffer-invisibility-spec. */
1655 && NILP (w
->update_mode_line
)
1656 /* Can't use this case if highlighting a region. */
1657 && !(!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1658 && NILP (w
->region_showing
)
1659 /* If end pos is out of date, scroll bar and percentage will be wrong */
1660 && INTEGERP (w
->window_end_vpos
)
1661 && XFASTINT (w
->window_end_vpos
) < XFASTINT (w
->height
)
1662 && !EQ (window
, minibuf_window
))
1664 pos
= *compute_motion (startp
, 0, (hscroll
? 1 - hscroll
: 0), 0,
1665 PT
, height
, 0, width
, hscroll
,
1666 pos_tab_offset (w
, startp
), w
);
1668 if (pos
.vpos
< height
)
1670 /* Ok, point is still on frame */
1671 if (w
== XWINDOW (FRAME_SELECTED_WINDOW (f
)))
1673 /* These variables are supposed to be origin 1 */
1674 FRAME_CURSOR_X (f
) = (XFASTINT (w
->left
)
1675 + minmax (0, pos
.hpos
, width
));
1676 FRAME_CURSOR_Y (f
) = pos
.vpos
+ XFASTINT (w
->top
);
1678 /* This doesn't do the trick, because if a window to the right of
1679 this one must be redisplayed, this does nothing because there
1680 is nothing in DesiredFrame yet, and then the other window is
1681 redisplayed, making likes that are empty in this window's columns.
1682 if (XFASTINT (w->width) != FRAME_WIDTH (f))
1683 preserve_my_columns (w);
1687 /* Don't bother trying redisplay with same start;
1688 we already know it will lose */
1690 /* If current starting point was originally the beginning of a line
1691 but no longer is, find a new starting point. */
1692 else if (!NILP (w
->start_at_line_beg
)
1694 || FETCH_CHAR (startp
- 1) == '\n'))
1698 else if (just_this_one
&& !MINI_WINDOW_P (w
)
1700 && XFASTINT (w
->last_modified
)
1701 /* or else vmotion on first line won't work. */
1702 && ! NILP (w
->start_at_line_beg
)
1703 && ! EQ (w
->window_end_valid
, Qnil
)
1704 && do_id
&& !current_buffer
->clip_changed
1705 && !blank_end_of_window
1706 && XFASTINT (w
->width
) == FRAME_WIDTH (f
)
1707 /* Can't use this case if highlighting a region. */
1708 && !(!NILP (Vtransient_mark_mode
)
1709 && !NILP (current_buffer
->mark_active
))
1710 /* Don't use try_window_id if newline
1711 doesn't display as the end of a line. */
1712 && !(dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, '\n')))
1713 && NILP (w
->region_showing
)
1714 && EQ (last_arrow_position
, Voverlay_arrow_position
)
1715 && EQ (last_arrow_string
, Voverlay_arrow_string
)
1716 && (tem
= try_window_id (FRAME_SELECTED_WINDOW (f
)))
1719 /* tem > 0 means success. tem == -1 means choose new start.
1720 tem == -2 means try again with same start,
1721 and nothing but whitespace follows the changed stuff.
1722 tem == 0 means try again with same start. */
1726 else if (startp
>= BEGV
&& startp
<= ZV
1728 /* Avoid starting at end of buffer. */
1729 #if 0 /* This change causes trouble for M-! finger & RET.
1730 It will have to be considered later. */
1731 || ! EQ (window
, selected_window
)
1732 /* Don't do the recentering if redisplay
1733 is not for no user action. */
1734 || preserve_echo_area
1737 || (XFASTINT (w
->last_modified
) >= MODIFF
1738 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
1740 /* Try to redisplay starting at same place as before */
1741 /* If point has not moved off frame, accept the results */
1742 try_window (window
, startp
);
1743 if (cursor_vpos
>= 0)
1745 if (!just_this_one
|| current_buffer
->clip_changed
1746 || beg_unchanged
< startp
)
1747 /* Forget any recorded base line for line number display. */
1748 w
->base_line_number
= Qnil
;
1752 cancel_my_columns (w
);
1755 XSETFASTINT (w
->last_modified
, 0);
1756 XSETFASTINT (w
->last_overlay_modified
, 0);
1757 /* Redisplay the mode line. Select the buffer properly for that. */
1758 if (!update_mode_line
)
1760 set_buffer_temp (old
);
1761 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1762 update_mode_line
= 1;
1763 w
->update_mode_line
= Qt
;
1766 /* Try to scroll by specified few lines */
1768 if (scroll_step
&& !current_buffer
->clip_changed
1769 && startp
>= BEGV
&& startp
<= ZV
)
1773 pos
= *vmotion (Z
- XFASTINT (w
->window_end_pos
), scroll_step
, w
);
1774 if (pos
.vpos
>= height
)
1778 pos
= *vmotion (startp
, (PT
< startp
? - scroll_step
: scroll_step
), w
);
1780 if (PT
>= pos
.bufpos
)
1782 if (! NILP (Vwindow_scroll_functions
))
1784 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
1785 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
1786 make_number (pos
.bufpos
));
1787 pos
.bufpos
= marker_position (w
->start
);
1789 try_window (window
, pos
.bufpos
);
1790 if (cursor_vpos
>= 0)
1792 if (!just_this_one
|| current_buffer
->clip_changed
1793 || beg_unchanged
< startp
)
1794 /* Forget any recorded base line for line number display. */
1795 w
->base_line_number
= Qnil
;
1799 cancel_my_columns (w
);
1804 /* Finally, just choose place to start which centers point */
1807 /* Forget any previously recorded base line for line number display. */
1808 w
->base_line_number
= Qnil
;
1810 pos
= *vmotion (PT
, - (height
/ 2), w
);
1811 /* Set startp here explicitly in case that helps avoid an infinite loop
1812 in case the window-scroll-functions functions get errors. */
1813 Fset_marker (w
->start
, make_number (pos
.bufpos
), Qnil
);
1814 if (! NILP (Vwindow_scroll_functions
))
1816 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
1817 make_number (pos
.bufpos
));
1818 pos
.bufpos
= marker_position (w
->start
);
1820 try_window (window
, pos
.bufpos
);
1822 startp
= marker_position (w
->start
);
1823 w
->start_at_line_beg
1824 = (startp
== BEGV
|| FETCH_CHAR (startp
- 1) == '\n') ? Qt
: Qnil
;
1827 if ((update_mode_line
1828 /* If window not full width, must redo its mode line
1829 if the window to its side is being redone */
1830 || (!just_this_one
&& width
< FRAME_WIDTH (f
) - 1)
1831 || INTEGERP (w
->base_line_pos
)
1832 || (!NILP (w
->column_number_displayed
)
1833 && XFASTINT (w
->column_number_displayed
) != current_column ()))
1834 && height
!= XFASTINT (w
->height
))
1835 display_mode_line (w
);
1836 if (! line_number_displayed
1837 && ! BUFFERP (w
->base_line_pos
))
1839 w
->base_line_pos
= Qnil
;
1840 w
->base_line_number
= Qnil
;
1843 /* When we reach a frame's selected window, redo the frame's menu bar. */
1844 if (update_mode_line
1845 && (FRAME_WINDOW_P (f
)
1847 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1848 FRAME_EXTERNAL_MENU_BAR (f
)
1850 FRAME_MENU_BAR_LINES (f
) > 0
1852 : FRAME_MENU_BAR_LINES (f
) > 0)
1853 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
1854 display_menu_bar (w
);
1857 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1859 int start
, end
, whole
;
1861 /* Calculate the start and end positions for the current window.
1862 At some point, it would be nice to choose between scrollbars
1863 which reflect the whole buffer size, with special markers
1864 indicating narrowing, and scrollbars which reflect only the
1867 Note that minibuffers sometimes aren't displaying any text. */
1868 if (! MINI_WINDOW_P (w
)
1869 || (w
== XWINDOW (minibuf_window
) && ! echo_area_glyphs
))
1872 start
= marker_position (w
->start
) - BEGV
;
1873 /* I don't think this is guaranteed to be right. For the
1874 moment, we'll pretend it is. */
1875 end
= (Z
- XINT (w
->window_end_pos
)) - BEGV
;
1877 if (end
< start
) end
= start
;
1878 if (whole
< (end
- start
)) whole
= end
- start
;
1881 start
= end
= whole
= 0;
1883 /* Indicate what this scroll bar ought to be displaying now. */
1884 (*set_vertical_scroll_bar_hook
) (w
, end
- start
, whole
, start
);
1886 /* Note that we actually used the scroll bar attached to this window,
1887 so it shouldn't be deleted at the end of redisplay. */
1888 (*redeem_scroll_bar_hook
) (w
);
1891 BUF_PT (current_buffer
) = opoint
;
1892 if (update_mode_line
)
1893 set_buffer_internal_1 (old
);
1895 set_buffer_temp (old
);
1896 BUF_PT (current_buffer
) = lpoint
;
1899 /* Do full redisplay on one window, starting at position `pos'. */
1902 try_window (window
, pos
)
1906 register struct window
*w
= XWINDOW (window
);
1907 register int height
= window_internal_height (w
);
1908 register int vpos
= XFASTINT (w
->top
);
1909 register int last_text_vpos
= vpos
;
1910 int tab_offset
= pos_tab_offset (w
, pos
);
1911 FRAME_PTR f
= XFRAME (w
->frame
);
1912 int width
= window_internal_width (w
) - 1;
1913 struct position val
;
1915 Fset_marker (w
->start
, make_number (pos
), Qnil
);
1917 overlay_arrow_seen
= 0;
1918 zv_strings_seen
= 0;
1919 val
.hpos
= XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0;
1921 while (--height
>= 0)
1923 val
= *display_text_line (w
, pos
, vpos
, val
.hpos
, tab_offset
);
1924 tab_offset
+= width
;
1925 /* For the first line displayed, display_text_line
1926 subtracts the prompt width from the tab offset.
1927 But it does not affect the value of our variable tab_offset.
1928 So we do the subtraction again,
1929 for the sake of continuation lines of that first line. */
1930 if (MINI_WINDOW_P (w
) && vpos
== XFASTINT (w
->top
))
1931 tab_offset
-= minibuf_prompt_width
;
1933 if (val
.vpos
) tab_offset
= 0;
1935 if (pos
!= val
.bufpos
)
1938 #ifdef USE_TEXT_PROPERTIES
1939 Lisp_Object invis_prop
;
1940 invis_prop
= Fget_char_property (val
.bufpos
-1, Qinvisible
, window
);
1941 invis
= TEXT_PROP_MEANS_INVISIBLE (invis_prop
);
1945 /* Next line, unless prev line ended in end of buffer with no cr */
1947 && (FETCH_CHAR (val
.bufpos
- 1) != '\n' || invis
));
1952 /* If last line is continued in middle of character,
1953 include the split character in the text considered on the frame */
1954 if (val
.hpos
< (XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0))
1957 /* If bottom just moved off end of frame, change mode line percentage. */
1958 if (XFASTINT (w
->window_end_pos
) == 0
1960 w
->update_mode_line
= Qt
;
1962 /* Say where last char on frame will be, once redisplay is finished. */
1963 XSETFASTINT (w
->window_end_pos
, Z
- pos
);
1964 XSETFASTINT (w
->window_end_vpos
, last_text_vpos
- XFASTINT (w
->top
));
1965 /* But that is not valid info until redisplay finishes. */
1966 w
->window_end_valid
= Qnil
;
1969 /* Try to redisplay when buffer is modified locally,
1970 computing insert/delete line to preserve text outside
1971 the bounds of the changes.
1972 Return 1 if successful, 0 if if cannot tell what to do,
1973 or -1 to tell caller to find a new window start,
1974 or -2 to tell caller to do normal redisplay with same window start. */
1977 try_window_id (window
)
1981 register struct window
*w
= XWINDOW (window
);
1982 register int height
= window_internal_height (w
);
1983 FRAME_PTR f
= XFRAME (w
->frame
);
1984 int top
= XFASTINT (w
->top
);
1985 int start
= marker_position (w
->start
);
1986 int width
= window_internal_width (w
) - 1;
1987 int hscroll
= XINT (w
->hscroll
);
1988 int lmargin
= hscroll
> 0 ? 1 - hscroll
: 0;
1991 register int i
, tem
;
1992 int last_text_vpos
= 0;
1994 int selective
= (INTEGERP (current_buffer
->selective_display
)
1995 ? XINT (current_buffer
->selective_display
)
1996 : !NILP (current_buffer
->selective_display
) ? -1 : 0);
1998 struct position val
, bp
, ep
, xp
, pp
;
1999 int scroll_amount
= 0;
2001 int tab_offset
, epto
, old_tick
;
2003 if (GPT
- BEG
< beg_unchanged
)
2004 beg_unchanged
= GPT
- BEG
;
2005 if (Z
- GPT
< end_unchanged
)
2006 end_unchanged
= Z
- GPT
;
2008 if (beg_unchanged
+ BEG
< start
)
2009 return 0; /* Give up if changes go above top of window */
2011 /* Find position before which nothing is changed. */
2012 bp
= *compute_motion (start
, 0, lmargin
, 0,
2013 min (ZV
, beg_unchanged
+ BEG
), height
, 0,
2014 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2015 if (bp
.vpos
>= height
)
2019 /* All changes are beyond the window end, and point is on the screen.
2020 We don't need to change the text at all.
2021 But we need to update window_end_pos to account for
2022 any change in buffer size. */
2023 bp
= *compute_motion (start
, 0, lmargin
, 0,
2025 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2026 XSETFASTINT (w
->window_end_vpos
, height
);
2027 XSETFASTINT (w
->window_end_pos
, Z
- bp
.bufpos
);
2035 /* Find beginning of that frame line. Must display from there. */
2036 bp
= *vmotion (bp
.bufpos
, 0, w
);
2044 /* If about to start displaying at the beginning of a continuation line,
2045 really start with previous frame line, in case it was not
2046 continued when last redisplayed */
2047 if ((bp
.contin
&& bp
.bufpos
- 1 == beg_unchanged
&& vpos
> 0)
2049 /* Likewise if we have to worry about selective display. */
2050 (selective
> 0 && bp
.bufpos
- 1 == beg_unchanged
&& vpos
> 0))
2052 bp
= *vmotion (bp
.bufpos
, -1, w
);
2057 if (bp
.contin
&& bp
.hpos
!= lmargin
)
2059 val
.hpos
= bp
.prevhpos
- width
+ lmargin
;
2066 /* Find first visible newline after which no more is changed. */
2067 tem
= find_next_newline (Z
- max (end_unchanged
, Z
- ZV
), 1);
2069 while (tem
< ZV
- 1 && (indented_beyond_p (tem
, selective
)))
2070 tem
= find_next_newline (tem
, 1);
2072 /* Compute the cursor position after that newline. */
2073 ep
= *compute_motion (pos
, vpos
, val
.hpos
, did_motion
, tem
,
2074 height
, - (1 << (BITS_PER_SHORT
- 1)),
2075 width
, hscroll
, pos_tab_offset (w
, bp
.bufpos
), w
);
2077 /* If changes reach past the text available on the frame,
2078 just display rest of frame. */
2079 if (ep
.bufpos
> Z
- XFASTINT (w
->window_end_pos
))
2082 stop_vpos
= ep
.vpos
;
2084 /* If no newline before ep, the line ep is on includes some changes
2085 that must be displayed. Make sure we don't stop before it. */
2086 /* Also, if changes reach all the way until ep.bufpos,
2087 it is possible that something was deleted after the
2088 newline before it, so the following line must be redrawn. */
2089 if (stop_vpos
== ep
.vpos
2090 && (ep
.bufpos
== BEGV
2091 || FETCH_CHAR (ep
.bufpos
- 1) != '\n'
2092 || ep
.bufpos
== Z
- end_unchanged
))
2093 stop_vpos
= ep
.vpos
+ 1;
2096 overlay_arrow_seen
= 0;
2097 zv_strings_seen
= 0;
2099 /* If changes do not reach to bottom of window,
2100 figure out how much to scroll the rest of the window */
2101 if (stop_vpos
< height
)
2103 /* Now determine how far up or down the rest of the window has moved */
2104 epto
= pos_tab_offset (w
, ep
.bufpos
);
2105 xp
= *compute_motion (ep
.bufpos
, ep
.vpos
, ep
.hpos
, 1,
2106 Z
- XFASTINT (w
->window_end_pos
),
2107 10000, 0, width
, hscroll
, epto
, w
);
2108 scroll_amount
= xp
.vpos
- XFASTINT (w
->window_end_vpos
);
2110 /* Is everything on frame below the changes whitespace?
2111 If so, no scrolling is really necessary. */
2112 for (i
= ep
.bufpos
; i
< xp
.bufpos
; i
++)
2114 tem
= FETCH_CHAR (i
);
2115 if (tem
!= ' ' && tem
!= '\n' && tem
!= '\t')
2121 XSETFASTINT (w
->window_end_vpos
,
2122 XFASTINT (w
->window_end_vpos
) + scroll_amount
);
2124 /* Before doing any scrolling, verify that point will be on frame. */
2125 if (PT
> ep
.bufpos
&& !(PT
<= xp
.bufpos
&& xp
.bufpos
< height
))
2127 if (PT
<= xp
.bufpos
)
2129 pp
= *compute_motion (ep
.bufpos
, ep
.vpos
, ep
.hpos
, 1,
2130 PT
, height
, - (1 << (BITS_PER_SHORT
- 1)),
2131 width
, hscroll
, epto
, w
);
2135 pp
= *compute_motion (xp
.bufpos
, xp
.vpos
, xp
.hpos
, 1,
2136 PT
, height
, - (1 << (BITS_PER_SHORT
- 1)),
2138 pos_tab_offset (w
, xp
.bufpos
), w
);
2140 if (pp
.bufpos
< PT
|| pp
.vpos
== height
)
2142 cursor_vpos
= pp
.vpos
+ top
;
2143 cursor_hpos
= XFASTINT (w
->left
) + minmax (0, pp
.hpos
, width
);
2146 if (stop_vpos
- scroll_amount
>= height
2147 || ep
.bufpos
== xp
.bufpos
)
2149 if (scroll_amount
< 0)
2150 stop_vpos
-= scroll_amount
;
2152 /* In this path, we have altered window_end_vpos
2153 and not left it negative.
2154 We must make sure that, in case display is preempted
2155 before the frame changes to reflect what we do here,
2156 further updates will not come to try_window_id
2157 and assume the frame and window_end_vpos match. */
2158 blank_end_of_window
= 1;
2160 else if (!scroll_amount
)
2162 /* Even if we don't need to scroll, we must adjust the
2163 charstarts of subsequent lines (that we won't redisplay)
2164 according to the amount of text inserted or deleted. */
2165 int oldpos
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[ep
.vpos
+ top
][0];
2166 int adjust
= ep
.bufpos
- oldpos
;
2167 adjust_window_charstarts (w
, ep
.vpos
+ top
- 1, adjust
);
2169 else if (bp
.bufpos
== Z
- end_unchanged
)
2171 /* If reprinting everything is nearly as fast as scrolling,
2172 don't bother scrolling. Can happen if lines are short. */
2173 if (scroll_cost (f
, bp
.vpos
+ top
- scroll_amount
,
2174 top
+ height
- max (0, scroll_amount
),
2176 > xp
.bufpos
- bp
.bufpos
- 20)
2177 /* Return "try normal display with same window-start."
2178 Too bad we can't prevent further scroll-thinking. */
2180 /* If pure deletion, scroll up as many lines as possible.
2181 In common case of killing a line, this can save the
2182 following line from being overwritten by scrolling
2183 and therefore having to be redrawn. */
2184 tem
= scroll_frame_lines (f
, bp
.vpos
+ top
- scroll_amount
,
2185 top
+ height
- max (0, scroll_amount
),
2186 scroll_amount
, bp
.bufpos
);
2191 /* scroll_frame_lines did not properly adjust subsequent
2192 lines' charstarts in the case where the text of the
2193 screen line at bp.vpos has changed.
2194 (This can happen in a deletion that ends in mid-line.)
2195 To adjust properly, we need to make things consistent
2197 So do a second adjust to make that happen.
2198 Note that stop_vpos >= ep.vpos, so it is sufficient
2199 to update the charstarts for lines at ep.vpos and below. */
2201 = FRAME_CURRENT_GLYPHS (f
)->charstarts
[ep
.vpos
+ top
][0];
2202 adjust_window_charstarts (w
, ep
.vpos
+ top
- 1,
2203 ep
.bufpos
- oldstart
);
2206 else if (scroll_amount
)
2208 /* If reprinting everything is nearly as fast as scrolling,
2209 don't bother scrolling. Can happen if lines are short. */
2210 /* Note that if scroll_amount > 0, xp.bufpos - bp.bufpos is an
2211 overestimate of cost of reprinting, since xp.bufpos
2212 would end up below the bottom of the window. */
2213 if (scroll_cost (f
, ep
.vpos
+ top
- scroll_amount
,
2214 top
+ height
- max (0, scroll_amount
),
2216 > xp
.bufpos
- ep
.bufpos
- 20)
2217 /* Return "try normal display with same window-start."
2218 Too bad we can't prevent further scroll-thinking. */
2220 tem
= scroll_frame_lines (f
, ep
.vpos
+ top
- scroll_amount
,
2221 top
+ height
- max (0, scroll_amount
),
2222 scroll_amount
, ep
.bufpos
);
2223 if (!tem
) stop_vpos
= height
;
2227 /* In any case, do not display past bottom of window */
2228 if (stop_vpos
>= height
)
2234 /* Handle case where pos is before w->start --
2235 can happen if part of line had been clipped and is not clipped now */
2236 if (vpos
== 0 && pos
< marker_position (w
->start
))
2237 Fset_marker (w
->start
, make_number (pos
), Qnil
);
2239 /* Redisplay the lines where the text was changed */
2240 last_text_vpos
= vpos
;
2241 tab_offset
= pos_tab_offset (w
, pos
);
2242 /* If we are starting display in mid-character, correct tab_offset
2243 to account for passing the line that that character really starts in. */
2244 if (val
.hpos
< lmargin
)
2245 tab_offset
+= width
;
2247 while (vpos
< stop_vpos
)
2249 val
= *display_text_line (w
, pos
, top
+ vpos
++, val
.hpos
, tab_offset
);
2250 /* If display_text_line ran a hook and changed some text,
2251 redisplay all the way to bottom of buffer
2252 So that we show the changes. */
2253 if (old_tick
!= MODIFF
)
2255 tab_offset
+= width
;
2256 if (val
.vpos
) tab_offset
= 0;
2257 if (pos
!= val
.bufpos
)
2259 /* Next line, unless prev line ended in end of buffer with no cr */
2260 = vpos
- (val
.vpos
&& FETCH_CHAR (val
.bufpos
- 1) != '\n');
2264 /* There are two cases:
2265 1) we have displayed down to the bottom of the window
2266 2) we have scrolled lines below stop_vpos by scroll_amount */
2270 /* If last line is continued in middle of character,
2271 include the split character in the text considered on the frame */
2272 if (val
.hpos
< lmargin
)
2274 XSETFASTINT (w
->window_end_vpos
, last_text_vpos
);
2275 XSETFASTINT (w
->window_end_pos
, Z
- val
.bufpos
);
2278 /* If scrolling made blank lines at window bottom,
2279 redisplay to fill those lines */
2280 if (scroll_amount
< 0)
2282 /* Don't consider these lines for general-purpose scrolling.
2283 That will save time in the scrolling computation. */
2284 FRAME_SCROLL_BOTTOM_VPOS (f
) = xp
.vpos
;
2289 vpos
= height
+ scroll_amount
;
2290 else if (xp
.contin
&& xp
.hpos
!= lmargin
)
2292 val
.hpos
= xp
.prevhpos
- width
+ lmargin
;
2296 blank_end_of_window
= 1;
2297 tab_offset
= pos_tab_offset (w
, pos
);
2298 /* If we are starting display in mid-character, correct tab_offset
2299 to account for passing the line that that character starts in. */
2300 if (val
.hpos
< lmargin
)
2301 tab_offset
+= width
;
2303 while (vpos
< height
)
2305 val
= *display_text_line (w
, pos
, top
+ vpos
++, val
.hpos
, tab_offset
);
2306 tab_offset
+= width
;
2307 if (val
.vpos
) tab_offset
= 0;
2311 /* Here is a case where display_text_line sets cursor_vpos wrong.
2312 Make it be fixed up, below. */
2318 /* If bottom just moved off end of frame, change mode line percentage. */
2319 if (XFASTINT (w
->window_end_pos
) == 0
2321 w
->update_mode_line
= Qt
;
2323 /* Attempt to adjust end-of-text positions to new bottom line */
2326 delta
= height
- xp
.vpos
;
2328 || (delta
> 0 && xp
.bufpos
<= ZV
)
2329 || (delta
== 0 && xp
.hpos
))
2331 val
= *vmotion (Z
- XFASTINT (w
->window_end_pos
), delta
, w
);
2332 XSETFASTINT (w
->window_end_pos
, Z
- val
.bufpos
);
2333 XSETFASTINT (w
->window_end_vpos
,
2334 XFASTINT (w
->window_end_vpos
) + val
.vpos
);
2338 w
->window_end_valid
= Qnil
;
2340 /* If point was not in a line that was displayed, find it */
2341 if (cursor_vpos
< 0)
2344 val
= *compute_motion (start
, 0, lmargin
, 0, PT
, 10000, 10000,
2345 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2346 /* Admit failure if point is off frame now */
2347 if (val
.vpos
>= height
)
2349 for (vpos
= 0; vpos
< height
; vpos
++)
2350 cancel_line (vpos
+ top
, f
);
2353 cursor_vpos
= val
.vpos
+ top
;
2354 cursor_hpos
= XFASTINT (w
->left
) + minmax (0, val
.hpos
, width
);
2357 FRAME_CURSOR_X (f
) = cursor_hpos
;
2358 FRAME_CURSOR_Y (f
) = cursor_vpos
;
2362 val
= *compute_motion (start
, 0, lmargin
, 0, ZV
,
2363 height
, - (1 << (BITS_PER_SHORT
- 1)),
2364 width
, hscroll
, pos_tab_offset (w
, start
), w
);
2365 if (val
.vpos
!= XFASTINT (w
->window_end_vpos
))
2367 if (XFASTINT (w
->window_end_pos
)
2375 /* Copy LEN glyphs starting address FROM to the rope TO.
2376 But don't actually copy the parts that would come in before S.
2377 Value is TO, advanced past the copied data.
2378 F is the frame we are displaying in. */
2381 copy_part_of_rope (f
, to
, s
, from
, len
, face
)
2383 register GLYPH
*to
; /* Copy to here. */
2384 register GLYPH
*s
; /* Starting point. */
2385 Lisp_Object
*from
; /* Data to copy. */
2387 int face
; /* Face to apply to glyphs which don't specify one. */
2390 register Lisp_Object
*fp
= from
;
2391 /* These cache the results of the last call to compute_glyph_face. */
2393 int last_merged
= 0;
2396 if (! FRAME_TERMCAP_P (f
))
2399 int glyph
= (INTEGERP (*fp
) ? XFASTINT (*fp
) : 0);
2402 if (FAST_GLYPH_FACE (glyph
) == 0)
2403 /* If GLYPH has no face code, use FACE. */
2405 else if (FAST_GLYPH_FACE (glyph
) == last_code
)
2406 /* If it's same as previous glyph, use same result. */
2407 facecode
= last_merged
;
2410 /* Merge this glyph's face and remember the result. */
2411 last_code
= FAST_GLYPH_FACE (glyph
);
2412 last_merged
= facecode
= compute_glyph_face (f
, last_code
, face
);
2416 *to
= FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph
), facecode
);
2424 if (to
>= s
) *to
= (INTEGERP (*fp
) ? XFASTINT (*fp
) : 0);
2431 /* Correct a glyph by replacing its specified user-level face code
2432 with a displayable computed face code. */
2435 fix_glyph (f
, glyph
, cface
)
2441 if (! FRAME_TERMCAP_P (f
))
2443 if (FAST_GLYPH_FACE (glyph
) != 0)
2444 cface
= compute_glyph_face (f
, FAST_GLYPH_FACE (glyph
), cface
);
2445 glyph
= FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph
), cface
);
2451 /* Display one line of window W, starting at position START in W's buffer.
2453 Display starting at horizontal position HPOS, expressed relative to
2454 W's left edge. In situations where the text at START shouldn't
2455 start at the left margin (i.e. when the window is hscrolled, or
2456 we're continuing a line which left off in the midst of a
2457 multi-column character), HPOS should be negative; we throw away
2458 characters up 'til hpos = 0. So, HPOS must take hscrolling into
2461 TABOFFSET is an offset for ostensible hpos, used in tab stop calculations.
2463 Display on position VPOS on the frame. It is origin 0, relative to
2464 the top of the frame, not W.
2466 Returns a STRUCT POSITION giving character to start next line with
2467 and where to display it, including a zero or negative hpos.
2468 The vpos field is not really a vpos; it is 1 unless the line is continued */
2470 struct position val_display_text_line
;
2472 static struct position
*
2473 display_text_line (w
, start
, vpos
, hpos
, taboffset
)
2480 register int pos
= start
;
2484 register unsigned char *p
;
2486 register GLYPH
*leftmargin
;
2487 register GLYPH
*p1prev
;
2488 register GLYPH
*p1start
;
2491 FRAME_PTR f
= XFRAME (w
->frame
);
2492 int tab_width
= XINT (current_buffer
->tab_width
);
2493 int ctl_arrow
= !NILP (current_buffer
->ctl_arrow
);
2494 int width
= window_internal_width (w
) - 1;
2495 struct position val
;
2498 int last_invis_skip
= 0;
2499 Lisp_Object last_invis_prop
;
2500 int hscroll
= XINT (w
->hscroll
);
2501 int truncate
= (hscroll
2502 || (truncate_partial_width_windows
2503 && XFASTINT (w
->width
) < FRAME_WIDTH (f
))
2504 || !NILP (current_buffer
->truncate_lines
));
2506 /* 1 if we should highlight the region. */
2507 int highlight_region
2508 = (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
)
2509 && XWINDOW (current_buffer
->last_selected_window
) == w
);
2510 int region_beg
, region_end
;
2512 int selective
= (INTEGERP (current_buffer
->selective_display
)
2513 ? XINT (current_buffer
->selective_display
)
2514 : !NILP (current_buffer
->selective_display
) ? -1 : 0);
2515 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (f
);
2516 register struct Lisp_Char_Table
*dp
= window_display_table (w
);
2518 Lisp_Object default_invis_vector
[3];
2519 /* Number of characters of ellipsis to display after an invisible line
2520 if it calls for an ellipsis.
2521 Note that this value can be nonzero regardless of whether
2522 selective display is enabled--you must check that separately. */
2524 = (dp
&& VECTORP (DISP_INVIS_VECTOR (dp
))
2525 ? XVECTOR (DISP_INVIS_VECTOR (dp
))->size
2526 : !NILP (current_buffer
->selective_display_ellipses
) ? 3 : 0);
2527 /* This is the sequence of Lisp objects to display
2528 when there are invisible lines. */
2529 Lisp_Object
*invis_vector_contents
2530 = (dp
&& VECTORP (DISP_INVIS_VECTOR (dp
))
2531 ? XVECTOR (DISP_INVIS_VECTOR (dp
))->contents
2532 : default_invis_vector
);
2534 GLYPH truncator
= (dp
== 0 || !INTEGERP (DISP_TRUNC_GLYPH (dp
))
2535 ? '$' : XINT (DISP_TRUNC_GLYPH (dp
)));
2536 GLYPH continuer
= (dp
== 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp
))
2537 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp
)));
2539 /* The next buffer location at which the face should change, due
2540 to overlays or text property changes. */
2541 int next_face_change
;
2543 /* The next location where the `invisible' property changes, or an
2544 overlay starts or ends. */
2547 /* The face we're currently using. */
2548 int current_face
= 0;
2551 XSETFASTINT (default_invis_vector
[2], '.');
2552 default_invis_vector
[0] = default_invis_vector
[1] = default_invis_vector
[2];
2554 hpos
+= XFASTINT (w
->left
);
2555 get_display_line (f
, vpos
, XFASTINT (w
->left
));
2556 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
2558 /* Show where to highlight the region. */
2559 if (highlight_region
&& XMARKER (current_buffer
->mark
)->buffer
!= 0
2560 /* Maybe highlight only in selected window. */
2561 && (highlight_nonselected_windows
2562 || w
== XWINDOW (selected_window
)))
2564 region_beg
= marker_position (current_buffer
->mark
);
2565 if (PT
< region_beg
)
2567 region_end
= region_beg
;
2572 w
->region_showing
= Qt
;
2575 region_beg
= region_end
= -1;
2577 if (MINI_WINDOW_P (w
)
2579 && vpos
== XFASTINT (w
->top
))
2581 if (! NILP (minibuf_prompt
))
2583 minibuf_prompt_width
2584 = (display_string (w
, vpos
, XSTRING (minibuf_prompt
)->data
,
2585 XSTRING (minibuf_prompt
)->size
, hpos
,
2586 /* Display a space if we truncate. */
2589 /* Truncate the prompt a little before the
2590 margin, so user input can at least start
2591 on the first line. */
2592 w
->width
> 10 ? w
->width
- 4 : -1)
2594 hpos
+= minibuf_prompt_width
;
2595 taboffset
-= minibuf_prompt_width
;
2598 minibuf_prompt_width
= 0;
2601 /* If we're hscrolled at all, use compute_motion to skip over any
2602 text off the left edge of the window. compute_motion may know
2603 tricks to do this faster than we can. */
2606 struct position
*left_edge
2607 = compute_motion (pos
, vpos
, hpos
, 0,
2609 width
, hscroll
, taboffset
, w
);
2611 /* Retrieve the buffer position and column provided by
2612 compute_motion. We can't assume that the column will be
2613 zero, because you may have multi-column characters crossing
2616 compute_motion may have moved us past the screen position we
2617 requested, if we hit a multi-column character, or the end of
2618 the line. If so, back up. */
2619 if (left_edge
->vpos
> vpos
2620 || left_edge
->hpos
> 0)
2622 pos
= left_edge
->bufpos
- 1;
2623 hpos
= left_edge
->prevhpos
;
2627 pos
= left_edge
->bufpos
;
2628 hpos
= left_edge
->hpos
;
2632 desired_glyphs
->bufp
[vpos
] = start
;
2633 p1
= desired_glyphs
->glyphs
[vpos
] + hpos
;
2635 charstart
= desired_glyphs
->charstarts
[vpos
] + hpos
;
2636 /* In case we don't ever write anything into it... */
2637 desired_glyphs
->charstarts
[vpos
][XFASTINT (w
->left
)] = -1;
2638 leftmargin
= desired_glyphs
->glyphs
[vpos
] + XFASTINT (w
->left
);
2639 endp
= leftmargin
+ width
;
2641 /* Arrange the overlays nicely for our purposes. Usually, we call
2642 display_text_line on only one line at a time, in which case this
2643 can't really hurt too much, or we call it on lines which appear
2644 one after another in the buffer, in which case all calls to
2645 recenter_overlay_lists but the first will be pretty cheap. */
2646 recenter_overlay_lists (current_buffer
, pos
);
2648 /* Loop generating characters.
2649 Stop at end of buffer, before newline,
2650 if reach or pass continuation column,
2651 or at face change. */
2653 next_face_change
= pos
;
2654 next_boundary
= pos
;
2663 while (pos
== next_boundary
)
2665 Lisp_Object position
, limit
, prop
, ww
;
2667 /* Display the overlay strings here, unless we're at ZV
2668 and have already displayed the appropriate strings
2669 on an earlier line. */
2670 if (pos
< ZV
|| !zv_strings_seen
++)
2674 ovlen
= overlay_strings (pos
, w
, &ovstr
);
2675 for (; ovlen
; ovlen
--, ovstr
++)
2677 if (p1
>= leftmargin
&& p1
< endp
)
2678 *p1
= MAKE_GLYPH (f
, *ovstr
, current_face
);
2683 /* Did we reach point? Record the cursor location. */
2684 if (pos
== PT
&& cursor_vpos
< 0)
2687 cursor_hpos
= p1
- leftmargin
;
2693 XSETFASTINT (position
, pos
);
2694 limit
= Fnext_overlay_change (position
);
2695 #ifdef USE_TEXT_PROPERTIES
2696 /* This is just an estimate to give reasonable
2697 performance; nothing should go wrong if it is too small. */
2698 if (XFASTINT (limit
) > pos
+ 50)
2699 XSETFASTINT (limit
, pos
+ 50);
2700 limit
= Fnext_single_property_change (position
, Qinvisible
,
2701 Fcurrent_buffer (), limit
);
2703 next_boundary
= XFASTINT (limit
);
2704 /* if the `invisible' property is set, we can skip to
2705 the next property change. */
2707 prop
= Fget_char_property (position
, Qinvisible
, ww
);
2708 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
2710 if (pos
< PT
&& next_boundary
>= PT
)
2713 cursor_hpos
= p1
- leftmargin
;
2715 pos
= next_boundary
;
2716 last_invis_skip
= pos
;
2717 last_invis_prop
= prop
;
2721 /* Did we reach point? Record the cursor location. */
2722 if (pos
== PT
&& cursor_vpos
< 0)
2725 cursor_hpos
= p1
- leftmargin
;
2728 /* Did we hit the end of the visible region of the buffer?
2732 /* Update charstarts for the end of this line. */
2733 /* Do nothing if off the left edge or at the right edge. */
2734 if (p1
>= leftmargin
&& p1
+ 1 != endp
)
2736 int *p2x
= &charstart
[(p1
< leftmargin
2744 /* Figure out where (if at all) the
2745 redisplay_end_trigger-hook should run. */
2746 if (MARKERP (w
->redisplay_end_trigger
)
2747 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2748 e_t_h
= marker_position (w
->redisplay_end_trigger
);
2749 else if (INTEGERP (w
->redisplay_end_trigger
))
2750 e_t_h
= XINT (w
->redisplay_end_trigger
);
2754 /* If we've gone past the place to run a hook,
2756 if (pos
>= e_t_h
&& e_t_h
!= ZV
)
2758 Lisp_Object args
[3];
2760 args
[0] = Qredisplay_end_trigger_functions
;
2761 XSETWINDOW (args
[1], w
);
2762 XSETINT (args
[2], e_t_h
);
2764 /* Since we are *trying* to run these functions,
2765 don't try to run them again, even if they get an error. */
2766 w
->redisplay_end_trigger
= Qnil
;
2767 Frun_hook_with_args (3, args
);
2770 /* Notice if it changed the face of this character. */
2771 next_face_change
= pos
;
2775 /* Did we hit a face change? Figure out what face we should
2776 use now. We also hit this the first time through the
2777 loop, to see what face we should start with. */
2778 if (pos
>= next_face_change
2779 && (FRAME_WINDOW_P (f
) || FRAME_MSDOS_P (f
)))
2780 current_face
= compute_char_face (f
, w
, pos
,
2781 region_beg
, region_end
,
2782 &next_face_change
, pos
+ 50, 0);
2785 /* Compute the next place we need to stop
2786 and do something special; set PAUSE. */
2790 if (pos
< next_boundary
&& next_boundary
< pause
)
2791 pause
= next_boundary
;
2792 if (pos
< next_face_change
&& next_face_change
< pause
)
2793 pause
= next_face_change
;
2798 /* Wouldn't you hate to read the next line to someone over
2800 if (pos
< PT
&& PT
< pause
)
2802 if (pos
< GPT
&& GPT
< pause
)
2805 p
= &FETCH_CHAR (pos
);
2814 /* Let a display table override all standard display methods. */
2815 if (dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
2817 p1
= copy_part_of_rope (f
, p1
, leftmargin
,
2818 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->contents
,
2819 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->size
,
2822 else if (c
>= 040 && c
< 0177)
2824 if (p1
>= leftmargin
)
2825 *p1
= MAKE_GLYPH (f
, c
, current_face
);
2831 if (last_invis_skip
== pos
2832 && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop
))
2836 && indented_beyond_p (pos
+ 1, selective
))
2839 pos
= find_next_newline (pos
+ 1, 1);
2840 if (FETCH_CHAR (pos
- 1) == '\n')
2843 if (invis
&& selective_rlen
> 0 && p1
>= leftmargin
)
2845 p1
+= selective_rlen
;
2846 if (p1
- leftmargin
> width
)
2848 copy_part_of_rope (f
, p1prev
, p1prev
, invis_vector_contents
,
2849 (p1
- p1prev
), current_face
);
2852 /* Draw the face of the newline character as extending all the
2853 way to the end of the frame line. */
2856 if (p1
< leftmargin
)
2859 *p1
++ = FAST_MAKE_GLYPH (' ', current_face
);
2863 /* Update charstarts for the newline that ended this line. */
2864 /* Do nothing here for a char that's entirely off the left edge
2865 or if it starts at the right edge. */
2866 if (p1
>= leftmargin
&& p1prev
!= endp
)
2868 /* Store the newline's position into charstarts
2869 for the column where the newline starts.
2870 Store -1 for the rest of the glyphs it occupies. */
2871 int *p2x
= &charstart
[(p1prev
< leftmargin
2872 ? leftmargin
: p1prev
)
2874 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
2887 if (p1
>= leftmargin
&& p1
< endp
)
2888 *p1
= MAKE_GLYPH (f
, ' ', current_face
);
2891 while ((p1
- leftmargin
+ taboffset
+ hscroll
- (hscroll
> 0))
2894 else if (c
== Ctl ('M') && selective
== -1)
2896 pos
= find_next_newline (pos
, 1);
2897 if (FETCH_CHAR (pos
- 1) == '\n')
2899 if (selective_rlen
> 0)
2901 p1
+= selective_rlen
;
2902 if (p1
- leftmargin
> width
)
2904 copy_part_of_rope (f
, p1prev
, p1prev
, invis_vector_contents
,
2905 (p1
- p1prev
), current_face
);
2908 /* Draw the face of the newline character as extending all the
2909 way to the end of the frame line. */
2912 if (p1
< leftmargin
)
2915 *p1
++ = FAST_MAKE_GLYPH (' ', current_face
);
2919 /* Update charstarts for the ^M that ended this line. */
2920 /* Do nothing here for a char that's entirely off the left edge
2921 or if it starts at the right edge. */
2922 if (p1
>= leftmargin
&& p1prev
!= endp
)
2924 /* Store the newline's position into charstarts
2925 for the column where the newline starts.
2926 Store -1 for the rest of the glyphs it occupies. */
2927 int *p2x
= &charstart
[(p1prev
< leftmargin
2928 ? leftmargin
: p1prev
)
2930 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
2938 else if (c
< 0200 && ctl_arrow
)
2940 if (p1
>= leftmargin
)
2941 *p1
= fix_glyph (f
, (dp
&& INTEGERP (DISP_CTRL_GLYPH (dp
))
2942 ? XINT (DISP_CTRL_GLYPH (dp
)) : '^'),
2945 if (p1
>= leftmargin
&& p1
< endp
)
2946 *p1
= MAKE_GLYPH (f
, c
^ 0100, current_face
);
2951 if (p1
>= leftmargin
)
2952 *p1
= fix_glyph (f
, (dp
&& INTEGERP (DISP_ESCAPE_GLYPH (dp
))
2953 ? XINT (DISP_ESCAPE_GLYPH (dp
)) : '\\'),
2956 if (p1
>= leftmargin
&& p1
< endp
)
2957 *p1
= MAKE_GLYPH (f
, (c
>> 6) + '0', current_face
);
2959 if (p1
>= leftmargin
&& p1
< endp
)
2960 *p1
= MAKE_GLYPH (f
, (7 & (c
>> 3)) + '0', current_face
);
2962 if (p1
>= leftmargin
&& p1
< endp
)
2963 *p1
= MAKE_GLYPH (f
, (7 & c
) + '0', current_face
);
2970 /* Update charstarts for the character just output. */
2972 /* Do nothing here for a char that's entirely off the left edge. */
2973 if (p1
>= leftmargin
)
2975 /* Store the char's position into charstarts
2976 for the first glyph occupied by this char.
2977 Store -1 for the rest of the glyphs it occupies. */
2980 int *p2x
= &charstart
[(p1prev
< leftmargin
2981 ? leftmargin
: p1prev
)
2983 int *p2
= &charstart
[(p1
< endp
? p1
: endp
) - p1start
];
2993 val
.hpos
= - XINT (w
->hscroll
);
3001 /* Store 0 in this charstart line for the positions where
3002 there is no character. But do leave what was recorded
3003 for the character that ended the line. */
3004 /* Add 1 in the endtest to compensate for the fact that ENDP was
3005 made from WIDTH, which is 1 less than the window's actual
3007 i
= p1
- p1start
+ 1;
3008 if (p1
< leftmargin
)
3009 i
+= leftmargin
- p1
;
3010 for (; i
< endp
- p1start
+ 1; i
++)
3013 /* Handle continuation in middle of a character */
3014 /* by backing up over it */
3017 /* Don't back up if we never actually displayed any text.
3018 This occurs when the minibuffer prompt takes up the whole line. */
3021 /* Start the next line with that same character */
3023 /* but at negative hpos, to skip the columns output on this line. */
3024 val
.hpos
+= p1prev
- endp
;
3027 /* Keep in this line everything up to the continuation column. */
3031 /* Finish deciding which character to start the next line on,
3032 and what hpos to start it at.
3033 Also set `lastpos' to the last position which counts as "on this line"
3034 for cursor-positioning. */
3038 if (FETCH_CHAR (pos
) == '\n')
3040 /* If stopped due to a newline, start next line after it */
3042 /* Check again for hidden lines, in case the newline occurred exactly
3043 at the right margin. */
3044 while (pos
< ZV
&& selective
> 0
3045 && indented_beyond_p (pos
, selective
))
3046 pos
= find_next_newline (pos
, 1);
3049 /* Stopped due to right margin of window */
3053 *p1
++ = fix_glyph (f
, truncator
, 0);
3054 /* Truncating => start next line after next newline,
3055 and point is on this line if it is before the newline,
3056 and skip none of first char of next line */
3058 pos
= find_next_newline (pos
, 1);
3059 while (pos
< ZV
&& selective
> 0
3060 && indented_beyond_p (pos
, selective
));
3061 val
.hpos
= XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0;
3063 lastpos
= pos
- (FETCH_CHAR (pos
- 1) == '\n');
3067 *p1
++ = fix_glyph (f
, continuer
, 0);
3074 /* If point is at eol or in invisible text at eol,
3075 record its frame location now. */
3077 if (start
<= PT
&& PT
<= lastpos
&& cursor_vpos
< 0)
3080 cursor_hpos
= p1
- leftmargin
;
3083 if (cursor_vpos
== vpos
)
3085 if (cursor_hpos
< 0) cursor_hpos
= 0;
3086 if (cursor_hpos
> width
) cursor_hpos
= width
;
3087 cursor_hpos
+= XFASTINT (w
->left
);
3088 if (w
== XWINDOW (FRAME_SELECTED_WINDOW (f
)))
3090 if (!(cursor_in_echo_area
&& FRAME_HAS_MINIBUF_P (f
)
3091 && EQ (FRAME_MINIBUF_WINDOW (f
), minibuf_window
)))
3093 FRAME_CURSOR_Y (f
) = cursor_vpos
;
3094 FRAME_CURSOR_X (f
) = cursor_hpos
;
3097 if (w
== XWINDOW (selected_window
))
3099 /* Line is not continued and did not start
3100 in middle of character */
3101 if ((hpos
- XFASTINT (w
->left
)
3102 == (XINT (w
->hscroll
) ? 1 - XINT (w
->hscroll
) : 0))
3105 this_line_bufpos
= start
;
3106 this_line_buffer
= current_buffer
;
3107 this_line_vpos
= cursor_vpos
;
3108 this_line_start_hpos
= hpos
;
3109 this_line_endpos
= Z
- lastpos
;
3112 this_line_bufpos
= 0;
3117 /* If hscroll and line not empty, insert truncation-at-left marker */
3118 if (hscroll
&& lastpos
!= start
)
3120 *leftmargin
= fix_glyph (f
, truncator
, 0);
3121 if (p1
<= leftmargin
)
3122 p1
= leftmargin
+ 1;
3125 if (XFASTINT (w
->width
) + XFASTINT (w
->left
) != FRAME_WIDTH (f
))
3128 if (p1
< leftmargin
) p1
= leftmargin
;
3129 while (p1
< endp
) *p1
++ = SPACEGLYPH
;
3131 /* Don't draw vertical bars if we're using scroll bars. They're
3132 covered up by the scroll bars, and it's distracting to see
3133 them when the scroll bar windows are flickering around to be
3135 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3138 for (i
= 0; i
< FRAME_SCROLL_BAR_COLS (f
); i
++)
3142 *p1
++ = (dp
&& INTEGERP (DISP_BORDER_GLYPH (dp
))
3143 ? DISP_BORDER_GLYPH (dp
)
3146 desired_glyphs
->used
[vpos
] = max (desired_glyphs
->used
[vpos
],
3147 p1
- desired_glyphs
->glyphs
[vpos
]);
3148 desired_glyphs
->glyphs
[vpos
][desired_glyphs
->used
[vpos
]] = 0;
3150 /* If the start of this line is the overlay arrow-position,
3151 then put the arrow string into the display-line. */
3153 if (MARKERP (Voverlay_arrow_position
)
3154 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
3155 && start
== marker_position (Voverlay_arrow_position
)
3156 && STRINGP (Voverlay_arrow_string
)
3157 && ! overlay_arrow_seen
)
3159 unsigned char *p
= XSTRING (Voverlay_arrow_string
)->data
;
3161 int len
= XSTRING (Voverlay_arrow_string
)->size
;
3167 if (!NULL_INTERVAL_P (XSTRING (Voverlay_arrow_string
)->intervals
))
3169 /* If the arrow string has text props, obey them when displaying. */
3170 for (i
= 0; i
< len
; i
++)
3173 Lisp_Object face
, ilisp
;
3176 XSETFASTINT (ilisp
, i
);
3177 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
3178 newface
= compute_glyph_face_1 (f
, face
, 0);
3179 leftmargin
[i
] = FAST_MAKE_GLYPH (c
, newface
);
3183 #endif /* HAVE_FACES */
3185 for (i
= 0; i
< len
; i
++)
3186 leftmargin
[i
] = p
[i
];
3189 /* Bug in SunOS 4.1.1 compiler requires this intermediate variable. */
3190 arrow_end
= (leftmargin
- desired_glyphs
->glyphs
[vpos
]) + len
;
3191 if (desired_glyphs
->used
[vpos
] < arrow_end
)
3192 desired_glyphs
->used
[vpos
] = arrow_end
;
3194 overlay_arrow_seen
= 1;
3198 val_display_text_line
= val
;
3199 return &val_display_text_line
;
3202 /* Redisplay the menu bar in the frame for window W. */
3205 display_menu_bar (w
)
3208 Lisp_Object items
, tail
;
3209 register int vpos
= 0;
3210 register FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
3211 int maxendcol
= FRAME_WIDTH (f
);
3216 if (!NILP (Vwindow_system
))
3220 #ifdef USE_X_TOOLKIT
3223 #endif /* USE_X_TOOLKIT */
3225 get_display_line (f
, vpos
, 0);
3227 items
= FRAME_MENU_BAR_ITEMS (f
);
3228 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
3230 Lisp_Object pos
, string
;
3231 string
= XVECTOR (items
)->contents
[i
+ 1];
3235 XSETFASTINT (XVECTOR (items
)->contents
[i
+ 3], hpos
);
3237 if (hpos
< maxendcol
)
3238 hpos
= display_string (XWINDOW (FRAME_ROOT_WINDOW (f
)), vpos
,
3239 XSTRING (string
)->data
,
3240 XSTRING (string
)->size
,
3241 hpos
, 0, 0, hpos
, maxendcol
);
3242 /* Put a space between items. */
3243 if (hpos
< maxendcol
)
3245 int hpos1
= hpos
+ 1;
3246 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 0,
3247 min (hpos1
, maxendcol
), maxendcol
);
3251 FRAME_DESIRED_GLYPHS (f
)->bufp
[vpos
] = 0;
3252 FRAME_DESIRED_GLYPHS (f
)->highlight
[vpos
] = mode_line_inverse_video
;
3254 /* Fill out the line with spaces. */
3255 if (maxendcol
> hpos
)
3256 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 0, maxendcol
, maxendcol
);
3258 /* Clear the rest of the lines allocated to the menu bar. */
3260 while (vpos
< FRAME_MENU_BAR_LINES (f
))
3261 get_display_line (f
, vpos
++, 0);
3264 /* Display the mode line for window w */
3267 display_mode_line (w
)
3270 register int vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
3271 register int left
= XFASTINT (w
->left
);
3272 register int right
= XFASTINT (w
->width
) + left
;
3273 register FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
3275 line_number_displayed
= 0;
3276 w
->column_number_displayed
= Qnil
;
3278 get_display_line (f
, vpos
, left
);
3280 /* Temporarily make frame F's kboard the current kboard
3281 so that kboard-local variables in the mode_line_format
3282 will get the right values. */
3283 push_frame_kboard (f
);
3285 display_mode_element (w
, vpos
, left
, 0, right
, right
,
3286 current_buffer
->mode_line_format
);
3288 pop_frame_kboard ();
3290 FRAME_DESIRED_GLYPHS (f
)->bufp
[vpos
] = 0;
3292 /* Make the mode line inverse video if the entire line
3293 is made of mode lines.
3294 I.e. if this window is full width,
3295 or if it is the child of a full width window
3296 (which implies that that window is split side-by-side
3297 and the rest of this line is mode lines of the sibling windows). */
3298 if (XFASTINT (w
->width
) == FRAME_WIDTH (f
)
3299 || XFASTINT (XWINDOW (w
->parent
)->width
) == FRAME_WIDTH (f
))
3300 FRAME_DESIRED_GLYPHS (f
)->highlight
[vpos
] = mode_line_inverse_video
;
3302 else if (! FRAME_TERMCAP_P (f
) && mode_line_inverse_video
)
3304 /* For a partial width window, explicitly set face of each glyph. */
3306 GLYPH
*ptr
= FRAME_DESIRED_GLYPHS (f
)->glyphs
[vpos
];
3307 for (i
= left
; i
< right
; ++i
)
3308 ptr
[i
] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr
[i
]), 1);
3313 /* Contribute ELT to the mode line for window W.
3314 How it translates into text depends on its data type.
3316 VPOS is the position of the mode line being displayed.
3318 HPOS is the position (absolute on frame) where this element's text
3319 should start. The output is truncated automatically at the right
3322 DEPTH is the depth in recursion. It is used to prevent
3323 infinite recursion here.
3325 MINENDCOL is the hpos before which the element may not end.
3326 The element is padded at the right with spaces if nec
3327 to reach this column.
3329 MAXENDCOL is the hpos past which this element may not extend.
3330 If MINENDCOL is > MAXENDCOL, MINENDCOL takes priority.
3331 (This is necessary to make nested padding and truncation work.)
3333 Returns the hpos of the end of the text generated by ELT.
3334 The next element will receive that value as its HPOS arg,
3335 so as to concatenate the elements. */
3338 display_mode_element (w
, vpos
, hpos
, depth
, minendcol
, maxendcol
, elt
)
3340 register int vpos
, hpos
;
3343 register int maxendcol
;
3344 register Lisp_Object elt
;
3352 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
3356 /* A string: output it and check for %-constructs within it. */
3357 register unsigned char c
;
3358 register unsigned char *this = XSTRING (elt
)->data
;
3360 while (hpos
< maxendcol
&& *this)
3362 unsigned char *last
= this;
3363 while ((c
= *this++) != '\0' && c
!= '%')
3365 if (this - 1 != last
)
3367 register int lim
= --this - last
+ hpos
;
3368 if (frame_title_ptr
)
3369 hpos
= store_frame_title (last
, hpos
, min (lim
, maxendcol
));
3371 hpos
= display_string (w
, vpos
, last
, -1, hpos
, 0, 1,
3372 hpos
, min (lim
, maxendcol
));
3376 register int minendcol
;
3377 register int spec_width
= 0;
3379 /* We can't allow -ve args due to the "%-" construct */
3380 /* Argument specifies minwidth but not maxwidth
3381 (maxwidth can be specified by
3382 (<negative-number> . <stuff>) mode-line elements) */
3384 while ((c
= *this++) >= '0' && c
<= '9')
3386 spec_width
= spec_width
* 10 + (c
- '0');
3389 minendcol
= hpos
+ spec_width
;
3390 if (minendcol
> maxendcol
)
3392 spec_width
= maxendcol
- hpos
;
3393 minendcol
= maxendcol
;
3397 hpos
= display_mode_element (w
, vpos
, hpos
, depth
,
3398 spec_width
, maxendcol
,
3399 Vglobal_mode_string
);
3402 char *spec
= decode_mode_spec (w
, c
, spec_width
,
3404 if (frame_title_ptr
)
3405 hpos
= store_frame_title (spec
, minendcol
, maxendcol
);
3407 hpos
= display_string (w
, vpos
, spec
, -1,
3409 minendcol
, maxendcol
);
3417 /* A symbol: process the value of the symbol recursively
3418 as if it appeared here directly. Avoid error if symbol void.
3419 Special case: if value of symbol is a string, output the string
3422 register Lisp_Object tem
;
3423 tem
= Fboundp (elt
);
3426 tem
= Fsymbol_value (elt
);
3427 /* If value is a string, output that string literally:
3428 don't check for % within it. */
3431 if (frame_title_ptr
)
3432 hpos
= store_frame_title (XSTRING (tem
)->data
,
3433 minendcol
, maxendcol
);
3435 hpos
= display_string (w
, vpos
, XSTRING (tem
)->data
,
3436 XSTRING (tem
)->size
,
3437 hpos
, 0, 1, minendcol
, maxendcol
);
3439 /* Give up right away for nil or t. */
3440 else if (!EQ (tem
, elt
))
3441 { elt
= tem
; goto tail_recurse
; }
3448 register Lisp_Object car
, tem
;
3450 /* A cons cell: three distinct cases.
3451 If first element is a string or a cons, process all the elements
3452 and effectively concatenate them.
3453 If first element is a negative number, truncate displaying cdr to
3454 at most that many characters. If positive, pad (with spaces)
3455 to at least that many characters.
3456 If first element is a symbol, process the cadr or caddr recursively
3457 according to whether the symbol's value is non-nil or nil. */
3458 car
= XCONS (elt
)->car
;
3461 tem
= Fboundp (car
);
3462 elt
= XCONS (elt
)->cdr
;
3465 /* elt is now the cdr, and we know it is a cons cell.
3466 Use its car if CAR has a non-nil value. */
3469 tem
= Fsymbol_value (car
);
3471 { elt
= XCONS (elt
)->car
; goto tail_recurse
; }
3473 /* Symbol's value is nil (or symbol is unbound)
3474 Get the cddr of the original list
3475 and if possible find the caddr and use that. */
3476 elt
= XCONS (elt
)->cdr
;
3479 else if (!CONSP (elt
))
3481 elt
= XCONS (elt
)->car
;
3484 else if (INTEGERP (car
))
3486 register int lim
= XINT (car
);
3487 elt
= XCONS (elt
)->cdr
;
3489 /* Negative int means reduce maximum width.
3490 DO NOT change MINENDCOL here!
3491 (20 -10 . foo) should truncate foo to 10 col
3492 and then pad to 20. */
3493 maxendcol
= min (maxendcol
, hpos
- lim
);
3496 /* Padding specified. Don't let it be more than
3499 if (lim
> maxendcol
)
3501 /* If that's more padding than already wanted, queue it.
3502 But don't reduce padding already specified even if
3503 that is beyond the current truncation point. */
3504 if (lim
> minendcol
)
3509 else if (STRINGP (car
) || CONSP (car
))
3511 register int limit
= 50;
3512 /* LIMIT is to protect against circular lists. */
3513 while (CONSP (elt
) && --limit
> 0
3514 && hpos
< maxendcol
)
3516 hpos
= display_mode_element (w
, vpos
, hpos
, depth
,
3519 elt
= XCONS (elt
)->cdr
;
3527 if (frame_title_ptr
)
3528 hpos
= store_frame_title ("*invalid*", minendcol
, maxendcol
);
3530 hpos
= display_string (w
, vpos
, "*invalid*", -1, hpos
, 0, 1,
3531 minendcol
, maxendcol
);
3535 if (minendcol
> hpos
)
3536 if (frame_title_ptr
)
3537 hpos
= store_frame_title ("", minendcol
, maxendcol
);
3539 hpos
= display_string (w
, vpos
, "", 0, hpos
, 0, 1, minendcol
, maxendcol
);
3543 /* Write a null-terminated, right justified decimal representation of
3544 the positive integer D to BUF using a minimal field width WIDTH. */
3547 pint2str (buf
, width
, d
)
3552 register char *p
= buf
;
3559 *p
++ = d
% 10 + '0';
3562 for (width
-= (int) (p
- buf
); width
> 0; --width
) *p
++ = ' ';
3572 /* Return a string for the output of a mode line %-spec for window W,
3573 generated by character C. SPEC_WIDTH is the field width when
3574 padding to the left (%c, %l). The value returned from this
3575 function will later be truncated to width MAXWIDTH. */
3577 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
3580 decode_mode_spec (w
, c
, spec_width
, maxwidth
)
3583 register int spec_width
;
3584 register int maxwidth
;
3587 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
3588 char *decode_mode_spec_buf
= (char *) FRAME_TEMP_GLYPHS (f
)->total_contents
;
3589 struct buffer
*b
= XBUFFER (w
->buffer
);
3592 if (maxwidth
> FRAME_WIDTH (f
))
3593 maxwidth
= FRAME_WIDTH (f
);
3598 if (!NILP (b
->read_only
))
3600 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
3605 /* This differs from %* only for a modified read-only buffer. */
3606 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
3608 if (!NILP (b
->read_only
))
3613 /* This differs from %* in ignoring read-only-ness. */
3614 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
3626 if (command_loop_level
> 5)
3628 p
= decode_mode_spec_buf
;
3629 for (i
= 0; i
< command_loop_level
; i
++)
3632 return decode_mode_spec_buf
;
3640 if (command_loop_level
> 5)
3642 p
= decode_mode_spec_buf
;
3643 for (i
= 0; i
< command_loop_level
; i
++)
3646 return decode_mode_spec_buf
;
3654 if (maxwidth
< sizeof (lots_of_dashes
))
3655 return lots_of_dashes
;
3658 for (p
= decode_mode_spec_buf
, i
= maxwidth
; i
> 0; i
--)
3662 return decode_mode_spec_buf
;
3668 if (maxwidth
>= 3 && XSTRING (obj
)->size
> maxwidth
)
3670 bcopy (XSTRING (obj
)->data
, decode_mode_spec_buf
, maxwidth
- 1);
3671 decode_mode_spec_buf
[maxwidth
- 1] = '\\';
3672 decode_mode_spec_buf
[maxwidth
] = '\0';
3673 return decode_mode_spec_buf
;
3680 int col
= current_column ();
3681 XSETFASTINT (w
->column_number_displayed
, col
);
3682 pint2str (decode_mode_spec_buf
, spec_width
, col
);
3683 return decode_mode_spec_buf
;
3687 /* %F displays the frame name. */
3688 if (!NILP (f
->title
))
3689 return (char *) XSTRING (f
->title
)->data
;
3690 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
3691 return (char *) XSTRING (f
->name
)->data
;
3699 else if (STRINGP (obj
) && XSTRING (obj
)->size
> maxwidth
)
3701 bcopy ("...", decode_mode_spec_buf
, 3);
3702 bcopy (XSTRING (obj
)->data
+ XSTRING (obj
)->size
- maxwidth
+ 3,
3703 decode_mode_spec_buf
+ 3, maxwidth
- 3);
3704 return decode_mode_spec_buf
;
3711 int startpos
= marker_position (w
->start
);
3712 int line
, linepos
, topline
;
3715 int height
= XFASTINT (w
->height
);
3717 /* If we decided that this buffer isn't suitable for line numbers,
3718 don't forget that too fast. */
3719 if (EQ (w
->base_line_pos
, w
->buffer
))
3722 /* If the buffer is very big, don't waste time. */
3723 if (BUF_ZV (b
) - BUF_BEGV (b
) > line_number_display_limit
)
3725 w
->base_line_pos
= Qnil
;
3726 w
->base_line_number
= Qnil
;
3730 if (!NILP (w
->base_line_number
)
3731 && !NILP (w
->base_line_pos
)
3732 && XFASTINT (w
->base_line_pos
) <= marker_position (w
->start
))
3734 line
= XFASTINT (w
->base_line_number
);
3735 linepos
= XFASTINT (w
->base_line_pos
);
3740 linepos
= BUF_BEGV (b
);
3743 /* Count lines from base line to window start position. */
3744 nlines
= display_count_lines (linepos
, startpos
, startpos
, &junk
);
3746 topline
= nlines
+ line
;
3748 /* Determine a new base line, if the old one is too close
3749 or too far away, or if we did not have one.
3750 "Too close" means it's plausible a scroll-down would
3752 if (startpos
== BUF_BEGV (b
))
3754 XSETFASTINT (w
->base_line_number
, topline
);
3755 XSETFASTINT (w
->base_line_pos
, BUF_BEGV (b
));
3757 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
3758 || linepos
== BUF_BEGV (b
))
3760 int limit
= BUF_BEGV (b
);
3762 int distance
= (height
* 2 + 30) * 200;
3764 if (startpos
- distance
> limit
)
3765 limit
= startpos
- distance
;
3767 nlines
= display_count_lines (startpos
, limit
,
3770 /* If we couldn't find the lines we wanted within
3772 give up on line numbers for this window. */
3773 if (position
== startpos
- distance
)
3775 w
->base_line_pos
= w
->buffer
;
3776 w
->base_line_number
= Qnil
;
3780 XSETFASTINT (w
->base_line_number
, topline
- nlines
);
3781 XSETFASTINT (w
->base_line_pos
, position
);
3784 /* Now count lines from the start pos to point. */
3785 nlines
= display_count_lines (startpos
, PT
, PT
, &junk
);
3787 /* Record that we did display the line number. */
3788 line_number_displayed
= 1;
3790 /* Make the string to show. */
3791 pint2str (decode_mode_spec_buf
, spec_width
, topline
+ nlines
);
3792 return decode_mode_spec_buf
;
3795 char* p
= decode_mode_spec_buf
;
3796 for (spec_width
-= 2; spec_width
> 0; --spec_width
) *p
++ = ' ';
3798 return decode_mode_spec_buf
;
3808 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
3814 int pos
= marker_position (w
->start
);
3815 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
3817 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
3819 if (pos
<= BUF_BEGV (b
))
3824 else if (pos
<= BUF_BEGV (b
))
3828 if (total
> 1000000)
3829 /* Do it differently for a large value, to avoid overflow. */
3830 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
3832 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
3833 /* We can't normally display a 3-digit number,
3834 so get us a 2-digit number that is close. */
3837 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
3838 return decode_mode_spec_buf
;
3842 /* Display percentage of size above the bottom of the screen. */
3845 int toppos
= marker_position (w
->start
);
3846 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
3847 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
3849 if (botpos
>= BUF_ZV (b
))
3851 if (toppos
<= BUF_BEGV (b
))
3858 if (total
> 1000000)
3859 /* Do it differently for a large value, to avoid overflow. */
3860 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
3862 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
3863 /* We can't normally display a 3-digit number,
3864 so get us a 2-digit number that is close. */
3867 if (toppos
<= BUF_BEGV (b
))
3868 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
3870 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
3871 return decode_mode_spec_buf
;
3876 /* status of process */
3877 obj
= Fget_buffer_process (w
->buffer
);
3879 return "no process";
3881 obj
= Fsymbol_name (Fprocess_status (obj
));
3885 case 't': /* indicate TEXT or BINARY */
3886 #ifdef MODE_LINE_BINARY_TEXT
3887 return MODE_LINE_BINARY_TEXT (b
);
3894 return (char *) XSTRING (obj
)->data
;
3899 /* Search for COUNT instances of a line boundary, which means either a
3900 newline or (if selective display enabled) a carriage return.
3901 Start at START. If COUNT is negative, search backwards.
3903 If we find COUNT instances, set *SHORTAGE to zero, and return the
3904 position after the COUNTth match. Note that for reverse motion
3905 this is not the same as the usual convention for Emacs motion commands.
3907 If we don't find COUNT instances before reaching the end of the
3908 buffer (or the beginning, if scanning backwards), set *SHORTAGE to
3909 the number of line boundaries left unfound, and return the end of the
3910 buffer we bumped up against. */
3913 display_scan_buffer (start
, count
, shortage
)
3914 int *shortage
, start
;
3917 int limit
= ((count
> 0) ? ZV
- 1 : BEGV
);
3918 int direction
= ((count
> 0) ? 1 : -1);
3920 register unsigned char *cursor
;
3921 unsigned char *base
;
3923 register int ceiling
;
3924 register unsigned char *ceiling_addr
;
3926 /* If we are not in selective display mode,
3927 check only for newlines. */
3928 if (! (!NILP (current_buffer
->selective_display
)
3929 && !INTEGERP (current_buffer
->selective_display
)))
3930 return scan_buffer ('\n', start
, 0, count
, shortage
, 0);
3932 /* The code that follows is like scan_buffer
3933 but checks for either newline or carriage return. */
3939 while (start
!= limit
+ 1)
3941 ceiling
= BUFFER_CEILING_OF (start
);
3942 ceiling
= min (limit
, ceiling
);
3943 ceiling_addr
= &FETCH_CHAR (ceiling
) + 1;
3944 base
= (cursor
= &FETCH_CHAR (start
));
3947 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
3949 if (cursor
!= ceiling_addr
)
3954 return (start
+ cursor
- base
+ 1);
3957 if (++cursor
== ceiling_addr
)
3963 start
+= cursor
- base
;
3967 start
--; /* first character we scan */
3968 while (start
> limit
- 1)
3969 { /* we WILL scan under start */
3970 ceiling
= BUFFER_FLOOR_OF (start
);
3971 ceiling
= max (limit
, ceiling
);
3972 ceiling_addr
= &FETCH_CHAR (ceiling
) - 1;
3973 base
= (cursor
= &FETCH_CHAR (start
));
3977 while (--cursor
!= ceiling_addr
3978 && *cursor
!= '\n' && *cursor
!= 015)
3980 if (cursor
!= ceiling_addr
)
3985 return (start
+ cursor
- base
+ 1);
3991 start
+= cursor
- base
;
3996 *shortage
= count
* direction
;
3997 return (start
+ ((direction
== 1 ? 0 : 1)));
4000 /* Count up to N lines starting from FROM.
4001 But don't go beyond LIMIT.
4002 Return the number of lines thus found (always positive).
4003 Store the position after what was found into *POS_PTR. */
4006 display_count_lines (from
, limit
, n
, pos_ptr
)
4019 *pos_ptr
= display_scan_buffer (from
, n
, &shortage
);
4025 /* When scanning backwards, scan_buffer stops *after* the last newline
4026 it finds, but does count it. Compensate for that. */
4027 return - n
- shortage
- (*pos_ptr
!= limit
);
4028 return n
- shortage
;
4031 /* Display STRING on one line of window W, starting at HPOS.
4032 Display at position VPOS. Caller should have done get_display_line.
4033 If VPOS == -1, display it as the current frame's title.
4034 LENGTH is the length of STRING, or -1 meaning STRING is null-terminated.
4036 TRUNCATE is GLYPH to display at end if truncated. Zero for none.
4038 MINCOL is the first column ok to end at. (Pad with spaces to this col.)
4039 MAXCOL is the last column ok to end at. Truncate here.
4040 -1 for MINCOL or MAXCOL means no explicit minimum or maximum.
4041 Both count from the left edge of the frame, as does HPOS.
4042 The right edge of W is an implicit maximum.
4043 If TRUNCATE is nonzero, the implicit maximum is one column before the edge.
4045 OBEY_WINDOW_WIDTH says to put spaces or vertical bars
4046 at the place where the current window ends in this line
4047 and not display anything beyond there. Otherwise, only MAXCOL
4048 controls where to stop output.
4050 Returns ending hpos. */
4053 display_string (w
, vpos
, string
, length
, hpos
, truncate
,
4054 obey_window_width
, mincol
, maxcol
)
4056 unsigned char *string
;
4060 int obey_window_width
;
4066 int hscroll
= XINT (w
->hscroll
);
4067 int tab_width
= XINT (XBUFFER (w
->buffer
)->tab_width
);
4068 register GLYPH
*start
;
4069 register GLYPH
*end
;
4070 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
4071 struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (f
);
4072 GLYPH
*p1start
= desired_glyphs
->glyphs
[vpos
] + hpos
;
4073 int window_width
= XFASTINT (w
->width
);
4075 /* Use the standard display table, not the window's display table.
4076 We don't want the mode line in rot13. */
4077 register struct Lisp_Char_Table
*dp
= 0;
4080 if (DISP_TABLE_P (Vstandard_display_table
))
4081 dp
= XCHAR_TABLE (Vstandard_display_table
);
4083 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
4086 start
= desired_glyphs
->glyphs
[vpos
] + XFASTINT (w
->left
);
4088 if (obey_window_width
)
4090 end
= start
+ window_width
- (truncate
!= 0);
4092 if ((window_width
+ XFASTINT (w
->left
)) != FRAME_WIDTH (f
))
4094 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4098 for (i
= 0; i
< FRAME_SCROLL_BAR_COLS (f
); i
++)
4106 if (! obey_window_width
4107 || (maxcol
>= 0 && end
- desired_glyphs
->glyphs
[vpos
] > maxcol
))
4108 end
= desired_glyphs
->glyphs
[vpos
] + maxcol
;
4110 /* Store 0 in charstart for these columns. */
4111 for (i
= (hpos
>= 0 ? hpos
: 0); i
< end
- p1start
+ hpos
; i
++)
4112 desired_glyphs
->charstarts
[vpos
][i
] = 0;
4114 if (maxcol
>= 0 && mincol
> maxcol
)
4117 /* We set truncated to 1 if we get stopped by trying to pass END
4118 (that is, trying to pass MAXCOL.) */
4125 /* Specified length. */
4128 /* Unspecified length (null-terminated string). */
4138 if (dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
4140 p1
= copy_part_of_rope (f
, p1
, start
,
4141 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->contents
,
4142 XVECTOR (DISP_CHAR_VECTOR (dp
, c
))->size
,
4145 else if (c
>= 040 && c
< 0177)
4155 if (p1
>= start
&& p1
< end
)
4159 while ((p1
- start
+ hscroll
- (hscroll
> 0)) % tab_width
);
4161 else if (c
< 0200 && ! NILP (buffer_defaults
.ctl_arrow
))
4164 *p1
= fix_glyph (f
, (dp
&& INTEGERP (DISP_CTRL_GLYPH (dp
))
4165 ? XINT (DISP_CTRL_GLYPH (dp
)) : '^'),
4168 if (p1
>= start
&& p1
< end
)
4175 *p1
= fix_glyph (f
, (dp
&& INTEGERP (DISP_ESCAPE_GLYPH (dp
))
4176 ? XINT (DISP_ESCAPE_GLYPH (dp
)) : '\\'),
4179 if (p1
>= start
&& p1
< end
)
4180 *p1
= (c
>> 6) + '0';
4182 if (p1
>= start
&& p1
< end
)
4183 *p1
= (7 & (c
>> 3)) + '0';
4185 if (p1
>= start
&& p1
< end
)
4186 *p1
= (7 & c
) + '0';
4194 if (truncate
) *p1
++ = fix_glyph (f
, truncate
, 0);
4196 else if (mincol
>= 0)
4198 end
= desired_glyphs
->glyphs
[vpos
] + mincol
;
4204 register int len
= p1
- desired_glyphs
->glyphs
[vpos
];
4206 if (len
> desired_glyphs
->used
[vpos
])
4207 desired_glyphs
->used
[vpos
] = len
;
4208 desired_glyphs
->glyphs
[vpos
][desired_glyphs
->used
[vpos
]] = 0;
4214 /* This is like a combination of memq and assq.
4215 Return 1 if PROPVAL appears as an element of LIST
4216 or as the car of an element of LIST.
4217 If PROPVAL is a list, compare each element against LIST
4218 in that way, and return 1 if any element of PROPVAL is found in LIST.
4220 This function cannot quit. */
4223 invisible_p (propval
, list
)
4224 register Lisp_Object propval
;
4227 register Lisp_Object tail
, proptail
;
4228 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4230 register Lisp_Object tem
;
4231 tem
= XCONS (tail
)->car
;
4232 if (EQ (propval
, tem
))
4234 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
4237 if (CONSP (propval
))
4238 for (proptail
= propval
; CONSP (proptail
);
4239 proptail
= XCONS (proptail
)->cdr
)
4241 Lisp_Object propelt
;
4242 propelt
= XCONS (proptail
)->car
;
4243 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4245 register Lisp_Object tem
;
4246 tem
= XCONS (tail
)->car
;
4247 if (EQ (propelt
, tem
))
4249 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
4256 /* Return 1 if PROPVAL appears as the car of an element of LIST
4257 and the cdr of that element is non-nil.
4258 If PROPVAL is a list, check each element of PROPVAL in that way,
4259 and the first time some element is found,
4260 return 1 if the cdr of that element is non-nil.
4262 This function cannot quit. */
4265 invisible_ellipsis_p (propval
, list
)
4266 register Lisp_Object propval
;
4269 register Lisp_Object tail
, proptail
;
4270 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4272 register Lisp_Object tem
;
4273 tem
= XCONS (tail
)->car
;
4274 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
4275 return ! NILP (XCONS (tem
)->cdr
);
4277 if (CONSP (propval
))
4278 for (proptail
= propval
; CONSP (proptail
);
4279 proptail
= XCONS (proptail
)->cdr
)
4281 Lisp_Object propelt
;
4282 propelt
= XCONS (proptail
)->car
;
4283 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4285 register Lisp_Object tem
;
4286 tem
= XCONS (tail
)->car
;
4287 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
4288 return ! NILP (XCONS (tem
)->cdr
);
4297 staticpro (&Qmenu_bar_update_hook
);
4298 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
4300 staticpro (&Qoverriding_terminal_local_map
);
4301 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
4303 staticpro (&Qoverriding_local_map
);
4304 Qoverriding_local_map
= intern ("overriding-local-map");
4306 staticpro (&Qwindow_scroll_functions
);
4307 Qwindow_scroll_functions
= intern ("window-scroll-functions");
4309 staticpro (&Qredisplay_end_trigger_functions
);
4310 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
4312 staticpro (&last_arrow_position
);
4313 staticpro (&last_arrow_string
);
4314 last_arrow_position
= Qnil
;
4315 last_arrow_string
= Qnil
;
4317 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
4318 "String (or mode line construct) included (normally) in `mode-line-format'.");
4319 Vglobal_mode_string
= Qnil
;
4321 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
4322 "Marker for where to display an arrow on top of the buffer text.\n\
4323 This must be the beginning of a line in order to work.\n\
4324 See also `overlay-arrow-string'.");
4325 Voverlay_arrow_position
= Qnil
;
4327 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
4328 "String to display as an arrow. See also `overlay-arrow-position'.");
4329 Voverlay_arrow_string
= Qnil
;
4331 DEFVAR_INT ("scroll-step", &scroll_step
,
4332 "*The number of lines to try scrolling a window by when point moves out.\n\
4333 If that fails to bring point back on frame, point is centered instead.\n\
4334 If this is zero, point is always centered after it moves off frame.");
4336 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, "Don't ask");
4338 DEFVAR_BOOL ("truncate-partial-width-windows",
4339 &truncate_partial_width_windows
,
4340 "*Non-nil means truncate lines in all windows less than full frame wide.");
4341 truncate_partial_width_windows
= 1;
4343 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
4344 "*Non-nil means use inverse video for the mode line.");
4345 mode_line_inverse_video
= 1;
4347 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit
,
4348 "*Maximum buffer size for which line number should be displayed.");
4349 line_number_display_limit
= 1000000;
4351 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
4352 "*Non-nil means highlight region even in nonselected windows.");
4353 highlight_nonselected_windows
= 1;
4355 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
4356 "Non-nil if more than one frame is visible on this display.\n\
4357 Minibuffer-only frames don't count, but iconified frames do.\n\
4358 This variable is not guaranteed to be accurate except while processing\n\
4359 `frame-title-format' and `icon-title-format'.");
4361 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
4362 "Template for displaying the titlebar of visible frames.\n\
4363 \(Assuming the window manager supports this feature.)\n\
4364 This variable has the same structure as `mode-line-format' (which see),\n\
4365 and is used only on frames for which no explicit name has been set\n\
4366 \(see `modify-frame-parameters').");
4367 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
4368 "Template for displaying the titlebar of an iconified frame.\n\
4369 \(Assuming the window manager supports this feature.)\n\
4370 This variable has the same structure as `mode-line-format' (which see),\n\
4371 and is used only on frames for which no explicit name has been set\n\
4372 \(see `modify-frame-parameters').");
4374 = Vframe_title_format
4375 = Fcons (intern ("multiple-frames"),
4376 Fcons (build_string ("%b"),
4377 Fcons (Fcons (build_string (""),
4378 Fcons (intern ("invocation-name"),
4379 Fcons (build_string ("@"),
4380 Fcons (intern ("system-name"),
4384 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
4385 "Maximum number of lines to keep in the message log buffer.\n\
4386 If nil, disable message logging. If t, log messages but don't truncate\n\
4387 the buffer when it becomes large.");
4388 XSETFASTINT (Vmessage_log_max
, 50);
4390 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
4391 "Functions called before redisplay, if window sizes have changed.\n\
4392 The value should be a list of functions that take one argument.\n\
4393 Just before redisplay, for each frame, if any of its windows have changed\n\
4394 size since the last redisplay, or have been split or deleted,\n\
4395 all the functions in the list are called, with the frame as argument.");
4396 Vwindow_size_change_functions
= Qnil
;
4398 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
4399 "List of Functions to call before redisplaying a window with scrolling.\n\
4400 Each function is called with two arguments, the window\n\
4401 and its new display-start position. Note that the value of `window-end'\n\
4402 is not valid when these functions are called.");
4403 Vwindow_scroll_functions
= Qnil
;
4406 /* initialize the window system */
4409 Lisp_Object root_window
;
4410 #ifndef COMPILER_REGISTER_BUG
4412 #endif /* COMPILER_REGISTER_BUG */
4413 struct window
*mini_w
;
4415 this_line_bufpos
= 0;
4417 mini_w
= XWINDOW (minibuf_window
);
4418 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
4420 echo_area_glyphs
= 0;
4421 previous_echo_glyphs
= 0;
4423 if (!noninteractive
)
4425 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
4426 XSETFASTINT (XWINDOW (root_window
)->top
, 0);
4427 set_window_height (root_window
, FRAME_HEIGHT (f
) - 1, 0);
4428 XSETFASTINT (mini_w
->top
, FRAME_HEIGHT (f
) - 1);
4429 set_window_height (minibuf_window
, 1, 0);
4431 XSETFASTINT (XWINDOW (root_window
)->width
, FRAME_WIDTH (f
));
4432 XSETFASTINT (mini_w
->width
, FRAME_WIDTH (f
));