You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <config.h>
#include "intervals.h"
#include "keyboard.h"
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
extern void set_frame_menubar ();
+extern int pending_menu_activation;
#endif
extern int interrupt_input;
extern Lisp_Object Voverriding_local_map_menu_flag;
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
+Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
+Lisp_Object Qredisplay_end_trigger_functions;
/* Nonzero means print newline to stdout before next minibuffer message. */
/* Nonzero means display mode line highlighted */
int mode_line_inverse_video;
+static void redisplay_internal ();
static int message_log_check_duplicate ();
static void echo_area_display ();
void mark_window_display_accurate ();
t means infinite. nil means don't log at all. */
Lisp_Object Vmessage_log_max;
\f
+/* Output a newline in the *Messages* buffer if "needs" one. */
+
void
message_log_maybe_newline ()
{
{
struct buffer *oldbuf;
int oldpoint, oldbegv, oldzv;
+ int old_windows_or_buffers_changed = windows_or_buffers_changed;
oldbuf = current_buffer;
Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
ZV = oldzv;
TEMP_SET_PT (oldpoint);
set_buffer_internal (oldbuf);
+ windows_or_buffers_changed = old_windows_or_buffers_changed;
message_log_need_newline = !nlflag;
}
}
-
/* We are at the end of the buffer after just having inserted a newline.
(Note: We depend on the fact we won't be crossing the gap.)
Check to see if the most recent message looks a lot like the previous one.
}
return 0;
}
-
+\f
/* Display an echo area message M with a specified length of LEN chars.
- The string may include null characters. If m is 0, clear out any
+ The string may include null characters. If M is 0, clear out any
existing message, and let the minibuffer text show through.
- Do not pass text that is stored in a Lisp string. */
+
+ The buffer M must continue to exist until after the echo area
+ gets cleared or some other message gets displayed there.
+
+ Do not pass text that is stored in a Lisp string.
+ Do not pass text in a buffer that was alloca'd. */
void
message2 (m, len)
}
-/* The non-logging part of that function. */
+/* The non-logging counterpart of message2. */
void
message2_nolog (m, len)
mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
-#ifdef MULTI_FRAME
FRAME_SAMPLE_VISIBILITY (f);
if (FRAME_VISIBLE_P (selected_frame)
&& ! FRAME_VISIBLE_P (f))
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
-#endif
if (m)
{
(*frame_up_to_date_hook) (f);
}
}
+\f
+/* Display a null-terminated echo area message M. If M is 0, clear out any
+ existing message, and let the minibuffer text show through.
+
+ The buffer M must continue to exist until after the echo area
+ gets cleared or some other message gets displayed there.
+
+ Do not pass text that is stored in a Lisp string.
+ Do not pass text in a buffer that was alloca'd. */
void
message1 (m)
zero if being used by message. */
int message_buf_print;
-/* Dump an informative message to the minibuf. If m is 0, clear out
+/* Dump an informative message to the minibuf. If M is 0, clear out
any existing message, and let the minibuffer text show through. */
+
/* VARARGS 1 */
void
message (m, a1, a2, a3)
a[2] = a3;
len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_WIDTH (f), m, (char *)0, 3, a);
+ (int) FRAME_WIDTH (f), m, (char *)0, 3, a);
#else
len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_WIDTH (f), m, (char *)0, 3, &a1);
+ (int) FRAME_WIDTH (f), m, (char *)0, 3, &a1);
#endif /* NO_ARG_ARRAY */
message2 (FRAME_MESSAGE_BUF (f), len);
}
}
-/* The non-logging version of that function. */
+/* The non-logging version of message. */
void
message_nolog (m, a1, a2, a3)
char *m;
{
message2 (echo_area_glyphs, echo_area_glyphs_length);
}
-
+\f
static void
echo_area_display ()
{
previous_echo_glyphs = echo_area_glyphs;
}
+\f
+/* Update frame titles. */
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
static char frame_title_buf[512];
static char *frame_title_ptr;
int len;
FRAME_PTR f = XFRAME (frame);
- if (!FRAME_X_P (f) || FRAME_MINIBUF_ONLY_P (f) || f->explicit_name)
+ if (!(FRAME_WINDOW_P (f) || FRAME_MINIBUF_ONLY_P (f) || f->explicit_name))
return;
/* Do we have more than one visible frame on this X display? */
create its menu bar using the name `emacs' if no other name
has yet been specified."
I think that is no longer a concern. */
-#ifdef HAVE_X_WINDOWS
- if (windows_or_buffers_changed)
+#ifdef HAVE_WINDOW_SYSTEM
+ if (windows_or_buffers_changed || update_mode_lines)
{
Lisp_Object tail, frame;
}
else
update_menu_bar (selected_frame, 1);
+
+ /* Motif needs this. See comment in xmenu.c.
+ Turn it off when pending_menu_activation is not defined. */
+#ifdef USE_X_TOOLKIT
+ pending_menu_activation = 0;
+#endif
}
\f
/* Do a frame update, taking possible shortcuts into account.
void
redisplay ()
+{
+ redisplay_internal (0);
+}
+
+/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay
+ is not in response to any user action; therefore, we should
+ preserve the echo area. (Actually, our caller does that job.)
+ Perhaps in the future avoid recentering windows
+ if it is not necessary; currently that causes some problems. */
+
+static void
+redisplay_internal (preserve_echo_area)
+ int preserve_echo_area;
{
register struct window *w = XWINDOW (selected_window);
register int pause;
if (noninteractive)
return;
-#ifdef MULTI_FRAME
- if (FRAME_TERMCAP_P (selected_frame)
+#ifdef USE_X_TOOLKIT
+ if (popup_activated ())
+ return;
+#endif
+
+ if (! FRAME_WINDOW_P (selected_frame)
&& previous_terminal_frame != selected_frame)
{
/* Since frames on an ASCII terminal share the same display area,
XSETFRAME (Vterminal_frame, selected_frame);
}
previous_terminal_frame = selected_frame;
-#endif
/* Set the visible flags for all frames.
Do this before checking for resized or garbaged frames; they want
if (windows_or_buffers_changed)
update_mode_lines++;
- /* Detect case that we need to write a star in the mode line. */
- if (XFASTINT (w->last_modified) < MODIFF
- && XFASTINT (w->last_modified) <= SAVE_MODIFF)
+ /* Detect case that we need to write or remove a star in the mode line. */
+ if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
{
w->update_mode_line = Qt;
if (buffer_shared > 1)
then we can't just move the cursor. */
else if (! (!NILP (Vtransient_mark_mode)
&& !NILP (current_buffer->mark_active))
+ && w == XWINDOW (current_buffer->last_selected_window)
&& NILP (w->region_showing)
&& !cursor_in_echo_area)
{
pos = *compute_motion (tlbufpos, 0,
XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
0,
- PT, 2, - (1 << (SHORTBITS - 1)),
+ PT, 2, - (1 << (BITS_PER_SHORT - 1)),
window_internal_width (w) - 1,
XINT (w->hscroll),
pos_tab_offset (w, tlbufpos), w);
FOR_EACH_FRAME (tail, frame)
{
FRAME_PTR f = XFRAME (frame);
- if (! FRAME_TERMCAP_P (f) || f == selected_frame)
+ if (FRAME_WINDOW_P (f) || f == selected_frame)
{
/* Mark all the scroll bars to be removed; we'll redeem the ones
(*condemn_scroll_bars_hook) (f);
if (FRAME_VISIBLE_P (f))
- redisplay_windows (FRAME_ROOT_WINDOW (f));
+ redisplay_windows (FRAME_ROOT_WINDOW (f), preserve_echo_area);
/* Any scroll bars which redisplay_windows should have nuked
should now go away. */
}
else if (FRAME_VISIBLE_P (selected_frame))
{
- redisplay_window (selected_window, 1);
+ redisplay_window (selected_window, 1, preserve_echo_area);
if (XFASTINT (w->width) != FRAME_WIDTH (selected_frame))
preserve_other_columns (w);
}
unrequest_sigio ();
stop_polling ();
-#ifdef MULTI_FRAME
if (all_windows)
{
Lisp_Object tail;
f = XFRAME (XCONS (tail)->car);
- if ((! FRAME_TERMCAP_P (f) || f == selected_frame)
+ if ((FRAME_WINDOW_P (f) || f == selected_frame)
&& FRAME_VISIBLE_P (f))
{
pause |= update_frame (f, 0, 0);
}
}
else
-#endif /* MULTI_FRAME */
{
if (FRAME_VISIBLE_P (selected_frame))
pause = update_frame (selected_frame, 0, 0);
mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- if (mini_frame != selected_frame
- && ! FRAME_TERMCAP_P (mini_frame))
+ if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
pause |= update_frame (mini_frame, 0, 0);
}
}
b->clip_changed = 0;
w->update_mode_line = Qnil;
XSETFASTINT (w->last_modified, BUF_MODIFF (b));
+ w->last_had_star
+ = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
+ ? Qt : Qnil);
w->window_end_valid = w->buffer;
last_arrow_position = Voverlay_arrow_position;
last_arrow_string = Voverlay_arrow_string;
if (echo_area_glyphs == 0 && previous_echo_glyphs != 0)
{
echo_area_glyphs = previous_echo_glyphs;
- redisplay ();
+ redisplay_internal (1);
echo_area_glyphs = 0;
}
else
- redisplay ();
+ redisplay_internal (1);
}
void
{
XSETFASTINT (w->last_modified,
!flag ? 0 : BUF_MODIFF (XBUFFER (w->buffer)));
+ w->last_had_star
+ = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
+ ? Qt : Qnil);
/* Record if we are showing a region, so can make sure to
update it fully at next redisplay. */
w->region_showing = (!NILP (Vtransient_mark_mode)
+ && w == XWINDOW (current_buffer->last_selected_window)
&& !NILP (XBUFFER (w->buffer)->mark_active)
? Fmarker_position (XBUFFER (w->buffer)->mark)
: Qnil);
w->window_end_valid = w->buffer;
w->update_mode_line = Qnil;
- if (!NILP (w->buffer))
+ if (!NILP (w->buffer) && flag)
XBUFFER (w->buffer)->clip_changed = 0;
if (!NILP (w->vchild))
if (update_mode_lines)
w->update_mode_line = Qt;
- if (
-#ifdef USE_X_TOOLKIT
+ if (FRAME_WINDOW_P (f)
+ ?
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
FRAME_EXTERNAL_MENU_BAR (f)
#else
FRAME_MENU_BAR_LINES (f) > 0
#endif
- )
+ : FRAME_MENU_BAR_LINES (f) > 0)
{
/* If the user has switched buffers or windows, we need to
recompute to reflect the new bindings. But we'll
windows_or_buffers_changed anyway. */
if (windows_or_buffers_changed
|| !NILP (w->update_mode_line)
- || (XFASTINT (w->last_modified) < MODIFF
- && (XFASTINT (w->last_modified)
- <= BUF_SAVE_MODIFF (XBUFFER (w->buffer))))
+ || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
+ < BUF_MODIFF (XBUFFER (w->buffer)))
+ != !NILP (w->last_had_star))
|| ((!NILP (Vtransient_mark_mode)
&& !NILP (XBUFFER (w->buffer)->mark_active))
!= !NILP (w->region_showing)))
really recompute the menubar from the value. */
if (! NILP (Vlucid_menu_bar_dirty_flag))
call0 (Qrecompute_lucid_menubar);
- call1 (Vrun_hooks, Qmenu_bar_update_hook);
+ safe_run_hooks (Qmenu_bar_update_hook);
FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
-#ifdef USE_X_TOOLKIT
- set_frame_menubar (f, 0, 0);
-#endif /* USE_X_TOOLKIT */
+ /* Redisplay the menu bar in case we changed it. */
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
+ if (FRAME_WINDOW_P (f))
+ set_frame_menubar (f, 0, 0);
+ else
+ /* On a terminal screen, the menu bar is an ordinary screen
+ line, and this makes it get updated. */
+ w->update_mode_line = Qt;
+#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
+ /* In the non-toolkit version, the menu bar is an ordinary screen
+ line, and this makes it get updated. */
+ w->update_mode_line = Qt;
+#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
unbind_to (count, Qnil);
set_buffer_internal_1 (prev);
/* Redisplay WINDOW and its subwindows and siblings. */
static void
-redisplay_windows (window)
+redisplay_windows (window, preserve_echo_area)
Lisp_Object window;
+ int preserve_echo_area;
{
for (; !NILP (window); window = XWINDOW (window)->next)
- redisplay_window (window, 0);
+ redisplay_window (window, 0, preserve_echo_area);
}
/* Redisplay window WINDOW and its subwindows. */
static void
-redisplay_window (window, just_this_one)
+redisplay_window (window, just_this_one, preserve_echo_area)
Lisp_Object window;
- int just_this_one;
+ int just_this_one, preserve_echo_area;
{
register struct window *w = XWINDOW (window);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int opoint = PT;
int tem;
int update_mode_line;
- struct Lisp_Vector *dp = window_display_table (w);
+ struct Lisp_Char_Table *dp = window_display_table (w);
if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
if (!NILP (w->vchild))
{
- redisplay_windows (w->vchild);
+ redisplay_windows (w->vchild, preserve_echo_area);
return;
}
if (!NILP (w->hchild))
{
- redisplay_windows (w->hchild);
+ redisplay_windows (w->hchild, preserve_echo_area);
return;
}
if (NILP (w->buffer))
changed, so why should we worry about doing any better? */
if (current_buffer->width_run_cache)
{
- struct Lisp_Vector *disptab = buffer_display_table ();
+ struct Lisp_Char_Table *disptab = buffer_display_table ();
if (! disptab_matches_widthtab (disptab,
XVECTOR (current_buffer->width_table)))
unless the specified location is outside the accessible range. */
if (!NILP (w->force_start))
{
+ w->force_start = Qnil;
/* Forget any recorded base line for line number display. */
w->base_line_number = Qnil;
- /* Redisplay the mode line. Select the buffer properly for that. */
- if (!update_mode_line)
+ /* Redisplay the mode line. Select the buffer properly for that.
+ Also, run the hook window-scroll-functions
+ because we have scrolled. */
+ /* Note, we do this after clearing force_start because
+ if there's an error, it is better to forget about force_start
+ than to get into an infinite loop calling the hook functions
+ and having them get more errors. */
+ if (!update_mode_line
+ || ! NILP (Vwindow_scroll_functions))
{
+ Lisp_Object temp[3];
+
set_buffer_temp (old);
set_buffer_internal_1 (XBUFFER (w->buffer));
update_mode_line = 1;
w->update_mode_line = Qt;
+ if (! NILP (Vwindow_scroll_functions))
+ {
+ run_hook_with_args_2 (Qwindow_scroll_functions, window,
+ make_number (startp));
+ startp = marker_position (w->start);
+ }
}
- w->force_start = Qnil;
XSETFASTINT (w->last_modified, 0);
if (startp < BEGV) startp = BEGV;
if (startp > ZV) startp = ZV;
+ (hscroll ? 1 - hscroll : 0)),
0,
ZV, height / 2,
- - (1 << (SHORTBITS - 1)),
+ - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, pos_tab_offset (w, startp), w);
BUF_PT (current_buffer) = pos.bufpos;
if (w != XWINDOW (selected_window))
}
/* Handle case where text has not changed, only point,
- and it has not moved off the frame */
+ and it has not moved off the frame. */
/* This code is not used for minibuffer for the sake of
the case of redisplaying to replace an echo area message;
goto done;
}
else if (startp >= BEGV && startp <= ZV
- /* Avoid starting display at end of buffer! */
- && (startp < ZV || startp == BEGV
+ && (startp < ZV
+ /* Avoid starting at end of buffer. */
+#if 0 /* This change causes trouble for M-! finger & RET.
+ It will have to be considered later. */
+ || ! EQ (window, selected_window)
+ /* Don't do the recentering if redisplay
+ is not for no user action. */
+ || preserve_echo_area
+#endif
+ || startp == BEGV
|| (XFASTINT (w->last_modified) >= MODIFF)))
{
/* Try to redisplay starting at same place as before */
/* Try to scroll by specified few lines */
- if (scroll_step && !current_buffer->clip_changed)
+ if (scroll_step && !current_buffer->clip_changed
+ && startp >= BEGV && startp <= ZV)
{
if (PT > startp)
{
if (PT >= pos.bufpos)
{
+ if (! NILP (Vwindow_scroll_functions))
+ {
+ Fset_marker (w->start, make_number (pos.bufpos), Qnil);
+ run_hook_with_args_2 (Qwindow_scroll_functions, window,
+ make_number (pos.bufpos));
+ pos.bufpos = marker_position (w->start);
+ }
try_window (window, pos.bufpos);
if (cursor_vpos >= 0)
{
w->base_line_number = Qnil;
pos = *vmotion (PT, - (height / 2), w);
+ /* Set startp here explicitly in case that helps avoid an infinite loop
+ in case the window-scroll-functions functions get errors. */
+ Fset_marker (w->start, make_number (pos.bufpos), Qnil);
+ if (! NILP (Vwindow_scroll_functions))
+ {
+ run_hook_with_args_2 (Qwindow_scroll_functions, window,
+ make_number (pos.bufpos));
+ pos.bufpos = marker_position (w->start);
+ }
try_window (window, pos.bufpos);
startp = marker_position (w->start);
/* When we reach a frame's selected window, redo the frame's menu bar. */
if (update_mode_line
-#ifdef USE_X_TOOLKIT
- && FRAME_EXTERNAL_MENU_BAR (f)
+ && (FRAME_WINDOW_P (f)
+ ?
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
+ FRAME_EXTERNAL_MENU_BAR (f)
#else
- && FRAME_MENU_BAR_LINES (f) > 0
+ FRAME_MENU_BAR_LINES (f) > 0
#endif
+ : FRAME_MENU_BAR_LINES (f) > 0)
&& EQ (FRAME_SELECTED_WINDOW (f), window))
display_menu_bar (w);
struct position val, bp, ep, xp, pp;
int scroll_amount = 0;
int delta;
- int tab_offset, epto;
+ int tab_offset, epto, old_tick;
if (GPT - BEG < beg_unchanged)
beg_unchanged = GPT - BEG;
{
if (PT < bp.bufpos)
{
- /* All changes are below the frame, and point is on the frame.
- We don't need to change the frame at all.
+ /* All changes are beyond the window end, and point is on the screen.
+ We don't need to change the text at all.
But we need to update window_end_pos to account for
any change in buffer size. */
bp = *compute_motion (start, 0, lmargin, 0,
- Z, height, 0,
+ ZV, height, 0,
width, hscroll, pos_tab_offset (w, start), w);
XSETFASTINT (w->window_end_vpos, height);
XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
/* Compute the cursor position after that newline. */
ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
- height, - (1 << (SHORTBITS - 1)),
+ height, - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, pos_tab_offset (w, bp.bufpos), w);
/* If changes reach past the text available on the frame,
if (PT <= xp.bufpos)
{
pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
- PT, height, - (1 << (SHORTBITS - 1)),
+ PT, height, - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, epto, w);
}
else
{
pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1,
- PT, height, - (1 << (SHORTBITS - 1)),
+ PT, height, - (1 << (BITS_PER_SHORT - 1)),
width, hscroll,
pos_tab_offset (w, xp.bufpos), w);
}
lines' charstarts in the case where the text of the
screen line at bp.vpos has changed.
(This can happen in a deletion that ends in mid-line.)
- To adjust properly, we need to make things constent at
- the position ep.
+ To adjust properly, we need to make things consistent
+ at the position ep.
So do a second adjust to make that happen.
Note that stop_vpos >= ep.vpos, so it is sufficient
to update the charstarts for lines at ep.vpos and below. */
to account for passing the line that that character really starts in. */
if (val.hpos < lmargin)
tab_offset += width;
+ old_tick = MODIFF;
while (vpos < stop_vpos)
{
val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset);
+ /* If display_text_line ran a hook and changed some text,
+ redisplay all the way to bottom of buffer
+ So that we show the changes. */
+ if (old_tick != MODIFF)
+ stop_vpos = height;
tab_offset += width;
if (val.vpos) tab_offset = 0;
if (pos != val.bufpos)
if (debug_end_pos)
{
val = *compute_motion (start, 0, lmargin, 0, ZV,
- height, - (1 << (SHORTBITS - 1)),
+ height, - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, pos_tab_offset (w, start), w);
if (val.vpos != XFASTINT (w->window_end_vpos))
abort ();
/* 1 if we should highlight the region. */
int highlight_region
- = !NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active);
+ = (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active)
+ && XWINDOW (current_buffer->last_selected_window) == w);
int region_beg, region_end;
int selective = (INTEGERP (current_buffer->selective_display)
? XINT (current_buffer->selective_display)
: !NILP (current_buffer->selective_display) ? -1 : 0);
register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (f);
- register struct Lisp_Vector *dp = window_display_table (w);
+ register struct Lisp_Char_Table *dp = window_display_table (w);
Lisp_Object default_invis_vector[3];
/* Number of characters of ellipsis to display after an invisible line
{
if (pos >= pause)
{
+ int e_t_h;
+
while (pos == next_boundary)
{
Lisp_Object position, limit, prop, ww;
break;
}
+ /* Figure out where (if at all) the
+ redisplay_end_trigger-hook should run. */
+ if (MARKERP (w->redisplay_end_trigger)
+ && XMARKER (w->redisplay_end_trigger)->buffer != 0)
+ e_t_h = marker_position (w->redisplay_end_trigger);
+ else if (INTEGERP (w->redisplay_end_trigger))
+ e_t_h = XINT (w->redisplay_end_trigger);
+ else
+ e_t_h = ZV;
+
+ /* If we've gone past the place to run a hook,
+ run the hook. */
+ if (pos >= e_t_h && e_t_h != ZV)
+ {
+ Lisp_Object args[3];
+
+ args[0] = Qredisplay_end_trigger_functions;
+ XSETWINDOW (args[1], w);
+ XSETINT (args[2], e_t_h);
+
+ /* Since we are *trying* to run these functions,
+ don't try to run them again, even if they get an error. */
+ w->redisplay_end_trigger = Qnil;
+ Frun_hook_with_args (3, args);
+
+ e_t_h = ZV;
+ /* Notice if it changed the face of this character. */
+ next_face_change = pos;
+ }
+
#ifdef HAVE_FACES
/* Did we hit a face change? Figure out what face we should
use now. We also hit this the first time through the
loop, to see what face we should start with. */
- if (pos >= next_face_change && FRAME_X_P (f))
+ if (pos >= next_face_change
+ && (FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f)))
current_face = compute_char_face (f, w, pos,
region_beg, region_end,
&next_face_change, pos + 50, 0);
#endif
+ /* Compute the next place we need to stop
+ and do something special; set PAUSE. */
+
pause = ZV;
if (pos < next_boundary && next_boundary < pause)
if (pos < next_face_change && next_face_change < pause)
pause = next_face_change;
+ if (e_t_h < pause)
+ pause = e_t_h;
+
/* Wouldn't you hate to read the next line to someone over
the phone? */
if (pos < PT && PT < pause)
int hpos = 0;
int i;
-#ifndef USE_X_TOOLKIT
- if (FRAME_MENU_BAR_LINES (f) <= 0)
+#ifdef HAVE_NTGUI
+ if (!NILP (Vwindow_system))
+ return;
+#endif
+
+#ifdef USE_X_TOOLKIT
+ if (FRAME_X_P (f))
return;
+#endif /* USE_X_TOOLKIT */
get_display_line (f, vpos, 0);
items = FRAME_MENU_BAR_ITEMS (f);
- for (i = 0; i < XVECTOR (items)->size; i += 3)
+ for (i = 0; i < XVECTOR (items)->size; i += 4)
{
Lisp_Object pos, string;
string = XVECTOR (items)->contents[i + 1];
if (NILP (string))
break;
- XSETFASTINT (XVECTOR (items)->contents[i + 2], hpos);
+ XSETFASTINT (XVECTOR (items)->contents[i + 3], hpos);
if (hpos < maxendcol)
hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos,
vpos++;
while (vpos < FRAME_MENU_BAR_LINES (f))
get_display_line (f, vpos++, 0);
-#endif /* not USE_X_TOOLKIT */
}
\f
/* Display the mode line for window w */
case 'F':
/* %F displays the frame name. */
-#ifdef MULTI_FRAME
- return (char *) XSTRING (selected_frame->name)->data;
-#else
+ if (!NILP (f->title))
+ return (char *) XSTRING (f->title)->data;
+ if (f->explicit_name || ! FRAME_WINDOW_P (f))
+ return (char *) XSTRING (f->name)->data;
return "Emacs";
-#endif
case 'f':
obj = b->filename;
return "Top";
else
{
- total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
+ if (total > 1000000)
+ /* Do it differently for a large value, to avoid overflow. */
+ total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
+ else
+ total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
/* We can't normally display a 3-digit number,
so get us a 2-digit number that is close. */
if (total == 100)
}
else
{
- total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
+ if (total > 1000000)
+ /* Do it differently for a large value, to avoid overflow. */
+ total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
+ else
+ total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
/* We can't normally display a 3-digit number,
so get us a 2-digit number that is close. */
if (total == 100)
int mincol, maxcol;
{
register int c;
+ int truncated;
register GLYPH *p1;
int hscroll = XINT (w->hscroll);
int tab_width = XINT (XBUFFER (w->buffer)->tab_width);
/* Use the standard display table, not the window's display table.
We don't want the mode line in rot13. */
- register struct Lisp_Vector *dp = 0;
+ register struct Lisp_Char_Table *dp = 0;
int i;
- if (VECTORP (Vstandard_display_table)
- && XVECTOR (Vstandard_display_table)->size == DISP_TABLE_SIZE)
- dp = XVECTOR (Vstandard_display_table);
+ if (DISP_TABLE_P (Vstandard_display_table))
+ dp = XCHAR_TABLE (Vstandard_display_table);
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
if (maxcol >= 0 && mincol > maxcol)
mincol = maxcol;
- while (p1 < end)
+ /* We set truncated to 1 if we get stopped by trying to pass END
+ (that is, trying to pass MAXCOL.) */
+ truncated = 0;
+ while (1)
{
if (length == 0)
break;
else if (c == 0)
break;
+ if (p1 >= end)
+ {
+ truncated = 1;
+ break;
+ }
+
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
{
p1 = copy_part_of_rope (f, p1, start,
}
}
- if (c && length > 0)
+ if (truncated)
{
p1 = end;
if (truncate) *p1++ = fix_glyph (f, truncate, 0);
staticpro (&Qoverriding_local_map);
Qoverriding_local_map = intern ("overriding-local-map");
+ staticpro (&Qwindow_scroll_functions);
+ Qwindow_scroll_functions = intern ("window-scroll-functions");
+
+ staticpro (&Qredisplay_end_trigger_functions);
+ Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
+
staticpro (&last_arrow_position);
staticpro (&last_arrow_string);
last_arrow_position = Qnil;
size since the last redisplay, or have been split or deleted,\n\
all the functions in the list are called, with the frame as argument.");
Vwindow_size_change_functions = Qnil;
+
+ DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
+ "List of Functions to call before redisplaying a window with scrolling.\n\
+Each function is called with two arguments, the window\n\
+and its new display-start position. Note that the value of `window-end'\n\
+is not valid when these functions are called.");
+ Vwindow_scroll_functions = Qnil;
}
/* initialize the window system */