/* Display generation from window structure and buffer text.
- Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
This file is part of GNU Emacs.
int windows_or_buffers_changed;
\f
-#ifndef MULTI_SCREEN
-
-DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
- "Clear the screen and output again what is supposed to appear on it.")
- ()
-{
- if (screen_height == 0) abort (); /* Some bug zeros some core */
- clear_screen ();
- fflush (stdout);
- clear_screen_records ();
- if (screen_height == 0) abort (); /* Some bug zeros some core */
- windows_or_buffers_changed++;
- /* Mark all windows as INaccurate,
- so that every window will have its redisplay done. */
- mark_window_display_accurate (XWINDOW (minibuf_window)->prev, 0);
- if (screen_height == 0) abort (); /* Some bug zeros some core */
- return Qnil;
-}
-
-#endif /* not MULTI_SCREEN */
-\f
-char *message_buf;
+/* Nonzero if SCREEN_MESSAGE_BUF (selected_screen) is being used by print;
+ zero if being used by message. */
+int message_buf_print;
/* dump an informative message to the minibuf */
/* VARARGS 1 */
fprintf (stderr, "\n");
fflush (stderr);
}
- else if (INTERACTIVE)
+ /* A null message buffer means that the screen 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 && SCREEN_MESSAGE_BUF (selected_screen))
{
+#ifdef MULTI_SCREEN
+ choose_minibuf_screen ();
+ Fmake_screen_visible (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+#endif
+
+ {
#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 (SCREEN_MESSAGE_BUF (selected_screen),
- SCREEN_WIDTH (selected_screen), m, 0, 3, a);
+ doprnt (SCREEN_MESSAGE_BUF (selected_screen),
+ SCREEN_WIDTH (selected_screen), m, 0, 3, a);
#else
- doprnt (SCREEN_MESSAGE_BUF (selected_screen),
- SCREEN_WIDTH (selected_screen), m, 0, 3, &a1);
-#endif /* NO_ARG_ARRAY */
+ doprnt (SCREEN_MESSAGE_BUF (selected_screen),
+ SCREEN_WIDTH (selected_screen), m, 0, 3, &a1);
+#endif /* NO_ARG_ARRAY */
+ }
echo_area_glyphs = SCREEN_MESSAGE_BUF (selected_screen);
+
+ /* Print should start at the beginning of the message
+ buffer next time. */
+ message_buf_print = 0;
+
do_pending_window_change ();
echo_area_display ();
update_screen (XSCREEN (XWINDOW (minibuf_window)->screen), 1, 1);
message1 (m)
char *m;
{
- if (!NULL (Vwindow_system) && SCREEN_IS_TERMCAP (selected_screen))
- return;
-
if (noninteractive)
{
if (noninteractive_need_newline)
fprintf (stderr, "%s\n", m);
fflush (stderr);
}
- else if (INTERACTIVE)
+ /* A null message buffer means that the screen 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 && SCREEN_MESSAGE_BUF (selected_screen))
{
+#ifdef MULTI_SCREEN
+ choose_minibuf_screen ();
+ Fmake_screen_visible (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+#endif
+
echo_area_glyphs = m;
do_pending_window_change ();
echo_area_display ();
#ifdef MULTI_SCREEN
choose_minibuf_screen ();
- s = XSCREEN (XWINDOW (minibuf_window)->screen);
+ s = XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)));
- if (!s->visible)
+ if (! SCREEN_VISIBLE_P (s))
return;
#endif
/* If desired cursor location is on this line, put it at end of text */
if (SCREEN_CURSOR_Y (s) == vpos)
- SCREEN_CURSOR_X (s) = s->desired_glyphs->used[vpos];
+ SCREEN_CURSOR_X (s) = SCREEN_DESIRED_GLYPHS (s)->used[vpos];
+
+ /* Fill the rest of the minibuffer window with blank lines. */
+ {
+ int i;
+
+ for (i = vpos + 1; i < vpos + XWINDOW (minibuf_window)->height; i++)
+ {
+ get_display_line (s, i, 0);
+ display_string (XWINDOW (minibuf_window), vpos,
+ "", 0, 0, 0, SCREEN_WIDTH (s));
+ }
+ }
}
else if (!EQ (minibuf_window, selected_window))
windows_or_buffers_changed++;
screen_garbaged = 0;
}
+ /* Normally the message* functions will have already displayed and
+ updated the echo area, but the screen 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 ();
SCREEN_SCROLL_BOTTOM_VPOS (XSCREEN (w->screen)) = -1;
all_windows = update_mode_lines || buffer_shared > 1;
-#ifdef MULTI_SCREEN
- all_windows |= (XTYPE (Vglobal_minibuffer_screen) == Lisp_Screen
- && selected_screen != XSCREEN (Vglobal_minibuffer_screen));
-#endif /* MULTI_SCREEN */
/* If specs for an arrow have changed, do thorough redisplay
to ensure we remove any arrow that should no longer exist. */
tlbufpos = this_line_bufpos;
tlendpos = this_line_endpos;
- if (!all_windows && tlbufpos > 0 && NULL (w->update_mode_line)
+ if (!all_windows && tlbufpos > 0 && NILP (w->update_mode_line)
&& SCREEN_VISIBLE_P (XSCREEN (w->screen))
/* Make sure recorded data applies to current buffer, etc */
&& this_line_buffer == current_buffer
&& current_buffer == XBUFFER (w->buffer)
- && NULL (w->force_start)
+ && NILP (w->force_start)
/* Point must be on the line that we have info recorded about */
&& point >= tlbufpos
&& point <= Z - tlendpos
&& (XFASTINT (w->last_modified) >= MODIFF
|| (beg_unchanged >= tlbufpos - 1
&& GPT >= tlbufpos
+ /* If selective display, can't optimize
+ if the changes start at the beginning of the line. */
+ && ((XTYPE (current_buffer->selective_display) == Lisp_Int
+ && XINT (current_buffer->selective_display) > 0
+ ? (beg_unchanged >= tlbufpos
+ && GPT > tlbufpos)
+ : 1))
&& end_unchanged >= tlendpos
&& Z - GPT >= tlendpos)))
{
XFASTINT (w->width) - 1
- (XFASTINT (w->width) + XFASTINT (w->left)
!= SCREEN_WIDTH (selected_screen)),
- XINT (w->hscroll), 0);
+ XINT (w->hscroll),
+ pos_tab_offset (w, tlbufpos));
if (pos.vpos < 1)
{
SCREEN_CURSOR_X (selected_screen)
Lisp_Object tail;
/* Recompute # windows showing selected buffer.
- This will be increment each time such a window is displayed. */
+ This will be incremented each time such a window is displayed. */
buffer_shared = 0;
for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
s = XSCREEN (XCONS (tail)->car);
if (s->visible)
- {
-
- /* Clear the echo area on screens where the minibuffer isn't. */
- if (s != XSCREEN (XWINDOW (minibuf_window)->screen)
- /* But only screens that have minibuffers. */
- && s->has_minibuffer)
- {
- int vpos = XFASTINT (XWINDOW (s->minibuffer_window)->top);
- register struct screen_glyphs *line;
-
- get_display_line (s, vpos, 0);
- display_string (XWINDOW (s->minibuffer_window), vpos, "",
- 0, 0, 0, s->width);
- }
-
- /* Redraw its windows. */
- redisplay_windows (SCREEN_ROOT_WINDOW (s));
- }
+ /* Redraw its windows. */
+ redisplay_windows (SCREEN_ROOT_WINDOW (s));
}
#else
redisplay_windows (SCREEN_ROOT_WINDOW (s));
s = XSCREEN (XCONS (tail)->car);
if (s->visible)
{
- pause |= update_screen (s, 0, 0, SCREEN_SCROLL_BOTTOM_VPOS (s));
+ pause |= update_screen (s, 0, 0);
if (!pause)
mark_window_display_accurate (s->root_window, 1);
}
}
else
#endif /* MULTI_SCREEN */
- if (SCREEN_VISIBLE_P (selected_screen))
- pause = update_screen (selected_screen, 0, 0);
+ {
+ if (SCREEN_VISIBLE_P (selected_screen))
+ pause = update_screen (selected_screen, 0, 0);
+#ifdef MULTI_SCREEN
+ /* We may have called echo_area_display at the top of this
+ function. If the echo area is on another screen, that may
+ have put text on a screen other than the selected one, so the
+ above call to update_screen would not have caught it. Catch
+ it here. */
+ {
+ SCREEN_PTR mini_screen =
+ XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+
+ if (mini_screen != selected_screen)
+ pause |= update_screen (mini_screen, 0, 0);
+ }
+#endif
+ }
/* If screen does not match, prevent doing single-line-update next time.
Also, don't forget to check every line to update the arrow. */
if (pause)
{
this_line_bufpos = 0;
- if (!NULL (last_arrow_position))
+ if (!NILP (last_arrow_position))
{
last_arrow_position = Qt;
last_arrow_string = Qt;
{
register struct window *w;
- for (;!NULL (window); window = w->next)
+ for (;!NILP (window); window = w->next)
{
w = XWINDOW (window);
- if (!NULL (w->buffer))
+ if (!NILP (w->buffer))
XFASTINT (w->last_modified)
= !flag ? 0
: XBUFFER (w->buffer) == current_buffer
w->window_end_valid = Qt;
w->update_mode_line = Qnil;
- if (!NULL (w->vchild))
+ if (!NILP (w->vchild))
mark_window_display_accurate (w->vchild, flag);
- if (!NULL (w->hchild))
+ if (!NILP (w->hchild))
mark_window_display_accurate (w->hchild, flag);
}
redisplay_windows (window)
Lisp_Object window;
{
- for (; !NULL (window); window = XWINDOW (window)->next)
+ for (; !NILP (window); window = XWINDOW (window)->next)
redisplay_window (window, 0);
}
/* If this is a combination window, do its children; that's all. */
- if (!NULL (w->vchild))
+ if (!NILP (w->vchild))
{
redisplay_windows (w->vchild);
return;
}
- if (!NULL (w->hchild))
+ if (!NILP (w->hchild))
{
redisplay_windows (w->hchild);
return;
}
- if (NULL (w->buffer))
+ if (NILP (w->buffer))
abort ();
+
+ height = window_internal_height (w);
+
+ if (MINI_WINDOW_P (w))
+ {
+ if (w == XWINDOW (minibuf_window))
+ {
+ if (echo_area_glyphs)
+ /* We've already displayed the echo area glyphs, if any. */
+ return;
+ }
+ else
+ {
+ /* This is a minibuffer, but it's not the currently active one, so
+ clear it. */
+ int vpos = XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (s))->top);
+ int i;
+
+ for (i = 0; i < height; i++)
+ {
+ get_display_line (s, vpos + i, 0);
+ display_string (w, vpos + i, "", 0, 0, 0, width);
+ }
+
+ return;
+ }
+ }
if (update_mode_lines)
w->update_mode_line = Qt;
/* Otherwise set up data on this window; select its buffer and point value */
- height = window_internal_height (w);
-
- if (MINI_WINDOW_P (w)
- && (echo_area_glyphs
- /* Don't display minibuffers except minibuf_window. */
- || w != XWINDOW (minibuf_window)))
- return;
-
current_buffer = XBUFFER (w->buffer);
opoint = point;
SET_PT (marker_position (w->pointm));
if (point < BEGV)
{
- point = BEGV;
+ SET_PT (BEGV);
Fset_marker (w->pointm, make_number (point), Qnil);
}
else if (point > (ZV - 1))
{
- point = ZV;
+ SET_PT (ZV);
Fset_marker (w->pointm, make_number (point), Qnil);
}
}
/* If window-start is screwed up, choose a new one. */
-
if (XMARKER (w->start)->buffer != current_buffer)
goto recenter;
startp = marker_position (w->start);
- /* Handle case where place to start displaying has been specified */
-
- if (!NULL (w->force_start))
+ /* Handle case where place to start displaying has been specified,
+ unless the specified location is outside the visible range. */
+ if (!NILP (w->force_start))
{
w->update_mode_line = Qt;
w->force_start = Qnil;
XFASTINT (w->last_modified) = 0;
+ if (startp < BEGV) startp = BEGV;
+ if (startp > ZV) startp = ZV;
try_window (window, startp);
if (cursor_vpos < 0)
{
}
/* If current starting point was originally the beginning of a line
but no longer is, find a new starting point. */
- else if (!NULL (w->start_at_line_beg)
+ else if (!NILP (w->start_at_line_beg)
&& !(startp == BEGV
|| FETCH_CHAR (startp - 1) == '\n'))
{
}
else if (startp >= BEGV && startp <= ZV
/* Avoid starting display at end of buffer! */
- && (startp <= ZV || startp == BEGV
+ && (startp < ZV || startp == BEGV
|| (XFASTINT (w->last_modified) >= MODIFF)))
{
/* Try to redisplay starting at same place as before */
done:
/* If window not full width, must redo its mode line
if the window to its side is being redone */
- if ((!NULL (w->update_mode_line)
+ if ((!NILP (w->update_mode_line)
|| (!just_this_one && width < SCREEN_WIDTH (s) - 1))
&& height != XFASTINT (w->height))
display_mode_line (w);
/* Find position before which nothing is changed. */
bp = *compute_motion (start, 0, lmargin,
- beg_unchanged + 1, 10000, 10000, width, hscroll,
+ beg_unchanged + 1, height + 1, 0, width, hscroll,
pos_tab_offset (w, start));
if (bp.vpos >= height)
- return point < bp.bufpos && !bp.contin;
+ {
+ if (point < bp.bufpos && !bp.contin)
+ {
+ /* All changes are below the screen, and point is on the screen.
+ We don't need to change the screen at all.
+ But we need to update window_end_pos to account for
+ any change in buffer size. */
+ bp = *compute_motion (start, 0, lmargin,
+ Z, height, 0,
+ width, hscroll, pos_tab_offset (w, start));
+ XFASTINT (w->window_end_vpos) = height;
+ XFASTINT (w->window_end_pos) = Z - bp.bufpos;
+ return 1;
+ }
+ return 0;
+ }
vpos = bp.vpos;
/* If about to start displaying at the beginning of a continuation line,
really start with previous screen line, in case it was not
continued when last redisplayed */
- if (bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0)
+ if ((bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0)
+ ||
+ /* Likewise if we have to worry about selective display. */
+ (XTYPE (current_buffer->selective_display) == Lisp_Int
+ && XINT (current_buffer->selective_display) > 0
+ && bp.bufpos - 1 == beg_unchanged && vpos > 0))
{
bp = *vmotion (bp.bufpos, -1, width, hscroll, window);
--vpos;
return 1;
}
\f
-/* Copy part of the contents of the string FROM into a glyph-vector at S.
- But don't actually copy the parts that would come in before T.
+/* Copy glyphs from the rope FROM to T.
+ But don't actually copy the parts that would come in before S.
Value is T, advanced past the copied data.
Characters in FROM are grouped into units of `sizeof GLYPH' chars;
register GLYPH *p1prev;
SCREEN_PTR s = XSCREEN (w->screen);
int tab_width = XINT (current_buffer->tab_width);
- int ctl_arrow = !NULL (current_buffer->ctl_arrow);
+ int ctl_arrow = !NILP (current_buffer->ctl_arrow);
int width = XFASTINT (w->width) - 1
- (XFASTINT (w->width) + XFASTINT (w->left) != SCREEN_WIDTH (s));
struct position val;
int truncate = hscroll
|| (truncate_partial_width_windows
&& XFASTINT (w->width) < SCREEN_WIDTH (s))
- || !NULL (current_buffer->truncate_lines);
+ || !NILP (current_buffer->truncate_lines);
int selective
= XTYPE (current_buffer->selective_display) == Lisp_Int
? XINT (current_buffer->selective_display)
- : !NULL (current_buffer->selective_display) ? -1 : 0;
+ : !NILP (current_buffer->selective_display) ? -1 : 0;
#ifndef old
- int selective_e = selective && !NULL (current_buffer->selective_display_ellipses);
+ int selective_e = selective && !NILP (current_buffer->selective_display_ellipses);
#endif
register struct screen_glyphs *desired_glyphs = SCREEN_DESIRED_GLYPHS (s);
register struct Lisp_Vector *dp = window_display_table (w);
while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
% tab_width);
}
- else if (c == Ctl('M') && selective == -1)
+ else if (c == Ctl ('M') && selective == -1)
{
pos = find_next_newline (pos, 1);
if (FETCH_CHAR (pos - 1) == '\n')
*p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
? XINT (DISP_CTRL_GLYPH (dp)) : '^');
p1++;
- if (p1 >= startp)
+ if (p1 >= startp && p1 < endp)
*p1 = c ^ 0100;
p1++;
}
*p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\');
p1++;
- if (p1 >= startp)
+ if (p1 >= startp && p1 < endp)
*p1 = (c >> 6) + '0';
p1++;
- if (p1 >= startp)
+ if (p1 >= startp && p1 < endp)
*p1 = (7 & (c >> 3)) + '0';
p1++;
- if (p1 >= startp)
+ if (p1 >= startp && p1 < endp)
*p1 = (7 & c) + '0';
p1++;
}
and the rest of this line is mode lines of the sibling windows). */
if (XFASTINT (w->width) == SCREEN_WIDTH (s)
|| XFASTINT (XWINDOW (w->parent)->width) == SCREEN_WIDTH (s))
- s->desired_glyphs->highlight[vpos] = mode_line_inverse_video;
+ SCREEN_DESIRED_GLYPHS (s)->highlight[vpos] = mode_line_inverse_video;
#ifdef HAVE_X_WINDOWS
/* I'm trying this out because I saw Unimpress use it, but it's
- possible that this may fuck adversely with some window managers. jla */
+ possible that this may mess adversely with some window managers. jla */
if (SCREEN_IS_X (s)
- && (XTYPE (Vglobal_minibuffer_screen) != Lisp_Screen
- || s != XSCREEN (Vglobal_minibuffer_screen))
+ && ! SCREEN_MINIBUF_ONLY_P (s)
&& w == XWINDOW (s->selected_window)
- && (NULL (Fstring_equal (XBUFFER (w->buffer)->name, s->name))))
+ && (NILP (Fstring_equal (XBUFFER (w->buffer)->name, s->name))))
x_set_name (s, XBUFFER (w->buffer)->name, Qnil);
#endif
}
{
register Lisp_Object tem;
tem = Fboundp (elt);
- if (!NULL (tem))
+ if (!NILP (tem))
{
tem = Fsymbol_value (elt);
/* If value is a string, output that string literally:
goto invalid;
/* elt is now the cdr, and we know it is a cons cell.
Use its car if CAR has a non-nil value. */
- if (!NULL (tem))
+ if (!NILP (tem))
{
tem = Fsymbol_value (car);
- if (!NULL (tem))
+ if (!NILP (tem))
{ elt = XCONS (elt)->car; goto tail_recurse; }
}
/* Symbol's value is nil (or symbol is unbound)
Get the cddr of the original list
and if possible find the caddr and use that. */
elt = XCONS (elt)->cdr;
- if (NULL (elt))
+ if (NILP (elt))
break;
else if (XTYPE (elt) != Lisp_Cons)
goto invalid;
case 'f':
obj = current_buffer->filename;
#if 0
- if (NULL (obj))
+ if (NILP (obj))
return "[none]";
else if (XTYPE (obj) == Lisp_String && XSTRING (obj)->size > maxwidth)
{
break;
case '*':
- if (!NULL (current_buffer->read_only))
+ if (!NILP (current_buffer->read_only))
return "%";
if (MODIFF > current_buffer->save_modified)
return "*";
case 's':
/* status of process */
-#ifdef subprocesses
obj = Fget_buffer_process (Fcurrent_buffer ());
- if (NULL (obj))
+ if (NILP (obj))
return "no process";
obj = Fsymbol_name (Fprocess_status (obj));
break;
-#else
- return "no processes";
-#endif /* subprocesses */
case 'p':
{
*p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
? XINT (DISP_CTRL_GLYPH (dp)) : '^');
p1++;
- if (p1 >= start)
+ if (p1 >= start && p1 < end)
*p1 = c ^ 0100;
p1++;
}
*p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\');
p1++;
- if (p1 >= start)
+ if (p1 >= start && p1 < end)
*p1 = (c >> 6) + '0';
p1++;
- if (p1 >= start)
+ if (p1 >= start && p1 < end)
*p1 = (7 & (c >> 3)) + '0';
p1++;
- if (p1 >= start)
+ if (p1 >= start && p1 < end)
*p1 = (7 & c) + '0';
p1++;
}
DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
"*Non-nil means use inverse video for the mode line.");
mode_line_inverse_video = 1;
-
-#ifndef MULTI_SCREEN
- defsubr (&Sredraw_display);
-#endif /* MULTI_SCREEN */
}
/* initialize the window system */