still left to right, i.e. the iterator "thinks" the first character
is at the leftmost pixel position. The iterator does not know that
PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
- delivers. This is important when functions from the the move_it_*
+ delivers. This is important when functions from the move_it_*
family are used to get to certain screen position or to match
screen coordinates with buffer coordinates: these functions use the
iterator geometry, which is left to right even in R2L paragraphs.
#define TEXT_PROP_DISTANCE_LIMIT 100
+/* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
+ iterator state and later restore it. This is needed because the
+ bidi iterator on bidi.c keeps a stacked cache of its states, which
+ is really a singleton. When we use scratch iterator objects to
+ move around the buffer, we can cause the bidi cache to be pushed or
+ popped, and therefore we need to restore the cache state when we
+ return to the original iterator. */
+#define SAVE_IT(ITCOPY,ITORIG,CACHE) \
+ do { \
+ if (CACHE) \
+ xfree (CACHE); \
+ ITCOPY = ITORIG; \
+ CACHE = bidi_shelve_cache(); \
+ } while (0)
+
+#define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
+ do { \
+ if (pITORIG != pITCOPY) \
+ *(pITORIG) = *(pITCOPY); \
+ bidi_unshelve_cache (CACHE); \
+ CACHE = NULL; \
+ } while (0)
+
#if GLYPH_DEBUG
/* Non-zero means print traces of redisplay if compiled with
static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
static int trailing_whitespace_p (EMACS_INT);
-static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
+static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
static void push_it (struct it *, struct text_pos *);
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
This is the height of W minus the height of a mode line, if any. */
-INLINE int
+inline int
window_text_bottom_y (struct window *w)
{
int height = WINDOW_TOTAL_HEIGHT (w);
means return the total width of W, not including fringes to
the left and right of the window. */
-INLINE int
+inline int
window_box_width (struct window *w, int area)
{
int cols = XFASTINT (w->total_cols);
/* Return the pixel height of the display area of window W, not
including mode lines of W, if any. */
-INLINE int
+inline int
window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left_offset (struct window *w, int area)
{
int x;
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right_offset (struct window *w, int area)
{
return window_box_left_offset (w, area) + window_box_width (w, area);
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left (struct window *w, int area)
{
struct frame *f = XFRAME (w->frame);
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right (struct window *w, int area)
{
return window_box_left (w, area) + window_box_width (w, area);
coordinates of the upper-left corner of the box. Return in
*BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
-INLINE void
+inline void
window_box (struct window *w, int area, int *box_x, int *box_y,
int *box_width, int *box_height)
{
*BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
box. */
-static INLINE void
+static inline void
window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
int *bottom_right_x, int *bottom_right_y)
{
int *rtop, int *rbot, int *rowh, int *vpos)
{
struct it it;
+ void *itdata = bidi_shelve_cache ();
struct text_pos top;
int visible_p = 0;
struct buffer *old_buffer = NULL;
move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
(charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
- if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
+ if (charpos >= 0
+ && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
+ && IT_CHARPOS (it) >= charpos)
+ /* When scanning backwards under bidi iteration, move_it_to
+ stops at or _before_ CHARPOS, because it stops at or to
+ the _right_ of the character at CHARPOS. */
+ || (it.bidi_p && it.bidi_it.scan_dir == -1
+ && IT_CHARPOS (it) <= charpos)))
{
/* We have reached CHARPOS, or passed it. How the call to
- move_it_to can overshoot: (i) If CHARPOS is on invisible
- text, move_it_to stops at the end of the invisible text,
- after CHARPOS. (ii) If CHARPOS is in a display vector,
- move_it_to stops on its last glyph. */
+ move_it_to can overshoot: (i) If CHARPOS is on invisible text
+ or covered by a display property, move_it_to stops at the end
+ of the invisible text, to the right of CHARPOS. (ii) If
+ CHARPOS is in a display vector, move_it_to stops on its last
+ glyph. */
int top_x = it.current_x;
int top_y = it.current_y;
enum it_method it_method = it.method;
}
else
{
+ /* We were asked to provide info about WINDOW_END. */
struct it it2;
+ void *it2data = NULL;
- it2 = it;
+ SAVE_IT (it2, it, it2data);
if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
move_it_by_lines (&it, 1);
if (charpos < IT_CHARPOS (it)
|| (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
{
visible_p = 1;
+ RESTORE_IT (&it2, &it2, it2data);
move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
*x = it2.current_x;
*y = it2.current_y + it2.max_ascent - it2.ascent;
WINDOW_HEADER_LINE_HEIGHT (w))));
*vpos = it2.vpos;
}
+ else
+ xfree (it2data);
}
+ bidi_unshelve_cache (itdata);
if (old_buffer)
set_buffer_internal_1 (old_buffer);
returns an invalid character. If we find one, we return a `?', but
with the length of the invalid character. */
-static INLINE int
+static inline int
string_char_and_length (const unsigned char *str, int *len)
{
int c;
c = STRING_CHAR_AND_LENGTH (str, *len);
- if (!CHAR_VALID_P (c, 1))
+ if (!CHAR_VALID_P (c))
/* We may not change the length here because other places in Emacs
don't use this function, i.e. they silently accept invalid
characters. */
/* Value is the text position, i.e. character and byte position,
for character position CHARPOS in STRING. */
-static INLINE struct text_pos
+static inline struct text_pos
string_pos (EMACS_INT charpos, Lisp_Object string)
{
struct text_pos pos;
redisplay during the evaluation. */
Lisp_Object
-safe_call (size_t nargs, Lisp_Object *args)
+safe_call (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object val;
This is for debugging. It is too slow to do unconditionally. */
static void
-check_it (it)
- struct it *it;
+check_it (struct it *it)
{
if (it->method == GET_FROM_STRING)
{
#endif /* not 0 */
-#if GLYPH_DEBUG
+#if GLYPH_DEBUG && XASSERTS
/* Check that the window end of window W is what we expect it
to be---the last row in the current matrix displaying text. */
static void
-check_window_end (w)
- struct window *w;
+check_window_end (struct window *w)
{
if (!MINI_WINDOW_P (w)
&& !NILP (w->window_end_valid))
#define CHECK_WINDOW_END(W) check_window_end ((W))
-#else /* not GLYPH_DEBUG */
+#else
#define CHECK_WINDOW_END(W) (void) 0
-#endif /* not GLYPH_DEBUG */
+#endif
\f
is invisible. >0 means lines indented more than this value are
invisible. */
it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
- ? XFASTINT (BVAR (current_buffer, selective_display))
+ ? XINT (BVAR (current_buffer, selective_display))
: (!NILP (BVAR (current_buffer, selective_display))
? -1 : 0));
it->selective_display_ellipsis_p
else if (INTEGERP (w->redisplay_end_trigger))
it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
- /* Correct bogus values of tab_width. */
- it->tab_width = XINT (BVAR (current_buffer, tab_width));
- if (it->tab_width <= 0 || it->tab_width > 1000)
- it->tab_width = 8;
+ it->tab_width = SANE_TAB_WIDTH (current_buffer);
/* Are lines in the display truncated? */
if (base_face_id != DEFAULT_FACE_ID
it->paragraph_embedding = R2L;
else
it->paragraph_embedding = NEUTRAL_DIR;
+ bidi_unshelve_cache (NULL);
bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
&it->bidi_it);
}
{
it->ignore_overlay_strings_at_pos_p = 1;
it->string_from_display_prop_p = 0;
+ it->from_disp_prop_p = 0;
handle_overlay_change_p = 0;
}
handled = HANDLED_RECOMPUTE_PROPS;
static EMACS_INT
next_overlay_change (EMACS_INT pos)
{
- int noverlays;
+ ptrdiff_t i, noverlays;
EMACS_INT endpos;
Lisp_Object *overlays;
- int i;
/* Get all overlays at the given position. */
GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
return endpos;
}
+/* Record one cached display string position found recently by
+ compute_display_string_pos. */
+static EMACS_INT cached_disp_pos;
+static EMACS_INT cached_prev_pos = -1;
+static struct buffer *cached_disp_buffer;
+static int cached_disp_modiff;
+static int cached_disp_overlay_modiff;
+
/* Return the character position of a display string at or after
position specified by POSITION. If no display string exists at or
after POSITION, return ZV. A display string is either an overlay
EMACS_INT begb = string_p ? 0 : BEGV;
EMACS_INT bufpos, charpos = CHARPOS (*position);
struct text_pos tpos;
+ struct buffer *b;
if (charpos >= eob
/* We don't support display properties whose values are strings
|| (string->s && !STRINGP (object)))
return eob;
+ /* Check the cached values. */
+ if (!STRINGP (object))
+ {
+ if (NILP (object))
+ b = current_buffer;
+ else
+ b = XBUFFER (object);
+ if (b == cached_disp_buffer
+ && BUF_MODIFF (b) == cached_disp_modiff
+ && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff
+ && !b->clip_changed)
+ {
+ if (cached_prev_pos >= 0
+ && cached_prev_pos < charpos && charpos <= cached_disp_pos)
+ return cached_disp_pos;
+ /* Handle overstepping either end of the known interval. */
+ if (charpos > cached_disp_pos)
+ cached_prev_pos = cached_disp_pos;
+ else /* charpos <= cached_prev_pos */
+ cached_prev_pos = max (charpos - 1, 0);
+ }
+
+ /* Record new values in the cache. */
+ if (b != cached_disp_buffer)
+ {
+ cached_disp_buffer = b;
+ cached_prev_pos = max (charpos - 1, 0);
+ }
+ cached_disp_modiff = BUF_MODIFF (b);
+ cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b);
+ }
+
/* If the character at CHARPOS is where the display string begins,
return CHARPOS. */
pos = make_number (charpos);
spec))
&& handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
frame_window_p))
- return charpos;
+ {
+ if (!STRINGP (object))
+ cached_disp_pos = charpos;
+ return charpos;
+ }
/* Look forward for the first character with a `display' property
that will replace the underlying text when displayed. */
|| !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
frame_window_p));
+ if (!STRINGP (object))
+ cached_disp_pos = CHARPOS (tpos);
return CHARPOS (tpos);
}
int face_id, limit;
EMACS_INT next_check_charpos;
struct it it_copy;
+ void *it_copy_data = NULL;
xassert (it->s == NULL);
character on this display line. */
if (it->current_x <= it->first_visible_x)
return it->face_id;
- it_copy = *it;
+ SAVE_IT (it_copy, *it, it_copy_data);
/* Implementation note: Since move_it_in_display_line
works in the iterator geometry, and thinks the first
character is always the leftmost, even in R2L lines,
move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
it_copy.current_x - 1, MOVE_TO_X);
charpos = IT_STRING_CHARPOS (it_copy);
+ RESTORE_IT (it, it, it_copy_data);
}
else
{
character on this display line. */
if (it->current_x <= it->first_visible_x)
return it->face_id;
- it_copy = *it;
+ SAVE_IT (it_copy, *it, it_copy_data);
/* Implementation note: Since move_it_in_display_line
works in the iterator geometry, and thinks the first
character is always the leftmost, even in R2L lines,
move_it_in_display_line (&it_copy, ZV,
it_copy.current_x - 1, MOVE_TO_X);
pos = it_copy.current.pos;
+ RESTORE_IT (it, it, it_copy_data);
}
else
{
&& COMPOSITION_VALID_P (start, end, prop)
&& (STRINGP (it->string) || (PT <= start || PT >= end)))
{
+ if (start < pos)
+ /* As we can't handle this situation (perhaps font-lock added
+ a new composition), we just return here hoping that next
+ redisplay will detect this composition much earlier. */
+ return HANDLED_NORMALLY;
if (start != pos)
{
if (STRINGP (it->string))
static int
forward_to_next_line_start (struct it *it, int *skipped_p)
{
- int old_selective, newline_found_p, n;
+ EMACS_INT old_selective;
+ int newline_found_p, n;
const int MAX_NEWLINE_DISTANCE = 500;
/* If already on a newline, just consume it to avoid unintended
invisible. */
if (it->selective > 0
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
- (double) it->selective)) /* iftc */
+ it->selective))
continue;
/* Check the newline before point for invisibility. */
{
struct it it2;
+ void *it2data = NULL;
EMACS_INT pos;
EMACS_INT beg, end;
Lisp_Object val, overlay;
+ SAVE_IT (it2, *it, it2data);
+
/* If newline is part of a composition, continue from start of composition */
if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
&& beg < IT_CHARPOS (*it))
/* If newline is replaced by a display property, find start of overlay
or interval and continue search from that point. */
- it2 = *it;
pos = --IT_CHARPOS (it2);
--IT_BYTEPOS (it2);
it2.sp = 0;
+ bidi_unshelve_cache (NULL);
it2.string_from_display_prop_p = 0;
+ it2.from_disp_prop_p = 0;
if (handle_display_prop (&it2) == HANDLED_RETURN
&& !NILP (val = get_char_property_and_overlay
(make_number (pos), Qdisplay, Qnil, &overlay))
? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
: get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
{
- /* If the call to handle_display_prop above pushed the
- iterator state, that causes side effects for the bidi
- iterator by calling bidi_push_it. Undo those side
- effects. */
- while (it2.sp > 0)
- {
- /* push_it calls bidi_push_it only if the bidi_p flag
- is set in the iterator being pushed. */
- if (it2.stack[--it2.sp].bidi_p)
- bidi_pop_it (&it2.bidi_it);
- }
+ RESTORE_IT (it, it, it2data);
goto replaced;
}
/* Newline is not replaced by anything -- so we are done. */
+ RESTORE_IT (it, it, it2data);
break;
replaced:
if (it->selective > 0)
while (IT_CHARPOS (*it) < ZV
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
- (double) it->selective)) /* iftc */
+ it->selective))
{
xassert (IT_BYTEPOS (*it) == BEGV
|| FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
{
/* For bidi iteration, we need to prime prev_stop and
base_level_stop with our best estimations. */
- if (CHARPOS (pos) < it->prev_stop)
- {
- handle_stop_backwards (it, BEGV);
- if (CHARPOS (pos) < it->base_level_stop)
- it->base_level_stop = 0;
- }
- else if (CHARPOS (pos) > it->stop_charpos
- && it->stop_charpos >= BEGV)
- handle_stop_backwards (it, it->stop_charpos);
- else /* force_p */
- handle_stop (it);
+ /* Implementation note: Of course, POS is not necessarily a
+ stop position, so assigning prev_pos to it is a lie; we
+ should have called compute_stop_backwards. However, if
+ the current buffer does not include any R2L characters,
+ that call would be a waste of cycles, because the
+ iterator will never move back, and thus never cross this
+ "fake" stop position. So we delay that backward search
+ until the time we really need it, in next_element_from_buffer. */
+ if (CHARPOS (pos) != it->prev_stop)
+ it->prev_stop = CHARPOS (pos);
+ if (CHARPOS (pos) < it->base_level_stop)
+ it->base_level_stop = 0; /* meaning it's unknown */
+ handle_stop (it);
}
else
{
it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
it->sp = 0;
it->string_from_display_prop_p = 0;
+ it->from_disp_prop_p = 0;
it->face_before_selective_p = 0;
if (it->bidi_p)
{
- it->bidi_it.first_elt = 1;
+ bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
+ &it->bidi_it);
+ bidi_unshelve_cache (NULL);
it->bidi_it.paragraph_dir = NEUTRAL_DIR;
- it->bidi_it.disp_pos = -1;
it->bidi_it.string.s = NULL;
it->bidi_it.string.lstring = Qnil;
it->bidi_it.string.bufpos = 0;
if (it->bidi_p)
{
it->bidi_it.string.lstring = Qnil;
- it->bidi_it.string.s = s;
+ it->bidi_it.string.s = (const unsigned char *) s;
it->bidi_it.string.schars = it->end_charpos;
it->bidi_it.string.bufpos = 0;
it->bidi_it.string.from_disp_str = 0;
display. Then, set IT->dpvec to these glyphs. */
Lisp_Object gc;
int ctl_len;
- int face_id, lface_id = 0 ;
+ int face_id;
+ EMACS_INT lface_id = 0;
int escape_glyph;
/* Handle control characters with ^. */
else
{
EMACS_INT pos = (it->s ? -1
- : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
- : IT_CHARPOS (*it));
+ : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+ : IT_CHARPOS (*it));
+ int c;
+
+ if (it->what == IT_CHARACTER)
+ c = it->char_to_display;
+ else
+ {
+ struct composition *cmp = composition_table[it->cmp_it.id];
+ int i;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
- it->string);
+ c = ' ';
+ for (i = 0; i < cmp->glyph_len; i++)
+ if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
+ break;
+ }
+ it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
}
}
it->face_id = it->dpvec_face_id;
else
{
- int lface_id = GLYPH_CODE_FACE (gc);
+ EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
if (lface_id > 0)
it->face_id = merge_faces (it->f, Qt, lface_id,
it->saved_face_id);
struct text_pos position;
xassert (STRINGP (it->string));
- xassert (!it->bidi_p || it->string == it->bidi_it.string.lstring);
+ xassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
xassert (IT_STRING_CHARPOS (*it) >= 0);
position = it->current.string_pos;
embedding level, so test for that explicitly. */
&& !BIDI_AT_BASE_LEVEL (it->bidi_it))
{
- /* If we lost track of base_level_stop, we have no better place
- for handle_stop_backwards to start from than BEGV. This
- happens, e.g., when we were reseated to the previous
- screenful of text by vertical-motion. */
+ /* If we lost track of base_level_stop, we have no better
+ place for handle_stop_backwards to start from than string
+ beginning. This happens, e.g., when we were reseated to
+ the previous screenful of text by vertical-motion. */
if (it->base_level_stop <= 0
|| IT_STRING_CHARPOS (*it) < it->base_level_stop)
it->base_level_stop = 0;
return 1;
}
+/* Scan backwards from IT's current position until we find a stop
+ position, or until BEGV. This is called when we find ourself
+ before both the last known prev_stop and base_level_stop while
+ reordering bidirectional text. */
+
+static void
+compute_stop_pos_backwards (struct it *it)
+{
+ const int SCAN_BACK_LIMIT = 1000;
+ struct text_pos pos;
+ struct display_pos save_current = it->current;
+ struct text_pos save_position = it->position;
+ EMACS_INT charpos = IT_CHARPOS (*it);
+ EMACS_INT where_we_are = charpos;
+ EMACS_INT save_stop_pos = it->stop_charpos;
+ EMACS_INT save_end_pos = it->end_charpos;
+
+ xassert (NILP (it->string) && !it->s);
+ xassert (it->bidi_p);
+ it->bidi_p = 0;
+ do
+ {
+ it->end_charpos = min (charpos + 1, ZV);
+ charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
+ SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
+ reseat_1 (it, pos, 0);
+ compute_stop_pos (it);
+ /* We must advance forward, right? */
+ if (it->stop_charpos <= charpos)
+ abort ();
+ }
+ while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
+
+ if (it->stop_charpos <= where_we_are)
+ it->prev_stop = it->stop_charpos;
+ else
+ it->prev_stop = BEGV;
+ it->bidi_p = 1;
+ it->current = save_current;
+ it->position = save_position;
+ it->stop_charpos = save_stop_pos;
+ it->end_charpos = save_end_pos;
+}
+
/* Scan forward from CHARPOS in the current buffer/string, until we
find a stop position > current IT's position. Then handle the stop
position before that. This is called when we bump into a stop
EMACS_INT next_stop;
/* Scan in strict logical order. */
+ xassert (it->bidi_p);
it->bidi_p = 0;
do
{
}
while (charpos <= where_we_are);
- next_stop = it->stop_charpos;
- it->stop_charpos = it->prev_stop;
it->bidi_p = 1;
it->current = save_current;
it->position = save_position;
+ next_stop = it->stop_charpos;
+ it->stop_charpos = it->prev_stop;
handle_stop (it);
it->stop_charpos = next_stop;
}
xassert (IT_CHARPOS (*it) >= BEGV);
xassert (NILP (it->string) && !it->s);
xassert (!it->bidi_p
- || (it->bidi_it.string.lstring == Qnil
+ || (EQ (it->bidi_it.string.lstring, Qnil)
&& it->bidi_it.string.s == NULL));
/* With bidi reordering, the character to display might not be the
embedding level, so test for that explicitly. */
&& !BIDI_AT_BASE_LEVEL (it->bidi_it))
{
- /* If we lost track of base_level_stop, we have no better place
- for handle_stop_backwards to start from than BEGV. This
- happens, e.g., when we were reseated to the previous
- screenful of text by vertical-motion. */
if (it->base_level_stop <= 0
|| IT_CHARPOS (*it) < it->base_level_stop)
- it->base_level_stop = BEGV;
- handle_stop_backwards (it, it->base_level_stop);
+ {
+ /* If we lost track of base_level_stop, we need to find
+ prev_stop by looking backwards. This happens, e.g., when
+ we were reseated to the previous screenful of text by
+ vertical-motion. */
+ it->base_level_stop = BEGV;
+ compute_stop_pos_backwards (it);
+ handle_stop_backwards (it, it->prev_stop);
+ }
+ else
+ handle_stop_backwards (it, it->base_level_stop);
return GET_NEXT_DISPLAY_ELEMENT (it);
}
else
&& IT_CHARPOS (*it) + 1 < ZV
&& indented_beyond_p (IT_CHARPOS (*it) + 1,
IT_BYTEPOS (*it) + 1,
- (double) it->selective)) /* iftc */
+ it->selective))
{
success_p = next_element_from_ellipsis (it);
it->dpvec_char_len = -1;
{
enum move_it_result result = MOVE_UNDEFINED;
struct glyph_row *saved_glyph_row;
- struct it wrap_it, atpos_it, atx_it;
+ struct it wrap_it, atpos_it, atx_it, ppos_it;
+ void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
+ void *ppos_data = NULL;
int may_wrap = 0;
enum it_method prev_method = it->method;
EMACS_INT prev_pos = IT_CHARPOS (*it);
+ int saw_smaller_pos = prev_pos < to_charpos;
/* Don't produce glyphs in produce_glyphs. */
saved_glyph_row = it->glyph_row;
atpos_it.sp = -1;
atx_it.sp = -1;
+ /* Use ppos_it under bidi reordering to save a copy of IT for the
+ position > CHARPOS that is the closest to CHARPOS. We restore
+ that position in IT when we have scanned the entire display line
+ without finding a match for CHARPOS and all the character
+ positions are greater than CHARPOS. */
+ if (it->bidi_p)
+ {
+ SAVE_IT (ppos_it, *it, ppos_data);
+ SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
+ if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
+ SAVE_IT (ppos_it, *it, ppos_data);
+ }
+
#define BUFFER_POS_REACHED_P() \
((op & MOVE_TO_POS) != 0 \
&& BUFFERP (it->object) \
((IT)->current_x = x, (IT)->max_ascent = ascent, \
(IT)->max_descent = descent)
- /* Stop if we move beyond TO_CHARPOS (after an image or stretch
- glyph). */
+ /* Stop if we move beyond TO_CHARPOS (after an image or a
+ display string or stretch glyph). */
if ((op & MOVE_TO_POS) != 0
&& BUFFERP (it->object)
&& it->method == GET_FROM_BUFFER
&& ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
|| (it->bidi_p
&& (prev_method == GET_FROM_IMAGE
- || prev_method == GET_FROM_STRETCH)
+ || prev_method == GET_FROM_STRETCH
+ || prev_method == GET_FROM_STRING)
/* Passed TO_CHARPOS from left to right. */
&& ((prev_pos < to_charpos
&& IT_CHARPOS (*it) > to_charpos)
/* If wrap_it is valid, the current position might be in a
word that is wrapped. So, save the iterator in
atpos_it and continue to see if wrapping happens. */
- atpos_it = *it;
+ SAVE_IT (atpos_it, *it, atpos_data);
}
- prev_method = it->method;
- if (it->method == GET_FROM_BUFFER)
- prev_pos = IT_CHARPOS (*it);
/* Stop when ZV reached.
We used to stop here when TO_CHARPOS reached as well, but that is
too soon if this glyph does not fit on this line. So we handle it
already found, we are done. */
if (atpos_it.sp >= 0)
{
- *it = atpos_it;
+ RESTORE_IT (it, &atpos_it, atpos_data);
result = MOVE_POS_MATCH_OR_ZV;
goto done;
}
if (atx_it.sp >= 0)
{
- *it = atx_it;
+ RESTORE_IT (it, &atx_it, atx_data);
result = MOVE_X_REACHED;
goto done;
}
/* Otherwise, we can wrap here. */
- wrap_it = *it;
+ SAVE_IT (wrap_it, *it, wrap_data);
may_wrap = 0;
}
}
if (it->area != TEXT_AREA)
{
+ prev_method = it->method;
+ if (it->method == GET_FROM_BUFFER)
+ prev_pos = IT_CHARPOS (*it);
set_iterator_to_next (it, 1);
if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
SET_TEXT_POS (this_line_min_pos,
IT_CHARPOS (*it), IT_BYTEPOS (*it));
+ if (it->bidi_p
+ && (op & MOVE_TO_POS)
+ && IT_CHARPOS (*it) > to_charpos
+ && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
+ SAVE_IT (ppos_it, *it, ppos_data);
continue;
}
goto buffer_pos_reached;
if (atpos_it.sp < 0)
{
- atpos_it = *it;
+ SAVE_IT (atpos_it, *it, atpos_data);
IT_RESET_X_ASCENT_DESCENT (&atpos_it);
}
}
}
if (atx_it.sp < 0)
{
- atx_it = *it;
+ SAVE_IT (atx_it, *it, atx_data);
IT_RESET_X_ASCENT_DESCENT (&atx_it);
}
}
if (it->line_wrap == WORD_WRAP
&& atpos_it.sp < 0)
{
- atpos_it = *it;
+ SAVE_IT (atpos_it, *it, atpos_data);
atpos_it.current_x = x_before_this_char;
atpos_it.hpos = hpos_before_this_char;
}
}
+ prev_method = it->method;
+ if (it->method == GET_FROM_BUFFER)
+ prev_pos = IT_CHARPOS (*it);
set_iterator_to_next (it, 1);
if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
SET_TEXT_POS (this_line_min_pos,
if (wrap_it.sp >= 0)
{
- *it = wrap_it;
+ RESTORE_IT (it, &wrap_it, wrap_data);
atpos_it.sp = -1;
atx_it.sp = -1;
}
goto buffer_pos_reached;
if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
{
- atpos_it = *it;
+ SAVE_IT (atpos_it, *it, atpos_data);
IT_RESET_X_ASCENT_DESCENT (&atpos_it);
}
}
/* Is this a line end? If yes, we're done. */
if (ITERATOR_AT_END_OF_LINE_P (it))
{
- result = MOVE_NEWLINE_OR_CR;
+ /* If we are past TO_CHARPOS, but never saw any character
+ positions smaller than TO_CHARPOS, return
+ MOVE_POS_MATCH_OR_ZV, like the unidirectional display
+ did. */
+ if ((op & MOVE_TO_POS) != 0
+ && !saw_smaller_pos
+ && IT_CHARPOS (*it) > to_charpos)
+ {
+ result = MOVE_POS_MATCH_OR_ZV;
+ if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
+ RESTORE_IT (it, &ppos_it, ppos_data);
+ }
+ else
+ result = MOVE_NEWLINE_OR_CR;
break;
}
+ prev_method = it->method;
if (it->method == GET_FROM_BUFFER)
prev_pos = IT_CHARPOS (*it);
/* The current display element has been consumed. Advance
set_iterator_to_next (it, 1);
if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
+ if (IT_CHARPOS (*it) < to_charpos)
+ saw_smaller_pos = 1;
+ if (it->bidi_p
+ && (op & MOVE_TO_POS)
+ && IT_CHARPOS (*it) >= to_charpos
+ && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
+ SAVE_IT (ppos_it, *it, ppos_data);
/* Stop if lines are truncated and IT's current x-position is
past the right edge of the window now. */
if (!FRAME_WINDOW_P (it->f)
|| IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
- if (!get_next_display_element (it)
- || BUFFER_POS_REACHED_P ())
+ int at_eob_p = 0;
+
+ if ((at_eob_p = !get_next_display_element (it))
+ || BUFFER_POS_REACHED_P ()
+ /* If we are past TO_CHARPOS, but never saw any
+ character positions smaller than TO_CHARPOS,
+ return MOVE_POS_MATCH_OR_ZV, like the
+ unidirectional display did. */
+ || ((op & MOVE_TO_POS) != 0
+ && !saw_smaller_pos
+ && IT_CHARPOS (*it) > to_charpos))
{
result = MOVE_POS_MATCH_OR_ZV;
+ if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
+ RESTORE_IT (it, &ppos_it, ppos_data);
break;
}
if (ITERATOR_AT_END_OF_LINE_P (it))
break;
}
}
+ else if ((op & MOVE_TO_POS) != 0
+ && !saw_smaller_pos
+ && IT_CHARPOS (*it) > to_charpos)
+ {
+ result = MOVE_POS_MATCH_OR_ZV;
+ if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
+ RESTORE_IT (it, &ppos_it, ppos_data);
+ break;
+ }
result = MOVE_LINE_TRUNCATED;
break;
}
/* If we scanned beyond to_pos and didn't find a point to wrap at,
restore the saved iterator. */
if (atpos_it.sp >= 0)
- *it = atpos_it;
+ RESTORE_IT (it, &atpos_it, atpos_data);
else if (atx_it.sp >= 0)
- *it = atx_it;
+ RESTORE_IT (it, &atx_it, atx_data);
done:
+ if (atpos_data)
+ xfree (atpos_data);
+ if (atx_data)
+ xfree (atx_data);
+ if (wrap_data)
+ xfree (wrap_data);
+ if (ppos_data)
+ xfree (ppos_data);
+
/* Restore the iterator settings altered at the beginning of this
function. */
it->glyph_row = saved_glyph_row;
if (it->line_wrap == WORD_WRAP
&& (op & MOVE_TO_X))
{
- struct it save_it = *it;
- int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
+ struct it save_it;
+ void *save_data = NULL;
+ int skip;
+
+ SAVE_IT (save_it, *it, save_data);
+ skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
/* When word-wrap is on, TO_X may lie past the end
of a wrapped line. Then it->current is the
character on the next line, so backtrack to the
if (skip == MOVE_LINE_CONTINUED)
{
int prev_x = max (it->current_x - 1, 0);
- *it = save_it;
+ RESTORE_IT (it, &save_it, save_data);
move_it_in_display_line_to
(it, -1, prev_x, MOVE_TO_X);
}
+ else
+ xfree (save_data);
}
else
move_it_in_display_line_to (it, to_charpos, to_x, op);
description of enum move_operation_enum.
If TO_CHARPOS is in invisible text, e.g. a truncated part of a
- screen line, this function will set IT to the next position >
- TO_CHARPOS. */
+ screen line, this function will set IT to the next position that is
+ displayed to the right of TO_CHARPOS on the screen. */
void
move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height, line_start_x = 0, reached = 0;
+ void *backup_data = NULL;
for (;;)
{
struct it it_backup;
if (it->line_wrap == WORD_WRAP)
- it_backup = *it;
+ SAVE_IT (it_backup, *it, backup_data);
/* TO_Y specified means stop at TO_X in the line containing
TO_Y---or at TO_CHARPOS if this is reached first. The
reached = 6;
break;
}
- it_backup = *it;
+ SAVE_IT (it_backup, *it, backup_data);
TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
skip2 = move_it_in_display_line_to (it, to_charpos, -1,
op & MOVE_TO_POS);
/* If TO_Y is in this line and TO_X was reached
above, we scanned too far. We have to restore
IT's settings to the ones before skipping. */
- *it = it_backup;
+ RESTORE_IT (it, &it_backup, backup_data);
reached = 6;
}
else
&& it->line_wrap == WORD_WRAP)
{
int prev_x = max (it->current_x - 1, 0);
- *it = it_backup;
+ RESTORE_IT (it, &it_backup, backup_data);
skip = move_it_in_display_line_to
(it, -1, prev_x, MOVE_TO_X);
}
last_max_ascent = it->max_ascent;
}
+ if (backup_data)
+ xfree (backup_data);
+
TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
}
{
int nlines, h;
struct it it2, it3;
+ void *it2data = NULL, *it3data = NULL;
EMACS_INT start_pos;
move_further_back:
start of the next line so that we get its height. We need this
height to be able to tell whether we reached the specified
y-distance. */
- it2 = *it;
+ SAVE_IT (it2, *it, it2data);
it2.max_ascent = it2.max_descent = 0;
do
{
}
while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
xassert (IT_CHARPOS (*it) >= BEGV);
- it3 = it2;
+ SAVE_IT (it3, it2, it3data);
move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
xassert (IT_CHARPOS (*it) >= BEGV);
{
/* DY == 0 means move to the start of the screen line. The
value of nlines is > 0 if continuation lines were involved. */
+ RESTORE_IT (it, it, it2data);
if (nlines > 0)
move_it_by_lines (it, nlines);
+ xfree (it3data);
}
else
{
Note that H has been subtracted in front of the if-statement. */
int target_y = it->current_y + h - dy;
int y0 = it3.current_y;
- int y1 = line_bottom_y (&it3);
- int line_height = y1 - y0;
+ int y1;
+ int line_height;
+ RESTORE_IT (&it3, &it3, it3data);
+ y1 = line_bottom_y (&it3);
+ line_height = y1 - y0;
+ RESTORE_IT (it, it, it2data);
/* If we did not reach target_y, try to move further backward if
we can. If we moved too far backward, try to move forward. */
if (target_y < it->current_y
else
{
struct it it2;
+ void *it2data = NULL;
EMACS_INT start_charpos, i;
/* Start at the beginning of the screen line containing IT's
/* Above call may have moved too far if continuation lines
are involved. Scan forward and see if it did. */
- it2 = *it;
+ SAVE_IT (it2, *it, it2data);
it2.vpos = it2.current_y = 0;
move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
it->vpos -= it2.vpos;
if (it2.vpos > -dvpos)
{
int delta = it2.vpos + dvpos;
- it2 = *it;
+
+ RESTORE_IT (&it2, &it2, it2data);
+ SAVE_IT (it2, *it, it2data);
move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
/* Move back again if we got too far ahead. */
if (IT_CHARPOS (*it) >= start_charpos)
- *it = it2;
+ RESTORE_IT (it, &it2, it2data);
+ else
+ xfree (it2data);
}
+ else
+ RESTORE_IT (it, it, it2data);
}
}
if (nlflag)
{
EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
- unsigned long int dups;
+ printmax_t dups;
insert_1 ("\n", 1, 1, 0, 0);
scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
this_bol, this_bol_byte, 0);
if (dups > 1)
{
- char dupstr[40];
+ char dupstr[sizeof " [ times]"
+ + INT_STRLEN_BOUND (printmax_t)];
int duplen;
/* If you change this format, don't forget to also
change message_log_check_duplicate. */
- sprintf (dupstr, " [%lu times]", dups);
+ sprintf (dupstr, " [%"pMd" times]", dups);
duplen = strlen (dupstr);
TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
insert_1 (dupstr, duplen, 1, 0, 1);
Return 0 if different, 1 if the new one should just replace it, or a
value N > 1 if we should also append " [N times]". */
-static unsigned long int
+static intmax_t
message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
{
EMACS_INT i;
if (*p1++ == ' ' && *p1++ == '[')
{
char *pend;
- unsigned long int n = strtoul ((char *) p1, &pend, 10);
- if (strncmp (pend, " times]\n", 8) == 0)
+ intmax_t n = strtoimax ((char *) p1, &pend, 10);
+ if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
return n+1;
}
return 0;
{
if (m)
{
- size_t len;
+ ptrdiff_t len;
len = doprnt (FRAME_MESSAGE_BUF (f),
FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
double the buffer's size. */
if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
{
- int len = MODE_LINE_NOPROP_LEN (0);
- int new_size = 2 * len * sizeof *mode_line_noprop_buf;
+ ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
+ ptrdiff_t new_size;
+
+ if (STRING_BYTES_BOUND / 2 < len)
+ memory_full (SIZE_MAX);
+ new_size = 2 * len;
mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
mode_line_noprop_ptr = mode_line_noprop_buf + len;
/* Do we have more than one visible frame on this X display? */
Lisp_Object tail;
Lisp_Object fmt;
- int title_start;
+ ptrdiff_t title_start;
char *title;
- int len;
+ ptrdiff_t len;
struct it it;
int count = SPECPDL_INDEX ();
f = XFRAME (frame);
if (WINDOWP (f->tool_bar_window)
- || (w = XWINDOW (f->tool_bar_window),
+ && (w = XWINDOW (f->tool_bar_window),
WINDOW_TOTAL_LINES (w) > 0))
{
update_tool_bar (f, 1);
/* First and last unchanged row for try_window_id. */
-int debug_first_unchanged_at_end_vpos;
-int debug_last_unchanged_at_beg_vpos;
+static int debug_first_unchanged_at_end_vpos;
+static int debug_last_unchanged_at_beg_vpos;
/* Delta vpos and y. */
-int debug_dvpos, debug_dy;
+static int debug_dvpos, debug_dy;
/* Delta in characters and bytes for try_window_id. */
-EMACS_INT debug_delta, debug_delta_bytes;
+static EMACS_INT debug_delta, debug_delta_bytes;
/* Values of window_end_pos and window_end_vpos at the end of
try_window_id. */
-EMACS_INT debug_end_vpos;
+static EMACS_INT debug_end_vpos;
/* Append a string to W->desired_matrix->method. FMT is a printf
- format string. A1...A9 are a supplement for a variable-length
- argument list. If trace_redisplay_p is non-zero also printf the
+ format string. If trace_redisplay_p is non-zero also printf the
resulting string to stderr. */
+static void debug_method_add (struct window *, char const *, ...)
+ ATTRIBUTE_FORMAT_PRINTF (2, 3);
+
static void
-debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- struct window *w;
- char *fmt;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9;
+debug_method_add (struct window *w, char const *fmt, ...)
{
char buffer[512];
char *method = w->desired_matrix->method;
int len = strlen (method);
int size = sizeof w->desired_matrix->method;
int remaining = size - len - 1;
+ va_list ap;
- sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ va_start (ap, fmt);
+ vsprintf (buffer, fmt, ap);
+ va_end (ap);
if (len && remaining)
{
method[len] = '|';
fprintf (stderr, "%p (%s): %s\n",
w,
((BUFFERP (w->buffer)
- && STRINGP (XBUFFER (w->buffer)->name))
- ? SSDATA (XBUFFER (w->buffer)->name)
+ && STRINGP (BVAR (XBUFFER (w->buffer), name)))
+ ? SSDATA (BVAR (XBUFFER (w->buffer), name))
: "no buffer"),
buffer);
}
buffer position, END is given as a distance from Z. Used in
redisplay_internal for display optimization. */
-static INLINE int
+static inline int
text_outside_line_unchanged_p (struct window *w,
EMACS_INT start, EMACS_INT end)
{
/* Reconsider the setting of B->clip_changed which is displayed
in window W. */
-static INLINE void
+static inline void
reconsider_clip_changes (struct window *w, struct buffer *b)
{
if (b->clip_changed
We assume that the window's buffer is really current. */
-static INLINE struct text_pos
+static inline struct text_pos
run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
{
struct window *w = XWINDOW (window);
which was computed as distance from window bottom to
point. This matters when lines at window top and lines
below window bottom have different height. */
- struct it it1 = it;
+ struct it it1;
+ void *it1data = NULL;
/* We use a temporary it1 because line_bottom_y can modify
its argument, if it moves one line down; see there. */
- int start_y = line_bottom_y (&it1);
+ int start_y;
+ SAVE_IT (it1, it, it1data);
+ start_y = line_bottom_y (&it1);
do {
+ RESTORE_IT (&it, &it, it1data);
move_it_by_lines (&it, 1);
- it1 = it;
+ SAVE_IT (it1, it, it1data);
} while (line_bottom_y (&it1) - start_y < amount_to_scroll);
}
&& BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
{
struct it it1;
+ void *it1data = NULL;
+ SAVE_IT (it1, it, it1data);
start_display (&it1, w, startp);
move_it_vertically (&it1, margin);
margin_pos = IT_CHARPOS (it1);
+ RESTORE_IT (&it, &it, it1data);
}
scrolling_up = PT > margin_pos;
aggressive =
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
it.current_y += row->height;
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
}
/* Scroll the current matrix. */
#if GLYPH_DEBUG
-void dump_glyph_row (struct glyph_row *, int, int);
-void dump_glyph_matrix (struct glyph_matrix *, int);
-void dump_glyph (struct glyph_row *, struct glyph *, int);
+void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
+void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
+void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
/* Dump the contents of glyph matrix MATRIX on stderr.
GLYPHS > 1 means show glyphs in long form. */
void
-dump_glyph_matrix (matrix, glyphs)
- struct glyph_matrix *matrix;
- int glyphs;
+dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
{
int i;
for (i = 0; i < matrix->nrows; ++i)
the glyph row and area where the glyph comes from. */
void
-dump_glyph (row, glyph, area)
- struct glyph_row *row;
- struct glyph *glyph;
- int area;
+dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
{
if (glyph->type == CHAR_GLYPH)
{
fprintf (stderr,
- " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
'C',
glyph->charpos,
else if (glyph->type == STRETCH_GLYPH)
{
fprintf (stderr,
- " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
'S',
glyph->charpos,
else if (glyph->type == IMAGE_GLYPH)
{
fprintf (stderr,
- " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
glyph - row->glyphs[TEXT_AREA],
'I',
glyph->charpos,
else if (glyph->type == COMPOSITE_GLYPH)
{
fprintf (stderr,
- " %5d %4c %6d %c %3d 0x%05x",
+ " %5td %4c %6"pI"d %c %3d 0x%05x",
glyph - row->glyphs[TEXT_AREA],
'+',
glyph->charpos,
GLYPHS > 1 means show glyphs in long form. */
void
-dump_glyph_row (row, vpos, glyphs)
- struct glyph_row *row;
- int vpos, glyphs;
+dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
{
if (glyphs != 1)
{
fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
fprintf (stderr, "======================================================================\n");
- fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
+ fprintf (stderr, "%3d %5"pI"d %5"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),
fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
row->end.overlay_string_index,
row->continuation_lines_width);
- fprintf (stderr, "%9d %5d\n",
+ fprintf (stderr, "%9"pI"d %5"pI"d\n",
CHARPOS (row->start.string_pos),
CHARPOS (row->end.string_pos));
fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
struct window *w = XWINDOW (selected_window);
struct buffer *buffer = XBUFFER (w->buffer);
- fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
+ fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
doc: /* Like `format', but print result to stderr.
usage: (trace-to-stderr STRING &rest OBJECTS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object s = Fformat (nargs, args);
fprintf (stderr, "%s", SDATA (s));
lines' rows is implemented for bidi-reordered rows. */
/* ROW->minpos is the value of min_pos, the minimal buffer position
- we have in ROW. */
- if (min_pos <= ZV)
+ we have in ROW, or ROW->start.pos if that is smaller. */
+ if (min_pos <= ZV && min_pos < row->start.pos.charpos)
SET_TEXT_POS (row->minpos, min_pos, min_bpos);
else
- /* We didn't find _any_ valid buffer positions in any of the
- glyphs, so we must trust the iterator's computed positions. */
+ /* We didn't find buffer positions smaller than ROW->start, or
+ didn't find _any_ valid buffer positions in any of the glyphs,
+ so we must trust the iterator's computed positions. */
row->minpos = row->start.pos;
if (max_pos <= 0)
{
struct glyph_row *row = it->glyph_row;
Lisp_Object overlay_arrow_string;
struct it wrap_it;
+ void *wrap_data = NULL;
int may_wrap = 0, wrap_x IF_LINT (= 0);
int wrap_row_used = -1;
int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
may_wrap = 1;
else if (may_wrap)
{
- wrap_it = *it;
+ SAVE_IT (wrap_it, *it, wrap_data);
wrap_x = x;
wrap_row_used = row->used[TEXT_AREA];
wrap_row_ascent = row->ascent;
if (row->reversed_p)
unproduce_glyphs (it,
row->used[TEXT_AREA] - wrap_row_used);
- *it = wrap_it;
+ RESTORE_IT (it, &wrap_it, wrap_data);
it->continuation_lines_width += wrap_x;
row->used[TEXT_AREA] = wrap_row_used;
row->ascent = wrap_row_ascent;
break;
case MODE_LINE_STRING:
{
- int len = strlen (spec);
- Lisp_Object tem = make_string (spec, len);
+ Lisp_Object tem = build_string (spec);
props = Ftext_properties_at (make_number (charpos), elt);
/* Should only keep face property in props */
n += store_mode_line_string (NULL, tem, 0, field, prec, props);
else if (CHARACTERP (eoltype))
{
unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
- eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
+ int c = XFASTINT (eoltype);
+ eol_str_len = CHAR_STRING (c, tmp);
eol_str = tmp;
}
else
if (FRAME_WINDOW_P (it->f)
&& valid_image_p (prop))
{
- int id = lookup_image (it->f, prop);
+ ptrdiff_t id = lookup_image (it->f, prop);
struct image *img = IMAGE_FROM_ID (it->f, id);
return OK_PIXELS (width_p ? img->width : img->height);
#if GLYPH_DEBUG
void
-dump_glyph_string (s)
- struct glyph_string *s;
+dump_glyph_string (struct glyph_string *s)
{
fprintf (stderr, "glyph string\n");
fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
/* Append the list of glyph strings with head H and tail T to the list
with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
-static INLINE void
+static inline void
append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
result. */
-static INLINE void
+static inline void
prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
/* Append glyph string S to the list with head *HEAD and tail *TAIL.
Set *HEAD and *TAIL to the resulting list. */
-static INLINE void
+static inline void
append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *s)
{
Value is a pointer to a realized face that is ready for display if
DISPLAY_P is non-zero. */
-static INLINE struct face *
+static inline struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
XChar2b *char2b, int display_p)
{
The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
a pointer to a realized face that is ready for display. */
-static INLINE struct face *
+static inline struct face *
get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
XChar2b *char2b, int *two_byte_p)
{
/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
Retunr 1 if FONT has a glyph for C, otherwise return 0. */
-static INLINE int
+static inline int
get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
{
unsigned code;
first glyph following S. LAST_X is the right-most x-position + 1
in the drawing area. */
-static INLINE void
+static inline void
set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
{
/* If the face of this glyph string has to be drawn to the end of
do { \
int face_id = (row)->glyphs[area][START].face_id; \
struct face *base_face = FACE_FROM_ID (f, face_id); \
- int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
+ ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
struct composition *cmp = composition_table[cmp_id]; \
XChar2b *char2b; \
struct glyph_string *first_s IF_LINT (= NULL); \
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
-static INLINE void
+static inline void
append_glyph (struct it *it)
{
struct glyph *glyph;
IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
non-null. */
-static INLINE void
+static inline void
append_composite_glyph (struct it *it)
{
struct glyph *glyph;
/* Change IT->ascent and IT->height according to the setting of
IT->voffset. */
-static INLINE void
+static inline void
take_vertical_position_into_account (struct it *it)
{
if (it->voffset)
base_width = font->average_width;
/* Get a face ID for the glyph by utilizing a cache (the same way as
- doen for `escape-glyph' in get_next_display_element). */
+ done for `escape-glyph' in get_next_display_element). */
if (it->f == last_glyphless_glyph_frame
&& it->face_id == last_glyphless_glyph_face_id)
{
while (g < e)
{
- if (BUFFERP (g->object)
+ if ((BUFFERP (g->object) || INTEGERP (g->object))
&& start_charpos <= g->charpos && g->charpos < end_charpos)
*start = row;
g++;
while (g < e)
{
- if (BUFFERP (g->object)
+ if ((BUFFERP (g->object) || INTEGERP (g->object))
&& start_charpos <= g->charpos && g->charpos < end_charpos)
break;
g++;
&& XFASTINT (w->last_modified) == BUF_MODIFF (b)
&& XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
{
- int hpos, vpos, i, dx, dy, area;
+ int hpos, vpos, dx, dy, area;
EMACS_INT pos;
struct glyph *glyph;
Lisp_Object object;
Lisp_Object mouse_face = Qnil, position;
Lisp_Object *overlay_vec = NULL;
- int noverlays;
+ ptrdiff_t i, noverlays;
struct buffer *obuf;
EMACS_INT obegv, ozv;
int same_region;
{
result->x = right->x;
- /* The right end of the intersection is the minimum of the
+ /* The right end of the intersection is the minimum of
the right ends of left and right. */
result->width = (min (left->x + left->width, right->x + right->width)
- result->x);
Vmessage_stack = Qnil;
staticpro (&Vmessage_stack);
- Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
- staticpro (&Qinhibit_redisplay);
+ DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
message_dolog_marker1 = Fmake_marker ();
staticpro (&message_dolog_marker1);
defsubr (&Sinvisible_p);
defsubr (&Scurrent_bidi_paragraph_direction);
- staticpro (&Qmenu_bar_update_hook);
- Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
-
- staticpro (&Qoverriding_terminal_local_map);
- Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
-
- staticpro (&Qoverriding_local_map);
- Qoverriding_local_map = intern_c_string ("overriding-local-map");
-
- staticpro (&Qwindow_scroll_functions);
- Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
-
- staticpro (&Qwindow_text_change_functions);
- Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
-
- staticpro (&Qredisplay_end_trigger_functions);
- Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
-
- staticpro (&Qinhibit_point_motion_hooks);
- Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
-
- Qeval = intern_c_string ("eval");
- staticpro (&Qeval);
-
- QCdata = intern_c_string (":data");
- staticpro (&QCdata);
- Qdisplay = intern_c_string ("display");
- staticpro (&Qdisplay);
- Qspace_width = intern_c_string ("space-width");
- staticpro (&Qspace_width);
- Qraise = intern_c_string ("raise");
- staticpro (&Qraise);
- Qslice = intern_c_string ("slice");
- staticpro (&Qslice);
- Qspace = intern_c_string ("space");
- staticpro (&Qspace);
- Qmargin = intern_c_string ("margin");
- staticpro (&Qmargin);
- Qpointer = intern_c_string ("pointer");
- staticpro (&Qpointer);
- Qleft_margin = intern_c_string ("left-margin");
- staticpro (&Qleft_margin);
- Qright_margin = intern_c_string ("right-margin");
- staticpro (&Qright_margin);
- Qcenter = intern_c_string ("center");
- staticpro (&Qcenter);
- Qline_height = intern_c_string ("line-height");
- staticpro (&Qline_height);
- QCalign_to = intern_c_string (":align-to");
- staticpro (&QCalign_to);
- QCrelative_width = intern_c_string (":relative-width");
- staticpro (&QCrelative_width);
- QCrelative_height = intern_c_string (":relative-height");
- staticpro (&QCrelative_height);
- QCeval = intern_c_string (":eval");
- staticpro (&QCeval);
- QCpropertize = intern_c_string (":propertize");
- staticpro (&QCpropertize);
- QCfile = intern_c_string (":file");
- staticpro (&QCfile);
- Qfontified = intern_c_string ("fontified");
- staticpro (&Qfontified);
- Qfontification_functions = intern_c_string ("fontification-functions");
- staticpro (&Qfontification_functions);
- Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
- staticpro (&Qtrailing_whitespace);
- Qescape_glyph = intern_c_string ("escape-glyph");
- staticpro (&Qescape_glyph);
- Qnobreak_space = intern_c_string ("nobreak-space");
- staticpro (&Qnobreak_space);
- Qimage = intern_c_string ("image");
- staticpro (&Qimage);
- Qtext = intern_c_string ("text");
- staticpro (&Qtext);
- Qboth = intern_c_string ("both");
- staticpro (&Qboth);
- Qboth_horiz = intern_c_string ("both-horiz");
- staticpro (&Qboth_horiz);
- Qtext_image_horiz = intern_c_string ("text-image-horiz");
- staticpro (&Qtext_image_horiz);
- QCmap = intern_c_string (":map");
- staticpro (&QCmap);
- QCpointer = intern_c_string (":pointer");
- staticpro (&QCpointer);
- Qrect = intern_c_string ("rect");
- staticpro (&Qrect);
- Qcircle = intern_c_string ("circle");
- staticpro (&Qcircle);
- Qpoly = intern_c_string ("poly");
- staticpro (&Qpoly);
- Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
- staticpro (&Qmessage_truncate_lines);
- Qgrow_only = intern_c_string ("grow-only");
- staticpro (&Qgrow_only);
- Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
- staticpro (&Qinhibit_menubar_update);
- Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
- staticpro (&Qinhibit_eval_during_redisplay);
- Qposition = intern_c_string ("position");
- staticpro (&Qposition);
- Qbuffer_position = intern_c_string ("buffer-position");
- staticpro (&Qbuffer_position);
- Qobject = intern_c_string ("object");
- staticpro (&Qobject);
- Qbar = intern_c_string ("bar");
- staticpro (&Qbar);
- Qhbar = intern_c_string ("hbar");
- staticpro (&Qhbar);
- Qbox = intern_c_string ("box");
- staticpro (&Qbox);
- Qhollow = intern_c_string ("hollow");
- staticpro (&Qhollow);
- Qhand = intern_c_string ("hand");
- staticpro (&Qhand);
- Qarrow = intern_c_string ("arrow");
- staticpro (&Qarrow);
- Qtext = intern_c_string ("text");
- staticpro (&Qtext);
- Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
- staticpro (&Qinhibit_free_realized_faces);
+ DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
+ DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
+ DEFSYM (Qoverriding_local_map, "overriding-local-map");
+ DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
+ DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
+ DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
+ DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
+ DEFSYM (Qeval, "eval");
+ DEFSYM (QCdata, ":data");
+ DEFSYM (Qdisplay, "display");
+ DEFSYM (Qspace_width, "space-width");
+ DEFSYM (Qraise, "raise");
+ DEFSYM (Qslice, "slice");
+ DEFSYM (Qspace, "space");
+ DEFSYM (Qmargin, "margin");
+ DEFSYM (Qpointer, "pointer");
+ DEFSYM (Qleft_margin, "left-margin");
+ DEFSYM (Qright_margin, "right-margin");
+ DEFSYM (Qcenter, "center");
+ DEFSYM (Qline_height, "line-height");
+ DEFSYM (QCalign_to, ":align-to");
+ DEFSYM (QCrelative_width, ":relative-width");
+ DEFSYM (QCrelative_height, ":relative-height");
+ DEFSYM (QCeval, ":eval");
+ DEFSYM (QCpropertize, ":propertize");
+ DEFSYM (QCfile, ":file");
+ DEFSYM (Qfontified, "fontified");
+ DEFSYM (Qfontification_functions, "fontification-functions");
+ DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
+ DEFSYM (Qescape_glyph, "escape-glyph");
+ DEFSYM (Qnobreak_space, "nobreak-space");
+ DEFSYM (Qimage, "image");
+ DEFSYM (Qtext, "text");
+ DEFSYM (Qboth, "both");
+ DEFSYM (Qboth_horiz, "both-horiz");
+ DEFSYM (Qtext_image_horiz, "text-image-horiz");
+ DEFSYM (QCmap, ":map");
+ DEFSYM (QCpointer, ":pointer");
+ DEFSYM (Qrect, "rect");
+ DEFSYM (Qcircle, "circle");
+ DEFSYM (Qpoly, "poly");
+ DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
+ DEFSYM (Qgrow_only, "grow-only");
+ DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
+ DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
+ DEFSYM (Qposition, "position");
+ DEFSYM (Qbuffer_position, "buffer-position");
+ DEFSYM (Qobject, "object");
+ DEFSYM (Qbar, "bar");
+ DEFSYM (Qhbar, "hbar");
+ DEFSYM (Qbox, "box");
+ DEFSYM (Qhollow, "hollow");
+ DEFSYM (Qhand, "hand");
+ DEFSYM (Qarrow, "arrow");
+ DEFSYM (Qtext, "text");
+ DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
list_of_error = Fcons (Fcons (intern_c_string ("error"),
Fcons (intern_c_string ("void-variable"), Qnil)),
Qnil);
staticpro (&list_of_error);
- Qlast_arrow_position = intern_c_string ("last-arrow-position");
- staticpro (&Qlast_arrow_position);
- Qlast_arrow_string = intern_c_string ("last-arrow-string");
- staticpro (&Qlast_arrow_string);
-
- Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
- staticpro (&Qoverlay_arrow_string);
- Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
- staticpro (&Qoverlay_arrow_bitmap);
+ DEFSYM (Qlast_arrow_position, "last-arrow-position");
+ DEFSYM (Qlast_arrow_string, "last-arrow-string");
+ DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
+ DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
echo_buffer[0] = echo_buffer[1] = Qnil;
staticpro (&echo_buffer[0]);
staticpro (&previous_help_echo_string);
help_echo_pos = -1;
- Qright_to_left = intern_c_string ("right-to-left");
- staticpro (&Qright_to_left);
- Qleft_to_right = intern_c_string ("left-to-right");
- staticpro (&Qleft_to_right);
+ DEFSYM (Qright_to_left, "right-to-left");
+ DEFSYM (Qleft_to_right, "left-to-right");
#ifdef HAVE_WINDOW_SYSTEM
DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
unibyte_display_via_language_environment = 0;
DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
- doc: /* *Maximum height for resizing mini-windows.
+ doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
If a float, it specifies a fraction of the mini-window frame's height.
If an integer, it specifies a number of lines. */);
Vmax_mini_window_height = make_float (0.25);
DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
- doc: /* *How to resize mini-windows.
+ doc: /* How to resize mini-windows (the minibuffer and the echo area).
A value of nil means don't automatically resize mini-windows.
A value of t means resize them to fit the text displayed in them.
-A value of `grow-only', the default, means let mini-windows grow
-only, until their display becomes empty, at which point the windows
-go back to their normal size. */);
+A value of `grow-only', the default, means let mini-windows grow only;
+they return to their normal size when the minibuffer is closed, or the
+echo area becomes empty. */);
Vresize_mini_windows = Qgrow_only;
DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
If non-nil, windows are automatically scrolled horizontally to make
point visible. */);
automatic_hscrolling_p = 1;
- Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
- staticpro (&Qauto_hscroll_mode);
+ DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
DEFVAR_INT ("hscroll-margin", hscroll_margin,
doc: /* *How many columns away from the window edge point is allowed to get
To add a prefix to non-continuation lines, use `line-prefix'. */);
Vwrap_prefix = Qnil;
- staticpro (&Qwrap_prefix);
- Qwrap_prefix = intern_c_string ("wrap-prefix");
+ DEFSYM (Qwrap_prefix, "wrap-prefix");
Fmake_variable_buffer_local (Qwrap_prefix);
DEFVAR_LISP ("line-prefix", Vline_prefix,
To add a prefix to continuation lines, use `wrap-prefix'. */);
Vline_prefix = Qnil;
- staticpro (&Qline_prefix);
- Qline_prefix = intern_c_string ("line-prefix");
+ DEFSYM (Qline_prefix, "line-prefix");
Fmake_variable_buffer_local (Qline_prefix);
DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
void
init_xdisp (void)
{
- Lisp_Object root_window;
- struct window *mini_w;
-
current_header_line_height = current_mode_line_height = -1;
CHARPOS (this_line_start_pos) = 0;
- mini_w = XWINDOW (minibuf_window);
- root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
- echo_area_window = minibuf_window;
-
if (!noninteractive)
{
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
+ struct window *m = XWINDOW (minibuf_window);
+ Lisp_Object frame = m->frame;
+ struct frame *f = XFRAME (frame);
+ Lisp_Object root = FRAME_ROOT_WINDOW (f);
+ struct window *r = XWINDOW (root);
int i;
- XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
- set_window_height (root_window,
- FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
- 0);
- mini_w->top_line = make_number (FRAME_LINES (f) - 1);
- set_window_height (minibuf_window, 1, 0);
+ echo_area_window = minibuf_window;
- XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
- mini_w->total_cols = make_number (FRAME_COLS (f));
+ XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
+ XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
+ XSETFASTINT (r->total_cols, FRAME_COLS (f));
+ XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
+ XSETFASTINT (m->total_lines, 1);
+ XSETFASTINT (m->total_cols, FRAME_COLS (f));
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]