/* Display generation from window structure and buffer text.
-Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
+Inc.
This file is part of GNU Emacs.
static Lisp_Object Qmargin, Qpointer;
static Lisp_Object Qline_height;
-/* These setters are used only in this file, so they can be private. */
-static void
-wset_base_line_number (struct window *w, Lisp_Object val)
-{
- w->base_line_number = val;
-}
-static void
-wset_base_line_pos (struct window *w, Lisp_Object val)
-{
- w->base_line_pos = val;
-}
-static void
-wset_column_number_displayed (struct window *w, Lisp_Object val)
-{
- w->column_number_displayed = val;
-}
-static void
-wset_region_showing (struct window *w, Lisp_Object val)
-{
- w->region_showing = val;
-}
-
#ifdef HAVE_WINDOW_SYSTEM
/* Test if overflow newline into fringe. Called with iterator IT
/* Ascent and height of the last line processed by move_it_to. */
-static int last_max_ascent, last_height;
+static int last_height;
/* Non-zero if there's a help-echo in the echo area. */
static void mark_window_display_accurate_1 (struct window *, int);
static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
static int display_prop_string_p (Lisp_Object, Lisp_Object);
+static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
static int cursor_row_p (struct glyph_row *);
static int redisplay_mode_lines (Lisp_Object, int);
static char *decode_mode_spec_coding (Lisp_Object, char *, int);
static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
static int with_echo_area_buffer (struct window *, int,
- int (*) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
- ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+ int (*) (ptrdiff_t, Lisp_Object),
+ ptrdiff_t, Lisp_Object);
static void clear_garbaged_frames (void);
-static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static int current_message_1 (ptrdiff_t, Lisp_Object);
static void pop_message (void);
-static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
-static void set_message (const char *, Lisp_Object, ptrdiff_t, int);
-static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static int truncate_message_1 (ptrdiff_t, Lisp_Object);
+static void set_message (Lisp_Object);
+static int set_message_1 (ptrdiff_t, Lisp_Object);
static int display_echo_area (struct window *);
-static int display_echo_area_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
-static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
+static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
static Lisp_Object unwind_redisplay (Lisp_Object);
static int string_char_and_length (const unsigned char *, int *);
static struct text_pos display_prop_end (struct it *, Lisp_Object,
static struct text_pos string_pos_nchars_ahead (struct text_pos,
Lisp_Object, ptrdiff_t);
static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
-static struct text_pos c_string_pos (ptrdiff_t, const char *, int);
-static ptrdiff_t number_of_chars (const char *, int);
+static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
+static ptrdiff_t number_of_chars (const char *, bool);
static void compute_stop_pos (struct it *);
static void compute_string_pos (struct text_pos *, struct text_pos,
Lisp_Object);
int
window_box_width (struct window *w, int area)
{
- int cols = XFASTINT (w->total_cols);
+ int cols = w->total_cols;
int pixels = 0;
if (!w->pseudo_window_p)
if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
return visible_p;
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
{
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
}
SET_TEXT_POS_FROM_MARKER (top, w->start);
Lisp_Object cpos = make_number (charpos);
Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
Lisp_Object string = string_from_display_spec (spec);
- int newline_in_string = 0;
-
- if (STRINGP (string))
- {
- const char *s = SSDATA (string);
- const char *e = s + SBYTES (string);
- while (s < e)
- {
- if (*s++ == '\n')
- {
- newline_in_string = 1;
- break;
- }
- }
- }
+ struct text_pos tpos;
+ int replacing_spec_p;
+ bool newline_in_string
+ = (STRINGP (string)
+ && memchr (SDATA (string), '\n', SBYTES (string)));
+
+ SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
+ replacing_spec_p
+ = (!NILP (spec)
+ && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
+ charpos, FRAME_WINDOW_P (it.f)));
/* The tricky code below is needed because there's a
discrepancy between move_it_to and how we set cursor
- when the display line ends in a newline from a
- display string. move_it_to will stop _after_ such
- display strings, whereas set_cursor_from_row
- conspires with cursor_row_p to place the cursor on
- the first glyph produced from the display string. */
+ when PT is at the beginning of a portion of text
+ covered by a display property or an overlay with a
+ display property, or the display line ends in a
+ newline from a display string. move_it_to will stop
+ _after_ such display strings, whereas
+ set_cursor_from_row conspires with cursor_row_p to
+ place the cursor on the first glyph produced from the
+ display string. */
/* We have overshoot PT because it is covered by a
- display property whose value is a string. If the
- string includes embedded newlines, we are also in the
- wrong display line. Backtrack to the correct line,
- where the display string begins. */
- if (newline_in_string)
+ display property that replaces the text it covers.
+ If the string includes embedded newlines, we are also
+ in the wrong display line. Backtrack to the correct
+ line, where the display property begins. */
+ if (replacing_spec_p)
{
Lisp_Object startpos, endpos;
EMACS_INT start, end;
rightmost character on a line that is
continued or word-wrapped. */
if (it3.method == GET_FROM_BUFFER
- && it3.c == '\n')
+ && (it3.c == '\n'
+ || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
move_it_by_lines (&it3, 1);
else if (move_it_in_display_line_to (&it3, -1,
it3.current_x
produced from the string, until we find the
rightmost glyph not from the string. */
if (it3_moved
+ && newline_in_string
&& IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
{
struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
means recognize multibyte characters. */
static struct text_pos
-c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p)
+c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
{
struct text_pos pos;
non-zero means recognize multibyte characters. */
static ptrdiff_t
-number_of_chars (const char *s, int multibyte_p)
+number_of_chars (const char *s, bool multibyte_p)
{
ptrdiff_t nchars;
static void
check_window_end (struct window *w)
{
- if (!MINI_WINDOW_P (w)
- && !NILP (w->window_end_valid))
+ if (!MINI_WINDOW_P (w) && w->window_end_valid)
{
struct glyph_row *row;
eassert ((row = MATRIX_ROW (w->current_matrix,
at character position CHARPOS. CHARPOS < 0 means that no buffer
position is specified which is useful when the iterator is assigned
a position later. BYTEPOS is the byte position corresponding to
- CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
+ CHARPOS.
If ROW is not null, calls to produce_glyphs with IT as parameter
will produce glyphs in that row.
and IT->region_end_charpos to the start and end of a visible region
in window IT->w. Set both to -1 to indicate no region. */
markpos = markpos_of_region ();
- if (0 <= markpos
+ if (markpos >= 0
/* Maybe highlight only in selected window. */
&& (/* Either show region everywhere. */
highlight_nonselected_windows
if (charpos >= BUF_BEG (current_buffer))
{
it->end_charpos = ZV;
+ eassert (charpos == BYTE_TO_CHAR (bytepos));
IT_CHARPOS (*it) = charpos;
+ IT_BYTEPOS (*it) = bytepos;
/* We will rely on `reseat' to set this up properly, via
handle_face_prop. */
it->face_id = it->base_face_id;
- /* Compute byte position if not specified. */
- if (bytepos < charpos)
- IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
- else
- IT_BYTEPOS (*it) = bytepos;
-
it->start = it->current;
/* Do we need to reorder bidirectional text? Not if this is a
unibyte buffer: by definition, none of the single-byte
if it was a text property. */
if (!STRINGP (it->string))
- object = it->w->buffer;
+ object = it->w->contents;
display_replaced_p = handle_display_spec (it, propval, object, overlay,
position, bufpos,
it->what = IT_IMAGE;
it->image_id = -1; /* no image */
it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
+ it->object = NILP (object) ? it->w->contents : object;
it->method = GET_FROM_IMAGE;
it->from_overlay = Qnil;
it->face_id = face_id;
it->what = IT_IMAGE;
it->image_id = lookup_image (it->f, value);
it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
+ it->object = NILP (object) ? it->w->contents : object;
it->method = GET_FROM_IMAGE;
/* Say that we haven't consumed the characters with
it->object = p->u.stretch.object;
break;
case GET_FROM_BUFFER:
- it->object = it->w->buffer;
+ it->object = it->w->contents;
break;
case GET_FROM_STRING:
it->object = it->string;
else
{
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
}
}
it->end_charpos = p->end_charpos;
static void
back_to_previous_line_start (struct it *it)
{
- IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
- IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
+ ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
+
+ DEC_BOTH (cp, bp);
+ IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
}
Newlines may come from buffer text, overlay strings, or strings
displayed via the `display' property. That's the reason we can't
- simply use find_next_newline_no_quit.
+ simply use find_newline_no_quit.
Note that this function may not skip over invisible text that is so
because of text properties and immediately follows a newline. If
short-cut. */
if (!newline_found_p)
{
- ptrdiff_t start = IT_CHARPOS (*it);
- ptrdiff_t limit = find_next_newline_no_quit (start, 1);
+ ptrdiff_t bytepos, start = IT_CHARPOS (*it);
+ ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
+ 1, &bytepos);
Lisp_Object pos;
eassert (!STRINGP (it->string));
if (!it->bidi_p)
{
IT_CHARPOS (*it) = limit;
- IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
+ IT_BYTEPOS (*it) = bytepos;
}
else
{
IT_STRING_BYTEPOS (*it) = -1;
it->string = Qnil;
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->area = TEXT_AREA;
it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
it->sp = 0;
else
{
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
}
it->dpvec = NULL;
else if (it->dpvec_char_len > 0)
{
if (it->method == GET_FROM_STRING
+ && it->current.overlay_string_index >= 0
&& it->n_overlay_strings > 0)
it->ignore_overlay_strings_at_pos_p = 1;
it->len = it->dpvec_char_len;
if (string_p)
it->bidi_it.charpos = it->bidi_it.bytepos = 0;
else
- {
- it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
- -1);
- it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
- }
+ it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
+ IT_BYTEPOS (*it), -1,
+ &it->bidi_it.bytepos);
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
do
{
setting face_before_selective_p. */
it->saved_face_id = it->face_id;
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
reseat_at_next_visible_line_start (it, 1);
it->face_before_selective_p = 1;
}
/* Record what we have and where it came from. */
it->what = IT_CHARACTER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->position = it->current.pos;
/* Normally we return the character found above, except when we
return 0;
}
it->position = it->current.pos;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it), Qnil);
}
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
- last_max_ascent = it->max_ascent;
it->max_ascent = it->max_descent = 0;
}
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
- last_max_ascent = it->max_ascent;
}
if (backup_data)
struct it it2, it3;
void *it2data = NULL, *it3data = NULL;
ptrdiff_t start_pos;
+ int nchars_per_row
+ = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
+ ptrdiff_t pos_limit;
move_further_back:
eassert (dy >= 0);
/* Estimate how many newlines we must move back. */
nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
+ if (it->line_wrap == TRUNCATE)
+ pos_limit = BEGV;
+ else
+ pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
- /* Set the iterator's position that many lines back. */
- while (nlines-- && IT_CHARPOS (*it) > BEGV)
+ /* Set the iterator's position that many lines back. But don't go
+ back more than NLINES full screen lines -- this wins a day with
+ buffers which have very long lines. */
+ while (nlines-- && IT_CHARPOS (*it) > pos_limit)
back_to_previous_visible_line_start (it);
/* Reseat the iterator here. When moving backward, we don't want
&& IT_CHARPOS (*it) > BEGV
&& FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
{
- ptrdiff_t nl_pos =
- find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
+ ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
- move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
+ DEC_BOTH (cp, bp);
+ cp = find_newline_no_quit (cp, bp, -1, NULL);
+ move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
}
bidi_unshelve_cache (it3data, 1);
}
struct it it2;
void *it2data = NULL;
ptrdiff_t start_charpos, i;
+ int nchars_per_row
+ = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
+ ptrdiff_t pos_limit;
/* Start at the beginning of the screen line containing IT's
position. This may actually move vertically backwards,
move_it_vertically_backward (it, 0);
dvpos -= it->vpos;
- /* Go back -DVPOS visible lines and reseat the iterator there. */
+ /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
+ screen lines, and reseat the iterator there. */
start_charpos = IT_CHARPOS (*it);
- for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
+ if (it->line_wrap == TRUNCATE)
+ pos_limit = BEGV;
+ else
+ pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
+ for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
back_to_previous_visible_line_start (it);
reseat (it, it->current.pos, 1);
/* Add a string M of length NBYTES to the message log, optionally
- terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
- nonzero, means interpret the contents of M as multibyte. This
+ terminated with a newline when NLFLAG is true. MULTIBYTE, if
+ true, means interpret the contents of M as multibyte. This
function calls low-level routines in order to bypass text property
hooks, etc. which might not be safe to run.
so the buffer M must NOT point to a Lisp string. */
void
-message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
+message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
{
const unsigned char *msg = (const unsigned char *) m;
bset_undo_list (current_buffer, Qt);
oldpoint = message_dolog_marker1;
- set_marker_restricted (oldpoint, make_number (PT), Qnil);
+ set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
oldbegv = message_dolog_marker2;
- set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
+ set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
oldzv = message_dolog_marker3;
- set_marker_restricted (oldzv, make_number (ZV), Qnil);
+ set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
GCPRO1 (old_deactivate_mark);
if (PT == Z)
}
}
else if (nbytes)
- insert_1 (m, nbytes, 1, 0, 0);
+ insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
if (nlflag)
{
ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
printmax_t dups;
- insert_1 ("\n", 1, 1, 0, 0);
+
+ insert_1_both ("\n", 1, 1, 1, 0, 0);
scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
this_bol = PT;
change message_log_check_duplicate. */
int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
- insert_1 (dupstr, duplen, 1, 0, 1);
+ insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
}
}
}
for (i = 0; i < len; i++)
{
- if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
+ if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
seen_dots = 1;
if (p1[i] != p2[i])
return seen_dots;
char *pend;
intmax_t n = strtoimax ((char *) p1, &pend, 10);
if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
- return n+1;
+ return n + 1;
}
return 0;
}
\f
-/* Display an echo area message M with a specified length of NBYTES
- bytes. The string may include null characters. If M is 0, clear
- out any existing message, and let the mini-buffer text show
- through.
-
- This may GC, so the buffer M must NOT point to a Lisp string. */
-
-void
-message2 (const char *m, ptrdiff_t nbytes, int multibyte)
-{
- /* First flush out any partial line written with print. */
- message_log_maybe_newline ();
- if (m)
- message_dolog (m, nbytes, 1, multibyte);
- message2_nolog (m, nbytes, multibyte);
-}
-
-
-/* The non-logging counterpart of message2. */
-
-void
-message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte)
-{
- struct frame *sf = SELECTED_FRAME ();
- message_enable_multibyte = multibyte;
-
- if (FRAME_INITIAL_P (sf))
- {
- if (noninteractive_need_newline)
- putc ('\n', stderr);
- noninteractive_need_newline = 0;
- if (m)
- fwrite (m, nbytes, 1, stderr);
- if (cursor_in_echo_area == 0)
- fprintf (stderr, "\n");
- fflush (stderr);
- }
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
- else if (INTERACTIVE
- && sf->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (sf))
- {
- Lisp_Object mini_window;
- struct frame *f;
-
- /* Get the frame containing the mini-buffer
- that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (sf);
- f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
-
- FRAME_SAMPLE_VISIBILITY (f);
- if (FRAME_VISIBLE_P (sf)
- && ! FRAME_VISIBLE_P (f))
- Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
-
- if (m)
- {
- set_message (m, Qnil, nbytes, multibyte);
- if (minibuffer_auto_raise)
- Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
- }
- else
- clear_message (1, 1);
-
- do_pending_window_change (0);
- echo_area_display (1);
- do_pending_window_change (0);
- if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
- (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
- }
-}
-
-
/* Display an echo area message M with a specified length of NBYTES
bytes. The string may include null characters. If M is not a
string, clear out any existing message, and let the mini-buffer
This function cancels echoing. */
void
-message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
+message3 (Lisp_Object m)
{
struct gcpro gcpro1;
message_log_maybe_newline ();
if (STRINGP (m))
{
+ ptrdiff_t nbytes = SBYTES (m);
+ bool multibyte = STRING_MULTIBYTE (m);
USE_SAFE_ALLOCA;
char *buffer = SAFE_ALLOCA (nbytes);
memcpy (buffer, SDATA (m), nbytes);
message_dolog (buffer, nbytes, 1, multibyte);
SAFE_FREE ();
}
- message3_nolog (m, nbytes, multibyte);
+ message3_nolog (m);
UNGCPRO;
}
and make this cancel echoing. */
void
-message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
+message3_nolog (Lisp_Object m)
{
struct frame *sf = SELECTED_FRAME ();
- message_enable_multibyte = multibyte;
if (FRAME_INITIAL_P (sf))
{
putc ('\n', stderr);
noninteractive_need_newline = 0;
if (STRINGP (m))
- fwrite (SDATA (m), nbytes, 1, stderr);
+ fwrite (SDATA (m), SBYTES (m), 1, stderr);
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
}
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
- else if (INTERACTIVE
- && sf->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (sf))
+ /* Error messages get reported properly by cmd_error, so this must be just an
+ informative message; if the frame hasn't really been initialized yet, just
+ toss it. */
+ else if (INTERACTIVE && sf->glyphs_initialized_p)
{
- Lisp_Object mini_window;
- Lisp_Object frame;
- struct frame *f;
-
/* Get the frame containing the mini-buffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (sf);
- frame = XWINDOW (mini_window)->frame;
- f = XFRAME (frame);
+ Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
+ Lisp_Object frame = XWINDOW (mini_window)->frame;
+ struct frame *f = XFRAME (frame);
- FRAME_SAMPLE_VISIBILITY (f);
- if (FRAME_VISIBLE_P (sf)
- && !FRAME_VISIBLE_P (f))
+ if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
Fmake_frame_visible (frame);
if (STRINGP (m) && SCHARS (m) > 0)
{
- set_message (NULL, m, nbytes, multibyte);
+ set_message (m);
if (minibuffer_auto_raise)
Fraise_frame (frame);
/* Assume we are not echoing.
void
message1 (const char *m)
{
- message2 (m, (m ? strlen (m) : 0), 0);
+ message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
}
void
message1_nolog (const char *m)
{
- message2_nolog (m, (m ? strlen (m) : 0), 0);
+ message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
}
/* Display a message M which contains a single %s
mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
- if (FRAME_MESSAGE_BUF (f))
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (f->glyphs_initialized_p)
{
Lisp_Object args[2], msg;
struct gcpro gcpro1, gcpro2;
msg = Fformat (2, args);
if (log)
- message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
+ message3 (msg);
else
- message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
+ message3_nolog (msg);
UNGCPRO;
mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss
- it. */
- if (FRAME_MESSAGE_BUF (f))
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (f->glyphs_initialized_p)
{
if (m)
{
ptrdiff_t len;
+ ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
+ char *message_buf = alloca (maxsize + 1);
- len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
+ len = doprnt (message_buf, maxsize, m, (char *)0, ap);
- message2 (FRAME_MESSAGE_BUF (f), len, 1);
+ message3 (make_string (message_buf, len));
}
else
message1 (0);
{
Lisp_Object string;
string = Fcurrent_message ();
- message3 (string, SBYTES (string),
- !NILP (BVAR (current_buffer, enable_multibyte_characters)));
+ message3 (string);
}
}
}
-/* Call FN with args A1..A4 with either the current or last displayed
+/* Call FN with args A1..A2 with either the current or last displayed
echo_area_buffer as current buffer.
WHICH zero means use the current message buffer
static int
with_echo_area_buffer (struct window *w, int which,
- int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
- ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+ int (*fn) (ptrdiff_t, Lisp_Object),
+ ptrdiff_t a1, Lisp_Object a2)
{
Lisp_Object buffer;
int this_one, the_other, clear_buffer_p, rc;
eassert (BEGV >= BEG);
eassert (ZV <= Z && ZV >= BEGV);
- rc = fn (a1, a2, a3, a4);
+ rc = fn (a1, a2);
eassert (BEGV >= BEG);
eassert (ZV <= Z && ZV >= BEGV);
Vwith_echo_area_save_vector = Qnil;
if (NILP (vector))
- vector = Fmake_vector (make_number (7), Qnil);
+ vector = Fmake_vector (make_number (9), Qnil);
XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
ASET (vector, i, Vdeactivate_mark); ++i;
if (w)
{
XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
- ASET (vector, i, w->buffer); ++i;
+ ASET (vector, i, w->contents); ++i;
ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
+ ASET (vector, i, make_number (marker_position (w->start))); ++i;
+ ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
}
else
{
- int end = i + 4;
+ int end = i + 6;
for (; i < end; ++i)
ASET (vector, i, Qnil);
}
if (WINDOWP (AREF (vector, 3)))
{
struct window *w;
- Lisp_Object buffer, charpos, bytepos;
+ Lisp_Object buffer;
w = XWINDOW (AREF (vector, 3));
buffer = AREF (vector, 4);
- charpos = AREF (vector, 5);
- bytepos = AREF (vector, 6);
wset_buffer (w, buffer);
set_marker_both (w->pointm, buffer,
- XFASTINT (charpos), XFASTINT (bytepos));
+ XFASTINT (AREF (vector, 5)),
+ XFASTINT (AREF (vector, 6)));
+ set_marker_both (w->start, buffer,
+ XFASTINT (AREF (vector, 7)),
+ XFASTINT (AREF (vector, 8)));
}
Vwith_echo_area_save_vector = vector;
window_height_changed_p
= with_echo_area_buffer (w, display_last_displayed_message_p,
display_echo_area_1,
- (intptr_t) w, Qnil, 0, 0);
+ (intptr_t) w, Qnil);
if (no_message_p)
echo_area_buffer[i] = Qnil;
Value is non-zero if height of W was changed. */
static int
-display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
{
intptr_t i1 = a1;
struct window *w = (struct window *) i1;
resize_exactly = Qnil;
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
- (intptr_t) w, resize_exactly,
- 0, 0);
+ (intptr_t) w, resize_exactly);
if (resized_p)
{
++windows_or_buffers_changed;
resize_mini_window returns. */
static int
-resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4)
+resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
{
intptr_t i1 = a1;
return resize_mini_window ((struct window *) i1, !NILP (exactly));
eassert (MINI_WINDOW_P (w));
/* By default, start display at the beginning. */
- set_marker_both (w->start, w->buffer,
- BUF_BEGV (XBUFFER (w->buffer)),
- BUF_BEGV_BYTE (XBUFFER (w->buffer)));
+ set_marker_both (w->start, w->contents,
+ BUF_BEGV (XBUFFER (w->contents)),
+ BUF_BEGV_BYTE (XBUFFER (w->contents)));
/* Don't resize windows while redisplaying a window; it would
confuse redisplay functions when the size of the window they are
struct text_pos start;
struct buffer *old_current_buffer = NULL;
- if (current_buffer != XBUFFER (w->buffer))
+ if (current_buffer != XBUFFER (w->contents))
{
old_current_buffer = current_buffer;
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
else
{
with_echo_area_buffer (0, 0, current_message_1,
- (intptr_t) &msg, Qnil, 0, 0);
+ (intptr_t) &msg, Qnil);
if (NILP (msg))
echo_area_buffer[0] = Qnil;
}
static int
-current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+current_message_1 (ptrdiff_t a1, Lisp_Object a2)
{
intptr_t i1 = a1;
Lisp_Object *msg = (Lisp_Object *) i1;
void
restore_message (void)
{
- Lisp_Object msg;
-
eassert (CONSP (Vmessage_stack));
- msg = XCAR (Vmessage_stack);
- if (STRINGP (msg))
- message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
- else
- message3_nolog (msg, 0, 0);
+ message3_nolog (XCAR (Vmessage_stack));
}
{
if (nchars == 0)
echo_area_buffer[0] = Qnil;
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
else if (!noninteractive
&& INTERACTIVE
&& !NILP (echo_area_buffer[0]))
{
struct frame *sf = SELECTED_FRAME ();
- if (FRAME_MESSAGE_BUF (sf))
- with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (sf->glyphs_initialized_p)
+ with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
}
}
message to at most NCHARS characters. */
static int
-truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
{
if (BEG + nchars < Z)
del_range (BEG + nchars, Z);
return 0;
}
-/* Set the current message to a substring of S or STRING.
-
- If STRING is a Lisp string, set the message to the first NBYTES
- bytes from STRING. NBYTES zero means use the whole string. If
- STRING is multibyte, the message will be displayed multibyte.
-
- If S is not null, set the message to the first LEN bytes of S. LEN
- zero means use the whole string. MULTIBYTE_P non-zero means S is
- multibyte. Display the message multibyte in that case.
-
- Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
- to t before calling set_message_1 (which calls insert).
- */
+/* Set the current message to STRING. */
static void
-set_message (const char *s, Lisp_Object string,
- ptrdiff_t nbytes, int multibyte_p)
+set_message (Lisp_Object string)
{
- message_enable_multibyte
- = ((s && multibyte_p)
- || (STRINGP (string) && STRING_MULTIBYTE (string)));
+ eassert (STRINGP (string));
- with_echo_area_buffer (0, -1, set_message_1,
- (intptr_t) s, string, nbytes, multibyte_p);
+ message_enable_multibyte = STRING_MULTIBYTE (string);
+
+ with_echo_area_buffer (0, -1, set_message_1, 0, string);
message_buf_print = 0;
help_echo_showing_p = 0;
if (STRINGP (Vdebug_on_message)
+ && STRINGP (string)
&& fast_string_match (Vdebug_on_message, string) >= 0)
call_debugger (list2 (Qerror, string));
}
-/* Helper function for set_message. Arguments have the same meaning
- as there, with A1 corresponding to S and A2 corresponding to STRING
- This function is called with the echo area buffer being
- current. */
+/* Helper function for set_message. First argument is ignored and second
+ argument has the same meaning as for set_message.
+ This function is called with the echo area buffer being current. */
static int
-set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p)
+set_message_1 (ptrdiff_t a1, Lisp_Object string)
{
- intptr_t i1 = a1;
- const char *s = (const char *) i1;
- const unsigned char *msg = (const unsigned char *) s;
- Lisp_Object string = a2;
+ eassert (STRINGP (string));
/* Change multibyteness of the echo buffer appropriately. */
if (message_enable_multibyte
/* Insert new message at BEG. */
TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
- if (STRINGP (string))
- {
- ptrdiff_t nchars;
-
- if (nbytes == 0)
- nbytes = SBYTES (string);
- nchars = string_byte_to_char (string, nbytes);
-
- /* This function takes care of single/multibyte conversion. We
- just have to ensure that the echo area buffer has the right
- setting of enable_multibyte_characters. */
- insert_from_string (string, 0, 0, nchars, nbytes, 1);
- }
- else if (s)
- {
- if (nbytes == 0)
- nbytes = strlen (s);
-
- if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
- {
- /* Convert from multi-byte to single-byte. */
- ptrdiff_t i;
- int c, n;
- char work[1];
-
- /* Convert a multibyte string to single-byte. */
- for (i = 0; i < nbytes; i += n)
- {
- c = string_char_and_length (msg + i, &n);
- work[0] = (ASCII_CHAR_P (c)
- ? c
- : multibyte_char_to_unibyte (c));
- insert_1_both (work, 1, 1, 1, 0, 0);
- }
- }
- else if (!multibyte_p
- && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
- {
- /* Convert from single-byte to multi-byte. */
- ptrdiff_t i;
- int c, n;
- unsigned char str[MAX_MULTIBYTE_LENGTH];
-
- /* Convert a single-byte string to multibyte. */
- for (i = 0; i < nbytes; i++)
- {
- c = msg[i];
- MAKE_CHAR_MULTIBYTE (c);
- n = CHAR_STRING (c, str);
- insert_1_both ((char *) str, 1, n, 1, 0, 0);
- }
- }
- else
- insert_1 (s, nbytes, 1, 0, 0);
- }
+ /* This function takes care of single/multibyte conversion.
+ We just have to ensure that the echo area buffer has the right
+ setting of enable_multibyte_characters. */
+ insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
return 0;
}
/* Nonzero if W doesn't reflect the actual state of current buffer due
to its text or overlays change. FIXME: this may be called when
- XBUFFER (w->buffer) != current_buffer, which looks suspicious. */
+ XBUFFER (w->contents) != current_buffer, which looks suspicious. */
static int
window_outdated (struct window *w)
static int
window_buffer_changed (struct window *w)
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
eassert (BUFFER_LIVE_P (b));
return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
|| ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
- != !NILP (w->region_showing)));
+ != (w->region_showing != 0)));
}
/* Nonzero if W has %c in its mode line and mode line should be updated. */
static int
mode_line_update_needed (struct window *w)
{
- return (!NILP (w->column_number_displayed)
+ return (w->column_number_displayed != -1
&& !(PT == w->last_point && !window_outdated (w))
- && (XFASTINT (w->column_number_displayed) != current_column ()));
+ && (w->column_number_displayed != current_column ()));
}
/***********************************************************************
Fselect_window (f->selected_window, Qt);
set_buffer_internal_1
- (XBUFFER (XWINDOW (f->selected_window)->buffer));
+ (XBUFFER (XWINDOW (f->selected_window)->contents));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
mode_line_target = MODE_LINE_TITLE;
if (windows_or_buffers_changed
&& FRAME_NS_P (f))
ns_set_doc_edited
- (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
+ (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
#endif
UNGCPRO;
}
specbind (Qinhibit_menubar_update, Qt);
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
if (save_match_data)
record_unwind_save_match_data ();
if (NILP (Voverriding_local_map_menu_flag))
/* Set current_buffer to the buffer of the selected
window of the frame, so that we get the right local
keymaps. */
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
/* Save match data, if we must. */
if (save_match_data)
no additional border below the possibly empty tool-bar lines.
So to make the extra empty lines look "normal", we have to
use the tool-bar face for the border too. */
- if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
+ if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
+ && !EQ (Vauto_resize_tool_bars, Qgrow_only))
it->face_id = DEFAULT_FACE_ID;
extend_face_to_end_of_line (it);
compute_line_metrics (it);
/* If line is empty, make it occupy the rest of the tool-bar. */
- if (!row->displays_text_p)
+ if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
{
row->height = row->phys_height = it->last_visible_y - row->y;
row->visible_height = row->height;
/* If there are blank lines at the end, except for a partially
visible blank line at the end that is smaller than
FRAME_LINE_HEIGHT, change the tool-bar's height. */
- if (!row->displays_text_p
+ if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
&& row->height >= FRAME_LINE_HEIGHT (f))
change_height_p = 1;
/* If row displays tool-bar items, but is partially visible,
change the tool-bar's height. */
- if (row->displays_text_p
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
&& MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
&& MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
change_height_p = 1;
{
struct window *w = XWINDOW (window);
- if (WINDOWP (w->hchild))
- hscrolled_p |= hscroll_window_tree (w->hchild);
- else if (WINDOWP (w->vchild))
- hscrolled_p |= hscroll_window_tree (w->vchild);
+ if (WINDOWP (w->contents))
+ hscrolled_p |= hscroll_window_tree (w->contents);
else if (w->cursor.vpos >= 0)
{
int h_margin;
/* Scroll when cursor is inside this scroll margin. */
h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
- if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
+ if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
/* For left-to-right rows, hscroll when cursor is either
(i) inside the right hscroll margin, or (ii) if it is
inside the left margin and the window is already
/* Find point in a display of infinite width. */
saved_current_buffer = current_buffer;
- current_buffer = XBUFFER (w->buffer);
+ current_buffer = XBUFFER (w->contents);
if (w == XWINDOW (selected_window))
pt = PT;
redisplay. */
if (w->hscroll != hscroll)
{
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
w->hscroll = hscroll;
hscrolled_p = 1;
}
if (trace_redisplay_p)
fprintf (stderr, "%p (%s): %s\n",
w,
- ((BUFFERP (w->buffer)
- && STRINGP (BVAR (XBUFFER (w->buffer), name)))
- ? SSDATA (BVAR (XBUFFER (w->buffer), name))
+ ((BUFFERP (w->contents)
+ && STRINGP (BVAR (XBUFFER (w->contents), name)))
+ ? SSDATA (BVAR (XBUFFER (w->contents), name))
: "no buffer"),
method + len);
}
require to redisplay the whole paragraph. It might be worthwhile
to find the paragraph limits and widen the range of redisplayed
lines to that, but for now just give up this optimization. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
- && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
+ && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
unchanged_p = 0;
}
reconsider_clip_changes (struct window *w, struct buffer *b)
{
if (b->clip_changed
- && !NILP (w->window_end_valid)
- && w->current_matrix->buffer == b
- && w->current_matrix->zv == BUF_ZV (b)
- && w->current_matrix->begv == BUF_BEGV (b))
+ && w->window_end_valid
+ && w->current_matrix->buffer == b
+ && w->current_matrix->zv == BUF_ZV (b)
+ && w->current_matrix->begv == BUF_BEGV (b))
b->clip_changed = 0;
/* If display wasn't paused, and W is not a tool bar window, see if
we set b->clip_changed to 1 to force updating the screen. If
b->clip_changed has already been set to 1, we can skip this
check. */
- if (!b->clip_changed
- && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
+ if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
{
ptrdiff_t pt;
else
pt = marker_position (w->pointm);
- if ((w->current_matrix->buffer != XBUFFER (w->buffer)
+ if ((w->current_matrix->buffer != XBUFFER (w->contents)
|| pt != w->last_point)
&& check_point_in_composition (w->current_matrix->buffer,
w->last_point,
- XBUFFER (w->buffer), pt))
+ XBUFFER (w->contents), pt))
b->clip_changed = 1;
}
}
{
struct frame *f = XFRAME (frame);
- FRAME_SAMPLE_VISIBILITY (f);
if (FRAME_VISIBLE_P (f))
++number_of_visible_frames;
clear_desired_matrices (f);
unbind_to (count1, Qnil);
- FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
-
consider_all_windows_p = (update_mode_lines
|| buffer_shared_and_changed ()
|| cursor_type_changed);
clear_garbaged_frames ();
}
-
/* If showing the region, and mark has changed, we must redisplay
the whole window. The assignment to this_line_start_pos prevents
the optimization directly below this if-statement. */
if (((!NILP (Vtransient_mark_mode)
- && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
- != !NILP (w->region_showing))
- || (!NILP (w->region_showing)
- && !EQ (w->region_showing,
- Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
+ && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
+ != (w->region_showing > 0))
+ || (w->region_showing
+ && w->region_showing
+ != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
CHARPOS (this_line_start_pos) = 0;
/* Optimize the case that only the line containing the cursor in the
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
- && current_buffer == XBUFFER (w->buffer)
+ && current_buffer == XBUFFER (w->contents)
&& !w->force_start
&& !w->optional_new_start
/* Point must be on the line that we have info recorded about. */
/* If this row displays text now but previously didn't,
or vice versa, w->window_end_vpos may have to be
adjusted. */
- if ((it.glyph_row - 1)->displays_text_p)
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
{
if (XFASTINT (w->window_end_vpos) < this_line_vpos)
wset_window_end_vpos (w, make_number (this_line_vpos));
else if (XFASTINT (w->window_end_vpos) == this_line_vpos
&& this_line_vpos > 0)
wset_window_end_vpos (w, make_number (this_line_vpos - 1));
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
/* Update hint: No need to try to scroll in update_window. */
w->desired_matrix->no_scrolling_p = 1;
/* Make sure the cursor was last displayed
in this window. Otherwise we have to reposition it. */
&& 0 <= w->cursor.vpos
- && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
+ && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
{
if (!must_finish)
{
&& (EQ (selected_window,
BVAR (current_buffer, last_selected_window))
|| highlight_nonselected_windows)
- && NILP (w->region_showing)
+ && !w->region_showing
&& NILP (Vshow_trailing_whitespace)
&& !cursor_in_echo_area)
{
Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
struct frame *mini_frame;
- displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
+ displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
/* Use list_of_error, not Qerror, so that
we catch only errors and don't run the debugger. */
internal_condition_case_1 (redisplay_window_1, selected_window,
{
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;
}
-/* Mark the display of window W as accurate or inaccurate. If
- ACCURATE_P is non-zero mark display of W as accurate. If
- ACCURATE_P is zero, arrange for W to be redisplayed the next time
- redisplay_internal is called. */
+/* Mark the display of leaf window W as accurate or inaccurate.
+ If ACCURATE_P is non-zero mark display of W as accurate. If
+ ACCURATE_P is zero, arrange for W to be redisplayed the next
+ time redisplay_internal is called. */
static void
mark_window_display_accurate_1 (struct window *w, int accurate_p)
{
- if (BUFFERP (w->buffer))
- {
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
- w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
- w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
- w->last_had_star
- = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
+ w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
+ w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
+ w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
- if (accurate_p)
- {
- b->clip_changed = 0;
- b->prevent_redisplay_optimizations_p = 0;
+ if (accurate_p)
+ {
+ b->clip_changed = 0;
+ b->prevent_redisplay_optimizations_p = 0;
- BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
- BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
- BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
- BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
+ BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
+ BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
+ BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
+ BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
- w->current_matrix->buffer = b;
- w->current_matrix->begv = BUF_BEGV (b);
- w->current_matrix->zv = BUF_ZV (b);
+ w->current_matrix->buffer = b;
+ w->current_matrix->begv = BUF_BEGV (b);
+ w->current_matrix->zv = BUF_ZV (b);
- w->last_cursor = w->cursor;
- w->last_cursor_off_p = w->cursor_off_p;
+ w->last_cursor = w->cursor;
+ w->last_cursor_off_p = w->cursor_off_p;
- if (w == XWINDOW (selected_window))
- w->last_point = BUF_PT (b);
- else
- w->last_point = marker_position (w->pointm);
- }
- }
+ if (w == XWINDOW (selected_window))
+ w->last_point = BUF_PT (b);
+ else
+ w->last_point = marker_position (w->pointm);
- if (accurate_p)
- {
- wset_window_end_valid (w, w->buffer);
+ w->window_end_valid = 1;
w->update_mode_line = 0;
}
}
for (; !NILP (window); window = w->next)
{
w = XWINDOW (window);
- mark_window_display_accurate_1 (w, accurate_p);
-
- if (!NILP (w->vchild))
- mark_window_display_accurate (w->vchild, accurate_p);
- if (!NILP (w->hchild))
- mark_window_display_accurate (w->hchild, accurate_p);
+ if (WINDOWP (w->contents))
+ mark_window_display_accurate (w->contents, accurate_p);
+ else
+ mark_window_display_accurate_1 (w, accurate_p);
}
if (accurate_p)
- {
- update_overlay_arrows (1);
- }
+ update_overlay_arrows (1);
else
- {
- /* Force a thorough redisplay the next time by setting
- last_arrow_position and last_arrow_string to t, which is
- unequal to any useful value of Voverlay_arrow_... */
- update_overlay_arrows (-1);
- }
+ /* Force a thorough redisplay the next time by setting
+ last_arrow_position and last_arrow_string to t, which is
+ unequal to any useful value of Voverlay_arrow_... */
+ update_overlay_arrows (-1);
}
{
struct window *w = XWINDOW (window);
- if (!NILP (w->hchild))
- redisplay_windows (w->hchild);
- else if (!NILP (w->vchild))
- redisplay_windows (w->vchild);
- else if (!NILP (w->buffer))
+ if (WINDOWP (w->contents))
+ redisplay_windows (w->contents);
+ else if (BUFFERP (w->contents))
{
- displayed_buffer = XBUFFER (w->buffer);
+ displayed_buffer = XBUFFER (w->contents);
/* Use list_of_error, not Qerror, so that
we catch only errors and don't run the debugger. */
internal_condition_case_1 (redisplay_window_0, window,
/* Skip over glyphs not having an object at the start and the end of
the row. These are special glyphs like truncation marks on
terminal frames. */
- if (row->displays_text_p)
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
{
if (!row->reversed_p)
{
CHARPOS is zero or negative. */
int empty_line_p =
(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
- && INTEGERP (glyph->object) && glyph->charpos > 0;
+ && INTEGERP (glyph->object) && glyph->charpos > 0
+ /* On a TTY, continued and truncated rows also have a glyph at
+ their end whose OBJECT is zero and whose CHARPOS is
+ positive (the continuation and truncation glyphs), but such
+ rows are obviously not "empty". */
+ && !(row->continued_p || row->truncated_on_right_p);
if (row->ends_in_ellipsis_p && pos_after == last_pos)
{
&& !MATRIX_ROW_CONTINUATION_LINE_P (row)
&& row->x == 0)
{
- this_line_buffer = XBUFFER (w->buffer);
+ this_line_buffer = XBUFFER (w->contents);
CHARPOS (this_line_start_pos)
= MATRIX_ROW_START_CHARPOS (row) + delta;
struct window *w = XWINDOW (window);
SET_MARKER_FROM_TEXT_POS (w->start, startp);
- if (current_buffer != XBUFFER (w->buffer))
+ if (current_buffer != XBUFFER (w->contents))
emacs_abort ();
if (!NILP (Vwindow_scroll_functions))
make_number (CHARPOS (startp)));
SET_TEXT_POS_FROM_MARKER (startp, w->start);
/* In case the hook functions switch buffers. */
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
return startp;
else
{
struct text_pos scroll_margin_pos = startp;
+ int y_offset = 0;
/* See if point is inside the scroll margin at the top of the
window. */
if (this_scroll_margin)
{
+ int y_start;
+
start_display (&it, w, startp);
+ y_start = it.current_y;
move_it_vertically (&it, this_scroll_margin);
scroll_margin_pos = it.current.pos;
+ /* If we didn't move enough before hitting ZV, request
+ additional amount of scroll, to move point out of the
+ scroll margin. */
+ if (IT_CHARPOS (it) == ZV
+ && it.current_y - y_start < this_scroll_margin)
+ y_offset = this_scroll_margin - (it.current_y - y_start);
}
if (PT < CHARPOS (scroll_margin_pos))
|| IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
return SCROLLING_FAILED;
+ /* Additional scroll for when ZV was too close to point. */
+ dy += y_offset;
+
/* Compute new window start. */
start_display (&it, w, startp);
if (!just_this_one_p
|| current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp))
- wset_base_line_number (w, Qnil);
+ w->base_line_number = 0;
/* If cursor ends up on a partially visible line,
treat that as being off the bottom of the screen. */
SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
/* Find the start of the continued line. This should be fast
- because scan_buffer is fast (newline cache). */
+ because find_newline is fast (newline cache). */
row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
row, DEFAULT_FACE_ID);
region exists, cursor movement has to do more than just
set the cursor. */
&& markpos_of_region () < 0
- && NILP (w->region_showing)
+ && !w->region_showing
&& NILP (Vshow_trailing_whitespace)
/* This code is not used for mini-buffer for the sake of the case
of redisplaying to replace an echo area message; since in
we would rather display cursor in the next line. */
while (MATRIX_ROW_BOTTOM_Y (row) < last_y
&& MATRIX_ROW_END_CHARPOS (row) == PT
- && row < w->current_matrix->rows
- + w->current_matrix->nrows - 1
+ && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
&& MATRIX_ROW_START_CHARPOS (row+1) == PT
&& !cursor_row_p (row))
++row;
must_scroll = 1;
}
else if (rc != CURSOR_MOVEMENT_SUCCESS
- && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
struct glyph_row *row1;
else if (scroll_p)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
else if (rc != CURSOR_MOVEMENT_SUCCESS
- && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
/* With bidi-reordered rows, there could be more than
one candidate row whose start and end positions
|| (w == XWINDOW (minibuf_window)
&& NILP (echo_area_buffer[0])))
{
- struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *buf = XBUFFER (w->contents);
whole = BUF_ZV (buf) - BUF_BEGV (buf);
start = marker_position (w->start) - BUF_BEGV (buf);
/* I don't think this is guaranteed to be right. For the
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
struct buffer *old = current_buffer;
struct text_pos lpoint, opoint, startp;
int update_mode_line;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
- /* W must be a leaf window here. */
- eassert (!NILP (w->buffer));
#ifdef GLYPH_DEBUG
*w->desired_matrix->method = 0;
#endif
+ /* Make sure that both W's markers are valid. */
+ eassert (XMARKER (w->start)->buffer == buffer);
+ eassert (XMARKER (w->pointm)->buffer == buffer);
+
restart:
reconsider_clip_changes (w, buffer);
else if ((w != XWINDOW (minibuf_window)
|| minibuf_level == 0)
/* When buffer is nonempty, redisplay window normally. */
- && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
+ && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
/* Quail displays non-mini buffers in minibuffer window.
In that case, redisplay the window normally. */
- && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
+ && !NILP (Fmemq (w->contents, Vminibuffer_list)))
{
/* W is a mini-buffer window, but it's not active, so clear
it. */
value. */
/* Really select the buffer, for the sake of buffer-local
variables. */
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
current_matrix_up_to_date_p
- = (!NILP (w->window_end_valid)
+ = (w->window_end_valid
&& !current_buffer->clip_changed
&& !current_buffer->prevent_redisplay_optimizations_p
&& !window_outdated (w));
specbind (Qinhibit_point_motion_hooks, Qt);
buffer_unchanged_p
- = (!NILP (w->window_end_valid)
+ = (w->window_end_valid
&& !current_buffer->clip_changed
&& !window_outdated (w));
if (XMARKER (w->start)->buffer == current_buffer)
compute_window_start_on_continuation_line (w);
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
}
/* Some sanity checks. */
w->force_start = 0;
w->vscroll = 0;
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
/* Forget any recorded base line for line number display. */
if (!buffer_unchanged_p)
- wset_base_line_number (w, Qnil);
+ w->base_line_number = 0;
/* Redisplay the mode line. Select the buffer properly for that.
Also, run the hook window-scroll-functions
/* If we are highlighting the region, then we just changed
the region, so redisplay to show it. */
- if (0 <= markpos_of_region ())
+ if (markpos_of_region () >= 0)
{
clear_glyph_matrix (w->desired_matrix);
if (!try_window (window, startp, 0))
|| current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp))
/* Forget any recorded base line for line number display. */
- wset_base_line_number (w, Qnil);
+ w->base_line_number = 0;
if (!cursor_row_fully_visible_p (w, 1, 0))
{
debug_method_add (w, "recenter");
#endif
- /* w->vscroll = 0; */
-
/* Forget any previously recorded base line for line number display. */
if (!buffer_unchanged_p)
- wset_base_line_number (w, Qnil);
+ w->base_line_number = 0;
/* Determine the window start relative to point. */
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
line.) */
if (w->cursor.vpos < 0)
{
- if (!NILP (w->window_end_valid)
- && PT >= Z - XFASTINT (w->window_end_pos))
+ if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
{
clear_glyph_matrix (w->desired_matrix);
move_it_by_lines (&it, 1);
&& !FRAME_WINDOW_P (f)
&& !WINDOW_FULL_WIDTH_P (w))
/* Line number to display. */
- || INTEGERP (w->base_line_pos)
+ || w->base_line_pos > 0
/* Column number is displayed and different from the one displayed. */
- || (!NILP (w->column_number_displayed)
- && (XFASTINT (w->column_number_displayed) != current_column ())))
+ || (w->column_number_displayed != -1
+ && (w->column_number_displayed != current_column ())))
/* This means that the window has a mode line. */
&& (WINDOW_WANTS_MODELINE_P (w)
|| WINDOW_WANTS_HEADER_LINE_P (w)))
goto need_larger_matrices;
}
- if (!line_number_displayed
- && !BUFFERP (w->base_line_pos))
+ if (!line_number_displayed && w->base_line_pos != -1)
{
- wset_base_line_pos (w, Qnil);
- wset_base_line_number (w, Qnil);
+ w->base_line_pos = 0;
+ w->base_line_number = 0;
}
finish_menu_bars:
wset_window_end_vpos
(w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
eassert
- (MATRIX_ROW (w->desired_matrix,
- XFASTINT (w->window_end_vpos))->displays_text_p);
+ (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
+ XFASTINT (w->window_end_vpos))));
}
else
{
}
/* But that is not valid info until redisplay finishes. */
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
return 1;
}
return 0;
/* Can't do this if region may have changed. */
- if (0 <= markpos_of_region ()
- || !NILP (w->region_showing)
+ if (markpos_of_region () >= 0
+ || w->region_showing
|| !NILP (Vshow_trailing_whitespace))
return 0;
wset_window_end_pos (w, make_number (Z - ZV));
wset_window_end_vpos (w, make_number (0));
}
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
/* Update hint: don't try scrolling again in update_window. */
w->desired_matrix->no_scrolling_p = 1;
bidi-reordered glyph rows. Let set_cursor_from_row
figure out where to put the cursor, and if it fails,
give up. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
if (!set_cursor_from_row (w, row, w->current_matrix,
0, 0, 0, 0))
(w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
}
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
w->desired_matrix->no_scrolling_p = 1;
#ifdef GLYPH_DEBUG
/* Display must not have been paused, otherwise the current matrix
is not up to date. */
- eassert (!NILP (w->window_end_valid));
+ eassert (w->window_end_valid);
/* A value of window_end_pos >= END_UNCHANGED means that the window
end is in the range of changed text. If so, there is no
/* Preconditions: W must be a leaf window and full-width. Its frame
must have a frame matrix. */
- eassert (NILP (w->hchild) && NILP (w->vchild));
+ eassert (BUFFERP (w->contents));
eassert (WINDOW_FULL_WIDTH_P (w));
eassert (!FRAME_WINDOW_P (f));
{
struct glyph_row *row = start;
struct glyph_row *best_row = NULL;
- ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
+ ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
int last_y;
/* If we happen to start on a header-line, skip that. */
|| (MATRIX_ROW_END_CHARPOS (row) == charpos
/* The end position of a row equals the start
position of the next row. If CHARPOS is there, we
- would rather display it in the next line, except
- when this line ends in ZV. */
- && !row->ends_at_zv_p
- && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
+ would rather consider it displayed in the next
+ line, except when this line ends in ZV. */
+ && !row_for_charpos_p (row, charpos)))
&& charpos >= MATRIX_ROW_START_CHARPOS (row))
{
struct glyph *g;
- if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
+ if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
|| (!best_row && !row->continued_p))
return row;
- /* In bidi-reordered rows, there could be several rows
- occluding point, all of them belonging to the same
- continued line. We need to find the row which fits
- CHARPOS the best. */
+ /* In bidi-reordered rows, there could be several rows whose
+ edges surround CHARPOS, all of these rows belonging to
+ the same continued line. We need to find the row which
+ fits CHARPOS the best. */
for (g = row->glyphs[TEXT_AREA];
g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
g++)
/* Try to redisplay window W by reusing its existing display. W's
current matrix must be up to date when this function is called,
- i.e. window_end_valid must not be nil.
+ i.e. window_end_valid must be nonzero.
Value is
GIVE_UP (7);
/* Verify that display wasn't paused. */
- if (NILP (w->window_end_valid))
+ if (!w->window_end_valid)
GIVE_UP (8);
/* Can't use this if highlighting a region because a cursor movement
will do more than just set the cursor. */
- if (0 <= markpos_of_region ())
+ if (markpos_of_region () >= 0)
GIVE_UP (9);
/* Likewise if highlighting trailing whitespace. */
GIVE_UP (11);
/* Likewise if showing a region. */
- if (!NILP (w->region_showing))
+ if (w->region_showing)
GIVE_UP (10);
/* Can't use this if overlay arrow position and/or string have
wrapped line can change the wrap position, altering the line
above it. It might be worthwhile to handle this more
intelligently, but for now just redisplay from scratch. */
- if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
+ if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
GIVE_UP (21);
/* Under bidi reordering, adding or deleting a character in the
to find the paragraph limits and widen the range of redisplayed
lines to that, but for now just give up this optimization and
redisplay from scratch. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
- && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
+ && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
GIVE_UP (22);
/* Make sure beg_unchanged and end_unchanged are up to date. Do it
struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
/* If last_row is the window end line, it should display text. */
- eassert (last_row->displays_text_p);
+ eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
/* If window end line was partially visible before, begin
displaying at that line. Otherwise begin displaying with the
matrix. Set row to the last row displaying text in current
matrix starting at first_unchanged_at_end_row, after
scrolling. */
- eassert (first_unchanged_at_end_row->displays_text_p);
+ eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
row = find_last_row_displaying_text (w->current_matrix, &it,
first_unchanged_at_end_row);
eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
{
if (desired_row->enabled_p)
{
- if (desired_row->displays_text_p)
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
row = desired_row;
}
- else if (current_row->displays_text_p)
+ else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
row = current_row;
}
debug_end_vpos = XFASTINT (w->window_end_vpos));
/* Record that display has not been completed. */
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
w->desired_matrix->no_scrolling_p = 1;
return 3;
void
dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
{
- if (glyph->type == CHAR_GLYPH)
+ if (glyph->type == CHAR_GLYPH
+ || glyph->type == GLYPHLESS_GLYPH)
{
fprintf (stderr,
- " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
- 'C',
+ (glyph->type == CHAR_GLYPH
+ ? 'C'
+ : 'G'),
glyph->charpos,
(BUFFERP (glyph->object)
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : '-')),
+ : (INTEGERP (glyph->object)
+ ? '0'
+ : '-'))),
glyph->pixel_width,
glyph->u.ch,
(glyph->u.ch < 0x80 && glyph->u.ch >= ' '
else if (glyph->type == STRETCH_GLYPH)
{
fprintf (stderr,
- " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
'S',
glyph->charpos,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : '-')),
+ : (INTEGERP (glyph->object)
+ ? '0'
+ : '-'))),
glyph->pixel_width,
0,
- '.',
+ ' ',
glyph->face_id,
glyph->left_box_line_p,
glyph->right_box_line_p);
else if (glyph->type == IMAGE_GLYPH)
{
fprintf (stderr,
- " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
'I',
glyph->charpos,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : '-')),
+ : (INTEGERP (glyph->object)
+ ? '0'
+ : '-'))),
glyph->pixel_width,
glyph->u.img_id,
'.',
else if (glyph->type == COMPOSITE_GLYPH)
{
fprintf (stderr,
- " %5td %4c %6"pI"d %c %3d 0x%05x",
+ " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
glyph - row->glyphs[TEXT_AREA],
'+',
glyph->charpos,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : '-')),
+ : (INTEGERP (glyph->object)
+ ? '0'
+ : '-'))),
glyph->pixel_width,
glyph->u.cmp.id);
if (glyph->u.cmp.automatic)
{
if (glyphs != 1)
{
- fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
- fprintf (stderr, "======================================================================\n");
+ fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
+ fprintf (stderr, "==============================================================================\n");
- fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
+ fprintf (stderr, "%3d %9"pI"d %9"pI"d %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 %4d %4d %4d %4d %4d %4d %4d\n",
vpos,
MATRIX_ROW_START_CHARPOS (row),
row->truncated_on_right_p,
row->continued_p,
MATRIX_ROW_CONTINUATION_LINE_P (row),
- row->displays_text_p,
+ MATRIX_ROW_DISPLAYS_TEXT_P (row),
row->ends_at_zv_p,
row->fill_line_p,
row->ends_in_middle_of_char_p,
row->visible_height,
row->ascent,
row->phys_ascent);
- fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index,
+ /* The next 3 lines should align to "Start" in the header. */
+ fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
row->end.overlay_string_index,
row->continuation_lines_width);
- fprintf (stderr, "%9"pI"d %5"pI"d\n",
+ fprintf (stderr, " %9"pI"d %9"pI"d\n",
CHARPOS (row->start.string_pos),
CHARPOS (row->end.string_pos));
- fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
+ fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
row->end.dpvec_index);
}
++glyph_end;
if (glyph < glyph_end)
- fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
+ fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
for (; glyph < glyph_end; ++glyph)
dump_glyph (row, glyph, area);
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
- char *s = alloca (row->used[area] + 1);
+ char *s = alloca (row->used[area] + 4);
int i;
for (i = 0; i < row->used[area]; ++i)
{
struct glyph *glyph = row->glyphs[area] + i;
- if (glyph->type == CHAR_GLYPH
- && glyph->u.ch < 0x80
- && glyph->u.ch >= ' ')
+ if (i == row->used[area] - 1
+ && area == TEXT_AREA
+ && INTEGERP (glyph->object)
+ && glyph->type == CHAR_GLYPH
+ && glyph->u.ch == ' ')
+ {
+ strcpy (&s[i], "[\\n]");
+ i += 4;
+ }
+ else if (glyph->type == CHAR_GLYPH
+ && glyph->u.ch < 0x80
+ && glyph->u.ch >= ' ')
s[i] = glyph->u.ch;
else
s[i] = '.';
(Lisp_Object glyphs)
{
struct window *w = XWINDOW (selected_window);
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
struct buffer *old = current_buffer;
const unsigned char *arrow_string = SDATA (overlay_arrow_string);
int arrow_len = SCHARS (overlay_arrow_string);
const unsigned char *arrow_end = arrow_string + arrow_len;
const unsigned char *p;
struct it it;
- int multibyte_p;
+ bool multibyte_p;
int n_glyphs_before;
set_buffer_temp (buffer);
face = FACE_FROM_ID (f, it->face_id);
if (FRAME_WINDOW_P (f)
- && it->glyph_row->displays_text_p
+ && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
&& face->box == FACE_NO_BOX
&& face->background == FRAME_BACKGROUND_PIXEL (f)
&& !face->stipple
/* Value is non-zero if glyph row ROW should be
- used to hold the cursor. */
+ considered to hold the buffer position CHARPOS. */
static int
-cursor_row_p (struct glyph_row *row)
+row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
{
int result = 1;
- if (PT == CHARPOS (row->end.pos)
- || PT == MATRIX_ROW_END_CHARPOS (row))
+ if (charpos == CHARPOS (row->end.pos)
+ || charpos == MATRIX_ROW_END_CHARPOS (row))
{
/* Suppose the row ends on a string.
Unless the row is continued, that means it ends on a newline
if (STRINGP (glyph->object))
{
Lisp_Object prop
- = Fget_char_property (make_number (PT),
+ = Fget_char_property (make_number (charpos),
Qdisplay, Qnil);
result =
(!NILP (prop)
return result;
}
+/* Value is non-zero if glyph row ROW should be
+ used to hold the cursor. */
+
+static int
+cursor_row_p (struct glyph_row *row)
+{
+ return row_for_charpos_p (row, PT);
+}
+
\f
/* Push the property PROP so that it will be rendered at the current
}
/* Is IT->w showing the region? */
- wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil);
+ it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
/* Clear the result glyph row and enable it. */
prepare_desired_row (row);
row->glyphs[TEXT_AREA]->charpos = -1;
row->displays_text_p = 0;
- if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
+ if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
&& (!MINI_WINDOW_P (it->w)
|| (minibuf_level && EQ (it->window, minibuf_window))))
row->indicate_empty_line_p = 1;
mark this glyph row as the one containing the overlay arrow.
This is clearly a mess with variable size fonts. It would be
better to let it be displayed like cursors under X. */
- if ((row->displays_text_p || !overlay_arrow_seen)
+ if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
&& (overlay_arrow_string = overlay_arrow_at_row (it, row),
!NILP (overlay_arrow_string)))
{
if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
it->glyph_row->reversed_p = row->reversed_p;
it->start = row->end;
- return row->displays_text_p;
+ return MATRIX_ROW_DISPLAYS_TEXT_P (row);
#undef RECORD_MAX_MIN_POS
}
to make sure we are within that paragraph. To that end, find
the previous non-empty line. */
if (pos >= ZV && pos > BEGV)
- {
- pos--;
- bytepos = CHAR_TO_BYTE (pos);
- }
+ DEC_BOTH (pos, bytepos);
if (fast_looking_at (build_string ("[\f\t ]*\n"),
pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
{
return;
#endif /* HAVE_NS */
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
eassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
-#else /* not USE_X_TOOLKIT */
+#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
if (FRAME_WINDOW_P (f))
{
/* Menu bar lines are displayed in the desired matrix of the
dummy window menu_bar_window. */
struct window *menu_w;
- eassert (WINDOWP (f->menu_bar_window));
menu_w = XWINDOW (f->menu_bar_window);
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
MENU_FACE_ID);
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
}
else
+#endif /* not USE_X_TOOLKIT and not USE_GTK */
{
/* This is a TTY frame, i.e. character hpos/vpos are used as
pixel x/y. */
it.first_visible_x = 0;
it.last_visible_x = FRAME_COLS (f);
}
-#endif /* not USE_X_TOOLKIT */
/* FIXME: This should be controlled by a user option. See the
comments in redisplay_tool_bar and display_mode_line about
{
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);
+ if (WINDOWP (w->contents))
+ nwindows += redisplay_mode_lines (w->contents, force);
else if (force
|| FRAME_GARBAGED_P (XFRAME (w->frame))
|| !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
/* Set the window's buffer for the mode line display. */
SET_TEXT_POS (lpoint, PT, PT_BYTE);
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
/* Point refers normally to the selected window. For any
other window, set up appropriate value. */
/* These will be set while the mode line specs are processed. */
line_number_displayed = 0;
- wset_column_number_displayed (w, Qnil);
+ w->column_number_displayed = -1;
if (WINDOW_WANTS_MODELINE_P (w))
{
risky);
else if (c != 0)
{
- int multibyte;
+ bool multibyte;
ptrdiff_t bytepos, charpos;
const char *spec;
Lisp_Object string;
XSETWINDOW (window, w);
if (NILP (buffer))
- buffer = w->buffer;
+ buffer = w->contents;
CHECK_BUFFER (buffer);
/* Make formatting the modeline a non-op when noninteractive, otherwise
char * psuffix;
char * p;
- if (1000 <= quotient)
+ if (quotient >= 1000)
{
/* Scale to the appropriate EXPONENT. */
do
quotient /= 1000;
exponent++;
}
- while (1000 <= quotient);
+ while (quotient >= 1000);
/* Round to nearest and decide whether to use TENTHS or not. */
if (quotient <= 9)
{
tenths = remainder / 100;
- if (50 <= remainder % 100)
+ if (remainder % 100 >= 50)
{
if (tenths < 9)
tenths++;
}
}
else
- if (500 <= remainder)
+ if (remainder >= 500)
{
if (quotient < 999)
quotient++;
decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
{
Lisp_Object val;
- int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
+ bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
const unsigned char *eol_str;
int eol_str_len;
/* The EOL conversion we are using. */
returned with spaces to that value. Return a Lisp string in
*STRING if the resulting string is taken from that Lisp string.
- Note we operate on the current buffer for most purposes,
- the exception being w->base_line_pos. */
+ Note we operate on the current buffer for most purposes. */
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
else
{
ptrdiff_t col = current_column ();
- wset_column_number_displayed (w, make_number (col));
+ w->column_number_displayed = col;
pint2str (decode_mode_spec_buf, width, col);
return decode_mode_spec_buf;
}
/* If we decided that this buffer isn't suitable for line numbers,
don't forget that too fast. */
- if (EQ (w->base_line_pos, w->buffer))
+ if (w->base_line_pos == -1)
goto no_value;
- /* But do forget it, if the window shows a different buffer now. */
- else if (BUFFERP (w->base_line_pos))
- wset_base_line_pos (w, Qnil);
/* If the buffer is very big, don't waste time. */
if (INTEGERP (Vline_number_display_limit)
&& BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
{
- wset_base_line_pos (w, Qnil);
- wset_base_line_number (w, Qnil);
+ w->base_line_pos = 0;
+ w->base_line_number = 0;
goto no_value;
}
- if (INTEGERP (w->base_line_number)
- && INTEGERP (w->base_line_pos)
- && XFASTINT (w->base_line_pos) <= startpos)
+ if (w->base_line_number > 0
+ && w->base_line_pos > 0
+ && w->base_line_pos <= startpos)
{
- line = XFASTINT (w->base_line_number);
- linepos = XFASTINT (w->base_line_pos);
+ line = w->base_line_number;
+ linepos = w->base_line_pos;
linepos_byte = buf_charpos_to_bytepos (b, linepos);
}
else
go back past it. */
if (startpos == BUF_BEGV (b))
{
- wset_base_line_number (w, make_number (topline));
- wset_base_line_pos (w, make_number (BUF_BEGV (b)));
+ w->base_line_number = topline;
+ w->base_line_pos = BUF_BEGV (b);
}
else if (nlines < height + 25 || nlines > height * 3 + 50
|| linepos == BUF_BEGV (b))
give up on line numbers for this window. */
if (position == limit_byte && limit == startpos - distance)
{
- wset_base_line_pos (w, w->buffer);
- wset_base_line_number (w, Qnil);
+ w->base_line_pos = -1;
+ w->base_line_number = 0;
goto no_value;
}
- wset_base_line_number (w, make_number (topline - nlines));
- wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position)));
+ w->base_line_number = topline - nlines;
+ w->base_line_pos = BYTE_TO_CHAR (position);
}
/* Now count lines from the start pos to point. */
return "@";
}
- case 't': /* indicate TEXT or BINARY */
- return "T";
-
case 'z':
/* coding-system (not including end-of-line format) */
case 'Z':
}
-/* Count up to COUNT lines starting from START_BYTE.
- But don't go beyond LIMIT_BYTE.
- Return the number of lines thus found (always nonnegative).
+/* Count up to COUNT lines starting from START_BYTE. COUNT negative
+ means count lines back from START_BYTE. But don't go beyond
+ LIMIT_BYTE. Return the number of lines thus found (always
+ nonnegative).
- Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
+ Set *BYTE_POS_PTR to the byte position where we stopped. This is
+ either the position COUNT lines after/before START_BYTE, if we
+ found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
+ COUNT lines. */
static ptrdiff_t
display_count_lines (ptrdiff_t start_byte,
ceiling = min (limit_byte - 1, ceiling);
ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
base = (cursor = BYTE_POS_ADDR (start_byte));
- while (1)
+
+ do
{
if (selective_display)
- while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
- ;
+ {
+ while (*cursor != '\n' && *cursor != 015
+ && ++cursor != ceiling_addr)
+ continue;
+ if (cursor == ceiling_addr)
+ break;
+ }
else
- while (*cursor != '\n' && ++cursor != ceiling_addr)
- ;
+ {
+ cursor = memchr (cursor, '\n', ceiling_addr - cursor);
+ if (! cursor)
+ break;
+ }
- if (cursor != ceiling_addr)
+ cursor++;
+
+ if (--count == 0)
{
- if (--count == 0)
- {
- start_byte += cursor - base + 1;
- *byte_pos_ptr = start_byte;
- return orig_count;
- }
- else
- if (++cursor == ceiling_addr)
- break;
+ start_byte += cursor - base;
+ *byte_pos_ptr = start_byte;
+ return orig_count;
}
- else
- break;
}
- start_byte += cursor - base;
+ while (cursor < ceiling_addr);
+
+ start_byte += ceiling_addr - base;
}
}
else
{
ceiling = BUFFER_FLOOR_OF (start_byte - 1);
ceiling = max (limit_byte, ceiling);
- ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
+ ceiling_addr = BYTE_POS_ADDR (ceiling);
base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
while (1)
{
if (selective_display)
- while (--cursor != ceiling_addr
- && *cursor != '\n' && *cursor != 015)
- ;
+ {
+ while (--cursor >= ceiling_addr
+ && *cursor != '\n' && *cursor != 015)
+ continue;
+ if (cursor < ceiling_addr)
+ break;
+ }
else
- while (--cursor != ceiling_addr && *cursor != '\n')
- ;
+ {
+ cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
+ if (! cursor)
+ break;
+ }
- if (cursor != ceiling_addr)
+ if (++count == 0)
{
- if (++count == 0)
- {
- start_byte += cursor - base + 1;
- *byte_pos_ptr = start_byte;
- /* When scanning backwards, we should
- not count the newline posterior to which we stop. */
- return - orig_count - 1;
- }
+ start_byte += cursor - base + 1;
+ *byte_pos_ptr = start_byte;
+ /* When scanning backwards, we should
+ not count the newline posterior to which we stop. */
+ return - orig_count - 1;
}
- else
- break;
}
- /* Here we add 1 to compensate for the last decrement
- of CURSOR, which took it past the valid range. */
- start_byte += cursor - base + 1;
+ start_byte += ceiling_addr - base;
}
}
*/
-#define NUMVAL(X) \
- ((INTEGERP (X) || FLOATP (X)) \
- ? XFLOATINT (X) \
- : - 1)
-
static int
calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
struct font *font, int width_p, int *align_to)
pixels = 0;
if (pixels > 0)
{
- double ppi;
-#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (it->f)
- && (ppi = (width_p
- ? FRAME_X_DISPLAY_INFO (it->f)->resx
- : FRAME_X_DISPLAY_INFO (it->f)->resy),
- ppi > 0))
- return OK_PIXELS (ppi / pixels);
-#endif
+ double ppi = (width_p ? FRAME_RES_X (it->f)
+ : FRAME_RES_Y (it->f));
- if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
- || (CONSP (Vdisplay_pixels_per_inch)
- && (ppi = (width_p
- ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
- : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
- ppi > 0)))
+ if (ppi > 0)
return OK_PIXELS (ppi / pixels);
-
return 0;
}
}
return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
}
- prop = buffer_local_value_1 (prop, it->w->buffer);
+ prop = buffer_local_value_1 (prop, it->w->contents);
if (EQ (prop, Qunbound))
prop = Qnil;
}
return OK_PIXELS (pixels);
}
- car = buffer_local_value_1 (car, it->w->buffer);
+ car = buffer_local_value_1 (car, it->w->contents);
if (EQ (car, Qunbound))
car = Qnil;
}
XChar2b *char2b, int display_p)
{
struct face *face = FACE_FROM_ID (f, face_id);
+ unsigned code = 0;
if (face->font)
{
- unsigned code = face->font->driver->encode_char (face->font, c);
+ code = face->font->driver->encode_char (face->font, c);
- if (code != FONT_INVALID_CODE)
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- else
- STORE_XCHAR2B (char2b, 0, 0);
+ if (code == FONT_INVALID_CODE)
+ code = 0;
}
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
/* Make sure X resources of the face are allocated. */
#ifdef HAVE_X_WINDOWS
XChar2b *char2b, int *two_byte_p)
{
struct face *face;
+ unsigned code = 0;
eassert (glyph->type == CHAR_GLYPH);
face = FACE_FROM_ID (f, glyph->face_id);
+ /* Make sure X resources of the face are allocated. */
+ eassert (face != NULL);
+ PREPARE_FACE_FOR_DISPLAY (f, face);
+
if (two_byte_p)
*two_byte_p = 0;
if (face->font)
{
- unsigned code;
-
if (CHAR_BYTE8_P (glyph->u.ch))
code = CHAR_TO_BYTE8 (glyph->u.ch);
else
code = face->font->driver->encode_char (face->font, glyph->u.ch);
- if (code != FONT_INVALID_CODE)
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- else
- STORE_XCHAR2B (char2b, 0, 0);
+ if (code == FONT_INVALID_CODE)
+ code = 0;
}
- /* Make sure X resources of the face are allocated. */
- eassert (face != NULL);
- PREPARE_FACE_FOR_DISPLAY (f, face);
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
return face;
}
get_per_char_metric (struct font *font, XChar2b *char2b)
{
static struct font_metrics metrics;
- unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+ unsigned code;
- if (! font || code == FONT_INVALID_CODE)
+ if (! font)
+ return NULL;
+ code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+ if (code == FONT_INVALID_CODE)
return NULL;
font->driver->text_extents (font, &code, 1, &metrics);
return &metrics;
int n = width;
if (!STRINGP (object))
- object = it->w->buffer;
+ object = it->w->contents;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (it->f))
append_stretch_glyph (it, object, width, height, ascent);
int *active_cursor)
{
struct frame *f = XFRAME (w->frame);
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
int cursor_type = DEFAULT_CURSOR;
Lisp_Object alt_cursor;
int non_selected = 0;
if (w->phys_cursor.vpos < 0
|| w->phys_cursor.vpos >= w->current_matrix->nrows
|| (row = w->current_matrix->rows + w->phys_cursor.vpos,
- !(row->enabled_p && row->displays_text_p)))
+ !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
return;
if (row->cursor_in_fringe_p)
{
while (w)
{
- if (!NILP (w->hchild))
- update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
- else if (!NILP (w->vchild))
- update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
+ if (WINDOWP (w->contents))
+ update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
else
update_window_cursor (w, on_p);
x = r1->x;
/* Skip truncation glyphs at the start of the glyph row. */
- if (r1->displays_text_p)
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
for (; glyph < end
&& INTEGERP (glyph->object)
&& glyph->charpos < 0;
glyph = end + r1->used[TEXT_AREA];
/* Skip truncation glyphs at the start of the glyph row. */
- if (r1->displays_text_p)
+ if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
for (; glyph > end
&& INTEGERP (glyph->object)
&& glyph->charpos < 0;
}
*y = best_row->y;
- *vpos = best_row - w->current_matrix->rows;
+ *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
}
return best_glyph != NULL;
if (EQ (g->object, object)
&& startpos <= g->charpos && g->charpos <= endpos)
{
- hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+ hlinfo->mouse_face_beg_row
+ = MATRIX_ROW_VPOS (r, w->current_matrix);
hlinfo->mouse_face_beg_y = r->y;
hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
hlinfo->mouse_face_beg_x = gx;
if (EQ ((g-1)->object, object)
&& startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
{
- hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+ hlinfo->mouse_face_beg_row
+ = MATRIX_ROW_VPOS (r, w->current_matrix);
hlinfo->mouse_face_beg_y = r->y;
hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
r--;
/* Set the end row and its vertical pixel coordinate. */
- hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
+ hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
hlinfo->mouse_face_end_y = r->y;
/* Compute and set the end column and the end column's horizontal
{
help_echo_string = help;
XSETWINDOW (help_echo_window, w);
- help_echo_object = w->buffer;
+ help_echo_object = w->contents;
help_echo_pos = charpos;
}
}
{
Lisp_Object default_help
= buffer_local_value_1 (Qmode_line_default_help_echo,
- w->buffer);
+ w->contents);
if (STRINGP (default_help))
{
/* Are we in a window whose display is up to date?
And verify the buffer's text has not changed. */
- b = XBUFFER (w->buffer);
+ b = XBUFFER (w->contents);
if (part == ON_TEXT
- && EQ (w->window_end_valid, w->buffer)
+ && w->window_end_valid
&& w->last_modified == BUF_MODIFF (b)
&& w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
{
/* Clear mouse face if X/Y not over text. */
if (glyph == NULL
|| area != TEXT_AREA
- || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
+ || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
/* Glyph's OBJECT is an integer for glyphs inserted by the
display engine for its internal purposes, like truncation
and continuation glyphs and blanks beyond the end of
all beyond the end of text. Treat such stretch glyphs
like we do with NULL glyphs in L2R rows. */
|| (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
- && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
+ && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
&& glyph->type == STRETCH_GLYPH
&& glyph->avoid_cursor_p))
{
if (pos > 0)
{
mouse_face = get_char_property_and_overlay
- (make_number (pos), Qmouse_face, w->buffer, &overlay);
- buffer = w->buffer;
+ (make_number (pos), Qmouse_face, w->contents, &overlay);
+ buffer = w->contents;
disp_string = object;
}
}
if (p > 0)
{
help = Fget_char_property (make_number (p),
- Qhelp_echo, w->buffer);
+ Qhelp_echo, w->contents);
if (!NILP (help))
{
charpos = p;
- obj = w->buffer;
+ obj = w->contents;
}
}
}
ptrdiff_t p = string_buffer_position (obj, start);
if (p > 0)
pointer = Fget_char_property (make_number (p),
- Qpointer, w->buffer);
+ Qpointer, w->contents);
}
}
else if (BUFFERP (obj)
if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
return;
+ /* Note: It is necessary to redraw both the left and the right
+ borders, for when only this single window W is being
+ redisplayed. */
if (!WINDOW_RIGHTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
{
FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
}
- else if (!WINDOW_LEFTMOST_P (w)
- && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ if (!WINDOW_LEFTMOST_P (w)
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
{
int x0, x1, y0, y1;
while (w && !FRAME_GARBAGED_P (f))
{
- if (!NILP (w->hchild))
- mouse_face_overwritten_p
- |= expose_window_tree (XWINDOW (w->hchild), r);
- else if (!NILP (w->vchild))
+ if (WINDOWP (w->contents))
mouse_face_overwritten_p
- |= expose_window_tree (XWINDOW (w->vchild), r);
+ |= expose_window_tree (XWINDOW (w->contents), r);
else
mouse_face_overwritten_p |= expose_window (w, r);
#ifdef HAVE_X_WINDOWS
#ifndef MSDOS
-#ifndef USE_X_TOOLKIT
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (WINDOWP (f->menu_bar_window))
mouse_face_overwritten_p
|= expose_window (XWINDOW (f->menu_bar_window), &r);
-#endif /* not USE_X_TOOLKIT */
+#endif /* not USE_X_TOOLKIT and not USE_GTK */
#endif
#endif
echo_area_window = minibuf_window;
- wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
- wset_total_lines
- (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
- wset_total_cols (r, make_number (FRAME_COLS (f)));
- wset_top_line (m, make_number (FRAME_LINES (f) - 1));
- wset_total_lines (m, make_number (1));
- wset_total_cols (m, make_number (FRAME_COLS (f)));
+ r->top_line = FRAME_TOP_MARGIN (f);
+ r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->total_cols = FRAME_COLS (f);
+
+ m->top_line = FRAME_LINES (f) - 1;
+ m->total_lines = 1;
+ m->total_cols = FRAME_COLS (f);
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]