/* Display generation from window structure and buffer text.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1997
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "termchar.h"
#include "dispextern.h"
#include "buffer.h"
+#include "charset.h"
#include "indent.h"
#include "commands.h"
#include "macros.h"
#include "termhooks.h"
#include "intervals.h"
#include "keyboard.h"
+#include "coding.h"
+#include "process.h"
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
extern void set_frame_menubar ();
extern int interrupt_input;
extern int command_loop_level;
+extern int minibuffer_auto_raise;
+
extern Lisp_Object Qface;
extern Lisp_Object Voverriding_local_map;
when appropriate. */
static int scroll_conservatively;
+/* Recenter the window whenever point gets within this many lines
+ of the top or bottom of the window. */
+int scroll_margin;
+
/* Nonzero if try_window_id has made blank lines at window bottom
since the last redisplay that paused */
static int blank_end_of_window;
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fwrite (m, len, 1, stderr);
+ if (m)
+ fwrite (m, len, 1, stderr);
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
{
echo_area_glyphs = m;
echo_area_glyphs_length = len;
+
+ if (minibuffer_auto_raise)
+ Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
}
else
echo_area_glyphs = previous_echo_glyphs = 0;
a[2] = a3;
len = doprnt (FRAME_MESSAGE_BUF (f),
- (int) FRAME_WIDTH (f), m, (char *)0, 3, a);
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
#else
len = doprnt (FRAME_MESSAGE_BUF (f),
- (int) FRAME_WIDTH (f), m, (char *)0, 3, &a1);
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, &a1);
#endif /* NO_ARG_ARRAY */
message2 (FRAME_MESSAGE_BUF (f), len);
echo_area_glyphs ? echo_area_glyphs : "",
echo_area_glyphs ? echo_area_glyphs_length : -1,
FRAME_LEFT_SCROLL_BAR_WIDTH (f),
- 0, 0, 0, FRAME_WIDTH (f));
+ 0, 0, 0,
+ FRAME_WIDTH (f) + FRAME_LEFT_SCROLL_BAR_WIDTH (f));
#if 0 /* This just gets in the way. update_frame does the job. */
/* If desired cursor location is on this line, put it at end of text */
i < vpos + XFASTINT (XWINDOW (mini_window)->height); i++)
{
get_display_line (f, i, 0);
- display_string (XWINDOW (mini_window), vpos,
+ /* We don't use FRAME_SCROLL_BAR_WIDTH (f) as the starting
+ hpos, because it is good to clear whatever is behind the
+ scroll bar. This does not affect the scroll bar itself. */
+ display_string (XWINDOW (mini_window), i,
"", 0,
- FRAME_LEFT_SCROLL_BAR_WIDTH (f),
- 0, 0, 0, FRAME_WIDTH (f));
+ 0, 0, 0,
+ 0, FRAME_WIDTH (f) + FRAME_SCROLL_BAR_WIDTH (f));
}
}
}
Lisp_Object tail, frame;
int count = specpdl_ptr - specpdl;
- record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
FOR_EACH_FRAME (tail, frame)
{
int all_windows;
register int tlbufpos, tlendpos;
struct position pos;
+ int number_of_frames_redisplayed;
if (noninteractive)
return;
return;
#endif
+ retry:
+
if (! FRAME_WINDOW_P (selected_frame)
&& previous_terminal_frame != selected_frame)
{
Fmarker_position (XBUFFER (w->buffer)->mark))))
this_line_bufpos = -1;
+ /* This is in case we goto update, below. */
+ number_of_frames_redisplayed = 1;
+
tlbufpos = this_line_bufpos;
tlendpos = this_line_endpos;
if (!all_windows && tlbufpos > 0 && NILP (w->update_mode_line)
&& end_unchanged >= tlendpos
&& Z - GPT >= tlendpos)))
{
- if (tlbufpos > BEGV && FETCH_CHAR (tlbufpos - 1) != '\n'
+ if (tlbufpos > BEGV && FETCH_BYTE (tlbufpos - 1) != '\n'
&& (tlbufpos == ZV
- || FETCH_CHAR (tlbufpos) == '\n'))
+ || FETCH_BYTE (tlbufpos) == '\n'))
/* Former continuation line has disappeared by becoming empty */
goto cancel;
else if (XFASTINT (w->last_modified) < MODIFF
|| XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
|| MINI_WINDOW_P (w))
{
+ /* We have to handle the case of continuation around a
+ wide-column character (See the comment in indent.c around
+ line 885).
+
+ For instance, in the following case:
+
+ -------- Insert --------
+ K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
+ J_I_ ==> J_I_ `^^' are cursors.
+ ^^ ^^
+ -------- --------
+
+ As we have to redraw the line above, we should goto cancel. */
+
+ struct position val;
+ int prevline;
+
+ prevline = find_next_newline (tlbufpos, -1);
+ val = *compute_motion (prevline, 0,
+ XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
+ 0,
+ tlbufpos,
+ 1 << (BITS_PER_SHORT - 1),
+ 1 << (BITS_PER_SHORT - 1),
+ window_internal_width (w) - 1,
+ XINT (w->hscroll), 0, w);
+ if (val.hpos != this_line_start_hpos)
+ goto cancel;
+
cursor_vpos = -1;
overlay_arrow_seen = 0;
zv_strings_seen = 0;
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)
+ && (w == XWINDOW (current_buffer->last_selected_window)
+ || highlight_nonselected_windows)
&& NILP (w->region_showing)
&& !cursor_in_echo_area)
{
/* Recompute # windows showing selected buffer.
This will be incremented each time such a window is displayed. */
buffer_shared = 0;
+ number_of_frames_redisplayed = 0;
FOR_EACH_FRAME (tail, frame)
{
(*condemn_scroll_bars_hook) (f);
if (FRAME_VISIBLE_P (f))
- redisplay_windows (FRAME_ROOT_WINDOW (f), preserve_echo_area);
+ {
+ redisplay_windows (FRAME_ROOT_WINDOW (f), preserve_echo_area);
+ number_of_frames_redisplayed++;
+ }
/* Any scroll bars which redisplay_windows should have nuked
should now go away. */
redisplay_window (selected_window, 1, preserve_echo_area);
if (!WINDOW_FULL_WIDTH_P (w))
preserve_other_columns (w);
+ number_of_frames_redisplayed = 1;
}
update:
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)
+ || highlight_nonselected_windows)
+ && !NILP (XBUFFER (w->buffer)->mark_active)
+ ? Fmarker_position (XBUFFER (w->buffer)->mark)
+ : Qnil);
+
w->window_end_valid = w->buffer;
last_arrow_position = Voverlay_arrow_position;
last_arrow_string = Voverlay_arrow_string;
request_sigio ();
start_polling ();
+ /* If something has become visible now which was not before,
+ redisplay again, so that we get them. */
+ if (!pause)
+ {
+ Lisp_Object tail, frame;
+ int new_count = 0;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ int this_is_visible = 0;
+ if (XFRAME (frame)->visible)
+ this_is_visible = 1;
+ FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+ if (XFRAME (frame)->visible)
+ this_is_visible = 1;
+
+ if (this_is_visible)
+ new_count++;
+ }
+
+ if (new_count != number_of_frames_redisplayed)
+ windows_or_buffers_changed++;
+ }
+
/* Change frame size now if a change is pending. */
do_pending_window_change ();
- /* If we just did a pending size change, redisplay again
- for the new size. */
+ /* If we just did a pending size change, or have additional
+ visible frames, redisplay again. */
if (windows_or_buffers_changed && !pause)
- redisplay ();
+ goto retry;
}
/* Redisplay, but leave alone any recent echo area message
/* 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)
+ && (w == XWINDOW (current_buffer->last_selected_window)
+ || highlight_nonselected_windows)
&& !NILP (XBUFFER (w->buffer)->mark_active)
? Fmarker_position (XBUFFER (w->buffer)->mark)
: Qnil);
set_buffer_internal_1 (XBUFFER (w->buffer));
if (save_match_data)
- record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
if (NILP (Voverriding_local_map_menu_flag))
{
specbind (Qoverriding_terminal_local_map, Qnil);
redisplay_window (window, 0, preserve_echo_area);
}
+/* Return value in display table DP (Lisp_Char_Table *) for character
+ C. Since a display table doesn't have any parent, we don't have to
+ follow parent. Do not call this function directly but use the
+ macro DISP_CHAR_VECTOR. */
+Lisp_Object
+disp_char_vector (dp, c)
+ struct Lisp_Char_Table *dp;
+ int c;
+{
+ int code[4], i;
+ Lisp_Object val;
+
+ if (SINGLE_BYTE_CHAR_P (c)) return (dp->contents[c]);
+
+ SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
+ if (code[0] != CHARSET_COMPOSITION)
+ {
+ if (code[1] < 32) code[1] = -1;
+ else if (code[2] < 32) code[2] = -1;
+ }
+ /* Here, the possible range of CODE[0] (== charset ID) is
+ 128..MAX_CHARSET. Since the top level char table contains data
+ for multibyte characters after 256th element, we must increment
+ CODE[0] by 128 to get a correct index. */
+ code[0] += 128;
+ code[3] = -1; /* anchor */
+
+ for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
+ {
+ val = dp->contents[code[i]];
+ if (!SUB_CHAR_TABLE_P (val))
+ return (NILP (val) ? dp->defalt : val);
+ }
+ /* Here, VAL is a sub char table. We return the default value of it. */
+ return (dp->defalt);
+}
+
/* Redisplay window WINDOW and its subwindows. */
static void
startp = marker_position (w->start);
+ /* If someone specified a new starting point but did not insist,
+ check whether it can be used. */
+ if (!NILP (w->optional_new_start))
+ {
+ w->optional_new_start = Qnil;
+ /* Check whether this start pos is usable given where point is. */
+
+ pos = *compute_motion (startp, 0,
+ (((EQ (window, minibuf_window)
+ && startp == BEG)
+ ? minibuf_prompt_width : 0)
+ + (hscroll ? 1 - hscroll : 0)),
+ 0,
+ PT, height,
+ /* BUG FIX: See the comment of
+ Fpos_visible_in_window_p (window.c). */
+ - (1 << (BITS_PER_SHORT - 1)),
+ width, hscroll, pos_tab_offset (w, startp), w);
+ /* If PT does fit on the screen, we will use this start pos,
+ so do so by setting force_start. */
+ if (pos.bufpos == PT)
+ w->force_start = Qt;
+ }
+
/* Handle case where place to start displaying has been specified,
unless the specified location is outside the accessible range. */
if (!NILP (w->force_start))
&& XFASTINT (w->window_end_vpos) < XFASTINT (w->height)
&& !EQ (window, minibuf_window))
{
- pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0,
- PT, height, 0, width, hscroll,
- pos_tab_offset (w, startp), w);
+ int this_scroll_margin = scroll_margin;
- if (pos.vpos < height)
+ pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0,
+ PT, height,
+ /* BUG FIX: See the comment of
+ Fpos_visible_in_window_p (window.c). */
+ - (1 << (BITS_PER_SHORT - 1)),
+ width, hscroll,
+ pos_tab_offset (w, startp), w);
+
+ /* Don't use a scroll margin that is negative or too large. */
+ if (this_scroll_margin < 0)
+ this_scroll_margin = 0;
+
+ if (XINT (w->height) < 4 * scroll_margin)
+ this_scroll_margin = XINT (w->height) / 4;
+
+ /* If point fits on the screen, and not within the scroll margin,
+ we are ok. */
+ if (pos.vpos < height - this_scroll_margin
+ && (pos.vpos >= this_scroll_margin || startp == BEGV))
{
/* Ok, point is still on frame */
if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
but no longer is, find a new starting point. */
else if (!NILP (w->start_at_line_beg)
&& !(startp <= BEGV
- || FETCH_CHAR (startp - 1) == '\n'))
+ || FETCH_BYTE (startp - 1) == '\n'))
{
goto recenter;
}
if (scroll_conservatively && !current_buffer->clip_changed
&& startp >= BEGV && startp <= ZV)
{
+ int this_scroll_margin = scroll_margin;
+
+ /* Don't use a scroll margin that is negative or too large. */
+ if (this_scroll_margin < 0)
+ this_scroll_margin = 0;
+
+ if (XINT (w->height) < 4 * scroll_margin)
+ this_scroll_margin = XINT (w->height) / 4;
+
if (PT >= Z - XFASTINT (w->window_end_pos))
{
struct position pos;
if (pos.vpos > scroll_conservatively)
goto scroll_fail_1;
- pos = *vmotion (startp, pos.vpos + 1, w);
+ pos = *vmotion (startp, pos.vpos + 1 + this_scroll_margin, w);
if (! NILP (Vwindow_scroll_functions))
{
if (pos.vpos >= scroll_conservatively)
goto scroll_fail_1;
- pos = *vmotion (startp, - pos.vpos, w);
+ pos = *vmotion (startp, - pos.vpos - this_scroll_margin, w);
if (! NILP (Vwindow_scroll_functions))
{
startp = marker_position (w->start);
w->start_at_line_beg
- = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil;
+ = (startp == BEGV || FETCH_BYTE (startp - 1) == '\n') ? Qt : Qnil;
done:
if ((update_mode_line
register int height = window_internal_height (w);
register int vpos = XFASTINT (w->top);
register int last_text_vpos = vpos;
- int tab_offset = pos_tab_offset (w, pos);
FRAME_PTR f = XFRAME (w->frame);
int width = window_internal_width (w) - 1;
struct position val;
+ /* POS should never be out of range! */
+ if (pos < XBUFFER (w->buffer)->begv
+ || pos > XBUFFER (w->buffer)->zv)
+ abort ();
+
Fset_marker (w->start, make_number (pos), Qnil);
cursor_vpos = -1;
overlay_arrow_seen = 0;
zv_strings_seen = 0;
val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
val.ovstring_chars_done = 0;
+ val.tab_offset = pos_tab_offset (w, pos);
while (--height >= 0)
{
- val = *display_text_line (w, pos, vpos, val.hpos, tab_offset,
+ val = *display_text_line (w, pos, vpos, val.hpos, val.tab_offset,
val.ovstring_chars_done);
+ /* The following code is omitted because we maintain tab_offset
+ in VAL. */
+#if 0
tab_offset += width;
- /* For the first line displayed, display_text_line
- subtracts the prompt width from the tab offset.
- But it does not affect the value of our variable tab_offset.
- So we do the subtraction again,
- for the sake of continuation lines of that first line. */
- if (MINI_WINDOW_P (w) && vpos == XFASTINT (w->top))
- tab_offset -= minibuf_prompt_width;
-
if (val.vpos) tab_offset = 0;
+#endif /* 0 */
vpos++;
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' || invis));
+ && (FETCH_BYTE (val.bufpos - 1) != '\n' || invis));
}
pos = val.bufpos;
}
struct position val, bp, ep, xp, pp;
int scroll_amount = 0;
int delta;
- int tab_offset, epto, old_tick;
+ int epto, old_tick;
if (GPT - BEG < beg_unchanged)
beg_unchanged = GPT - BEG;
/* Find position before which nothing is changed. */
bp = *compute_motion (start, 0, lmargin, 0,
- min (ZV, beg_unchanged + BEG), height, 0,
+ min (ZV, beg_unchanged + BEG), height,
+ /* BUG FIX: See the comment of
+ Fpos_visible_in_window_p() (window.c). */
+ - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, pos_tab_offset (w, start), w);
if (bp.vpos >= height)
{
But we need to update window_end_pos to account for
any change in buffer size. */
bp = *compute_motion (start, 0, lmargin, 0,
- ZV, height, 0,
+ ZV, height,
+ /* BUG FIX: See the comment of
+ Fpos_visible_in_window_p() (window.c). */
+ - (1 << (BITS_PER_SHORT - 1)),
width, hscroll, pos_tab_offset (w, start), w);
XSETFASTINT (w->window_end_vpos, height);
XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
--vpos;
pos = bp.bufpos;
}
+ val.tab_offset = bp.tab_offset; /* Update tab offset. */
if (bp.contin && bp.hpos != lmargin)
{
val.hpos = bp.prevhpos - width + lmargin;
+ val.tab_offset = bp.tab_offset + bp.prevhpos - width;
did_motion = 1;
- pos--;
+ DEC_POS (pos);
}
bp.vpos = vpos;
/* Compute the cursor position after that newline. */
ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
height, - (1 << (BITS_PER_SHORT - 1)),
- width, hscroll, pos_tab_offset (w, bp.bufpos), w);
+ width, hscroll,
+ /* We have tab offset in VAL, use it. */
+ val.tab_offset, w);
/* If changes reach past the text available on the frame,
just display rest of frame. */
newline before it, so the following line must be redrawn. */
if (stop_vpos == ep.vpos
&& (ep.bufpos == BEGV
- || FETCH_CHAR (ep.bufpos - 1) != '\n'
+ || FETCH_BYTE (ep.bufpos - 1) != '\n'
|| ep.bufpos == Z - end_unchanged))
stop_vpos = ep.vpos + 1;
if (stop_vpos < height)
{
/* Now determine how far up or down the rest of the window has moved */
- epto = pos_tab_offset (w, ep.bufpos);
xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
Z - XFASTINT (w->window_end_pos),
- 10000, 0, width, hscroll, epto, w);
+ /* Don't care for VPOS... */
+ 1 << (BITS_PER_SHORT - 1),
+ /* ... nor HPOS. */
+ 1 << (BITS_PER_SHORT - 1),
+ width, hscroll, ep.tab_offset, w);
scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos);
/* Is everything on frame below the changes whitespace?
If so, no scrolling is really necessary. */
for (i = ep.bufpos; i < xp.bufpos; i++)
{
- tem = FETCH_CHAR (i);
+ tem = FETCH_BYTE (i);
if (tem != ' ' && tem != '\n' && tem != '\t')
break;
}
XFASTINT (w->window_end_vpos) + scroll_amount);
/* Before doing any scrolling, verify that point will be on frame. */
- if (PT > ep.bufpos && !(PT <= xp.bufpos && xp.bufpos < height))
+ if (PT > ep.bufpos && !(PT <= xp.bufpos && xp.vpos < height))
{
if (PT <= xp.bufpos)
{
pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
PT, height, - (1 << (BITS_PER_SHORT - 1)),
- width, hscroll, epto, w);
+ width, hscroll,
+ /* We have tab offset in EP, use it. */
+ ep.tab_offset, w);
}
else
{
pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1,
PT, height, - (1 << (BITS_PER_SHORT - 1)),
width, hscroll,
- pos_tab_offset (w, xp.bufpos), w);
+ /* We have tab offset in XP, use it. */
+ xp.tab_offset, w);
}
if (pp.bufpos < PT || pp.vpos == height)
return 0;
/* Redisplay the lines where the text was changed */
last_text_vpos = vpos;
+ /* The following code is omitted because we maintain tab offset in
+ val.tab_offset. */
+#if 0
tab_offset = pos_tab_offset (w, pos);
/* If we are starting display in mid-character, correct tab_offset
to account for passing the line that that character really starts in. */
if (val.hpos < lmargin)
tab_offset += width;
+#endif /* 0 */
old_tick = MODIFF;
while (vpos < stop_vpos)
{
- val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset,
+ val = *display_text_line (w, pos, top + vpos++, val.hpos, val.tab_offset,
val.ovstring_chars_done);
/* 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;
+ /* The following code is omitted because we maintain tab offset
+ in val.tab_offset. */
+#if 0
tab_offset += width;
if (val.vpos) tab_offset = 0;
+#endif
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_BYTE (val.bufpos - 1) != '\n');
pos = val.bufpos;
}
FRAME_SCROLL_BOTTOM_VPOS (f) = xp.vpos;
vpos = xp.vpos;
pos = xp.bufpos;
- val.hpos = lmargin;
+ val.hpos = xp.hpos;
+ val.tab_offset = xp.tab_offset;
if (pos == ZV)
- vpos = height + scroll_amount;
+ { /* Display from next line */
+ vpos = height + scroll_amount;
+ val.hpos = lmargin;
+ val.tab_offset = 0;
+ }
else if (xp.contin && xp.hpos != lmargin)
{
val.hpos = xp.prevhpos - width + lmargin;
- pos--;
+ val.tab_offset = xp.tab_offset + bp.prevhpos - width;
+ DEC_POS (pos);
}
blank_end_of_window = 1;
+ /* The following code is omitted because we maintain tab offset
+ in val.tab_offset. */
+#if 0
tab_offset = pos_tab_offset (w, pos);
/* If we are starting display in mid-character, correct tab_offset
to account for passing the line that that character starts in. */
if (val.hpos < lmargin)
tab_offset += width;
-
+#endif
while (vpos < height)
{
- val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset,
- val.ovstring_chars_done);
+ val = *display_text_line (w, pos, top + vpos++, val.hpos,
+ val.tab_offset, val.ovstring_chars_done);
+ /* The following code is omitted because we maintain tab
+ offset in val.tab_offset. */
+#if 0
tab_offset += width;
if (val.vpos) tab_offset = 0;
+#endif /* 0 */
pos = val.bufpos;
}
if (cursor_vpos < 0)
{
findpoint:
- val = *compute_motion (start, 0, lmargin, 0, PT, 10000, 10000,
+ val = *compute_motion (start, 0, lmargin, 0, PT,
+ /* Don't care for VPOS... */
+ 1 << (BITS_PER_SHORT - 1),
+ /* ... nor HPOS. */
+ 1 << (BITS_PER_SHORT - 1),
width, hscroll, pos_tab_offset (w, start), w);
/* Admit failure if point is off frame now */
if (val.vpos >= height)
if (! FRAME_TERMCAP_P (f))
while (n--)
{
- int glyph = (INTEGERP (*fp) ? XFASTINT (*fp) : 0);
+ GLYPH glyph = (INTEGERP (*fp) ? XFASTINT (*fp) : 0);
int facecode;
+ unsigned int c = FAST_GLYPH_CHAR (glyph);
+
+ if (c > MAX_CHAR)
+ /* For an invalid character code, use space. */
+ c = ' ';
if (FAST_GLYPH_FACE (glyph) == 0)
/* If GLYPH has no face code, use FACE. */
}
if (to >= s)
- *to = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph), facecode);
+ *to = FAST_MAKE_GLYPH (c, facecode);
++to;
++fp;
}
/* 1 if we should highlight the region. */
int highlight_region
= (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active)
- && XWINDOW (current_buffer->last_selected_window) == w);
+ && (XWINDOW (current_buffer->last_selected_window) == w
+ || highlight_nonselected_windows));
int region_beg, region_end;
int selective = (INTEGERP (current_buffer->selective_display)
: default_invis_vector);
GLYPH truncator = (dp == 0 || !INTEGERP (DISP_TRUNC_GLYPH (dp))
+ || !GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (dp)))
? '$' : XINT (DISP_TRUNC_GLYPH (dp)));
GLYPH continuer = (dp == 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp))
+ || !GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (dp)))
? '\\' : XINT (DISP_CONTINUE_GLYPH (dp)));
+ /* If 1, we must handle multibyte characters. */
+ int multibyte = !NILP (current_buffer->enable_multibyte_characters);
+ /* Length of multibyte form of each character. */
+ int len;
+ /* Glyphs generated should be set this bit mask if text must be
+ displayed from right to left. */
+ GLYPH rev_dir_bit = (NILP (current_buffer->direction_reversed)
+ ? 0 : GLYPH_MASK_REV_DIR);
+
/* The next buffer location at which the face should change, due
to overlays or text property changes. */
int next_face_change;
w->region_showing = Qt;
}
else
- region_beg = region_end = -1;
+ {
+ region_beg = region_end = -1;
+ w->region_showing = Qnil;
+ }
if (MINI_WINDOW_P (w)
&& start == BEG
/* Truncate the prompt a little before the
margin, so user input can at least start
on the first line. */
- w->width > 10 ? w->width - 4 : -1)
+ (XFASTINT (w->width) > 10
+ ? XFASTINT (w->width) - 4 : -1))
- hpos);
hpos += minibuf_prompt_width;
taboffset -= minibuf_prompt_width;
if (left_edge->vpos > vpos
|| left_edge->hpos > 0)
{
- pos = left_edge->bufpos - 1;
+ pos = left_edge->bufpos;
+ /* Since this should not be a valid multibyte character, we
+ can decrease POS by 1. */
+ pos--;
hpos = left_edge->prevhpos;
}
else
next_boundary = pos;
p1prev = p1;
prevpos = pos;
- while (1)
+ while (p1 < endp)
{
if (pos >= pause)
{
ovstr += ovstr_done;
ovlen -= ovstr_done;
- /* Start outputting. */
- for (; ovlen; ovlen--, ovstr++)
+ while (ovlen > 0)
{
- if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, *ovstr, current_face);
- p1++;
- ovstr_done++;
+ int charset, cols;
+ GLYPH g;
+
+ if (multibyte)
+ {
+ c = STRING_CHAR_AND_LENGTH (ovstr, ovlen, len);
+ ovstr += len, ovlen -= len, ovstr_done += len;
+ charset = CHAR_CHARSET (c);
+ cols = (charset == CHARSET_COMPOSITION
+ ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
+ : CHARSET_WIDTH (charset));
+ }
+ else
+ {
+ c = *ovstr++, ovlen--, ovstr_done++;
+ cols = 1;
+ }
+ g = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
+ while (cols-- > 0)
+ {
+ if (p1 >= leftmargin && p1 < endp)
+ *p1 = g, g |= GLYPH_MASK_PADDING;
+ p1++;
+ }
}
/* If we did all the overlay strings
and we have room for text, clear ovstr_done
/* This is just an estimate to give reasonable
performance; nothing should go wrong if it is too small. */
if (XFASTINT (limit) > pos + 50)
- XSETFASTINT (limit, pos + 50);
+ {
+ int limitpos = pos + 50;
+ if (limitpos < Z)
+ INC_POS (limitpos); /* Adjust to character boundary. */
+ XSETFASTINT (limit, limitpos);
+ }
limit = Fnext_single_property_change (position, Qinvisible,
Fcurrent_buffer (), limit);
#endif
loop, to see what face we should start with. */
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);
+ {
+ int limit = pos + 50;
+
+ if (limit < Z && !CHAR_HEAD_P (POS_ADDR (limit)))
+ INC_POS (limit); /* Adjust to character boundary. */
+ current_face = compute_char_face (f, w, pos,
+ region_beg, region_end,
+ &next_face_change, limit, 0);
+ }
#endif
/* Compute the next place we need to stop
if (pos < GPT && GPT < pause)
pause = GPT;
- p = &FETCH_CHAR (pos);
+ p = POS_ADDR (pos);
}
if (p1 >= endp)
p1prev = p1;
- c = *p++;
+ if (multibyte)
+ /* PAUSE is surely at character boundary. */
+ c = STRING_CHAR_AND_LENGTH (p, pause - pos, len), p += len;
+ else
+ c = *p++, len = 1;
/* Let a display table override all standard display methods. */
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
{
p1 = copy_part_of_rope (f, p1, leftmargin,
XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
- current_face);
+ current_face, rev_dir_bit);
}
else if (c >= 040 && c < 0177)
{
if (p1 >= leftmargin)
- *p1 = MAKE_GLYPH (f, c, current_face);
+ *p1 = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
p1++;
}
else if (c == '\n')
{
+#if 0
+ /* Same as p1prev, but after the invis_vector_contents text
+ (if we have that on this line). */
+ GLYPH *p1prev_modified;
+#endif
+
invis = 0;
if (last_invis_skip == pos
&& TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop))
{
invis = 1;
pos = find_next_newline (pos + 1, 1);
- if (FETCH_CHAR (pos - 1) == '\n')
+ if (FETCH_BYTE (pos - 1) == '\n')
pos--;
}
if (invis && selective_rlen > 0 && p1 >= leftmargin)
{
+#if 0
+ GLYPH *cs, *csend;
+
+ cs = charstart + (p1 - p1start);
+#endif
+
p1 += selective_rlen;
if (p1 - leftmargin > width)
p1 = endp;
+
+#if 0 /* This needs more work; charstarts needs to record
+ both whether a position ho;ds an ellipsis character
+ and what buffer position it corresponds to. */
+ csend = charstart + (p1 - p1start);
+ while (cs != csend)
+ *cs++ = -2;
+ /* The idea is to use p1prev_modified instead of p1prev
+ in the loop below over p2x. */
+ p1prev_modified = p1;
+#endif
+
copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents,
- (p1 - p1prev), current_face);
- }
-#ifdef HAVE_FACES
- /* Draw the face of the newline character as extending all the
- way to the end of the frame line. */
- if (current_face)
- {
- if (p1 < leftmargin)
- p1 = leftmargin;
- while (p1 < endp)
- *p1++ = FAST_MAKE_GLYPH (' ', current_face);
+ (p1 - p1prev), current_face, rev_dir_bit);
}
-#endif
/* Update charstarts for the newline that ended this line. */
/* Do nothing here for a char that's entirely off the left edge
while (p2x < p2)
*p2x++ = -1;
}
+#ifdef HAVE_FACES
+ /* Draw the face of the newline character as extending all the
+ way to the end of the frame line. */
+ if (current_face)
+ {
+ if (p1 < leftmargin)
+ p1 = leftmargin;
+ while (p1 < endp)
+ *p1++ = FAST_MAKE_GLYPH (' ', current_face) | rev_dir_bit;
+ }
+#endif
break;
}
do
{
if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, ' ', current_face);
+ *p1 = MAKE_GLYPH (f, ' ', current_face) | rev_dir_bit;
p1++;
}
while ((p1 - leftmargin + taboffset + hscroll - (hscroll > 0))
else if (c == Ctl ('M') && selective == -1)
{
pos = find_next_newline (pos, 1);
- if (FETCH_CHAR (pos - 1) == '\n')
+ if (FETCH_BYTE (pos - 1) == '\n')
pos--;
if (selective_rlen > 0)
{
if (p1 - leftmargin > width)
p1 = endp;
copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents,
- (p1 - p1prev), current_face);
+ (p1 - p1prev), current_face, rev_dir_bit);
}
#ifdef HAVE_FACES
/* Draw the face of the newline character as extending all the
if (p1 < leftmargin)
p1 = leftmargin;
while (p1 < endp)
- *p1++ = FAST_MAKE_GLYPH (' ', current_face);
+ *p1++ = FAST_MAKE_GLYPH (' ', current_face) | rev_dir_bit;
}
#endif
else if (c < 0200 && ctl_arrow)
{
if (p1 >= leftmargin)
- *p1 = fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp))
- ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
- current_face);
+ *p1 = (fix_glyph
+ (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp))
+ && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (dp)))
+ ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
+ current_face)
+ | rev_dir_bit);
p1++;
if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, c ^ 0100, current_face);
+ *p1 = MAKE_GLYPH (f, c ^ 0100, current_face) | rev_dir_bit;
p1++;
}
- else
+ else if (len == 1)
{
+ /* C is not a multibyte character. */
if (p1 >= leftmargin)
- *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
- ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
- current_face);
+ *p1 = (fix_glyph
+ (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
+ && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
+ ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
+ current_face)
+ | rev_dir_bit);
p1++;
if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face);
+ *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face) | rev_dir_bit;
p1++;
if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face);
+ *p1 = (MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face)
+ | rev_dir_bit);
p1++;
if (p1 >= leftmargin && p1 < endp)
- *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face);
+ *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face) | rev_dir_bit;
p1++;
}
+ else
+ {
+ /* C is a multibyte character. */
+ int charset = CHAR_CHARSET (c);
+ int columns = (charset == CHARSET_COMPOSITION
+ ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
+ : CHARSET_WIDTH (charset));
+ GLYPH g = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
+
+ while (columns--)
+ {
+ if (p1 >= leftmargin && p1 < endp)
+ *p1 = g, g |= GLYPH_MASK_PADDING;
+ p1++;
+ }
+ }
prevpos = pos;
- pos++;
+ pos += len;
/* Update charstarts for the character just output. */
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;
+ /* Start the next line with that same character whose
+ character code is C and the length of multi-byte form is
+ LEN. */
+ pos = prevpos;
+
+ if (len == 1)
+ /* C is not a multi-byte character. We can break it and
+ start from the middle column in the next line. So,
+ adjust VAL.HPOS to skip the columns output on this
+ line. */
+ val.hpos += p1prev - endp;
+ else
+ {
+ /* C is a multibyte character. Since we can't broke it
+ in the middle, the whole character should be driven
+ into the next line. */
+ /* As the result, the actual columns occupied by the
+ text on this line is less than WIDTH. VAL.TAB_OFFSET
+ must be adjusted. */
+ taboffset = taboffset + (p1prev - endp);
+ /* Let's fill unused columns with TRUNCATOR or CONTINUER. */
+ {
+ GLYPH g = fix_glyph (f, truncate ? truncator : continuer, 0);
+ while (p1prev < endp)
+ *p1prev++ = g;
+ }
+ /* If POINT is at POS, cursor should not on this line. */
+ lastpos = pos;
+ if (PT == pos)
+ cursor_vpos = -1;
+ }
}
/* Keep in this line everything up to the continuation column. */
if (pos < ZV)
{
- if (FETCH_CHAR (pos) == '\n')
+ if (FETCH_BYTE (pos) == '\n')
{
/* If stopped due to a newline, start next line after it */
pos++;
+ val.tab_offset = 0;
/* Check again for hidden lines, in case the newline occurred exactly
at the right margin. */
while (pos < ZV && selective > 0
&& indented_beyond_p (pos, selective));
val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
- lastpos = pos - (FETCH_CHAR (pos - 1) == '\n');
+ lastpos = pos - (FETCH_BYTE (pos - 1) == '\n');
+ val.tab_offset = 0;
}
else
{
*p1++ = fix_glyph (f, continuer, 0);
val.vpos = 0;
lastpos--;
+ val.tab_offset = taboffset + width;
}
}
}
+ else
+ val.tab_offset = 0;
/* If point is at eol or in invisible text at eol,
record its frame location now. */
/* If hscroll and line not empty, insert truncation-at-left marker */
if (hscroll && lastpos != start)
{
- *leftmargin = fix_glyph (f, truncator, 0);
+ GLYPH g = fix_glyph (f, truncator, 0);
+ *leftmargin = g;
if (p1 <= leftmargin)
p1 = leftmargin + 1;
+ else /* MULE: it may be a wide-column character */
+ {
+ p1prev = leftmargin + 1;
+ while (p1prev < p1 && *p1prev & GLYPH_MASK_PADDING)
+ *p1prev++ = g;
+ }
}
if (!WINDOW_RIGHTMOST_P (w))
}
else if (!FRAME_HAS_VERTICAL_SCROLL_BARS (f))
*p1++ = (dp && INTEGERP (DISP_BORDER_GLYPH (dp))
- ? DISP_BORDER_GLYPH (dp)
+ ? XINT (DISP_BORDER_GLYPH (dp))
: '|');
}
desired_glyphs->used[vpos] = max (desired_glyphs->used[vpos],
XSETFASTINT (XVECTOR (items)->contents[i + 3], hpos);
if (hpos < maxendcol)
- hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos,
+ hpos = display_string (w, vpos,
XSTRING (string)->data,
XSTRING (string)->size,
hpos, 0, 0, hpos, maxendcol);
{
/* For a partial width window, explicitly set face of each glyph. */
int i;
+ unsigned int padding;
GLYPH *ptr = FRAME_DESIRED_GLYPHS (f)->glyphs[vpos];
for (i = left; i < right; ++i)
- ptr[i] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr[i]), 1);
+ {
+ padding = ptr[i] & GLYPH_MASK_PADDING;
+ ptr[i] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr[i]), 1) | padding;
+ }
}
+ else
#endif
/* Make the mode line inverse video if the entire line
or if it is the child of a full width window
(which implies that that window is split side-by-side
and the rest of this line is mode lines of the sibling windows). */
- else if (WINDOW_FULL_WIDTH_P (w)
- || WINDOW_FULL_WIDTH_P (XWINDOW (w->parent)))
+ if (WINDOW_FULL_WIDTH_P (w)
+ || WINDOW_FULL_WIDTH_P (XWINDOW (w->parent)))
FRAME_DESIRED_GLYPHS (f)->highlight[vpos] = mode_line_inverse_video;
}
}
}
+/* Set a mnemonic character for CODING_SYSTEM (Lisp symbol) in BUF.
+ If EOL_FLAG is 1, set also a mnemonic character for end-of-line
+ type of CODING_SYSTEM. Return updated pointer into BUF. */
+
+static char *
+decode_mode_spec_coding (coding_system, buf, eol_flag)
+ Lisp_Object coding_system;
+ register char *buf;
+ int eol_flag;
+{
+ Lisp_Object val;
+
+ val = coding_system;
+
+ if (NILP (val)) /* Not yet decided. */
+ {
+ *buf++ = '-';
+ if (eol_flag)
+ *buf++ = eol_mnemonic_undecided;
+ /* Don't mention EOL conversion if it isn't decided. */
+ }
+ else
+ {
+ Lisp_Object eolvalue;
+
+ eolvalue = Fget (coding_system, Qeol_type);
+
+ while (!NILP (val) && SYMBOLP (val))
+ {
+ val = Fget (val, Qcoding_system);
+ if (NILP (eolvalue))
+ eolvalue = Fget (coding_system, Qeol_type);
+ }
+
+ *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
+ if (eol_flag)
+ {
+ /* The EOL conversion we are using. */
+ int eoltype;
+ /* The EOL conversion that is normal on this system. */
+
+ if (NILP (eolvalue)) /* Not yet decided. */
+ eoltype = eol_mnemonic_undecided;
+ else if (VECTORP (eolvalue)) /* Not yet decided. */
+ eoltype = eol_mnemonic_undecided;
+ else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
+ eoltype = (XFASTINT (eolvalue) == 0
+ ? eol_mnemonic_unix
+ : (XFASTINT (eolvalue) == 1
+ ? eol_mnemonic_dos : eol_mnemonic_mac));
+
+ /* Mention the EOL conversion if it is not the usual one. */
+ *buf++ = eoltype;
+ }
+ }
+ return buf;
+}
+
/* Return a string for the output of a mode line %-spec for window W,
generated by character C. SPEC_WIDTH is the field width when
padding to the left (%c, %l). The value returned from this
#else
return "T";
#endif
+
+ case 'z':
+ /* coding-system (not including end-of-line format) */
+ case 'Z':
+ /* coding-system (including end-of-line type) */
+ {
+ int eol_flag = (c == 'Z');
+ char *p = decode_mode_spec_buf;
+
+ if (FRAME_TERMCAP_P (f))
+ {
+ /* No need to mention EOL here--the terminal never needs
+ to do EOL conversion. */
+ p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
+ p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+ }
+ p = decode_mode_spec_coding (b->buffer_file_coding_system,
+ p, eol_flag);
+
+#if 0 /* This proves to be annoying; I think we can do without. -- rms. */
+#ifdef subprocesses
+ obj = Fget_buffer_process (Fcurrent_buffer ());
+ if (PROCESSP (obj))
+ {
+ p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
+ p, eol_flag);
+ p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
+ p, eol_flag);
+ }
+#endif /* subprocesses */
+#endif /* 0 */
+ *p = 0;
+ return decode_mode_spec_buf;
+ }
}
if (STRINGP (obj))
{
ceiling = BUFFER_CEILING_OF (start);
ceiling = min (limit, ceiling);
- ceiling_addr = &FETCH_CHAR (ceiling) + 1;
- base = (cursor = &FETCH_CHAR (start));
+ ceiling_addr = POS_ADDR (ceiling) + 1;
+ base = (cursor = POS_ADDR (start));
while (1)
{
while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
{ /* we WILL scan under start */
ceiling = BUFFER_FLOOR_OF (start);
ceiling = max (limit, ceiling);
- ceiling_addr = &FETCH_CHAR (ceiling) - 1;
- base = (cursor = &FETCH_CHAR (start));
+ ceiling_addr = POS_ADDR (ceiling) - 1;
+ base = (cursor = POS_ADDR (start));
cursor++;
while (1)
{
struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (f);
GLYPH *p1start = desired_glyphs->glyphs[vpos] + hpos;
int window_width = XFASTINT (w->width);
+ /* If 1, we must display multibyte characters. */
+ int multibyte = !NILP (XBUFFER (w->buffer)->enable_multibyte_characters);
/* Use the standard display table, not the window's display table.
We don't want the mode line in rot13. */
if (maxcol >= 0 && mincol > maxcol)
mincol = maxcol;
+ if (length < 0)
+ /* We need this value for multibyte characters. */
+ length = strlen (string);
+
/* 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;
- c = *string++;
- /* Specified length. */
- if (length >= 0)
- length--;
- /* Unspecified length (null-terminated string). */
- else if (c == 0)
+ int len;
+
+ if (length <= 0)
break;
+ if (multibyte)
+ c = STRING_CHAR_AND_LENGTH (string, length, len);
+ else
+ c = *string, len = 1;
+
+ string += len, length -= len;
if (p1 >= end)
{
else if (c < 0200 && ! NILP (buffer_defaults.ctl_arrow))
{
if (p1 >= start)
- *p1 = fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp))
- ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
- 0);
+ *p1 = (fix_glyph
+ (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp))
+ && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (dp)))
+ ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
+ 0));
p1++;
if (p1 >= start && p1 < end)
*p1 = c ^ 0100;
p1++;
}
- else
+ else if (len == 1)
{
+ /* C is a control character or a binary byte data. */
if (p1 >= start)
- *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
- ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
- 0);
+ *p1 = (fix_glyph
+ (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
+ && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
+ ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
+ 0));
p1++;
if (p1 >= start && p1 < end)
*p1 = (c >> 6) + '0';
*p1 = (7 & c) + '0';
p1++;
}
+ else
+ {
+ /* C is a multibyte character. */
+ int charset = CHAR_CHARSET (c);
+ int columns = (charset == CHARSET_COMPOSITION
+ ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
+ : CHARSET_WIDTH (charset));
+
+ if (p1 < start)
+ {
+ /* Since we can't show the left part of C, fill all
+ columns with spaces. */
+ columns -= start - p1;
+ p1 = start;
+ while (columns--)
+ {
+ if (p1 < end)
+ *p1 = SPACEGLYPH;
+ p1++;
+ }
+ }
+ else if (p1 + columns > end)
+ {
+ /* Since we can't show the right part of C, fill all
+ columns with TRUNCATE if TRUNCATE is specified. */
+ if (truncate)
+ {
+ while (p1 < end)
+ *p1++ = fix_glyph (f, truncate, 0);
+ /* And tell the line is truncated. */
+ truncated = 1;
+ }
+ break;
+ }
+ else
+ {
+ /* We can show the whole glyph of C. */
+ *p1++ = c;
+ while (--columns)
+ *p1++ = c | GLYPH_MASK_PADDING;
+ }
+ }
}
if (truncated)
"*Scroll up to this many lines, to bring point back on screen.");
scroll_conservatively = 0;
+ DEFVAR_INT ("scroll-margin", &scroll_margin,
+ "*Number of lines of margin at the top and bottom of a window.\n\
+Recenter the window whenever point gets within this many lines\n\
+of the top or bottom of the window.");
+ scroll_margin = 0;
+
DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
DEFVAR_BOOL ("truncate-partial-width-windows",
DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
"*Non-nil means highlight region even in nonselected windows.");
- highlight_nonselected_windows = 1;
+ highlight_nonselected_windows = 0;
DEFVAR_BOOL ("multiple-frames", &multiple_frames,
"Non-nil if more than one frame is visible on this display.\n\
if (!noninteractive)
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
- XSETFASTINT (XWINDOW (root_window)->top, 0);
- set_window_height (root_window, FRAME_HEIGHT (f) - 1, 0);
+ XSETFASTINT (XWINDOW (root_window)->top, FRAME_MENU_BAR_LINES (f));
+ set_window_height (root_window,
+ FRAME_HEIGHT (f) - 1 - FRAME_MENU_BAR_LINES (f),
+ 0);
XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
set_window_height (minibuf_window, 1, 0);