/* Display generation from window structure and buffer text.
- Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Emacs.
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include "config.h"
+#include <config.h>
#include <stdio.h>
/*#include <ctype.h>*/
#undef NULL
#include "macros.h"
#include "disptab.h"
#include "termhooks.h"
+#include "intervals.h"
+
+#ifdef USE_X_TOOLKIT
+extern void set_frame_menubar ();
+#endif
extern int interrupt_input;
extern int command_loop_level;
/* Nonzero if overlay arrow has been displayed once in this window. */
static int overlay_arrow_seen;
+/* Nonzero means highlight the region even in nonselected windows. */
+static int highlight_nonselected_windows;
+
/* If cursor motion alone moves point off frame,
Try scrolling this many lines up or down if that will bring it back. */
int scroll_step;
void mark_window_display_accurate ();
static void redisplay_windows ();
static void redisplay_window ();
+static void update_menu_bars ();
+static void update_menu_bar ();
static void try_window ();
static int try_window_id ();
static struct position *display_text_line ();
It overrides the minibuf_prompt as well as the buffer. */
char *echo_area_glyphs;
+/* This is the length of the message in echo_area_glyphs. */
+int echo_area_glyphs_length;
+
/* true iff we should redraw the mode lines on the next redisplay */
int update_mode_lines;
\f
/* Specify m, a string, as a message in the minibuf. If m is 0, clear out
any existing message, and let the minibuffer text show through. */
+
void
message1 (m)
char *m;
#endif
if (m)
- echo_area_glyphs = m;
+ {
+ echo_area_glyphs = m;
+ echo_area_glyphs_length = strlen (m);
+ }
else
echo_area_glyphs = previous_echo_glyphs = 0;
}
}
+/* Display an echo area message M with a specified length of LEN chars.
+ This way, null characters can be included. */
+
+void
+message2 (m, len)
+ char *m;
+ int len;
+{
+ if (noninteractive)
+ {
+ if (noninteractive_need_newline)
+ putc ('\n', stderr);
+ noninteractive_need_newline = 0;
+ fwrite (m, len, 1, stderr);
+ if (cursor_in_echo_area == 0)
+ fprintf (stderr, "\n");
+ fflush (stderr);
+ }
+ /* A null message buffer means that the frame hasn't really been
+ initialized yet. Error messages get reported properly by
+ cmd_error, so this must be just an informative message; toss it. */
+ else if (INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame))
+ {
+#ifdef MULTI_FRAME
+ Lisp_Object minibuf_frame;
+
+ choose_minibuf_frame ();
+ minibuf_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
+ FRAME_SAMPLE_VISIBILITY (XFRAME (minibuf_frame));
+ if (FRAME_VISIBLE_P (selected_frame)
+ && ! FRAME_VISIBLE_P (XFRAME (minibuf_frame)))
+ Fmake_frame_visible (WINDOW_FRAME (XWINDOW (minibuf_window)));
+#endif
+
+ if (m)
+ {
+ echo_area_glyphs = m;
+ echo_area_glyphs_length = len;
+ }
+ else
+ echo_area_glyphs = previous_echo_glyphs = 0;
+
+ do_pending_window_change ();
+ echo_area_display ();
+ update_frame (XFRAME (XWINDOW (minibuf_window)->frame), 1, 1);
+ do_pending_window_change ();
+ }
+}
+
+/* Truncate what will be displayed in the echo area
+ the next time we display it--but don't redisplay it now. */
+
+void
+truncate_echo_area (len)
+ int len;
+{
+ /* A null message buffer means that the frame hasn't really been
+ initialized yet. Error messages get reported properly by
+ cmd_error, so this must be just an informative message; toss it. */
+ if (!noninteractive && INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame))
+ echo_area_glyphs_length = len;
+}
+
/* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by print;
zero if being used by message. */
int message_buf_print;
{
if (m)
{
- {
+ int len;
#ifdef NO_ARG_ARRAY
- int a[3];
- a[0] = a1;
- a[1] = a2;
- a[2] = a3;
+ int a[3];
+ a[0] = a1;
+ a[1] = a2;
+ a[2] = a3;
- doprnt (FRAME_MESSAGE_BUF (echo_frame),
- FRAME_WIDTH (echo_frame), m, 0, 3, a);
+ len = doprnt (FRAME_MESSAGE_BUF (echo_frame),
+ FRAME_WIDTH (echo_frame), m, 0, 3, a);
#else
- doprnt (FRAME_MESSAGE_BUF (echo_frame),
- FRAME_WIDTH (echo_frame), m, 0, 3, &a1);
+ len = doprnt (FRAME_MESSAGE_BUF (echo_frame),
+ FRAME_WIDTH (echo_frame), m, 0, 3, &a1);
#endif /* NO_ARG_ARRAY */
- }
- message1 (FRAME_MESSAGE_BUF (echo_frame));
+ message2 (FRAME_MESSAGE_BUF (echo_frame), len);
}
else
message1 (0);
if (frame_garbaged)
{
- Fredraw_display ();
+ redraw_garbaged_frames ();
frame_garbaged = 0;
}
get_display_line (f, vpos, 0);
display_string (XWINDOW (minibuf_window), vpos,
echo_area_glyphs ? echo_area_glyphs : "",
+ echo_area_glyphs ? echo_area_glyphs_length : -1,
0, 0, 0, FRAME_WIDTH (f));
/* If desired cursor location is on this line, put it at end of text */
{
int i;
- for (i = vpos + 1; i < vpos + XWINDOW (minibuf_window)->height; i++)
+ for (i = vpos + 1;
+ i < vpos + XFASTINT (XWINDOW (minibuf_window)->height); i++)
{
get_display_line (f, i, 0);
display_string (XWINDOW (minibuf_window), vpos,
- "", 0, 0, 0, FRAME_WIDTH (f));
+ "", 0, 0, 0, 0, FRAME_WIDTH (f));
}
}
}
previous_echo_glyphs = echo_area_glyphs;
}
\f
+/* Prepare for redisplay by updating menu-bar item lists when appropriate.
+ This can't be done in `redisplay' itself because it can call eval. */
+
+void
+prepare_menu_bars ()
+{
+ register struct window *w = XWINDOW (selected_window);
+ int all_windows;
+
+ if (noninteractive)
+ return;
+
+ /* Set the visible flags for all frames.
+ Do this before checking for resized or garbaged frames; they want
+ to know if their frames are visible.
+ See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
+ {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+ }
+
+ /* Notice any pending interrupt request to change frame size. */
+ do_pending_window_change ();
+
+ if (frame_garbaged)
+ {
+ redraw_garbaged_frames ();
+ frame_garbaged = 0;
+ }
+
+ if (clip_changed || 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) <= current_buffer->save_modified)
+ {
+ w->update_mode_line = Qt;
+ if (buffer_shared > 1)
+ update_mode_lines++;
+ }
+
+ all_windows = update_mode_lines || buffer_shared > 1;
+
+ /* If specs for an arrow have changed, do thorough redisplay
+ to ensure we remove any arrow that should no longer exist. */
+ if (! EQ (Voverlay_arrow_position, last_arrow_position)
+ || ! EQ (Voverlay_arrow_string, last_arrow_string))
+ all_windows = 1, clip_changed = 1;
+
+ /* Update the menu bar item lists, if appropriate.
+ This has to be done before any actual redisplay
+ or generation of display lines. */
+ if (all_windows)
+ {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ FRAME_PTR f = XFRAME (frame);
+
+ if (FRAME_VISIBLE_P (f))
+ update_menu_bars (FRAME_ROOT_WINDOW (f));
+ }
+ }
+ else if (FRAME_VISIBLE_P (selected_frame))
+ update_menu_bar (selected_window);
+}
+\f
/* Do a frame update, taking possible shortcuts into account.
This is the main external entry point for redisplay.
message is no longer requested, we clear the echo area
or bring back the minibuffer if that is in use.
- Everyone would like to have a hook here to call eval,
- but that cannot be done safely without a lot of changes elsewhere.
- This can be called from signal handlers; with alarms set up;
+ Do not call eval from within this function.
+ Calls to eval after the call to echo_area_display would confuse
+ the display_line mechanism and would cause a crash.
+ Calls to eval before that point will work most of the time,
+ but can still lose, because this function
+ can be called from signal handlers; with alarms set up;
or with synchronous processes running.
- See the function `echo' in keyboard.c.
+
See Fcall_process; if you called it from here, it could be
entered recursively. */
if (frame_garbaged)
{
- Fredraw_display ();
+ redraw_garbaged_frames ();
frame_garbaged = 0;
}
- /* Normally the message* functions will have already displayed and
- updated the echo area, but the frame may have been trashed, or
- the update may have been preempted, so display the echo area
- again here. */
- if (echo_area_glyphs || previous_echo_glyphs)
- {
- echo_area_display ();
- must_finish = 1;
- }
-
if (clip_changed || windows_or_buffers_changed)
update_mode_lines++;
|| ! EQ (Voverlay_arrow_string, last_arrow_string))
all_windows = 1, clip_changed = 1;
+ /* Normally the message* functions will have already displayed and
+ updated the echo area, but the frame may have been trashed, or
+ the update may have been preempted, so display the echo area
+ again here. */
+ if (echo_area_glyphs || previous_echo_glyphs)
+ {
+ echo_area_display ();
+ must_finish = 1;
+ }
+
+ /* If showing region, and mark has changed, must redisplay whole window. */
+ if (((!NILP (Vtransient_mark_mode)
+ && !NILP (XBUFFER (w->buffer)->mark_active))
+ != !NILP (w->region_showing))
+ || (!NILP (w->region_showing)
+ && !EQ (w->region_showing,
+ Fmarker_position (XBUFFER (w->buffer)->mark))))
+ this_line_bufpos = -1;
+
tlbufpos = this_line_bufpos;
tlendpos = this_line_endpos;
if (!all_windows && tlbufpos > 0 && NILP (w->update_mode_line)
}
goto update;
}
- else
+ /* If highlighting the region, we can't just move the cursor. */
+ else if (! (!NILP (Vtransient_mark_mode)
+ && !NILP (current_buffer->mark_active))
+ && NILP (w->region_showing))
{
pos = *compute_motion (tlbufpos, 0,
XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
w = XWINDOW (window);
if (!NILP (w->buffer))
- XFASTINT (w->last_modified)
- = !flag ? 0
- : XBUFFER (w->buffer) == current_buffer
- ? MODIFF : BUF_MODIFF (XBUFFER (w->buffer));
+ {
+ XFASTINT (w->last_modified)
+ = !flag ? 0
+ : XBUFFER (w->buffer) == current_buffer
+ ? MODIFF : BUF_MODIFF (XBUFFER (w->buffer));
+
+ /* 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)
+ && !NILP (XBUFFER (w->buffer)->mark_active)
+ ? Fmarker_position (XBUFFER (w->buffer)->mark)
+ : Qnil);
+ }
+
w->window_end_valid = Qt;
w->update_mode_line = Qnil;
}
}
\f
+/* Update the menu bar item lists for WINDOW
+ and its subwindows and siblings.
+ This has to be done before we start to fill in any display lines,
+ because it can call eval. */
+
+static void
+update_menu_bars (window)
+ Lisp_Object window;
+{
+ for (; !NILP (window); window = XWINDOW (window)->next)
+ update_menu_bar (window, 0);
+}
+
+/* Update the menu bar item list for window WINDOW and its subwindows. */
+
+static void
+update_menu_bar (window, just_this_one)
+ Lisp_Object window;
+ int just_this_one;
+{
+ register struct window *w = XWINDOW (window);
+ struct buffer *old = current_buffer;
+ FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
+
+ /* If this is a combination window, do its children; that's all. */
+
+ if (!NILP (w->vchild))
+ {
+ update_menu_bars (w->vchild);
+ return;
+ }
+ if (!NILP (w->hchild))
+ {
+ update_menu_bars (w->hchild);
+ return;
+ }
+ if (NILP (w->buffer))
+ abort ();
+
+ if (update_mode_lines)
+ w->update_mode_line = Qt;
+
+ /* When we reach a frame's selected window, redo the frame's menu bar. */
+ if (!NILP (w->update_mode_line)
+#ifdef USE_X_TOOLKIT
+ && FRAME_EXTERNAL_MENU_BAR (f)
+#else
+ && FRAME_MENU_BAR_LINES (f) > 0
+#endif
+ && EQ (FRAME_SELECTED_WINDOW (f), window))
+ {
+ /* If the user has switched buffers or windows, we need to
+ recompute to reflect the new bindings. But we'll
+ recompute when update_mode_lines is set too; that means
+ that people can use force-mode-line-update to request
+ that the menu bar be recomputed. The adverse effect on
+ the rest of the redisplay algorithm is about the same as
+ windows_or_buffers_changed anyway. */
+ if (windows_or_buffers_changed
+ || update_mode_lines
+ || (XFASTINT (w->last_modified) < MODIFF
+ && (XFASTINT (w->last_modified)
+ <= XBUFFER (w->buffer)->save_modified)))
+ {
+ struct buffer *prev = current_buffer;
+ current_buffer = XBUFFER (w->buffer);
+ FRAME_MENU_BAR_ITEMS (f) = menu_bar_items ();
+ current_buffer = prev;
+#ifdef USE_X_TOOLKIT
+ set_frame_menubar (f);
+#endif /* USE_X_TOOLKIT */
+ }
+ }
+}
+\f
int do_id = 1;
+/* Redisplay WINDOW and its subwindows and siblings. */
+
static void
redisplay_windows (window)
Lisp_Object window;
redisplay_window (window, 0);
}
+/* Redisplay window WINDOW and its subwindows. */
+
static void
redisplay_window (window, just_this_one)
Lisp_Object window;
for (i = 0; i < height; i++)
{
get_display_line (f, vpos + i, 0);
- display_string (w, vpos + i, "", 0, 0, 0, width);
+ display_string (w, vpos + i, "", 0, 0, 0, 0, width);
}
goto finish_scroll_bars;
try_window (window, startp);
if (cursor_vpos < 0)
{
+ /* ??? What should happen here if highlighting a region? */
/* If point does not appear, move point so it does appear */
pos = *compute_motion (startp, 0,
((EQ (window, minibuf_window) && startp == 1)
- (1 << (SHORTBITS - 1)),
width, hscroll, pos_tab_offset (w, startp));
SET_PT (pos.bufpos);
- if (w != XWINDOW (FRAME_SELECTED_WINDOW (f)))
+ if (w != XWINDOW (selected_window))
Fset_marker (w->pointm, make_number (point), Qnil);
else
{
- lpoint = point;
+ if (current_buffer == old)
+ lpoint = point;
FRAME_CURSOR_X (f) = max (0, pos.hpos) + XFASTINT (w->left);
FRAME_CURSOR_Y (f) = pos.vpos + XFASTINT (w->top);
}
if (XFASTINT (w->last_modified) >= MODIFF
&& point >= startp && !clip_changed
&& (just_this_one || XFASTINT (w->width) == FRAME_WIDTH (f))
+ /* Can't use this case if highlighting a region. */
+ && !(!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
+ && NILP (w->region_showing)
&& !EQ (window, minibuf_window))
{
pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0),
else if (just_this_one && !MINI_WINDOW_P (w)
&& point >= startp
&& XFASTINT (w->last_modified)
+ /* or else vmotion on first line won't work. */
+ && ! NILP (w->start_at_line_beg)
&& ! EQ (w->window_end_valid, Qnil)
&& do_id && !clip_changed
&& !blank_end_of_window
&& XFASTINT (w->width) == FRAME_WIDTH (f)
+ /* Can't use this case if highlighting a region. */
+ && !(!NILP (Vtransient_mark_mode)
+ && !NILP (current_buffer->mark_active))
+ && NILP (w->region_showing)
&& EQ (last_arrow_position, Voverlay_arrow_position)
&& EQ (last_arrow_string, Voverlay_arrow_string)
&& (tem = try_window_id (FRAME_SELECTED_WINDOW (f)))
/* When we reach a frame's selected window, redo the frame's menu bar. */
if (!NILP (w->update_mode_line)
+#ifdef USE_X_TOOLKIT
+ && FRAME_EXTERNAL_MENU_BAR (f)
+#else
&& FRAME_MENU_BAR_LINES (f) > 0
+#endif
&& EQ (FRAME_SELECTED_WINDOW (f), window))
display_menu_bar (w);
int start, end, whole;
/* Calculate the start and end positions for the current window.
+ At some point, it would be nice to choose between scrollbars
+ which reflect the whole buffer size, with special markers
+ indicating narrowing, and scrollbars which reflect only the
+ visible region.
+
Note that minibuffers sometimes aren't displaying any text. */
if (! MINI_WINDOW_P (w)
|| (w == XWINDOW (minibuf_window) && ! echo_area_glyphs))
{
- start = startp;
+ whole = ZV - BEGV;
+ start = startp - BEGV;
/* I don't think this is guaranteed to be right. For the
moment, we'll pretend it is. */
- end = Z - XINT (w->window_end_pos);
- whole = Z - BEG;
+ end = (Z - XINT (w->window_end_pos)) - BEGV;
+
+ if (end < start) end = start;
+ if (whole < (end - start)) whole = end - start;
}
else
start = end = whole = 0;
/* Indicate what this scroll bar ought to be displaying now. */
- (*set_vertical_scroll_bar_hook) (w, end - start, whole, start - 1);
+ (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
/* Note that we actually used the scroll bar attached to this window,
so it shouldn't be deleted at the end of redisplay. */
if (pos != val.bufpos)
last_text_vpos
/* Next line, unless prev line ended in end of buffer with no cr */
- = vpos - (val.vpos && FETCH_CHAR (val.bufpos - 1) != '\n');
+ = vpos - (val.vpos && (FETCH_CHAR (val.bufpos - 1) != '\n'
+ || ! NILP (Fget_text_property (val.bufpos-1,
+ Qinvisible,
+ Fcurrent_buffer ()))));
pos = val.bufpos;
}
if (Z - GPT < end_unchanged)
end_unchanged = Z - GPT;
- if (beg_unchanged + 1 < start)
+ if (beg_unchanged + BEG < start)
return 0; /* Give up if changes go above top of window */
/* Find position before which nothing is changed. */
bp = *compute_motion (start, 0, lmargin,
- beg_unchanged + 1, height + 1, 0, width, hscroll,
- pos_tab_offset (w, start));
+ min (ZV, beg_unchanged + BEG), height + 1, 0,
+ width, hscroll, pos_tab_offset (w, start));
if (bp.vpos >= height)
{
if (point < bp.bufpos && !bp.contin)
while (n--)
{
- if (t >= s) *t = MAKE_GLYPH (GLYPH_CHAR (*f),
- (GLYPH_FACE (*f)
- ? GLYPH_FACE (*f)
+ int glyph = XFASTINT (*f);
+
+ if (t >= s) *t = MAKE_GLYPH (GLYPH_CHAR (glyph),
+ (GLYPH_FACE (glyph)
+ ? GLYPH_FACE (glyph)
: face));
++t;
++f;
while (n--)
{
- if (t >= s) *t = MAKE_GLYPH (GLYPH_CHAR (*f),
- (GLYPH_FACE (*f)
- ? GLYPH_FACE (*f)
+ int glyph = XFASTINT (*f);
+
+ if (t >= s) *t = MAKE_GLYPH (GLYPH_CHAR (glyph),
+ (GLYPH_FACE (glyph)
+ ? GLYPH_FACE (glyph)
: face));
++t;
++f;
register unsigned char *p;
GLYPH *endp;
register GLYPH *startp;
- register GLYPH *p1prev;
+ register GLYPH *p1prev = 0;
FRAME_PTR f = XFRAME (w->frame);
int tab_width = XINT (current_buffer->tab_width);
int ctl_arrow = !NILP (current_buffer->ctl_arrow);
|| (truncate_partial_width_windows
&& XFASTINT (w->width) < FRAME_WIDTH (f))
|| !NILP (current_buffer->truncate_lines);
+
+ /* 1 if we should highlight the region. */
+ int highlight_region
+ = !NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active);
+ int region_beg, region_end;
+
int selective
= XTYPE (current_buffer->selective_display) == Lisp_Int
? XINT (current_buffer->selective_display)
to overlays or text property changes. */
int next_face_change;
+#ifdef USE_TEXT_PROPERTIES
+ /* The next location where the `invisible' property changes */
+ int next_invisible;
+#endif
+
/* The face we're currently using. */
int current_face = 0;
get_display_line (f, vpos, XFASTINT (w->left));
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
+ /* Show where to highlight the region. */
+ if (highlight_region && XMARKER (current_buffer->mark)->buffer != 0
+ /* Maybe highlight only in selected window. */
+ && (highlight_nonselected_windows
+ || w == XWINDOW (selected_window)))
+ {
+ region_beg = marker_position (current_buffer->mark);
+ if (PT < region_beg)
+ {
+ region_end = region_beg;
+ region_beg = PT;
+ }
+ else
+ region_end = PT;
+ w->region_showing = Qt;
+ }
+ else
+ region_beg = region_end = -1;
+
if (MINI_WINDOW_P (w) && start == 1
&& vpos == XFASTINT (w->top))
{
if (minibuf_prompt)
- hpos = display_string (w, vpos, minibuf_prompt, hpos,
+ hpos = display_string (w, vpos, minibuf_prompt, -1, hpos,
(!truncate ? continuer : truncator),
-1, -1);
minibuf_prompt_width = hpos;
or at face change. */
pause = pos;
next_face_change = pos;
+#ifdef USE_TEXT_PROPERTIES
+ next_invisible = pos;
+#endif
while (p1 < endp)
{
p1prev = p1;
cursor_hpos = p1 - startp;
}
+#ifdef USE_TEXT_PROPERTIES
+ /* if the `invisible' property is set to t, we can skip to
+ the next property change */
+ while (pos == next_invisible && pos < end)
+ {
+ Lisp_Object position, limit, endpos, prop;
+ XFASTINT (position) = pos;
+ prop = Fget_text_property (position, Qinvisible,
+ Fcurrent_buffer ());
+ /* This is just an estimate to give reasonable
+ performance; nothing should go wrong if it is too small. */
+ XFASTINT (limit) = pos + 50;
+ endpos
+ = Fnext_single_property_change (position, Qinvisible,
+ Fcurrent_buffer (), limit);
+ if (INTEGERP (endpos))
+ next_invisible = XINT (endpos);
+ else
+ next_invisible = end;
+ if (! NILP (prop))
+ {
+ if (pos < point && next_invisible >= point)
+ {
+ cursor_vpos = vpos;
+ cursor_hpos = p1 - startp;
+ }
+ pos = next_invisible;
+ }
+ }
+ if (pos >= end)
+ break;
+#endif
+
#ifdef HAVE_X_WINDOWS
/* 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)
- current_face = compute_char_face (f, w, pos, &next_face_change);
+ if (pos >= next_face_change && FRAME_X_P (f))
+ current_face = compute_char_face (f, w, pos,
+ region_beg, region_end,
+ &next_face_change, pos + 50);
#endif
pause = end;
+#ifdef USE_TEXT_PROPERTIES
+ if (pos < next_invisible && next_invisible < pause)
+ pause = next_invisible;
+#endif
if (pos < next_face_change && next_face_change < pause)
pause = next_face_change;
copy_part_of_rope (p1prev, p1prev, invis_vector_contents,
(p1 - p1prev), current_face);
}
+#if 1
+ /* Draw the face of the newline character as extending all the
+ way to the end of the frame line. */
+ if (current_face)
+ while (p1 < endp)
+ *p1++ = MAKE_GLYPH (' ', current_face);
+#endif
break;
}
else if (c == '\t')
copy_part_of_rope (p1prev, p1prev, invis_vector_contents,
(p1 - p1prev), current_face);
}
+#if 1
+ /* Draw the face of the newline character as extending all the
+ way to the end of the frame line. */
+ if (current_face)
+ while (p1 < endp)
+ *p1++ = MAKE_GLYPH (' ', current_face);
+#endif
break;
}
else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector)
/* by backing up over it */
if (p1 > endp)
{
- /* Start the next line with that same character */
- pos--;
- /* but at a negative hpos, to skip the columns output on this line. */
- val.hpos += p1prev - endp;
+ /* Don't back up if we never actually displayed any text.
+ This occurs when the minibuffer prompt takes up the whole line. */
+ if (p1prev)
+ {
+ /* Start the next line with that same character */
+ pos--;
+ /* but at negative hpos, to skip the columns output on this line. */
+ val.hpos += p1prev - endp;
+ }
+
/* Keep in this line everything up to the continuation column. */
p1 = endp;
}
unsigned char *p = XSTRING (Voverlay_arrow_string)->data;
int i;
int len = XSTRING (Voverlay_arrow_string)->size;
+ int arrow_end;
if (len > width)
len = width;
for (i = 0; i < len; i++)
startp[i] = p[i];
- if (desired_glyphs->used[vpos] <
- (len + startp - desired_glyphs->glyphs[vpos]))
- desired_glyphs->used[vpos] = len + startp - desired_glyphs->glyphs[vpos];
+
+ /* Bug in SunOS 4.1.1 compiler requires this intermediate variable. */
+ arrow_end = (startp - desired_glyphs->glyphs[vpos]) + len;
+ if (desired_glyphs->used[vpos] < arrow_end)
+ desired_glyphs->used[vpos] = arrow_end;
overlay_arrow_seen = 1;
}
int maxendcol = FRAME_WIDTH (f);
int hpos = 0;
+#ifndef USE_X_TOOLKIT
if (FRAME_MENU_BAR_LINES (f) <= 0)
return;
if (hpos < maxendcol)
hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos,
XSTRING (string)->data,
+ XSTRING (string)->size,
hpos, 0, hpos, maxendcol);
/* Put a gap of 3 spaces between items. */
if (hpos < maxendcol)
{
int hpos1 = hpos + 3;
- hpos = display_string (w, vpos, "", hpos, 0,
+ hpos = display_string (w, vpos, "", 0, hpos, 0,
min (hpos1, maxendcol), maxendcol);
}
}
/* Fill out the line with spaces. */
if (maxendcol > hpos)
- hpos = display_string (w, vpos, "", hpos, 0, maxendcol, -1);
+ hpos = display_string (w, vpos, "", 0, hpos, 0, maxendcol, -1);
+
+ /* Clear the rest of the lines allocated to the menu bar. */
+ 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 */
if (this - 1 != last)
{
register int lim = --this - last + hpos;
- hpos = display_string (w, vpos, last, hpos, 0, hpos,
+ hpos = display_string (w, vpos, last, -1, hpos, 0, hpos,
min (lim, maxendcol));
}
else /* c == '%' */
hpos = display_string (w, vpos,
decode_mode_spec (w, c,
maxendcol - hpos),
+ -1,
hpos, 0, spec_width, maxendcol);
}
}
don't check for % within it. */
if (XTYPE (tem) == Lisp_String)
hpos = display_string (w, vpos, XSTRING (tem)->data,
+ XSTRING (tem)->size,
hpos, 0, minendcol, maxendcol);
/* Give up right away for nil or t. */
else if (!EQ (tem, elt))
default:
invalid:
- return (display_string (w, vpos, "*invalid*", hpos, 0,
+ return (display_string (w, vpos, "*invalid*", -1, hpos, 0,
minendcol, maxendcol));
}
end:
if (minendcol > hpos)
- hpos = display_string (w, vpos, "", hpos, 0, minendcol, -1);
+ hpos = display_string (w, vpos, "", 0, hpos, 0, minendcol, -1);
return hpos;
}
\f
obj = Fget_buffer_process (Fcurrent_buffer ());
if (NILP (obj))
return "no process";
+#ifdef subprocesses
obj = Fsymbol_name (Fprocess_status (obj));
+#endif
break;
+ case 't': /* indicate TEXT or BINARY */
+#ifdef MSDOS
+ decode_mode_spec_buf[0]
+ = NILP (current_buffer->buffer_file_type) ? "T" : "B";
+ decode_mode_spec_buf[1] = 0;
+ return decode_mode_spec_buf;
+#else /* not MSDOS */
+ return "T";
+#endif /* not MSDOS */
+
case 'p':
{
int pos = marker_position (w->start);
/* Display STRING on one line of window W, starting at HPOS.
Display at position VPOS. Caller should have done get_display_line.
If VPOS == -1, display it as the current frame's title.
+ LENGTH is the length of STRING, or -1 meaning STRING is null-terminated.
TRUNCATE is GLYPH to display at end if truncated. Zero for none.
Returns ending hpos */
static int
-display_string (w, vpos, string, hpos, truncate, mincol, maxcol)
+display_string (w, vpos, string, length, hpos, truncate, mincol, maxcol)
struct window *w;
unsigned char *string;
+ int length;
int vpos, hpos;
GLYPH truncate;
int mincol, maxcol;
while (p1 < end)
{
+ if (length == 0)
+ break;
c = *string++;
- if (!c) break;
+ /* Specified length. */
+ if (length >= 0)
+ length--;
+ /* Unspecified length (null-terminated string). */
+ else if (c == 0)
+ break;
+
if (c >= 040 && c < 0177
&& (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector))
{
}
}
- if (c)
+ if (c && length > 0)
{
p1 = end;
if (truncate) *p1++ = truncate;
DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
"*Maximum buffer size for which line number should be displayed.");
line_number_display_limit = 1000000;
+
+ DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
+ "*Non-nil means highlight region even in nonselected windows.");
+ highlight_nonselected_windows = 1;
}
/* initialize the window system */