/* 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.
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 ? 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));
}
}
}
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)
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);
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
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)
{
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;
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. */
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;
|| left_edge->hpos > 0)
{
pos = left_edge->bufpos;
- DEC_POS (pos); /* MULE: It may be a multi-byte character */
+ /* 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)
{
}
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))
}
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, rev_dir_bit);
}
-#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
/* 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;
}
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)
{
/* 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)
}
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);
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;
}
register char *buf;
int eol_flag;
{
- register Lisp_Object val = coding_system;
+ Lisp_Object val;
+
+ val = coding_system;
if (NILP (val)) /* Not yet decided. */
{
*buf++ = '-';
- if (eol_flag) *buf++ = eol_mnemonic_undecided;
+ 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);
+ {
+ val = Fget (val, Qcoding_system);
+ if (NILP (eolvalue))
+ eolvalue = Fget (coding_system, Qeol_type);
+ }
+
*buf++ = XFASTINT (XVECTOR (val)->contents[1]);
if (eol_flag)
{
- val = Fget (coding_system, Qeol_type);
-
- if (NILP (val)) /* Not yet decided. */
- *buf++ = eol_mnemonic_undecided;
- else if (VECTORP (val)) /* Not yet decided. */
- *buf++ = eol_mnemonic_undecided;
- else /* INTEGERP (val) -- 1:LF, 2:CRLF, 3:CR */
- *buf++ = (XFASTINT (val) == 1
- ? eol_mnemonic_unix
- : (XFASTINT (val) == 2
- ? eol_mnemonic_dos : eol_mnemonic_mac));
+ /* 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;
/* coding-system (including end-of-line type) */
{
int eol_flag = (c == 'Z');
- char *p;
+ char *p = decode_mode_spec_buf;
- p = decode_mode_spec_coding
- (find_symbol_value (Qbuffer_file_coding_system),
- decode_mode_spec_buf, eol_flag);
if (FRAME_TERMCAP_P (f))
{
- p = decode_mode_spec_coding (keyboard_coding.symbol, p, eol_flag);
- p = decode_mode_spec_coding (terminal_coding.symbol, p, eol_flag);
+ /* 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, eol_flag);
}
#endif /* subprocesses */
+#endif /* 0 */
*p = 0;
return decode_mode_spec_buf;
}
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;
{
/* 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';
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);