/* Display generation from window structure and buffer text.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99, 2000
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
#include "lisp.h"
+#include "keyboard.h"
#include "frame.h"
#include "window.h"
#include "termchar.h"
#include "disptab.h"
#include "termhooks.h"
#include "intervals.h"
-#include "keyboard.h"
#include "coding.h"
#include "process.h"
#include "region-cache.h"
Lisp_Object Vmessage_log_max;
+/* The name of the *Messages* buffer, a string. */
+
+static Lisp_Object Vmessages_buffer_name;
+
/* Current, index 0, and last displayed echo area message. Either
buffers from echo_buffers, or nil to indicate no message. */
#define TEXT_PROP_DISTANCE_LIMIT 100
+#if GLYPH_DEBUG
+
/* Non-zero means print traces of redisplay if compiled with
GLYPH_DEBUG != 0. */
-#if GLYPH_DEBUG
int trace_redisplay_p;
-#endif
+#endif /* GLYPH_DEBUG */
+
+#ifdef DEBUG_TRACE_MOVE
+/* Non-zero means trace with TRACE_MOVE to stderr. */
+int trace_move;
+
+#define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
+#else
+#define TRACE_MOVE(x) (void) 0
+#endif
+
/* Non-zero means automatically scroll windows horizontally to make
point visible. */
\f
/* Function prototypes. */
+static int redisplay_mode_lines P_ ((Lisp_Object, int));
static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
static int invisible_text_between_p P_ ((struct it *, int, int));
static int next_element_from_ellipsis P_ ((struct it *));
static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
static int with_echo_area_buffer P_ ((struct window *, int,
- int (*) (EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT),
- EMACS_INT, EMACS_INT, EMACS_INT,
- EMACS_INT));
+ int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
+ EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static void clear_garbaged_frames P_ ((void));
-static int current_message_1 P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
-static int truncate_message_1 P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
-static int set_message_1 P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
+static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
+static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
+static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static int display_echo_area P_ ((struct window *));
-static int display_echo_area_1 P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
-static int resize_mini_window_1 P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
+static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
+static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
static int string_char_and_length P_ ((unsigned char *, int, int *));
static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
static int append_space P_ ((struct it *, int));
static void make_cursor_line_fully_visible P_ ((struct window *));
static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
+static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
static int trailing_whitespace_p P_ ((int));
static int message_log_check_duplicate P_ ((int, int, int, int));
int invisible_p P_ ((Lisp_Object, Lisp_Object));
static int try_window_reusing_current_matrix P_ ((struct window *));
static int try_window_id P_ ((struct window *));
static int display_line P_ ((struct it *));
-static void display_mode_lines P_ ((struct window *));
+static int display_mode_lines P_ ((struct window *));
static void display_mode_line P_ ((struct window *, enum face_id,
Lisp_Object));
static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
\003, or in the middle of an overlay string). In this case
move_it_to above will not have taken us to the start of
the continuation line but to the end of the continued line. */
- if (!it->truncate_lines_p && it->current_x > 0)
+ if (!it->truncate_lines_p)
{
- if (it->current.dpvec_index >= 0
- || it->current.overlay_string_index >= 0)
+ if (it->current_x > 0)
{
- set_iterator_to_next (it);
- move_it_in_display_line_to (it, -1, -1, 0);
+ if (it->current.dpvec_index >= 0
+ || it->current.overlay_string_index >= 0)
+ {
+ set_iterator_to_next (it);
+ move_it_in_display_line_to (it, -1, -1, 0);
+ }
+
+ it->continuation_lines_width += it->current_x;
}
- it->continuation_lines_width += it->current_x;
+
+ /* We're starting a new display line, not affected by the
+ height of the continued line, so clear the appropriate
+ fields in the iterator structure. */
+ it->max_ascent = it->max_descent = 0;
+ it->max_phys_ascent = it->max_phys_descent = 0;
}
it->current_y = first_y;
/* Get all overlays at the given position. */
len = 10;
overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
- noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
+ noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
if (noverlays > len)
{
len = noverlays;
overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
- noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
+ noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
}
/* If any of these overlays ends before endpos,
if (!STRINGP (it->string)
&& it->s == NULL
&& !NILP (Vfontification_functions)
+ && !NILP (Vrun_hooks)
&& (pos = make_number (IT_CHARPOS (*it)),
prop = Fget_char_property (pos, Qfontified, Qnil),
NILP (prop)))
{
- Lisp_Object args[2];
+ int count = specpdl_ptr - specpdl;
+ Lisp_Object val;
+
+ val = Vfontification_functions;
+ specbind (Qfontification_functions, Qnil);
+ specbind (Qafter_change_functions, Qnil);
+
+ if (!CONSP (val) || EQ (XCAR (val), Qlambda))
+ call1 (val, pos);
+ else
+ {
+ Lisp_Object globals, fn;
+ struct gcpro gcpro1, gcpro2;
+
+ globals = Qnil;
+ GCPRO2 (val, globals);
+
+ for (; CONSP (val); val = XCDR (val))
+ {
+ fn = XCAR (val);
+
+ if (EQ (fn, Qt))
+ {
+ /* A value of t indicates this hook has a local
+ binding; it means to run the global binding too.
+ In a global value, t should not occur. If it
+ does, we must ignore it to avoid an endless
+ loop. */
+ for (globals = Fdefault_value (Qfontification_functions);
+ CONSP (globals);
+ globals = XCDR (globals))
+ {
+ fn = XCAR (globals);
+ if (!EQ (fn, Qt))
+ call1 (fn, pos);
+ }
+ }
+ else
+ call1 (fn, pos);
+ }
- /* Run the hook functions. */
- args[0] = Qfontification_functions;
- args[1] = pos;
- Frun_hook_with_args (2, args);
+ UNGCPRO;
+ }
+
+ unbind_to (count, Qnil);
/* Return HANDLED_RECOMPUTE_PROPS only if function fontified
something. This avoids an endless loop if they failed to
while (1)
{
- int x, i;
+ int x, i, ascent = 0, descent = 0;
/* Stop when ZV or TO_CHARPOS reached. */
if (!get_next_display_element (it)
x-position before this display element in case it does not
fit on the line. */
x = it->current_x;
+
+ /* Remember the line height so far in case the next element doesn't
+ fit on the line. */
+ if (!it->truncate_lines_p)
+ {
+ ascent = it->max_ascent;
+ descent = it->max_descent;
+ }
+
PRODUCE_GLYPHS (it);
if (it->area != TEXT_AREA)
set_iterator_to_next (it);
}
else
- it->current_x = x;
-
+ {
+ it->current_x = x;
+ it->max_ascent = ascent;
+ it->max_descent = descent;
+ }
+
+ TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
+ IT_CHARPOS (*it)));
result = MOVE_LINE_CONTINUED;
break;
}
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height;
+ int reached = 0;
- while (1)
+ for (;;)
{
if (op & MOVE_TO_VPOS)
{
if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
{
if (it->vpos == to_vpos)
- break;
- skip = move_it_in_display_line_to (it, -1, -1, 0);
+ {
+ reached = 1;
+ break;
+ }
+ else
+ skip = move_it_in_display_line_to (it, -1, -1, 0);
}
else
{
/* TO_VPOS >= 0 means stop at TO_X in the line at
TO_VPOS, or at TO_POS, whichever comes first. */
+ if (it->vpos == to_vpos)
+ {
+ reached = 2;
+ break;
+ }
+
skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
- break;
+ {
+ reached = 3;
+ break;
+ }
else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
{
/* We have reached TO_X but not in the line we want. */
skip = move_it_in_display_line_to (it, to_charpos,
-1, MOVE_TO_POS);
if (skip == MOVE_POS_MATCH_OR_ZV)
- break;
+ {
+ reached = 4;
+ break;
+ }
}
}
}
else if (op & MOVE_TO_Y)
{
struct it it_backup;
- int done_p;
/* TO_Y specified means stop at TO_X in the line containing
TO_Y---or at TO_CHARPOS if this is reached first. The
/* If TO_CHARPOS is reached or ZV, we don't have to do more. */
if (skip == MOVE_POS_MATCH_OR_ZV)
- break;
+ {
+ reached = 5;
+ break;
+ }
/* If TO_X was reached, we would like to know whether TO_Y
is in the line. This can only be said if we know the
total line height which requires us to scan the rest of
the line. */
- done_p = 0;
if (skip == MOVE_X_REACHED)
{
it_backup = *it;
+ TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
skip2 = move_it_in_display_line_to (it, to_charpos, -1,
op & MOVE_TO_POS);
+ TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
}
/* Now, decide whether TO_Y is in this line. */
line_height = it->max_ascent + it->max_descent;
+ TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
if (to_y >= it->current_y
&& to_y < it->current_y + line_height)
we scanned too far. We have to restore IT's settings
to the ones before skipping. */
*it = it_backup;
- done_p = 1;
+ reached = 6;
}
else if (skip == MOVE_X_REACHED)
{
skip = skip2;
if (skip == MOVE_POS_MATCH_OR_ZV)
- done_p = 1;
+ reached = 7;
}
- if (done_p)
+ if (reached)
break;
}
else
switch (skip)
{
case MOVE_POS_MATCH_OR_ZV:
- return;
+ reached = 8;
+ goto out;
case MOVE_NEWLINE_OR_CR:
set_iterator_to_next (it);
reseat_at_next_visible_line_start (it, 0);
if ((op & MOVE_TO_POS) != 0
&& IT_CHARPOS (*it) > to_charpos)
- goto out;
+ {
+ reached = 9;
+ goto out;
+ }
break;
case MOVE_LINE_CONTINUED:
last_max_ascent = it->max_ascent;
it->max_ascent = it->max_descent = 0;
}
- out:;
+
+ out:
+
+ TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
}
MOVE_TO_POS | MOVE_TO_VPOS);
xassert (IT_CHARPOS (*it) >= BEGV);
line_height = it2.max_ascent + it2.max_descent;
+
move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
xassert (IT_CHARPOS (*it) >= BEGV);
h = it2.current_y - it->current_y;
move_it_vertically_backward (it, -dy);
else if (dy > 0)
{
+ TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
move_it_to (it, ZV, -1, it->current_y + dy, -1,
MOVE_TO_POS | MOVE_TO_Y);
+ TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
/* If buffer ends in ZV without a newline, move to the start of
the line to satisfy the post-condition. */
old_deactivate_mark = Vdeactivate_mark;
oldbuf = current_buffer;
- Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
+ Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
current_buffer->undo_list = Qt;
oldpoint = Fpoint_marker ();
|| NILP (XBUFFER (echo_buffer[i])->name))
{
char name[30];
+ Lisp_Object old_buffer;
+ int j;
+
+ old_buffer = echo_buffer[i];
sprintf (name, " *Echo Area %d*", i);
echo_buffer[i] = Fget_buffer_create (build_string (name));
XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
+
+ for (j = 0; j < 2; ++j)
+ if (EQ (old_buffer, echo_area_buffer[j]))
+ echo_area_buffer[j] = echo_buffer[i];
}
}
with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
struct window *w;
int which;
- int (*fn) P_ ((EMACS_INT, EMACS_INT, EMACS_INT, EMACS_INT));
- EMACS_INT a1, a2, a3, a4;
+ int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
+ EMACS_INT a1;
+ Lisp_Object a2;
+ EMACS_INT a3, a4;
{
Lisp_Object buffer;
int this_one, the_other, clear_buffer_p, rc;
window_height_changed_p
= with_echo_area_buffer (w, display_last_displayed_message_p,
display_echo_area_1,
- (EMACS_INT) w, 0, 0, 0);
+ (EMACS_INT) w, Qnil, 0, 0);
if (no_message_p)
echo_area_buffer[i] = Qnil;
static int
display_echo_area_1 (a1, a2, a3, a4)
- EMACS_INT a1, a2, a3, a4;
+ EMACS_INT a1;
+ Lisp_Object a2;
+ EMACS_INT a3, a4;
{
struct window *w = (struct window *) a1;
Lisp_Object window;
int resized_p;
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
- (EMACS_INT) w, 0, 0, 0);
+ (EMACS_INT) w, Qnil, 0, 0);
if (resized_p)
{
++windows_or_buffers_changed;
static int
resize_mini_window_1 (a1, a2, a3, a4)
- EMACS_INT a1, a2, a3, a4;
+ EMACS_INT a1;
+ Lisp_Object a2;
+ EMACS_INT a3, a4;
{
return resize_mini_window ((struct window *) a1, 1);
}
else
{
with_echo_area_buffer (0, 0, current_message_1,
- (EMACS_INT) &msg, 0, 0, 0);
+ (EMACS_INT) &msg, Qnil, 0, 0);
if (NILP (msg))
echo_area_buffer[0] = Qnil;
}
static int
current_message_1 (a1, a2, a3, a4)
- EMACS_INT a1, a2, a3, a4;
+ EMACS_INT a1;
+ Lisp_Object a2;
+ EMACS_INT a3, a4;
{
Lisp_Object *msg = (Lisp_Object *) a1;
{
struct frame *sf = SELECTED_FRAME ();
if (FRAME_MESSAGE_BUF (sf))
- with_echo_area_buffer (0, 0, truncate_message_1, nchars, 0, 0, 0);
+ with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
}
}
static int
truncate_message_1 (nchars, a2, a3, a4)
- EMACS_INT nchars, a2, a3, a4;
+ EMACS_INT nchars;
+ Lisp_Object a2;
+ EMACS_INT a3, a4;
{
if (BEG + nchars < Z)
del_range (BEG + nchars, Z);
static int
set_message_1 (a1, a2, nbytes, multibyte_p)
- EMACS_INT a1, a2, nbytes, multibyte_p;
+ EMACS_INT a1;
+ Lisp_Object a2;
+ EMACS_INT nbytes, multibyte_p;
{
char *s = (char *) a1;
- Lisp_Object string = (Lisp_Object) a2;
+ Lisp_Object string = a2;
xassert (BEG == Z);
window_height_changed_p = display_echo_area (w);
w->must_be_updated_p = 1;
+ /* Update the display, unless called from redisplay_internal. */
if (update_frame_p)
{
- /* Not called from redisplay_internal. If we changed
- window configuration, we must redisplay thoroughly.
- Otherwise, we can do with updating what we displayed
- above. */
+ int n = 0;
+
+ /* If the display update has been interrupted by pending
+ input, update mode lines in the frame. Due to the
+ pending input, it might have been that redisplay hasn't
+ been called, so that mode lines above the echo area are
+ garbaged. This looks odd, so we prevent it here. */
+ if (!display_completed)
+ n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
+
if (window_height_changed_p)
{
- ++windows_or_buffers_changed;
- ++update_mode_lines;
+ /* Must update other windows. */
+ windows_or_buffers_changed = 1;
redisplay_internal (0);
}
- else if (FRAME_WINDOW_P (f))
+ else if (FRAME_WINDOW_P (f) && n == 0)
{
+ /* Window configuration is the same as before.
+ Can do with a display update of the echo area,
+ unless we displayed some mode lines. */
update_single_window (w, 1);
rif->flush_display (f);
}
++redisplaying_p;
retry:
-
+ pause = 0;
reconsider_clip_changes (w, current_buffer);
/* If new fonts have been loaded that make a glyph matrix adjustment
clear_garbaged_frames ();
}
}
- else if (w == XWINDOW (minibuf_window)
+ else if (EQ (selected_window, minibuf_window)
&& (current_buffer->clip_changed
|| XFASTINT (w->last_modified) < MODIFF
|| XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
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)
+ && (EQ (selected_window, current_buffer->last_selected_window)
|| highlight_nonselected_windows)
&& NILP (w->region_showing)
&& NILP (Vshow_trailing_whitespace)
++clear_face_cache_count;
- /* Build desired matrices. If consider_all_windows_p is non-zero,
- do it for all windows on all frames. Otherwise do it for
- selected_window, only. */
+ /* Build desired matrices, and update the display. If
+ consider_all_windows_p is non-zero, do it for all windows on all
+ frames. Otherwise do it for selected_window, only. */
if (consider_all_windows_p)
{
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
+
if (FRAME_WINDOW_P (f) || f == sf)
{
/* Mark all the scroll bars to be removed; we'll redeem
nuked should now go away. */
if (judge_scroll_bars_hook)
(*judge_scroll_bars_hook) (f);
+
+ /* If fonts changed, display again. */
+ if (fonts_changed_p)
+ goto retry;
+
+ if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
+ {
+ /* See if we have to hscroll. */
+ if (hscroll_windows (f->root_window))
+ goto retry;
+
+ /* Prevent various kinds of signals during display
+ update. stdio is not robust about handling
+ signals, which can cause an apparent I/O
+ error. */
+ if (interrupt_input)
+ unrequest_sigio ();
+ stop_polling ();
+
+ /* Update the display. */
+ set_window_update_flags (XWINDOW (f->root_window), 1);
+ pause |= update_frame (f, 0, 0);
+ if (pause)
+ break;
+
+ mark_window_display_accurate (f->root_window, 1);
+ if (frame_up_to_date_hook)
+ frame_up_to_date_hook (f);
+ }
}
}
}
- else if (FRAME_VISIBLE_P (sf)
- && !FRAME_OBSCURED_P (sf))
- redisplay_window (selected_window, 1);
+ else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
+ {
+ Lisp_Object mini_window;
+ struct frame *mini_frame;
+ redisplay_window (selected_window, 1);
- /* Compare desired and current matrices, perform output. */
-
-update:
+ /* Compare desired and current matrices, perform output. */
+ update:
- /* If fonts changed, display again. */
- if (fonts_changed_p)
- goto retry;
-
- /* Prevent various kinds of signals during display update.
- stdio is not robust about handling signals,
- which can cause an apparent I/O error. */
- if (interrupt_input)
- unrequest_sigio ();
- stop_polling ();
-
- if (consider_all_windows_p)
- {
- Lisp_Object tail;
- struct frame *f;
- int hscrolled_p;
-
- pause = 0;
- hscrolled_p = 0;
-
- /* See if we have to hscroll. */
- for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
- if (FRAMEP (XCAR (tail)))
- {
- f = XFRAME (XCAR (tail));
-
- if ((FRAME_WINDOW_P (f)
- || f == sf)
- && FRAME_VISIBLE_P (f)
- && !FRAME_OBSCURED_P (f)
- && hscroll_windows (f->root_window))
- hscrolled_p = 1;
- }
-
- if (hscrolled_p)
+ /* If fonts changed, display again. */
+ if (fonts_changed_p)
goto retry;
- for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
- {
- if (!FRAMEP (XCAR (tail)))
- continue;
+ /* Prevent various kinds of signals during display update.
+ stdio is not robust about handling signals,
+ which can cause an apparent I/O error. */
+ if (interrupt_input)
+ unrequest_sigio ();
+ stop_polling ();
- f = XFRAME (XCAR (tail));
-
- if ((FRAME_WINDOW_P (f) || f == sf)
- && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
- {
- /* Mark all windows as to be updated. */
- set_window_update_flags (XWINDOW (f->root_window), 1);
- pause |= update_frame (f, 0, 0);
- if (!pause)
- {
- mark_window_display_accurate (f->root_window, 1);
- if (frame_up_to_date_hook != 0)
- (*frame_up_to_date_hook) (f);
- }
- }
- }
- }
- else
- {
- if (FRAME_VISIBLE_P (sf)
- && !FRAME_OBSCURED_P (sf))
+ if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
{
if (hscroll_windows (selected_window))
goto retry;
XWINDOW (selected_window)->must_be_updated_p = 1;
pause = update_frame (sf, 0, 0);
}
- else
- pause = 0;
/* We may have called echo_area_display at the top of this
function. If the echo area is on another frame, that may
have put text on a frame other than the selected one, so the
above call to update_frame would not have caught it. Catch
it here. */
- {
- Lisp_Object mini_window;
- struct frame *mini_frame;
-
- mini_window = FRAME_MINIBUF_WINDOW (sf);
- mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
+ mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
- {
- XWINDOW (mini_window)->must_be_updated_p = 1;
- pause |= update_frame (mini_frame, 0, 0);
- if (!pause && hscroll_windows (mini_window))
- goto retry;
- }
- }
+ if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
+ {
+ XWINDOW (mini_window)->must_be_updated_p = 1;
+ pause |= update_frame (mini_frame, 0, 0);
+ if (!pause && hscroll_windows (mini_window))
+ goto retry;
+ }
}
/* If display was paused because of pending input, make sure we do a
/* 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)
+ && (EQ (selected_window,
+ current_buffer->last_selected_window)
|| highlight_nonselected_windows)
&& !NILP (XBUFFER (w->buffer)->mark_active)
? Fmarker_position (XBUFFER (w->buffer)->mark)
{
struct glyph_matrix *matrix;
struct glyph_row *row;
+ int window_height, header_line_height;
/* It's not always possible to find the cursor, e.g, when a window
is full of overlay strings. Don't do anything in that case. */
matrix = w->desired_matrix;
row = MATRIX_ROW (matrix, w->cursor.vpos);
- if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)
- /* The row may be partially visible at the top because we
- already have chosen a vscroll to align the bottom of the
- row with the bottom of the window. This happens for rows
- taller than the window. */
- && row->y + row->height < window_box_height (w))
+ /* If the cursor row is not partially visible, there's nothing
+ to do. */
+ if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
+ return;
+
+ /* If the row the cursor is in is taller than the window's height,
+ it's not clear what to do, so do nothing. */
+ window_height = window_box_height (w);
+ if (row->height >= window_height)
+ return;
+
+ if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
{
int dy = row->height - row->visible_height;
w->vscroll = 0;
w->cursor.y += dy;
shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
}
- else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)
- /* The row may be partially visible at the bottom because
- we chose a vscroll to align the row's top with the
- window's top. This happens for rows taller than the
- window. */
- && row->y > WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w))
+ else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
{
int dy = - (row->height - row->visible_height);
w->vscroll = dy;
w->cursor.y += dy;
shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
}
-
+
/* When we change the cursor y-position of the selected window,
change this_line_y as well so that the display optimization for
the cursor line of the selected window in redisplay_internal uses
/* Point is in the scroll margin at the bottom of the window, or
below. Compute a new window start that makes point visible. */
-
+
/* Compute the distance from the scroll margin to PT.
Give up if the distance is greater than scroll_max. */
start_display (&it, w, scroll_margin_pos);
? it.max_ascent + it.max_descent
: last_height);
dy = it.current_y + line_height - y0;
+
if (dy > scroll_max)
return 0;
}
+/* Try cursor movement in case text has not changes in window WINDOW,
+ with window start STARTP. Value is
+
+ 1 if successful
+
+ 0 if this method cannot be used
+
+ -1 if we know we have to scroll the display. *SCROLL_STEP is
+ set to 1, under certain circumstances, if we want to scroll as
+ if scroll-step were set to 1. See the code. */
+
+static int
+try_cursor_movement (window, startp, scroll_step)
+ Lisp_Object window;
+ struct text_pos startp;
+ int *scroll_step;
+{
+ struct window *w = XWINDOW (window);
+ struct frame *f = XFRAME (w->frame);
+ int rc = 0;
+
+ /* Handle case where text has not changed, only point, and it has
+ not moved off the frame. */
+ if (/* Point may be in this window. */
+ PT >= CHARPOS (startp)
+ /* If we don't check this, we are called to move the cursor in a
+ horizontally split window with a current matrix that doesn't
+ fit the display. */
+ && !windows_or_buffers_changed
+ /* Selective display hasn't changed. */
+ && !current_buffer->clip_changed
+ /* If force-mode-line-update was called, really redisplay;
+ that's how redisplay is forced after e.g. changing
+ buffer-invisibility-spec. */
+ && NILP (w->update_mode_line)
+ /* Can't use this case if highlighting a region. When a
+ region exists, cursor movement has to do more than just
+ set the cursor. */
+ && !(!NILP (Vtransient_mark_mode)
+ && !NILP (current_buffer->mark_active))
+ && NILP (w->region_showing)
+ && NILP (Vshow_trailing_whitespace)
+ /* Right after splitting windows, last_point may be nil. */
+ && INTEGERP (w->last_point)
+ /* This code is not used for mini-buffer for the sake of the case
+ of redisplaying to replace an echo area message; since in
+ that case the mini-buffer contents per se are usually
+ unchanged. This code is of no real use in the mini-buffer
+ since the handling of this_line_start_pos, etc., in redisplay
+ handles the same cases. */
+ && !EQ (window, minibuf_window)
+ /* When splitting windows or for new windows, it happens that
+ redisplay is called with a nil window_end_vpos or one being
+ larger than the window. This should really be fixed in
+ window.c. I don't have this on my list, now, so we do
+ approximately the same as the old redisplay code. --gerd. */
+ && INTEGERP (w->window_end_vpos)
+ && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
+ && (FRAME_WINDOW_P (f)
+ || !MARKERP (Voverlay_arrow_position)
+ || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
+ {
+ int this_scroll_margin;
+ struct glyph_row *row;
+
+#if GLYPH_DEBUG
+ debug_method_add (w, "cursor movement");
+#endif
+
+ /* Scroll if point within this distance from the top or bottom
+ of the window. This is a pixel value. */
+ this_scroll_margin = max (0, scroll_margin);
+ this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
+ this_scroll_margin *= CANON_Y_UNIT (f);
+
+ /* Start with the row the cursor was displayed during the last
+ not paused redisplay. Give up if that row is not valid. */
+ if (w->last_cursor.vpos < 0
+ || w->last_cursor.vpos >= w->current_matrix->nrows)
+ rc = -1;
+ else
+ {
+ row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
+ if (row->mode_line_p)
+ ++row;
+ if (!row->enabled_p)
+ rc = -1;
+ }
+
+ if (rc == 0)
+ {
+ int scroll_p = 0;
+
+ if (PT > XFASTINT (w->last_point))
+ {
+ /* Point has moved forward. */
+ int last_y = window_text_bottom_y (w) - this_scroll_margin;
+
+ while (MATRIX_ROW_END_CHARPOS (row) < PT
+ && MATRIX_ROW_BOTTOM_Y (row) < last_y)
+ {
+ xassert (row->enabled_p);
+ ++row;
+ }
+
+ /* The end position of a row equals the start position
+ of the next row. If PT is there, we would rather
+ display it in the next line. Exceptions are when the
+ row ends in the middle of a character, or ends in
+ ZV. */
+ if (MATRIX_ROW_BOTTOM_Y (row) < last_y
+ && MATRIX_ROW_END_CHARPOS (row) == PT
+ && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
+ && !row->ends_at_zv_p)
+ {
+ xassert (row->enabled_p);
+ ++row;
+ }
+
+ /* If within the scroll margin, scroll. Note that
+ MATRIX_ROW_BOTTOM_Y gives the pixel position at which
+ the next line would be drawn, and that
+ this_scroll_margin can be zero. */
+ if (MATRIX_ROW_BOTTOM_Y (row) > last_y
+ || PT > MATRIX_ROW_END_CHARPOS (row)
+ /* Line is completely visible last line in window
+ and PT is to be set in the next line. */
+ || (MATRIX_ROW_BOTTOM_Y (row) == last_y
+ && PT == MATRIX_ROW_END_CHARPOS (row)
+ && !row->ends_at_zv_p
+ && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
+ scroll_p = 1;
+ }
+ else if (PT < XFASTINT (w->last_point))
+ {
+ /* Cursor has to be moved backward. Note that PT >=
+ CHARPOS (startp) because of the outer
+ if-statement. */
+ while (!row->mode_line_p
+ && (MATRIX_ROW_START_CHARPOS (row) > PT
+ || (MATRIX_ROW_START_CHARPOS (row) == PT
+ && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
+ && (row->y > this_scroll_margin
+ || CHARPOS (startp) == BEGV))
+ {
+ xassert (row->enabled_p);
+ --row;
+ }
+
+ /* Consider the following case: Window starts at BEGV,
+ there is invisible, intangible text at BEGV, so that
+ display starts at some point START > BEGV. It can
+ happen that we are called with PT somewhere between
+ BEGV and START. Try to handle that case. */
+ if (row < w->current_matrix->rows
+ || row->mode_line_p)
+ {
+ row = w->current_matrix->rows;
+ if (row->mode_line_p)
+ ++row;
+ }
+
+ /* Due to newlines in overlay strings, we may have to
+ skip forward over overlay strings. */
+ while (MATRIX_ROW_END_CHARPOS (row) == PT
+ && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
+ && !row->ends_at_zv_p)
+ ++row;
+
+ /* If within the scroll margin, scroll. */
+ if (row->y < this_scroll_margin
+ && CHARPOS (startp) != BEGV)
+ scroll_p = 1;
+ }
+
+ if (PT < MATRIX_ROW_START_CHARPOS (row)
+ || PT > MATRIX_ROW_END_CHARPOS (row))
+ {
+ /* if PT is not in the glyph row, give up. */
+ rc = -1;
+ }
+ else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
+ {
+ /* If we end up in a partially visible line, let's make it
+ fully visible, except when it's taller than the window,
+ in which case we can't do much about it. */
+ if (row->height > window_box_height (w))
+ {
+ *scroll_step = 1;
+ rc = -1;
+ }
+ else
+ {
+ set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+ try_window (window, startp);
+ make_cursor_line_fully_visible (w);
+ rc = 1;
+ }
+ }
+ else if (scroll_p)
+ rc = -1;
+ else
+ {
+ set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+ rc = 1;
+ }
+ }
+ }
+
+ return rc;
+}
+
+
/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
selected_window is redisplayed. */
int current_matrix_up_to_date_p = 0;
int temp_scroll_step = 0;
int count = specpdl_ptr - specpdl;
+ int rc;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
&& CHARPOS (startp) <= ZV)
{
w->optional_new_start = Qnil;
- /* This takes a mini-buffer prompt into account. */
start_display (&it, w, startp);
move_it_to (&it, PT, 0, it.last_visible_y, -1,
MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
{
- /* If point does not appear, or on a line that is not fully
- visible, move point so it does appear. The desired
- matrix has been built above, so we can use it. */
- int height = window_box_height (w) / 2;
- struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
-
- while (row->y < height)
+ /* If point does not appear, try to move point so it does
+ appear. The desired matrix has been built above, so we
+ can use it here. */
+ int window_height;
+ struct glyph_row *row;
+
+ window_height = window_box_height (w) / 2;
+ row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
+ while (MATRIX_ROW_BOTTOM_Y (row) < window_height)
++row;
TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
/* Handle case where text has not changed, only point, and it has
not moved off the frame. */
if (current_matrix_up_to_date_p
- /* Point may be in this window. */
- && PT >= CHARPOS (startp)
- /* If we don't check this, we are called to move the cursor in a
- horizontally split window with a current matrix that doesn't
- fit the display. */
- && !windows_or_buffers_changed
- /* Selective display hasn't changed. */
- && !current_buffer->clip_changed
- /* If force-mode-line-update was called, really redisplay;
- that's how redisplay is forced after e.g. changing
- buffer-invisibility-spec. */
- && NILP (w->update_mode_line)
- /* Can't use this case if highlighting a region. When a
- region exists, cursor movement has to do more than just
- set the cursor. */
- && !(!NILP (Vtransient_mark_mode)
- && !NILP (current_buffer->mark_active))
- && NILP (w->region_showing)
- && NILP (Vshow_trailing_whitespace)
- /* Right after splitting windows, last_point may be nil. */
- && INTEGERP (w->last_point)
- /* This code is not used for mini-buffer for the sake of the case
- of redisplaying to replace an echo area message; since in
- that case the mini-buffer contents per se are usually
- unchanged. This code is of no real use in the mini-buffer
- since the handling of this_line_start_pos, etc., in redisplay
- handles the same cases. */
- && !EQ (window, minibuf_window)
- /* When splitting windows or for new windows, it happens that
- redisplay is called with a nil window_end_vpos or one being
- larger than the window. This should really be fixed in
- window.c. I don't have this on my list, now, so we do
- approximately the same as the old redisplay code. --gerd. */
- && INTEGERP (w->window_end_vpos)
- && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
- && (FRAME_WINDOW_P (f)
- || !MARKERP (Voverlay_arrow_position)
- || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
+ && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
+ rc != 0))
{
- int this_scroll_margin;
- struct glyph_row *row;
- int scroll_p;
-
-#if GLYPH_DEBUG
- debug_method_add (w, "cursor movement");
-#endif
-
- /* Scroll if point within this distance from the top or bottom
- of the window. This is a pixel value. */
- this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
- this_scroll_margin *= CANON_Y_UNIT (f);
-
- /* Start with the row the cursor was displayed during the last
- not paused redisplay. Give up if that row is not valid. */
- if (w->last_cursor.vpos >= w->current_matrix->nrows)
- goto try_to_scroll;
- row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
- if (row->mode_line_p)
- ++row;
- if (!row->enabled_p)
- goto try_to_scroll;
-
- scroll_p = 0;
- if (PT > XFASTINT (w->last_point))
- {
- /* Point has moved forward. */
- int last_y = window_text_bottom_y (w) - this_scroll_margin;
-
- while (MATRIX_ROW_END_CHARPOS (row) < PT
- && MATRIX_ROW_BOTTOM_Y (row) < last_y)
- {
- xassert (row->enabled_p);
- ++row;
- }
-
- /* The end position of a row equals the start position of
- the next row. If PT is there, we would rather display it
- in the next line. Exceptions are when the row ends in
- the middle of a character, or ends in ZV. */
- if (MATRIX_ROW_BOTTOM_Y (row) < last_y
- && MATRIX_ROW_END_CHARPOS (row) == PT
- && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
- && !row->ends_at_zv_p)
- {
- xassert (row->enabled_p);
- ++row;
- }
-
- /* If within the scroll margin, scroll. Note that
- MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
- next line would be drawn, and that this_scroll_margin can
- be zero. */
- if (MATRIX_ROW_BOTTOM_Y (row) > last_y
- || PT > MATRIX_ROW_END_CHARPOS (row)
- /* Line is completely visible last line in window and PT
- is to be set in the next line. */
- || (MATRIX_ROW_BOTTOM_Y (row) == last_y
- && PT == MATRIX_ROW_END_CHARPOS (row)
- && !row->ends_at_zv_p
- && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
- scroll_p = 1;
- }
- else if (PT < XFASTINT (w->last_point))
- {
- /* Cursor has to be moved backward. Note that PT >=
- CHARPOS (startp) because of the outer if-statement. */
- while (!row->mode_line_p
- && (MATRIX_ROW_START_CHARPOS (row) > PT
- || (MATRIX_ROW_START_CHARPOS (row) == PT
- && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
- && (row->y > this_scroll_margin
- || CHARPOS (startp) == BEGV))
- {
- xassert (row->enabled_p);
- --row;
- }
-
- /* Consider the following case: Window starts at BEGV, there
- is invisible, intangible text at BEGV, so that display
- starts at some point START > BEGV. It can happen that
- we are called with PT somewhere between BEGV and START.
- Try to handle that case. */
- if (row < w->current_matrix->rows
- || row->mode_line_p)
- {
- row = w->current_matrix->rows;
- if (row->mode_line_p)
- ++row;
- }
-
- /* Due to newlines in overlay strings, we may have to skip
- forward over overlay strings. */
- while (MATRIX_ROW_END_CHARPOS (row) == PT
- && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
- && !row->ends_at_zv_p)
- ++row;
-
- /* If within the scroll margin, scroll. */
- if (row->y < this_scroll_margin
- && CHARPOS (startp) != BEGV)
- scroll_p = 1;
- }
-
- /* if PT is not in the glyph row, give up. */
- if (PT < MATRIX_ROW_START_CHARPOS (row)
- || PT > MATRIX_ROW_END_CHARPOS (row))
+ if (rc == -1)
goto try_to_scroll;
-
- /* If we end up in a partially visible line, let's make it fully
- visible. This can be done most easily by using the existing
- scrolling code. */
- if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
- {
- temp_scroll_step = 1;
- goto try_to_scroll;
- }
- else if (scroll_p)
- goto try_to_scroll;
-
- set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
- goto done;
+ else
+ goto done;
}
-
/* If current starting point was originally the beginning of a line
but no longer is, find a new starting point. */
else if (!NILP (w->start_at_line_beg)
row = row_containing_pos (w, PT,
MATRIX_FIRST_TEXT_ROW (w->current_matrix),
last_unchanged_at_beg_row + 1);
- xassert (row && row <= last_unchanged_at_beg_row);
- set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+ if (row)
+ set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
}
/* Start from first_unchanged_at_end_row looking for PT. */
row = MATRIX_ROW (matrix, vpos);
- fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W\n");
- fprintf (stderr, "=============================================\n");
+ fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W H V A P\n");
+ fprintf (stderr, "=======================================================================\n");
- fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d\n",
+ fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d\
+%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
row - matrix->rows,
MATRIX_ROW_START_CHARPOS (row),
MATRIX_ROW_END_CHARPOS (row),
row->starts_in_middle_of_char_p,
row->x,
row->y,
- row->pixel_width);
+ row->pixel_width,
+ row->height,
+ row->visible_height,
+ row->ascent,
+ row->phys_ascent);
fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
row->end.overlay_string_index);
fprintf (stderr, "%9d %5d\n",
/* If first line's physical ascent is larger than its logical
ascent, use the physical ascent, and make the row taller.
This makes accented characters fully visible. */
- if (row == it->w->desired_matrix->rows
+ if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
&& row->phys_ascent > row->ascent)
{
row->height += row->phys_ascent - row->ascent;
{
int n_glyphs_before, hpos_before, x_before;
int x, i, nglyphs;
- int ascent, descent, phys_ascent, phys_descent;
-
+ int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
+
/* Retrieve the next thing to display. Value is zero if end of
buffer reached. */
if (!get_next_display_element (it))
Mode Line
***********************************************************************/
-/* Display the mode and/or top line of window W. */
+/* Redisplay mode lines in the window tree whose root is WINDOW. If
+ FORCE is non-zero, redisplay mode lines unconditionally.
+ Otherwise, redisplay only mode lines that are garbaged. Value is
+ the number of windows whose mode lines were redisplayed. */
-static void
+static int
+redisplay_mode_lines (window, force)
+ Lisp_Object window;
+ int force;
+{
+ int nwindows = 0;
+
+ while (!NILP (window))
+ {
+ struct window *w = XWINDOW (window);
+
+ if (WINDOWP (w->hchild))
+ nwindows += redisplay_mode_lines (w->hchild, force);
+ else if (WINDOWP (w->vchild))
+ nwindows += redisplay_mode_lines (w->vchild, force);
+ else if (force
+ || FRAME_GARBAGED_P (XFRAME (w->frame))
+ || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
+ {
+ Lisp_Object old_selected_frame;
+ struct text_pos lpoint;
+ struct buffer *old = current_buffer;
+
+ /* Set the window's buffer for the mode line display. */
+ SET_TEXT_POS (lpoint, PT, PT_BYTE);
+ set_buffer_internal_1 (XBUFFER (w->buffer));
+
+ /* Point refers normally to the selected window. For any
+ other window, set up appropriate value. */
+ if (!EQ (window, selected_window))
+ {
+ struct text_pos pt;
+
+ SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
+ if (CHARPOS (pt) < BEGV)
+ TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+ else if (CHARPOS (pt) > (ZV - 1))
+ TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
+ else
+ TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
+ }
+
+ /* Temporarily set up the selected frame. */
+ old_selected_frame = selected_frame;
+ selected_frame = w->frame;
+
+ /* Display mode lines. */
+ clear_glyph_matrix (w->desired_matrix);
+ if (display_mode_lines (w))
+ {
+ ++nwindows;
+ w->must_be_updated_p = 1;
+ }
+
+ /* Restore old settings. */
+ selected_frame = old_selected_frame;
+ set_buffer_internal_1 (old);
+ TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
+ }
+
+ window = w->next;
+ }
+
+ return nwindows;
+}
+
+
+/* Display the mode and/or top line of window W. Value is the number
+ of mode lines displayed. */
+
+static int
display_mode_lines (w)
struct window *w;
{
+ int n = 0;
+
/* These will be set while the mode line specs are processed. */
line_number_displayed = 0;
w->column_number_displayed = Qnil;
if (WINDOW_WANTS_MODELINE_P (w))
- display_mode_line (w, MODE_LINE_FACE_ID,
- current_buffer->mode_line_format);
+ {
+ display_mode_line (w, MODE_LINE_FACE_ID,
+ current_buffer->mode_line_format);
+ ++n;
+ }
if (WINDOW_WANTS_HEADER_LINE_P (w))
- display_mode_line (w, HEADER_LINE_FACE_ID,
- current_buffer->header_line_format);
+ {
+ display_mode_line (w, HEADER_LINE_FACE_ID,
+ current_buffer->header_line_format);
+ ++n;
+ }
+
+ return n;
}
Lisp_Object eoltype;
val = Fget (coding_system, Qcoding_system);
+ eoltype = Qnil;
if (!VECTORP (val)) /* Not yet decided. */
{
Lisp_Object list;
{
register Lisp_Object tail, proptail;
+
for (tail = list; CONSP (tail); tail = XCDR (tail))
{
register Lisp_Object tem;
if (CONSP (tem) && EQ (propval, XCAR (tem)))
return 1;
}
+
if (CONSP (propval))
- for (proptail = propval; CONSP (proptail);
- proptail = XCDR (proptail))
- {
- Lisp_Object propelt;
- propelt = XCAR (proptail);
- for (tail = list; CONSP (tail); tail = XCDR (tail))
- {
- register Lisp_Object tem;
- tem = XCAR (tail);
- if (EQ (propelt, tem))
- return 1;
- if (CONSP (tem) && EQ (propelt, XCAR (tem)))
- return 1;
- }
- }
+ {
+ for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
+ {
+ Lisp_Object propelt;
+ propelt = XCAR (proptail);
+ for (tail = list; CONSP (tail); tail = XCDR (tail))
+ {
+ register Lisp_Object tem;
+ tem = XCAR (tail);
+ if (EQ (propelt, tem))
+ return 1;
+ if (CONSP (tem) && EQ (propelt, XCAR (tem)))
+ return 1;
+ }
+ }
+ }
+
return 0;
}
staticpro (&echo_area_buffer[0]);
staticpro (&echo_area_buffer[1]);
+ Vmessages_buffer_name = build_string ("*Messages*");
+ staticpro (&Vmessages_buffer_name);
+
DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
"Non-nil means highlight trailing whitespace.\n\
The face used for trailing whitespace is `trailing-whitespace'.");