static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, int, int, int, int *,
- Lisp_Object *));
+static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
static void display_menu_bar P_ ((struct window *));
static int display_count_lines P_ ((int, int, int, int, int *));
static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
- int, int, struct it *, int, int, int, int));
+ EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
static void compute_line_metrics P_ ((struct it *));
static void run_redisplay_end_trigger_hook P_ ((struct it *));
static int get_overlay_strings P_ ((struct it *, int));
static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
Lisp_Object));
static int face_before_or_after_it_pos P_ ((struct it *, int));
-static int next_overlay_change P_ ((int));
+static EMACS_INT next_overlay_change P_ ((EMACS_INT));
static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
Lisp_Object, Lisp_Object,
struct text_pos *, int));
/* Evaluate SEXPR and return the result, or nil if something went
wrong. Prevent redisplay during the evaluation. */
-Lisp_Object
-safe_eval (sexpr)
- Lisp_Object sexpr;
-{
- Lisp_Object val;
-
- if (inhibit_eval_during_redisplay)
- val = Qnil;
- else
- {
- int count = SPECPDL_INDEX ();
- struct gcpro gcpro1;
-
- GCPRO1 (sexpr);
- specbind (Qinhibit_redisplay, Qt);
- /* Use Qt to ensure debugger does not run,
- so there is no possibility of wanting to redisplay. */
- val = internal_condition_case_1 (Feval, sexpr, Qt,
- safe_eval_handler);
- UNGCPRO;
- val = unbind_to (count, val);
- }
-
- return val;
-}
-
-
/* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
Return the result, or nil if something went wrong. Prevent
redisplay during the evaluation. */
return safe_call (2, args);
}
+static Lisp_Object Qeval;
+
+Lisp_Object
+safe_eval (Lisp_Object sexpr)
+{
+ return safe_call1 (Qeval, sexpr);
+}
+
+/* Call function FN with one argument ARG.
+ Return the result, or nil if something went wrong. */
+
+Lisp_Object
+safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
+{
+ Lisp_Object args[3];
+ args[0] = fn;
+ args[1] = arg1;
+ args[2] = arg2;
+ return safe_call (3, args);
+}
+
\f
/***********************************************************************
follows. This is like `next-overlay-change' but doesn't use
xmalloc. */
-static int
+static EMACS_INT
next_overlay_change (pos)
- int pos;
+ EMACS_INT pos;
{
int noverlays;
- int endpos;
+ EMACS_INT endpos;
Lisp_Object *overlays;
int i;
for (i = 0; i < noverlays; ++i)
{
Lisp_Object oend;
- int oendpos;
+ EMACS_INT oendpos;
oend = OVERLAY_END (overlays[i]);
oendpos = OVERLAY_POSITION (oend);
handle_face_prop (it)
struct it *it;
{
- int new_face_id, next_stop;
+ int new_face_id;
+ EMACS_INT next_stop;
if (!STRINGP (it->string))
{
int before_p;
{
int face_id, limit;
- int next_check_charpos;
+ EMACS_INT next_check_charpos;
struct text_pos pos;
xassert (it->s == NULL);
`display' property yet. The call to pop_it in
set_iterator_to_next will clean this up. */
if (BUFFERP (object))
- it->current.pos = start_pos;
+ *position = start_pos;
}
else if (CONSP (value) && EQ (XCAR (value), Qspace))
{
it->method = GET_FROM_STRETCH;
it->object = value;
- it->position = start_pos;
- if (BUFFERP (object))
- it->current.pos = start_pos;
+ *position = it->position = start_pos;
}
#ifdef HAVE_WINDOW_SYSTEM
else
/* Say that we haven't consumed the characters with
`display' property yet. The call to pop_it in
set_iterator_to_next will clean this up. */
- if (BUFFERP (object))
- it->current.pos = start_pos;
+ *position = start_pos;
}
#endif /* HAVE_WINDOW_SYSTEM */
val = Qnil;
}
}
- if (NILP (val))
+ if (NILP (val) && ! STRINGP (it->string))
{
if (limit < 0)
limit = (STRINGP (it->string) ? SCHARS (it->string)
#ifdef USE_FONT_BACKEND
if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
{
+ /* FIXME: This doesn't do anything!?! */
Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
->key_and_value,
cmp->hash_index * 2);
/* If we're at the end of the buffer, record that we have
processed the overlay strings there already, so that
next_element_from_buffer doesn't try it again. */
- if (IT_CHARPOS (*it) >= it->end_charpos)
+ if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
it->overlay_strings_at_end_processed_p = 1;
/* If we have to display `...' for invisible text, set
get_overlay_strings_1 (it, charpos, compute_stop_p)
struct it *it;
int charpos;
+ int compute_stop_p;
{
/* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
process. This fills IT->overlay_strings with strings, and sets
next_element_from_stretch
};
+#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
/* Load IT's display element fields with information about the next
display element from the current position of IT. Value is zero if
int success_p;
get_next:
- success_p = (*get_next_element[it->method]) (it);
+ success_p = GET_NEXT_DISPLAY_ELEMENT (it);
if (it->what == IT_CHARACTER)
{
can be defined in the display table. Fill
IT->ctl_chars with glyphs for what we have to
display. Then, set IT->dpvec to these glyphs. */
- GLYPH g;
+ Lisp_Object gc;
int ctl_len;
int face_id, lface_id = 0 ;
- GLYPH escape_glyph;
+ int escape_glyph;
/* Handle control characters with ^. */
if (it->c < 128 && it->ctl_arrow_p)
{
+ int g;
+
g = '^'; /* default glyph for Control */
/* Set IT->ctl_chars[0] to the glyph for `^'. */
if (it->dp
- && INTEGERP (DISP_CTRL_GLYPH (it->dp))
- && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
+ && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
{
- g = XINT (DISP_CTRL_GLYPH (it->dp));
- lface_id = FAST_GLYPH_FACE (g);
+ g = GLYPH_CODE_CHAR (gc);
+ lface_id = GLYPH_CODE_FACE (gc);
}
if (lface_id)
{
- g = FAST_GLYPH_CHAR (g);
- face_id = merge_faces (it->f, Qt, lface_id,
- it->face_id);
+ face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
}
else if (it->f == last_escape_glyph_frame
&& it->face_id == last_escape_glyph_face_id)
}
XSETINT (it->ctl_chars[0], g);
- g = it->c ^ 0100;
- XSETINT (it->ctl_chars[1], g);
+ XSETINT (it->ctl_chars[1], it->c ^ 0100);
ctl_len = 2;
goto display_control;
}
face_id = merge_faces (it->f, Qnobreak_space, 0,
it->face_id);
- g = it->c = ' ';
- XSETINT (it->ctl_chars[0], g);
+ it->c = ' ';
+ XSETINT (it->ctl_chars[0], ' ');
ctl_len = 1;
goto display_control;
}
escape_glyph = '\\';
if (it->dp
- && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
- && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
+ && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
{
- escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
- lface_id = FAST_GLYPH_FACE (escape_glyph);
+ escape_glyph = GLYPH_CODE_CHAR (gc);
+ lface_id = GLYPH_CODE_FACE (gc);
}
if (lface_id)
{
/* The display table specified a face.
Merge it into face_id and also into escape_glyph. */
- escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
face_id = merge_faces (it->f, Qt, lface_id,
it->face_id);
}
if (EQ (Vnobreak_char_display, Qt)
&& it->c == 0xAD)
{
- g = it->c = '-';
- XSETINT (it->ctl_chars[0], g);
+ it->c = '-';
+ XSETINT (it->ctl_chars[0], '-');
ctl_len = 1;
goto display_control;
}
if (it->c == 0xA0 || it->c == 0xAD)
{
XSETINT (it->ctl_chars[0], escape_glyph);
- g = it->c = (it->c == 0xA0 ? ' ' : '-');
- XSETINT (it->ctl_chars[1], g);
+ it->c = (it->c == 0xA0 ? ' ' : '-');
+ XSETINT (it->ctl_chars[1], it->c);
ctl_len = 2;
goto display_control;
}
for (i = 0; i < len; i++)
{
+ int g;
XSETINT (it->ctl_chars[i * 4], escape_glyph);
/* Insert three more glyphs into IT->ctl_chars for
the octal display of the character. */
next_element_from_display_vector (it)
struct it *it;
{
+ Lisp_Object gc;
+
/* Precondition. */
xassert (it->dpvec && it->current.dpvec_index >= 0);
it->face_id = it->saved_face_id;
- if (INTEGERP (*it->dpvec)
- && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
- {
- GLYPH g;
+ /* KFS: This code used to check ip->dpvec[0] instead of the current element.
+ That seemed totally bogus - so I changed it... */
- g = XFASTINT (it->dpvec[it->current.dpvec_index]);
- it->c = FAST_GLYPH_CHAR (g);
+ if ((gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
+ {
+ it->c = GLYPH_CODE_CHAR (gc);
it->len = CHAR_BYTES (it->c);
/* The entry may contain a face id to use. Such a face id is
it->face_id = it->dpvec_face_id;
else
{
- int lface_id = FAST_GLYPH_FACE (g);
+ 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);
/* Since a handler may have changed IT->method, we must
recurse here. */
- return get_next_display_element (it);
+ return GET_NEXT_DISPLAY_ELEMENT (it);
}
if (it->current.overlay_string_index >= 0)
it->face_before_selective_p = 1;
}
- return get_next_display_element (it);
+ return GET_NEXT_DISPLAY_ELEMENT (it);
}
}
if (overlay_strings_follow_p)
- success_p = get_next_display_element (it);
+ success_p = GET_NEXT_DISPLAY_ELEMENT (it);
else
{
it->what = IT_EOB;
else
{
handle_stop (it);
- return get_next_display_element (it);
+ return GET_NEXT_DISPLAY_ELEMENT (it);
}
}
else
{
Lisp_Object msg;
- if (NILP (echo_area_buffer[0]))
+ if (!BUFFERP (echo_area_buffer[0]))
msg = Qnil;
else
{
static Lisp_Object Vmode_line_unwind_vector;
static Lisp_Object
-format_mode_line_unwind_data (obuf, save_proptrans)
- struct buffer *obuf;
+format_mode_line_unwind_data (struct buffer *obuf,
+ Lisp_Object owin,
+ int save_proptrans)
{
Lisp_Object vector, tmp;
Vmode_line_unwind_vector = Qnil;
if (NILP (vector))
- vector = Fmake_vector (make_number (7), Qnil);
+ vector = Fmake_vector (make_number (8), Qnil);
ASET (vector, 0, make_number (mode_line_target));
ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
else
tmp = Qnil;
ASET (vector, 6, tmp);
+ ASET (vector, 7, owin);
return vector;
}
mode_line_string_face = AREF (vector, 4);
mode_line_string_face_prop = AREF (vector, 5);
+ if (!NILP (AREF (vector, 7)))
+ /* Select window before buffer, since it may change the buffer. */
+ Fselect_window (AREF (vector, 7), Qt);
+
if (!NILP (AREF (vector, 6)))
{
set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
mode_line_target so that display_mode_element will output into
mode_line_noprop_buf; then display the title. */
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (current_buffer, 0));
+ format_mode_line_unwind_data
+ (current_buffer, selected_window, 0));
+ Fselect_window (f->selected_window, Qt);
set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
selected_frame = frame;
- for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
- if (CONSP (XCAR (tail))
- && (sym = XCAR (XCAR (tail)),
- SYMBOLP (sym))
- && (sym = indirect_variable (sym),
- val = SYMBOL_VALUE (sym),
- (BUFFER_LOCAL_VALUEP (val)))
- && XBUFFER_LOCAL_VALUE (val)->check_frame)
- /* Use find_symbol_value rather than Fsymbol_value
- to avoid an error if it is void. */
- find_symbol_value (sym);
-
- for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
- if (CONSP (XCAR (tail))
- && (sym = XCAR (XCAR (tail)),
- SYMBOLP (sym))
- && (sym = indirect_variable (sym),
- val = SYMBOL_VALUE (sym),
- (BUFFER_LOCAL_VALUEP (val)))
- && XBUFFER_LOCAL_VALUE (val)->check_frame)
- find_symbol_value (sym);
+ do
+ {
+ for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
+ if (CONSP (XCAR (tail))
+ && (sym = XCAR (XCAR (tail)),
+ SYMBOLP (sym))
+ && (sym = indirect_variable (sym),
+ val = SYMBOL_VALUE (sym),
+ (BUFFER_LOCAL_VALUEP (val)))
+ && XBUFFER_LOCAL_VALUE (val)->check_frame)
+ /* Use find_symbol_value rather than Fsymbol_value
+ to avoid an error if it is void. */
+ find_symbol_value (sym);
+ } while (!EQ (frame, old) && (frame = old, 1));
}
}
}
+ if (!EQ (old_frame, selected_frame)
+ && FRAME_LIVE_P (XFRAME (old_frame)))
+ /* We played a bit fast-and-loose above and allowed selected_frame
+ and selected_window to be temporarily out-of-sync but let's make
+ sure this stays contained. */
+ select_frame_for_redisplay (old_frame);
+ eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
+
if (!pause)
{
/* Do the mark_window_display_accurate after all windows have
#ifdef HAVE_WINDOW_SYSTEM
if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
{
- clear_image_caches (0);
+ clear_image_caches (Qnil);
clear_image_cache_count = 0;
}
#endif /* HAVE_WINDOW_SYSTEM */
/* Display must not have been paused, otherwise the current matrix
is not up to date. */
- if (NILP (w->window_end_valid))
- abort ();
+ eassert (!NILP (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
}
}
- if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
- abort ();
+ eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
return row_found;
}
}
else
{
- delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
+ delta = delta_bytes = dvpos = dy
+ = run.current_y = run.desired_y = run.height = 0;
first_unchanged_at_end_row = NULL;
}
IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
it.base_face_id = it.face_id = DEFAULT_FACE_ID;
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (NULL, 0));
+ format_mode_line_unwind_data (NULL, Qnil, 0));
mode_line_target = MODE_LINE_DISPLAY;
int multibyte;
int bytepos, charpos;
unsigned char *spec;
- Lisp_Object string;
bytepos = percent_position;
charpos = (STRING_MULTIBYTE (elt)
? string_byte_to_char (elt, bytepos)
: bytepos);
- spec = decode_mode_spec (it->w, c, field, prec, &multibyte,
- &string);
+ spec
+ = decode_mode_spec (it->w, c, field, prec, &multibyte);
switch (mode_line_target)
{
break;
case MODE_LINE_STRING:
{
- if (NILP (string))
- {
- int len = strlen (spec);
- string = make_string (spec, len);
- }
+ int len = strlen (spec);
+ Lisp_Object tem = make_string (spec, len);
props = Ftext_properties_at (make_number (charpos), elt);
/* Should only keep face property in props */
- n += store_mode_line_string (NULL, string, 0, field, prec, props);
+ n += store_mode_line_string (NULL, tem, 0, field, prec, props);
}
break;
case MODE_LINE_DISPLAY:
{
int nglyphs_before, nwritten;
- if (STRINGP (string))
- spec = NULL;
nglyphs_before = it->glyph_row->used[TEXT_AREA];
- nwritten = display_string (spec, string, elt,
+ nwritten = display_string (spec, Qnil, elt,
charpos, 0, it,
field, prec, 0,
multibyte);
/* Save things including mode_line_proptrans_alist,
and set that to nil so that we don't alter the outer value. */
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (old_buffer, 1));
+ format_mode_line_unwind_data
+ (old_buffer, selected_window, 1));
mode_line_proptrans_alist = Qnil;
+ Fselect_window (window, Qt);
if (old_buffer)
set_buffer_internal_1 (XBUFFER (buffer));
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
static char *
-decode_mode_spec (w, c, field_width, precision, multibyte, string)
+decode_mode_spec (w, c, field_width, precision, multibyte)
struct window *w;
register int c;
int field_width, precision;
int *multibyte;
- Lisp_Object *string;
{
Lisp_Object obj;
struct frame *f = XFRAME (WINDOW_FRAME (w));
char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
struct buffer *b = current_buffer;
- *string = obj = Qnil;
+ obj = Qnil;
*multibyte = 0;
switch (c)
goto no_value;
}
- if (!NILP (w->base_line_number)
- && !NILP (w->base_line_pos)
+ if (INTEGERP (w->base_line_number)
+ && INTEGERP (w->base_line_pos)
&& XFASTINT (w->base_line_pos) <= startpos)
{
line = XFASTINT (w->base_line_number);
if (STRINGP (obj))
{
*multibyte = STRING_MULTIBYTE (obj);
- *string = obj;
return (char *) SDATA (obj);
}
else
unsigned char *string;
Lisp_Object lisp_string;
Lisp_Object face_string;
- int face_string_pos;
- int start;
+ EMACS_INT face_string_pos;
+ EMACS_INT start;
struct it *it;
int field_width, precision, max_x;
int multibyte;
from LISP_STRING, if that's given. */
if (STRINGP (face_string))
{
- int endptr;
+ EMACS_INT endptr;
struct face *face;
it->face_id
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
voffset = glyph->voffset;
-
+ s->padding_p = glyph->padding_p;
glyph_not_available_p = glyph->glyph_not_available_p;
while (glyph < last
++s->nchars;
xassert (s->nchars <= end - start);
s->width += glyph->pixel_width;
- ++glyph;
+ if (glyph++->padding_p != s->padding_p)
+ break;
}
s->font = s->face->font;
{
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
- glyph->pixel_width = it->pixel_width;
+ if (it->pixel_width > 0)
+ {
+ glyph->pixel_width = it->pixel_width;
+ glyph->padding_p = 0;
+ }
+ else
+ {
+ /* Assure at least 1-pixel width. Otherwise, cursor can't
+ be displayed correctly. */
+ glyph->pixel_width = 1;
+ glyph->padding_p = 1;
+ }
glyph->ascent = it->ascent;
glyph->descent = it->descent;
glyph->voffset = it->voffset;
glyph->right_box_line_p = it->end_of_box_run_p;
glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
|| it->phys_descent > it->descent);
- glyph->padding_p = 0;
glyph->glyph_not_available_p = it->glyph_not_available_p;
glyph->face_id = it->face_id;
glyph->u.ch = it->char_to_display;
if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
it->glyph_row->contains_overlapping_glyphs_p = 1;
}
+ if (! stretched_p && it->pixel_width == 0)
+ /* We assure that all visible glyphs have at least 1-pixel
+ width. */
+ it->pixel_width = 1;
}
else if (it->char_to_display == '\n')
{
if (it->glyph_row)
append_glyph (it);
+ if (it->pixel_width == 0)
+ /* We assure that all visible glyphs have at least 1-pixel
+ width. */
+ it->pixel_width = 1;
}
it->multibyte_p = saved_multibyte_p;
}
int gpos;
int gseq_length;
int total_pixel_width;
- int ignore;
+ EMACS_INT ignore;
int vpos, hpos;
/* Find the range of text around this char that
should be active. */
Lisp_Object before, after;
- int ignore;
+ EMACS_INT ignore;
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
/* Find the range of text around this char that
should be active. */
Lisp_Object before, after, beginning, end;
- int ignore;
+ EMACS_INT ignore;
beginning = Fmarker_position (w->start);
end = make_number (BUF_Z (XBUFFER (object))
else if (!NILP (mouse_face) && STRINGP (object))
{
Lisp_Object b, e;
- int ignore;
+ EMACS_INT ignore;
b = Fprevious_single_property_change (make_number (pos + 1),
Qmouse_face,
{
Lisp_Object before = Foverlay_start (overlay);
Lisp_Object after = Foverlay_end (overlay);
- int ignore;
+ EMACS_INT ignore;
/* Note that we might not be able to find position
BEFORE in the glyph matrix if the overlay is
staticpro (&Qinhibit_point_motion_hooks);
Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
+ Qeval = intern ("eval");
+ staticpro (&Qeval);
+
QCdata = intern (":data");
staticpro (&QCdata);
Qdisplay = intern ("display");