/* Display generation from window structure and buffer text.
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
#include <limits.h>
+#include <setjmp.h>
#include "lisp.h"
#include "keyboard.h"
extern Lisp_Object Qmenu_item;
extern Lisp_Object Qwhen;
extern Lisp_Object Qhelp_echo;
+extern Lisp_Object Qbefore_string, Qafter_string;
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
&& it->current_x == it->last_visible_x \
&& it->line_wrap != WORD_WRAP)
+#else /* !HAVE_WINDOW_SYSTEM */
+#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
#endif /* HAVE_WINDOW_SYSTEM */
/* Test if the display element loaded in IT is a space or tab
static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
-static int string_char_and_length P_ ((const unsigned char *, int, int *));
+static int string_char_and_length P_ ((const unsigned char *, int *));
static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
struct text_pos));
static int compute_window_start_on_continuation_line P_ ((struct window *));
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 *));
+static char *decode_mode_spec P_ ((struct window *, int, int, int,
+ Lisp_Object *));
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,
move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
(charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
- /* Note that we may overshoot because of invisible text. */
if (charpos >= 0 && 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. */
int top_x = it.current_x;
int top_y = it.current_y;
+ enum it_method it_method = it.method;
+ /* Calling line_bottom_y may change it.method, it.position, etc. */
int bottom_y = (last_height = 0, line_bottom_y (&it));
int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
if (top_y < window_top_y)
visible_p = bottom_y > window_top_y;
else if (top_y < it.last_visible_y)
- visible_p = 1;
+ visible_p = 1;
if (visible_p)
{
- if (it.method == GET_FROM_BUFFER)
+ if (it_method == GET_FROM_DISPLAY_VECTOR)
{
- Lisp_Object window, prop;
-
- XSETWINDOW (window, w);
- prop = Fget_char_property (make_number (it.position.charpos),
- Qinvisible, window);
-
- /* If charpos coincides with invisible text covered with an
- ellipsis, use the first glyph of the ellipsis to compute
- the pixel positions. */
- if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
+ /* We stopped on the last glyph of a display vector.
+ Try and recompute. Hack alert! */
+ if (charpos < 2 || top.charpos >= charpos)
+ top_x = it.glyph_row->x;
+ else
{
- struct glyph_row *row = it.glyph_row;
- struct glyph *glyph = row->glyphs[TEXT_AREA];
- struct glyph *end = glyph + row->used[TEXT_AREA];
- int x = row->x;
-
- for (; glyph < end && glyph->charpos < charpos; glyph++)
- x += glyph->pixel_width;
-
- top_x = x;
+ struct it it2;
+ start_display (&it2, w, top);
+ move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
+ get_next_display_element (&it2);
+ PRODUCE_GLYPHS (&it2);
+ if (ITERATOR_AT_END_OF_LINE_P (&it2)
+ || it2.current_x > it2.last_visible_x)
+ top_x = it.glyph_row->x;
+ else
+ {
+ top_x = it2.current_x;
+ top_y = it2.current_y;
+ }
}
}
character. */
static INLINE int
-string_char_and_length (str, maxlen, len)
+string_char_and_length (str, len)
const unsigned char *str;
- int maxlen, *len;
+ int *len;
{
int c;
- c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
+ c = STRING_CHAR_AND_LENGTH (str, *len);
if (!CHAR_VALID_P (c, 1))
/* We may not change the length here because other places in Emacs
don't use this function, i.e. they silently accept invalid
while (nchars--)
{
- string_char_and_length (p, rest, &len);
+ string_char_and_length (p, &len);
p += len, rest -= len;
xassert (rest >= 0);
CHARPOS (pos) += 1;
SET_TEXT_POS (pos, 0, 0);
while (charpos--)
{
- string_char_and_length (s, rest, &len);
+ string_char_and_length (s, &len);
s += len, rest -= len;
xassert (rest >= 0);
CHARPOS (pos) += 1;
for (nchars = 0; rest > 0; ++nchars)
{
- string_char_and_length (p, rest, &len);
+ string_char_and_length (p, &len);
rest -= len, p += len;
}
}
}
/* EXPORT:
- Return an estimation of the pixel height of mode or top lines on
+ Return an estimation of the pixel height of mode or header lines on
frame F. FACE_ID specifies what line's height to estimate. */
int
r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
else
r.y = max (0, s->row->y);
-
- /* If drawing a tool-bar window, draw it over the internal border
- at the top of the window. */
- if (WINDOWP (s->f->tool_bar_window)
- && s->w == XWINDOW (s->f->tool_bar_window))
- r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
}
r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
it->current_x = it->hpos = 0;
}
}
-
-#if 0 /* Don't assert the following because start_display is sometimes
- called intentionally with a window start that is not at a
- line start. Please leave this code in as a comment. */
-
- /* Window start should be on a line start, now. */
- xassert (it->continuation_lines_width
- || IT_CHARPOS (it) == BEGV
- || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
-#endif /* 0 */
}
&next_stop,
(IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT),
- 0);
+ 0, it->base_face_id);
/* Is this a start of a run of characters with box face?
Caveat: this can be called for a freshly initialized
&next_stop,
base_face_id, 0);
-#if 0 /* This shouldn't be neccessary. Let's check it. */
- /* If IT is used to display a mode line we would really like to
- use the mode line face instead of the frame's default face. */
- if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
- && new_face_id == DEFAULT_FACE_ID)
- new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
-#endif
-
/* Is this a start of a run of characters with box? Caveat:
this can be called for a freshly allocated iterator; face_id
is -1 is this case. We know that the new face will not
int c, len;
struct face *face = FACE_FROM_ID (it->f, face_id);
- c = string_char_and_length (p, rest, &len);
+ c = string_char_and_length (p, &len);
face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
}
}
it->region_beg_charpos,
it->region_end_charpos,
&next_check_charpos,
- limit, 0);
+ limit, 0, -1);
/* Correct the face for charsets different from ASCII. Do it
for the multibyte case only. The face returned above is
}
-/* Determine from which buffer position in W's buffer STRING comes
- from. AROUND_CHARPOS is an approximate position where it could
- be from. Value is the buffer position or 0 if it couldn't be
- determined.
+/* Determine which buffer position in W's buffer STRING comes from.
+ AROUND_CHARPOS is an approximate position where it could come from.
+ Value is the buffer position or 0 if it couldn't be determined.
W's buffer must be current.
pos_byte = IT_STRING_BYTEPOS (*it);
string = it->string;
s = SDATA (string) + pos_byte;
- it->c = STRING_CHAR (s, 0);
+ it->c = STRING_CHAR (s);
}
else
{
struct it *it;
int charpos;
{
- extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
+ extern Lisp_Object Qwindow, Qpriority;
Lisp_Object overlay, window, str, invisible;
struct Lisp_Overlay *ov;
int start, end;
p->voffset = it->voffset;
p->string_from_display_prop_p = it->string_from_display_prop_p;
p->display_ellipsis_p = 0;
+ p->line_wrap = it->line_wrap;
++it->sp;
}
case GET_FROM_STRING:
it->object = it->string;
break;
+ case GET_FROM_DISPLAY_VECTOR:
+ if (it->s)
+ it->method = GET_FROM_C_STRING;
+ else if (STRINGP (it->string))
+ it->method = GET_FROM_STRING;
+ else
+ {
+ it->method = GET_FROM_BUFFER;
+ it->object = it->w->buffer;
+ }
}
it->end_charpos = p->end_charpos;
it->string_nchars = p->string_nchars;
it->font_height = p->font_height;
it->voffset = p->voffset;
it->string_from_display_prop_p = p->string_from_display_prop_p;
+ it->line_wrap = p->line_wrap;
}
it->dp = XCHAR_TABLE (Vstandard_display_table);
it->stop_charpos = charpos;
+ if (s == NULL && it->multibyte_p)
+ {
+ EMACS_INT endpos = SCHARS (it->string);
+ if (endpos > it->end_charpos)
+ endpos = it->end_charpos;
+ composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
+ it->string);
+ }
CHECK_IT (it);
}
/* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
(possibly with the following characters). */
-#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS) \
+#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
((IT)->cmp_it.id >= 0 \
|| ((IT)->cmp_it.stop_pos == (CHARPOS) \
&& composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
- (IT)->end_charpos, (IT)->w, \
+ END_CHARPOS, (IT)->w, \
FACE_FROM_ID ((IT)->f, (IT)->face_id), \
(IT)->string)))
if (success_p && it->dpvec == NULL)
{
Lisp_Object dv;
+ struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
+ enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
+ nbsp_or_shy = char_is_other;
+ int c = it->c; /* This is the character to display. */
+
+ if (! it->multibyte_p && ! ASCII_CHAR_P (c))
+ {
+ xassert (SINGLE_BYTE_CHAR_P (c));
+ if (unibyte_display_via_language_environment)
+ {
+ c = DECODE_CHAR (unibyte, c);
+ if (c < 0)
+ c = BYTE8_TO_CHAR (it->c);
+ }
+ else
+ c = BYTE8_TO_CHAR (it->c);
+ }
if (it->dp
- && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
+ && (dv = DISP_CHAR_VECTOR (it->dp, c),
VECTORP (dv)))
{
struct Lisp_Vector *v = XVECTOR (dv);
goto get_next;
}
+ if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
+ nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
+ : c == 0xAD ? char_is_soft_hyphen
+ : char_is_other);
+
/* Translate control characters into `\003' or `^C' form.
Control characters coming from a display table entry are
currently not translated because we use IT->dpvec to hold
the translation. This could easily be changed but I
don't believe that it is worth doing.
- If it->multibyte_p is nonzero, non-printable non-ASCII
- characters are also translated to octal form.
+ NBSP and SOFT-HYPEN are property translated too.
- If it->multibyte_p is zero, eight-bit characters that
- don't have corresponding multibyte char code are also
+ Non-printable characters and raw-byte characters are also
translated to octal form. */
- else if ((it->c < ' '
- ? (it->area != TEXT_AREA
- /* In mode line, treat \n, \t like other crl chars. */
- || (it->c != '\t'
- && it->glyph_row && it->glyph_row->mode_line_p)
- || (it->c != '\n' && it->c != '\t'))
- : (it->multibyte_p
- ? (!CHAR_PRINTABLE_P (it->c)
- || (!NILP (Vnobreak_char_display)
- && (it->c == 0xA0 /* NO-BREAK SPACE */
- || it->c == 0xAD /* SOFT HYPHEN */)))
- : (it->c >= 127
- && (! unibyte_display_via_language_environment
- || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
+ if (((c < ' ' || c == 127) /* ASCII control chars */
+ ? (it->area != TEXT_AREA
+ /* In mode line, treat \n, \t like other crl chars. */
+ || (c != '\t'
+ && it->glyph_row
+ && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
+ || (c != '\n' && c != '\t'))
+ : (nbsp_or_shy
+ || CHAR_BYTE8_P (c)
+ || ! CHAR_PRINTABLE_P (c))))
{
- /* IT->c is a control character which must be displayed
+ /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
+ or a non-printable character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
can be defined in the display table. Fill
IT->ctl_chars with glyphs for what we have to
/* Handle control characters with ^. */
- if (it->c < 128 && it->ctl_arrow_p)
+ if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
{
int g;
}
XSETINT (it->ctl_chars[0], g);
- XSETINT (it->ctl_chars[1], it->c ^ 0100);
+ XSETINT (it->ctl_chars[1], c ^ 0100);
ctl_len = 2;
goto display_control;
}
highlighting. */
if (EQ (Vnobreak_char_display, Qt)
- && it->c == 0xA0)
+ && nbsp_or_shy == char_is_nbsp)
{
/* Merge the no-break-space face into the current face. */
face_id = merge_faces (it->f, Qnobreak_space, 0,
it->face_id);
- it->c = ' ';
+ c = ' ';
XSETINT (it->ctl_chars[0], ' ');
ctl_len = 1;
goto display_control;
highlighting. */
if (EQ (Vnobreak_char_display, Qt)
- && it->c == 0xAD)
+ && nbsp_or_shy == char_is_soft_hyphen)
{
- it->c = '-';
XSETINT (it->ctl_chars[0], '-');
ctl_len = 1;
goto display_control;
/* Handle non-break space and soft hyphen
with the escape glyph. */
- if (it->c == 0xA0 || it->c == 0xAD)
+ if (nbsp_or_shy)
{
XSETINT (it->ctl_chars[0], escape_glyph);
- it->c = (it->c == 0xA0 ? ' ' : '-');
- XSETINT (it->ctl_chars[1], it->c);
+ c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
+ XSETINT (it->ctl_chars[1], c);
ctl_len = 2;
goto display_control;
}
{
- unsigned char str[MAX_MULTIBYTE_LENGTH];
- int len;
- int i;
+ char str[10];
+ int len, i;
- /* Set IT->ctl_chars[0] to the glyph for `\\'. */
- if (CHAR_BYTE8_P (it->c))
- {
- str[0] = CHAR_TO_BYTE8 (it->c);
- len = 1;
- }
- else if (it->c < 256)
- {
- str[0] = it->c;
- len = 1;
- }
- else
- {
- /* It's an invalid character, which shouldn't
- happen actually, but due to bugs it may
- happen. Let's print the char as is, there's
- not much meaningful we can do with it. */
- str[0] = it->c;
- str[1] = it->c >> 8;
- str[2] = it->c >> 16;
- str[3] = it->c >> 24;
- len = 4;
- }
+ if (CHAR_BYTE8_P (c))
+ /* Display \200 instead of \17777600. */
+ c = CHAR_TO_BYTE8 (c);
+ len = sprintf (str, "%03o", c);
+ XSETINT (it->ctl_chars[0], escape_glyph);
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. */
- g = ((str[i] >> 6) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 1], g);
- g = ((str[i] >> 3) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 2], g);
- g = (str[i] & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 3], g);
- }
- ctl_len = len * 4;
+ XSETINT (it->ctl_chars[i + 1], str[i]);
+ ctl_len = len + 1;
}
display_control:
it->ellipsis_p = 0;
goto get_next;
}
+ it->char_to_display = c;
+ }
+ else if (success_p)
+ {
+ it->char_to_display = it->c;
}
}
: STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
: IT_CHARPOS (*it));
- it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
+ it->string);
}
}
#endif
next_face_id = face_at_buffer_position
(it->w, CHARPOS (pos), it->region_beg_charpos,
it->region_end_charpos, &ignore,
- (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0);
+ (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
+ -1);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
or `\003'.
IT->dpvec holds the glyphs to return as characters.
- IT->saved_face_id holds the face id before the display vector--
- it is restored into IT->face_idin set_iterator_to_next. */
+ IT->saved_face_id holds the face id before the display vector--it
+ is restored into IT->face_id in set_iterator_to_next. */
static int
next_element_from_display_vector (it)
return 0;
}
else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
- IT_STRING_BYTEPOS (*it))
+ IT_STRING_BYTEPOS (*it), SCHARS (it->string))
&& next_element_from_composition (it))
{
return 1;
int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
const unsigned char *s = (SDATA (it->string)
+ IT_STRING_BYTEPOS (*it));
- it->c = string_char_and_length (s, remaining, &it->len);
+ it->c = string_char_and_length (s, &it->len);
}
else
{
CHARPOS (position) = BYTEPOS (position) = -1;
}
else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
- IT_STRING_BYTEPOS (*it))
+ IT_STRING_BYTEPOS (*it), it->string_nchars)
&& next_element_from_composition (it))
{
return 1;
int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
const unsigned char *s = (SDATA (it->string)
+ IT_STRING_BYTEPOS (*it));
- it->c = string_char_and_length (s, maxlen, &it->len);
+ it->c = string_char_and_length (s, &it->len);
}
else
{
performance problem because there is no noticeable performance
difference between Emacs running in unibyte or multibyte mode. */
int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
- it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
- maxlen, &it->len);
+ it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
}
else
it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
/* Set up IT to return characters from an ellipsis, if appropriate.
The definition of the ellipsis glyphs may come from a display table
- entry. This function Fills IT with the first glyph from the
+ entry. This function fills IT with the first glyph from the
ellipsis if an ellipsis is to be displayed. */
static int
struct it *it;
{
it->what = IT_IMAGE;
+ it->ignore_overlay_strings_at_pos_p = 0;
return 1;
}
&& IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
run_redisplay_end_trigger_hook (it);
- if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
+ if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
+ it->end_charpos)
&& next_element_from_composition (it))
{
return 1;
/* Get the next character, maybe multibyte. */
p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
if (it->multibyte_p && !ASCII_BYTE_P (*p))
- it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
+ it->c = STRING_CHAR_AND_LENGTH (p, it->len);
else
it->c = *p, it->len = 1;
/* The number of glyphs we get back in IT->nglyphs will normally
be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
character on a terminal frame, or (iii) a line end. For the
- second case, IT->nglyphs - 1 padding glyphs will be present
- (on X frames, there is only one glyph produced for a
- composite character.
+ second case, IT->nglyphs - 1 padding glyphs will be present.
+ (On X frames, there is only one glyph produced for a
+ composite character.)
The behavior implemented below means, for continuation lines,
that as many spaces of a TAB as fit on the current line are
}
set_iterator_to_next (it, 1);
-#ifdef HAVE_WINDOW_SYSTEM
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ /* On graphical terminals, newlines may
+ "overflow" into the fringe if
+ overflow-newline-into-fringe is non-nil.
+ On text-only terminals, newlines may
+ overflow into the last glyph on the
+ display line.*/
+ if (!FRAME_WINDOW_P (it->f)
+ || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it))
{
break;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
}
}
else
if (it->line_wrap == TRUNCATE
&& it->current_x >= it->last_visible_x)
{
-#ifdef HAVE_WINDOW_SYSTEM
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ if (!FRAME_WINDOW_P (it->f)
+ || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it)
|| BUFFER_POS_REACHED_P ())
break;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
result = MOVE_LINE_TRUNCATED;
break;
}
int op;
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
- int line_height;
- int reached = 0;
+ int line_height, line_start_x = 0, reached = 0;
for (;;)
{
if (it->current_x != it->last_visible_x
&& (op & MOVE_TO_VPOS)
&& !(op & (MOVE_TO_X | MOVE_TO_POS)))
- set_iterator_to_next (it, 0);
+ {
+ line_start_x = it->current_x + it->pixel_width
+ - it->last_visible_x;
+ set_iterator_to_next (it, 0);
+ }
}
else
it->continuation_lines_width += it->current_x;
/* Reset/increment for the next run. */
recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
- it->current_x = it->hpos = 0;
+ it->current_x = line_start_x;
+ line_start_x = 0;
+ it->hpos = 0;
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
value of nlines is > 0 if continuation lines were involved. */
if (nlines > 0)
move_it_by_lines (it, nlines, 1);
-#if 0
- /* I think this assert is bogus if buffer contains
- invisible text or images. KFS. */
- xassert (IT_CHARPOS (*it) <= start_pos);
-#endif
}
else
{
}
while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
}
-
-#if 0
- /* I think this assert is bogus if buffer contains
- invisible text or images. KFS. */
- xassert (IT_CHARPOS (*it) >= BEGV);
-#endif
}
}
}
for the *Message* buffer. */
for (i = 0; i < nbytes; i += char_bytes)
{
- c = string_char_and_length (m + i, nbytes - i, &char_bytes);
+ c = string_char_and_length (m + i, &char_bytes);
work[0] = (ASCII_CHAR_P (c)
? c
: multibyte_char_to_unibyte (c, Qnil));
for (i = 0; i < nbytes; i++)
{
c = msg[i];
- c = unibyte_char_to_multibyte (c);
+ MAKE_CHAR_MULTIBYTE (c);
char_bytes = CHAR_STRING (c, str);
insert_1_both (str, 1, char_bytes, 1, 0, 0);
}
/* Convert a multibyte string to single-byte. */
for (i = 0; i < nbytes; i += n)
{
- c = string_char_and_length (s + i, nbytes - i, &n);
+ c = string_char_and_length (s + i, &n);
work[0] = (ASCII_CHAR_P (c)
? c
: multibyte_char_to_unibyte (c, Qnil));
for (i = 0; i < nbytes; i++)
{
c = msg[i];
- c = unibyte_char_to_multibyte (c);
+ MAKE_CHAR_MULTIBYTE (c);
n = CHAR_STRING (c, str);
insert_1_both (str, 1, n, 1, 0, 0);
}
if (! STRINGP (f->name)
|| SBYTES (f->name) != len
|| bcmp (title, SDATA (f->name), len) != 0)
- {
-#ifdef HAVE_NS
- if (FRAME_NS_P (f))
- {
- if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
- {
- if (EQ (fmt, Qt))
- ns_set_name_as_filename (f);
- else
- x_implicitly_set_name (f, make_string(title, len),
- Qnil);
- }
- }
- else
-#endif
- x_implicitly_set_name (f, make_string (title, len), Qnil);
- }
-#ifdef HAVE_NS
- if (FRAME_NS_P (f))
- {
- /* do this also for frames with explicit names */
- ns_implicitly_set_icon_type(f);
- ns_set_doc_edited(f, Fbuffer_modified_p
- (XWINDOW (f->selected_window)->buffer), Qnil);
- }
-#endif
+ x_implicitly_set_name (f, make_string (title, len), Qnil);
}
}
menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
#ifdef HAVE_WINDOW_SYSTEM
update_tool_bar (f, 0);
+#endif
+#ifdef HAVE_NS
+ if (windows_or_buffers_changed
+ && FRAME_NS_P (f))
+ ns_set_doc_edited (f, Fbuffer_modified_p
+ (XWINDOW (f->selected_window)->buffer));
#endif
UNGCPRO;
}
struct frame *f;
int save_match_data;
{
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
struct it it;
struct glyph_row *row;
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
}
}
-
/* Notice any pending interrupt request to change frame size. */
do_pending_window_change (1);
&& PT >= CHARPOS (tlbufpos)
&& PT <= Z - CHARPOS (tlendpos)
/* All text outside that line, including its final newline,
- must be unchanged */
+ must be unchanged. */
&& text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
CHARPOS (tlendpos)))
{
&& FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
&& (CHARPOS (tlbufpos) == ZV
|| FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
- /* Former continuation line has disappeared by becoming empty */
+ /* Former continuation line has disappeared by becoming empty. */
goto cancel;
else if (XFASTINT (w->last_modified) < MODIFF
|| XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
|| MINI_WINDOW_P (w))
{
/* We have to handle the case of continuation around a
- wide-column character (See the comment in indent.c around
- line 885).
+ wide-column character (see the comment in indent.c around
+ line 1340).
For instance, in the following case:
^^ ^^
-------- --------
- As we have to redraw the line above, we should goto cancel. */
+ As we have to redraw the line above, we cannot use this
+ optimization. */
struct it it;
int line_height_before = this_line_pixel_height;
/* Note that start_display will handle the case that the
- line starting at tlbufpos is a continuation lines. */
+ line starting at tlbufpos is a continuation line. */
start_display (&it, w, tlbufpos);
/* Implementation note: It this still necessary? */
display_line (&it);
/* If line contains point, is not continued,
- and ends at same distance from eob as before, we win */
+ and ends at same distance from eob as before, we win. */
if (w->cursor.vpos >= 0
/* Line is not continued, otherwise this_line_start_pos
would have been set to 0 in display_line. */
= MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
int delta, delta_bytes;
- if (Z - CHARPOS (tlendpos) == ZV)
- {
- /* This line ends at end of (accessible part of)
- buffer. There is no newline to count. */
- delta = (Z
- - CHARPOS (tlendpos)
- - MATRIX_ROW_START_CHARPOS (row));
- delta_bytes = (Z_BYTE
- - BYTEPOS (tlendpos)
- - MATRIX_ROW_START_BYTEPOS (row));
- }
- else
- {
- /* This line ends in a newline. Must take
- account of the newline and the rest of the
- text that follows. */
- delta = (Z
- - CHARPOS (tlendpos)
- - MATRIX_ROW_START_CHARPOS (row));
- delta_bytes = (Z_BYTE
- - BYTEPOS (tlendpos)
- - MATRIX_ROW_START_BYTEPOS (row));
- }
+ /* We used to distinguish between two cases here,
+ conditioned by Z - CHARPOS (tlendpos) == ZV, for
+ when the line ends in a newline or the end of the
+ buffer's accessible portion. But both cases did
+ the same, so they were collapsed. */
+ delta = (Z
+ - CHARPOS (tlendpos)
+ - MATRIX_ROW_START_CHARPOS (row));
+ delta_bytes = (Z_BYTE
+ - BYTEPOS (tlendpos)
+ - MATRIX_ROW_START_BYTEPOS (row));
increment_matrix_positions (w->current_matrix,
this_line_vpos + 1,
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
redisplay_windows (FRAME_ROOT_WINDOW (f));
+ /* The X error handler may have deleted that frame. */
+ if (!FRAME_LIVE_P (f))
+ continue;
+
/* Any scroll bars which redisplay_windows should have
nuked should now go away. */
if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
redisplay_windows (w->hchild);
else if (!NILP (w->vchild))
redisplay_windows (w->vchild);
- else
+ else if (!NILP (w->buffer))
{
displayed_buffer = XBUFFER (w->buffer);
/* Use list_of_error, not Qerror, so that
/* Set cursor position of W. PT is assumed to be displayed in ROW.
- DELTA is the number of bytes by which positions recorded in ROW
- differ from current buffer positions.
+ DELTA and DELTA_BYTES are the numbers of characters and bytes by
+ which positions recorded in ROW differ from current buffer
+ positions.
- Return 0 if cursor is not on this row. 1 otherwise. */
+ Return 0 if cursor is not on this row, 1 otherwise. */
int
set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
struct glyph *glyph = row->glyphs[TEXT_AREA];
struct glyph *end = glyph + row->used[TEXT_AREA];
struct glyph *cursor = NULL;
- /* The first glyph that starts a sequence of glyphs from string. */
+ /* The first glyph that starts a sequence of glyphs from a string
+ that is a value of a display property. */
struct glyph *string_start;
/* The X coordinate of string_start. */
int string_start_x;
- /* The last known character position. */
+ /* The last known character position in row. */
int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
/* The last known character position before string_start. */
int string_before_pos;
int x = row->x;
int cursor_x = x;
+ /* Last buffer position covered by an overlay. */
int cursor_from_overlay_pos = 0;
int pt_old = PT - delta;
string_start = NULL;
x += glyph->pixel_width;
++glyph;
+ /* If we are beyond the cursor position computed from the
+ last overlay seen, that overlay is not in effect for
+ current cursor position. Reset the cursor information
+ computed from that overlay. */
if (cursor_from_overlay_pos
&& last_pos >= cursor_from_overlay_pos)
{
cursor_from_overlay_pos = 0;
- cursor = 0;
+ cursor = NULL;
}
}
else
string_start = glyph;
string_start_x = x;
}
- /* Skip all glyphs from string. */
+ /* Skip all glyphs from a string. */
do
{
Lisp_Object cprop;
!NILP (cprop))
&& (pos = string_buffer_position (w, glyph->object,
string_before_pos),
- (pos == 0 /* From overlay */
+ (pos == 0 /* from overlay */
|| pos == pt_old)))
{
- /* Estimate overlay buffer position from the buffer
- positions of the glyphs before and after the overlay.
- Add 1 to last_pos so that if point corresponds to the
- glyph right after the overlay, we still use a 'cursor'
- property found in that overlay. */
+ /* Compute the first buffer position after the overlay.
+ If the `cursor' property tells us how many positions
+ are associated with the overlay, use that. Otherwise,
+ estimate from the buffer positions of the glyphs
+ before and after the overlay. */
cursor_from_overlay_pos = (pos ? 0 : last_pos
+ (INTEGERP (cprop) ? XINT (cprop) : 0));
cursor = glyph;
while (glyph > row->glyphs[TEXT_AREA]
&& (glyph - 1)->charpos == last_pos)
glyph--, x -= glyph->pixel_width;
- /* That loop always goes one position too far,
- including the glyph before the ellipsis.
- So scan forward over that one. */
+ /* That loop always goes one position too far, including the
+ glyph before the ellipsis. So scan forward over that one. */
x += glyph->pixel_width;
glyph++;
}
x = string_start_x;
string = glyph->object;
pos = string_buffer_position (w, string, string_before_pos);
- /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
- because we always put cursor after overlay strings. */
+ /* If POS == 0, STRING is from overlay. We skip such glyphs
+ because we always put the cursor after overlay strings. */
while (pos == 0 && glyph < stop)
{
string = glyph->object;
}
}
- /* If we reached the end of the line, and end was from a string,
- cursor is not on this line. */
+ /* If we reached the end of the line, and END was from a string,
+ the cursor is not on this line. */
if (glyph == end && row->continued_p)
return 0;
}
return 1;
}
return 0;
-
-#if 0
- /* This code used to try to scroll the window just enough to make
- the line visible. It returned 0 to say that the caller should
- allocate larger glyph matrices. */
-
- if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
- {
- int dy = row->height - row->visible_height;
- w->vscroll = 0;
- w->cursor.y += dy;
- shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
- }
- else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
- {
- int dy = - (row->height - row->visible_height);
- w->vscroll = dy;
- w->cursor.y += dy;
- shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
- }
-
- /* When we change the cursor y-position of the selected window,
- change this_line_y as well so that the display optimization for
- the cursor line of the selected window in redisplay_internal uses
- the correct y-position. */
- if (w == XWINDOW (selected_window))
- this_line_y = w->cursor.y;
-
- /* If vscrolling requires a larger glyph matrix, arrange for a fresh
- redisplay with larger matrices. */
- if (matrix->nrows < required_matrix_height (w))
- {
- fonts_changed_p = 1;
- return 0;
- }
-
- return 1;
-#endif /* 0 */
}
used_current_matrix_p = 1;
goto done;
-#if 0 /* try_cursor_movement never returns this value. */
- case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
- goto need_larger_matrices;
-#endif
-
case CURSOR_MOVEMENT_MUST_SCROLL:
goto try_to_scroll;
= try_window_reusing_current_matrix (w)))
{
IF_DEBUG (debug_method_add (w, "1"));
- if (try_window (window, startp, 1) < 0)
+ if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
/* -1 means we need to scroll.
0 means we need new matrices, but fonts_changed_p
is set in that case, so we will detect it below. */
= DESIRED_MODE_LINE_HEIGHT (w);
}
- /* If top line height has changed, arrange for a thorough
- immediate redisplay using the correct mode line height. */
+ /* If header line height has changed, arrange for a thorough
+ immediate redisplay using the correct header line height. */
if (WINDOW_WANTS_HEADER_LINE_P (w)
&& CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
{
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
(*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
}
- /* Restore current_buffer and value of point in it. */
- TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+ /* Restore current_buffer and value of point in it. The window
+ update may have changed the buffer, so first make sure `opoint'
+ is still valid (Bug#6177). */
+ if (CHARPOS (opoint) < BEGV)
+ TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+ else if (CHARPOS (opoint) > ZV)
+ TEMP_SET_PT_BOTH (Z, Z_BYTE);
+ else
+ TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+
set_buffer_internal_1 (old);
/* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
shorter. This can be caused by log truncation in *Messages*. */
Value is 1 if successful. It is zero if fonts were loaded during
redisplay which makes re-adjusting glyph matrices necessary, and -1
if point would appear in the scroll margins.
- (We check that only if CHECK_MARGINS is nonzero. */
+ (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
+ unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
+ set in FLAGS.) */
int
-try_window (window, pos, check_margins)
+try_window (window, pos, flags)
Lisp_Object window;
struct text_pos pos;
- int check_margins;
+ int flags;
{
struct window *w = XWINDOW (window);
struct it it;
{
if (display_line (&it))
last_text_row = it.glyph_row - 1;
- if (fonts_changed_p)
+ if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
return 0;
}
/* Don't let the cursor end in the scroll margins. */
- if (check_margins
+ if ((flags & TRY_WINDOW_CHECK_MARGINS)
&& !MINI_WINDOW_P (w))
{
int this_scroll_margin;
if (row < bottom_row)
{
struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
- while (glyph->charpos < PT)
+ struct glyph *end = glyph + row->used[TEXT_AREA];
+
+ for (; glyph < end
+ && (!BUFFERP (glyph->object)
+ || glyph->charpos < PT);
+ glyph++)
{
w->cursor.hpos++;
w->cursor.x += glyph->pixel_width;
- glyph++;
}
}
}
|| !WINDOW_FULL_WIDTH_P (w)))
GIVE_UP (4);
- /* Give up if point is not known NOT to appear in W. */
+ /* Give up if point is known NOT to appear in W. */
if (PT < CHARPOS (start))
GIVE_UP (5);
if (!NILP (w->region_showing))
GIVE_UP (10);
- /* Can use this if overlay arrow position and or string have changed. */
+ /* Can't use this if overlay arrow position and/or string have
+ changed. */
if (overlay_arrows_changed_p ())
GIVE_UP (12);
else
abort ();
-#if 0 /* This leads to problems, for instance when the cursor is
- at ZV, and the cursor line displays no text. */
- /* Disable rows below what's displayed in the window. This makes
- debugging easier. */
- enable_glyph_matrix_rows (current_matrix,
- XFASTINT (w->window_end_vpos) + 1,
- bottom_vpos, 0);
-#endif
-
IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
debug_end_vpos = XFASTINT (w->window_end_vpos));
fprintf (stderr,
"[%d-%d]",
glyph->u.cmp.from, glyph->u.cmp.to);
- fprintf (stderr, " . %4d %1.1d%1.1d\n"
+ fprintf (stderr, " . %4d %1.1d%1.1d\n",
glyph->face_id,
glyph->left_box_line_p,
glyph->right_box_line_p);
/* Get the next character. */
if (multibyte_p)
- it.c = string_char_and_length (p, arrow_len, &it.len);
+ it.c = it.char_to_display = string_char_and_length (p, &it.len);
else
- it.c = *p, it.len = 1;
+ {
+ it.c = it.char_to_display = *p, it.len = 1;
+ if (! ASCII_CHAR_P (it.c))
+ it.char_to_display = BYTE8_TO_CHAR (it.c);
+ }
p += it.len;
/* Get its face. */
ilisp = make_number (p - arrow_string);
face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
- it.face_id = compute_char_face (f, it.c, face);
+ it.face_id = compute_char_face (f, it.char_to_display, face);
/* Compute its width, get its glyphs. */
n_glyphs_before = it.glyph_row->used[TEXT_AREA];
append_space_for_newline has been called. */
enum display_element_type saved_what = it->what;
int saved_c = it->c, saved_len = it->len;
+ int saved_char_to_display = it->char_to_display;
int saved_x = it->current_x;
int saved_face_id = it->face_id;
struct text_pos saved_pos;
it->what = IT_CHARACTER;
bzero (&it->position, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
if (default_face_p)
it->face_id = saved_face_id;
it->len = saved_len;
it->c = saved_c;
+ it->char_to_display = saved_char_to_display;
return 1;
}
}
it->glyph_row->fill_line_p = 1;
/* If current character of IT is not ASCII, make sure we have the
- ASCII face. This will be automatically undone the next time
- get_next_display_element returns a multibyte character. Note
- that the character will always be single byte in unibyte text. */
+ ASCII face. This will be automatically undone the next time
+ get_next_display_element returns a multibyte character. Note
+ that the character will always be single byte in unibyte
+ text. */
if (!ASCII_CHAR_P (it->c))
{
it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
it->what = IT_CHARACTER;
bzero (&it->position, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
it->face_id = face->id;
\f
/* Push the display property PROP so that it will be rendered at the
- current position in IT. */
+ current position in IT. Return 1 if PROP was successfully pushed,
+ 0 otherwise. */
-static void
+static int
push_display_prop (struct it *it, Lisp_Object prop)
{
push_it (it);
- /* Never display a cursor on the prefix. */
- it->avoid_cursor_p = 1;
-
if (STRINGP (prop))
{
if (SCHARS (prop) == 0)
{
pop_it (it);
- return;
+ return 0;
}
it->string = prop;
else
{
pop_it (it); /* bogus display property, give up */
- return;
+ return 0;
}
+
+ return 1;
}
/* Return the character-property PROP at the current position in IT. */
if (NILP (prefix))
prefix = Vline_prefix;
}
- if (! NILP (prefix))
- push_display_prop (it, prefix);
+ if (! NILP (prefix) && push_display_prop (it, prefix))
+ {
+ /* If the prefix is wider than the window, and we try to wrap
+ it, it would acquire its own wrap prefix, and so on till the
+ iterator stack overflows. So, don't wrap the prefix. */
+ it->line_wrap = TRUNCATE;
+ it->avoid_cursor_p = 1;
+ }
}
\f
display the cursor there under X. Set the charpos of the
first glyph of blank lines not corresponding to any text
to -1. */
-#ifdef HAVE_WINDOW_SYSTEM
if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
row->exact_window_width_line_p = 1;
- else
-#endif /* HAVE_WINDOW_SYSTEM */
- if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
- || row->used[TEXT_AREA] == 0)
+ else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
+ || row->used[TEXT_AREA] == 0)
{
row->glyphs[TEXT_AREA]->charpos = -1;
row->displays_text_p = 0;
goto back_to_wrap;
set_iterator_to_next (it, 1);
-#ifdef HAVE_WINDOW_SYSTEM
if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it))
row->exact_window_width_line_p = 1;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
}
}
else if (CHAR_GLYPH_PADDING_P (*glyph)
row->ends_in_newline_from_string_p = STRINGP (it->object);
-#ifdef HAVE_WINDOW_SYSTEM
/* Add a space at the end of the line that is used to
display the cursor there. */
if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
append_space_for_newline (it, 0);
-#endif /* HAVE_WINDOW_SYSTEM */
/* Extend the face to the end of the line. */
extend_face_to_end_of_line (it);
produce_special_glyphs (it, IT_TRUNCATION);
}
}
-#ifdef HAVE_WINDOW_SYSTEM
- else
+ else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
/* Don't truncate if we can overflow newline into fringe. */
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ if (!get_next_display_element (it))
{
- if (!get_next_display_element (it))
- {
- it->continuation_lines_width = 0;
- row->ends_at_zv_p = 1;
- row->exact_window_width_line_p = 1;
- break;
- }
- if (ITERATOR_AT_END_OF_LINE_P (it))
- {
- row->exact_window_width_line_p = 1;
- goto at_end_of_line;
- }
+ it->continuation_lines_width = 0;
+ row->ends_at_zv_p = 1;
+ row->exact_window_width_line_p = 1;
+ break;
+ }
+ if (ITERATOR_AT_END_OF_LINE_P (it))
+ {
+ row->exact_window_width_line_p = 1;
+ goto at_end_of_line;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
row->truncated_on_right_p = 1;
it->continuation_lines_width = 0;
}
-/* Display the mode and/or top line of window W. Value is the number
- of mode lines displayed. */
+/* Display the mode and/or header line of window W. Value is the
+ sum number of mode lines and header lines displayed. */
static int
display_mode_lines (w)
}
-/* Display mode or top line of window W. FACE_ID specifies which line
- to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
- FORMAT is the mode line format to display. Value is the pixel
- height of the mode line displayed. */
+/* Display mode or header line of window W. FACE_ID specifies which
+ line to display; it is either MODE_LINE_FACE_ID or
+ HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
+ display. Value is the pixel height of the mode/header line
+ displayed. */
static int
display_mode_line (w, face_id, format)
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);
+ spec = decode_mode_spec (it->w, c, field, prec, &string);
+ multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
switch (mode_line_target)
{
int nglyphs_before, nwritten;
nglyphs_before = it->glyph_row->used[TEXT_AREA];
- nwritten = display_string (spec, Qnil, elt,
+ nwritten = display_string (spec, string, elt,
charpos, 0, it,
field, prec, 0,
multibyte);
}
else if (STRINGP (car) || CONSP (car))
{
- register int limit = 50;
- /* Limit is to protect against circular lists. */
+ Lisp_Object halftail = elt;
+ int len = 0;
+
while (CONSP (elt)
- && --limit > 0
&& (precision <= 0 || n < precision))
{
n += display_mode_element (it, depth,
precision - n, XCAR (elt),
props, risky);
elt = XCDR (elt);
+ len++;
+ if ((len & 1) == 0)
+ halftail = XCDR (halftail);
+ /* Check for cycle. */
+ if (EQ (halftail, elt))
+ break;
}
}
}
/* Return a string for the output of a mode line %-spec for window W,
generated by character C. PRECISION >= 0 means don't return a
string longer than that value. FIELD_WIDTH > 0 means pad the
- string returned with spaces to that value. Return 1 in *MULTIBYTE
- if the result is multibyte text.
+ string 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. */
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
static char *
-decode_mode_spec (w, c, field_width, precision, multibyte)
+decode_mode_spec (w, c, field_width, precision, string)
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));
struct buffer *b = current_buffer;
obj = Qnil;
- *multibyte = 0;
+ *string = Qnil;
switch (c)
{
case '@':
{
- Lisp_Object val;
- val = call1 (intern ("file-remote-p"), current_buffer->directory);
+ int count = inhibit_garbage_collection ();
+ Lisp_Object val = call1 (intern ("file-remote-p"),
+ current_buffer->directory);
+ unbind_to (count, Qnil);
+
if (NILP (val))
return "-";
else
if (STRINGP (obj))
{
- *multibyte = STRING_MULTIBYTE (obj);
+ *string = obj;
return (char *) SDATA (obj);
}
else
/* Display a NUL-terminated string, starting with index START.
If STRING is non-null, display that C string. Otherwise, the Lisp
- string LISP_STRING is displayed.
+ string LISP_STRING is displayed. There's a case that STRING is
+ non-null and LISP_STRING is not nil. It means STRING is a string
+ data of LISP_STRING. In that case, we display LISP_STRING while
+ ignoring its text properties.
If FACE_STRING is not nil, FACE_STRING_POS is a position in
FACE_STRING. Display STRING or LISP_STRING with the face at
/* Initialize the iterator IT for iteration over STRING beginning
with index START. */
- reseat_to_string (it, string, lisp_string, start,
+ reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
precision, field_width, multibyte);
+ if (string && STRINGP (lisp_string))
+ /* LISP_STRING is the one returned by decode_mode_spec. We should
+ ignore its text properties. */
+ it->stop_charpos = -1;
/* If displaying STRING, set up the face of the iterator
from LISP_STRING, if that's given. */
s->first_glyph = row->glyphs[area] + start;
s->height = row->height;
s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
-
- /* Display the internal border below the tool-bar window. */
- if (WINDOWP (s->f->tool_bar_window)
- && s->w == XWINDOW (s->f->tool_bar_window))
- s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
-
s->ybase = s->y + row->ascent;
}
if (face->font)
{
- unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
+ 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));
}
+/* 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
+get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
+{
+ unsigned code;
+
+ if (CHAR_BYTE8_P (c))
+ code = CHAR_TO_BYTE8 (c);
+ else
+ code = font->driver->encode_char (font, c);
+
+ if (code == FONT_INVALID_CODE)
+ return 0;
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ return 1;
+}
+
+
/* Fill glyph string S with composition components specified by S->cmp.
BASE_FACE is the base face of the composition.
last = s->row->glyphs[s->area] + end;
s->cmp_id = glyph->u.cmp.id;
s->cmp_from = glyph->u.cmp.from;
- s->cmp_to = glyph->u.cmp.to;
+ s->cmp_to = glyph->u.cmp.to + 1;
s->face = FACE_FROM_ID (s->f, face_id);
lgstring = composition_gstring_from_id (s->cmp_id);
s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
glyph++;
while (glyph < last
&& glyph->u.cmp.automatic
- && glyph->u.cmp.id == s->cmp_id)
- s->cmp_to = (glyph++)->u.cmp.to;
+ && glyph->u.cmp.id == s->cmp_id
+ && s->cmp_to == glyph->u.cmp.from)
+ s->cmp_to = (glyph++)->u.cmp.to + 1;
for (i = s->cmp_from; i < s->cmp_to; i++)
{
{
struct composition *cmp = composition_table[glyph->u.cmp.id];
- if (cmp->rbearing - cmp->pixel_width)
+ if (cmp->rbearing > cmp->pixel_width)
*right = cmp->rbearing - cmp->pixel_width;
- if (cmp->lbearing < 0);
- *left = - cmp->lbearing;
+ if (cmp->lbearing < 0)
+ *left = - cmp->lbearing;
}
else
{
struct font_metrics metrics;
composition_gstring_width (gstring, glyph->u.cmp.from,
- glyph->u.cmp.to, &metrics);
+ glyph->u.cmp.to + 1, &metrics);
if (metrics.rbearing > metrics.width)
- *right = metrics.rbearing;
+ *right = metrics.rbearing - metrics.width;
if (metrics.lbearing < 0)
*left = - metrics.lbearing;
}
j = i;
BUILD_GLYPH_STRINGS (j, start, h, t,
overlap_hl, dummy_x, last_x);
+ start = i;
compute_overhangs_and_x (t, head->x, 1);
prepend_glyph_string_lists (&head, &tail, h, t);
clip_head = head;
BUILD_GLYPH_STRINGS (end, i, h, t,
overlap_hl, x, last_x);
+ /* Because BUILD_GLYPH_STRINGS updates the first argument,
+ we don't have `end = i;' here. */
compute_overhangs_and_x (h, tail->x + tail->width, 0);
append_glyph_string_lists (&head, &tail, h, t);
clip_tail = tail;
glyph->u.cmp.automatic = 1;
glyph->u.cmp.id = it->cmp_it.id;
glyph->u.cmp.from = it->cmp_it.from;
- glyph->u.cmp.to = it->cmp_it.to;
+ glyph->u.cmp.to = it->cmp_it.to - 1;
}
glyph->avoid_cursor_p = it->avoid_cursor_p;
glyph->multibyte_p = it->multibyte_p;
if (it->descent < 0)
it->descent = 0;
-#if 0 /* this breaks image tiling */
- /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
- int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
- if (face_ascent > it->ascent)
- it->ascent = it->phys_ascent = face_ascent;
-#endif
-
it->nglyphs = 1;
if (face->box != FACE_NO_BOX)
{
int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
- IT_BYTEPOS (*it));
- it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
+ it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
}
else
- it2.c = *p, it2.len = 1;
+ {
+ it2.c = it2.char_to_display = *p, it2.len = 1;
+ if (! ASCII_CHAR_P (it2.c))
+ it2.char_to_display = BYTE8_TO_CHAR (it2.c);
+ }
it2.glyph_row = NULL;
it2.what = IT_CHARACTER;
if (it->what == IT_CHARACTER)
{
XChar2b char2b;
- struct font *font;
struct face *face = FACE_FROM_ID (it->f, it->face_id);
- struct font_metrics *pcm;
- int font_not_found_p;
+ struct font *font = face->font;
+ int font_not_found_p = font == NULL;
+ struct font_metrics *pcm = NULL;
int boff; /* baseline offset */
- /* We may change it->multibyte_p upon unibyte<->multibyte
- conversion. So, save the current value now and restore it
- later.
-
- Note: It seems that we don't have to record multibyte_p in
- struct glyph because the character code itself tells if or
- not the character is multibyte. Thus, in the future, we must
- consider eliminating the field `multibyte_p' in the struct
- glyph. */
- int saved_multibyte_p = it->multibyte_p;
-
- /* Maybe translate single-byte characters to multibyte, or the
- other way. */
- it->char_to_display = it->c;
- if (!ASCII_BYTE_P (it->c)
- && ! it->multibyte_p)
- {
- if (SINGLE_BYTE_CHAR_P (it->c)
- && unibyte_display_via_language_environment)
- it->char_to_display = unibyte_char_to_multibyte (it->c);
- if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
- {
- it->multibyte_p = 1;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
- -1, Qnil);
- face = FACE_FROM_ID (it->f, it->face_id);
- }
- }
- /* Get font to use. Encode IT->char_to_display. */
- get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
- &char2b, it->multibyte_p, 0);
- font = face->font;
-
- /* When no suitable font found, use the default font. */
- font_not_found_p = font == NULL;
if (font_not_found_p)
{
- font = FRAME_FONT (it->f);
- boff = FRAME_BASELINE_OFFSET (it->f);
+ /* When no suitable font found, display an empty box based
+ on the metrics of the font of the default face (or what
+ remapped). */
+ struct face *no_font_face
+ = FACE_FROM_ID (it->f,
+ NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
+ : lookup_basic_face (it->f, DEFAULT_FACE_ID));
+ font = no_font_face->font;
+ boff = font->baseline_offset;
}
else
{
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
}
- if (it->char_to_display >= ' '
- && (!it->multibyte_p || it->char_to_display < 128))
+ if (it->char_to_display != '\n' && it->char_to_display != '\t')
{
- /* Either unibyte or ASCII. */
int stretched_p;
it->nglyphs = 1;
- pcm = get_per_char_metric (it->f, font, &char2b);
-
if (it->override_ascent >= 0)
{
it->ascent = it->override_ascent;
it->descent = FONT_DESCENT (font) - boff;
}
+ if (! font_not_found_p
+ && get_char_glyph_code (it->char_to_display, font, &char2b))
+ {
+ pcm = get_per_char_metric (it->f, font, &char2b);
+ if (pcm->width == 0
+ && pcm->rbearing == 0 && pcm->lbearing == 0)
+ pcm = NULL;
+ }
+
if (pcm)
{
it->phys_ascent = pcm->ascent + boff;
it->glyph_not_available_p = 1;
it->phys_ascent = it->ascent;
it->phys_descent = it->descent;
- it->pixel_width = FONT_WIDTH (font);
+ it->pixel_width = font->space_width;
}
if (it->constrain_row_ascent_descent_p)
}
else if (it->char_to_display == '\n')
{
- /* A newline has no width but we need the height of the line.
- But if previous part of the line set a height, don't
- increase that height */
+ /* A newline has no width, but we need the height of the
+ line. But if previous part of the line sets a height,
+ don't increase that height */
Lisp_Object height;
Lisp_Object total_height = Qnil;
}
}
}
- else if (it->char_to_display == '\t')
+ else /* i.e. (it->char_to_display == '\t') */
{
if (font->space_width > 0)
{
it->nglyphs = 1;
}
}
- else
- {
- /* A multi-byte character. Assume that the display width of the
- character is the width of the character multiplied by the
- width of the font. */
-
- /* If we found a font, this font should give us the right
- metrics. If we didn't find a font, use the frame's
- default font and calculate the width of the character by
- multiplying the width of font by the width of the
- character. */
-
- pcm = get_per_char_metric (it->f, font, &char2b);
-
- if (font_not_found_p || !pcm)
- {
- int char_width = CHAR_WIDTH (it->char_to_display);
-
- if (char_width == 0)
- /* This is a non spacing character. But, as we are
- going to display an empty box, the box must occupy
- at least one column. */
- char_width = 1;
- it->glyph_not_available_p = 1;
- it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
- it->phys_ascent = FONT_BASE (font) + boff;
- it->phys_descent = FONT_DESCENT (font) - boff;
- }
- else
- {
- it->pixel_width = pcm->width;
- it->phys_ascent = pcm->ascent + boff;
- it->phys_descent = pcm->descent - boff;
- if (it->glyph_row
- && (pcm->lbearing < 0
- || pcm->rbearing > pcm->width))
- it->glyph_row->contains_overlapping_glyphs_p = 1;
- }
- it->nglyphs = 1;
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
- if (face->box != FACE_NO_BOX)
- {
- int thick = face->box_line_width;
-
- if (thick > 0)
- {
- it->ascent += thick;
- it->descent += thick;
- }
- else
- thick = - thick;
-
- if (it->start_of_box_run_p)
- it->pixel_width += thick;
- if (it->end_of_box_run_p)
- it->pixel_width += thick;
- }
-
- /* If face has an overline, add the height of the overline
- (1 pixel) and a 1 pixel margin to the character height. */
- if (face->overline_p)
- it->ascent += overline_margin;
-
- take_vertical_position_into_account (it);
-
- if (it->ascent < 0)
- it->ascent = 0;
- if (it->descent < 0)
- it->descent = 0;
-
- 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;
}
else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
{
- /* A static compositoin.
+ /* A static composition.
Note: A composition is represented as one glyph in the
glyph matrix. There are no padding glyphs.
- Important is that pixel_width, ascent, and descent are the
+ Important note: pixel_width, ascent, and descent are the
values of what is drawn by draw_glyphs (i.e. the values of
the overall glyphs composed). */
struct face *face = FACE_FROM_ID (it->f, it->face_id);
the composition for the current face font, calculate them
now. Theoretically, we have to check all fonts for the
glyphs, but that requires much time and memory space. So,
- here we check only the font of the first glyph. This leads
- to incorrect display, but it's very rare, and C-l (recenter)
- can correct the display anyway. */
+ here we check only the font of the first glyph. This may
+ lead to incorrect display, but it's very rare, and C-l
+ (recenter-top-bottom) can correct the display anyway. */
if (! cmp->font || cmp->font != font)
{
/* Ascent and descent of the font of the first character
of this composition (adjusted by baseline offset).
Ascent and descent of overall glyphs should not be less
- than them respectively. */
+ than these, respectively. */
int font_ascent, font_descent, font_height;
/* Bounding box of the overall glyphs. */
int leftmost, rightmost, lowest, highest;
pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
: IT_CHARPOS (*it));
- /* When no suitable font found, use the default font. */
+ /* If no suitable font is found, use the default font. */
font_not_found_p = font == NULL;
if (font_not_found_p)
{
}
else
{
- width = FONT_WIDTH (font);
+ width = font->space_width;
ascent = FONT_BASE (font);
descent = FONT_DESCENT (font);
lbearing = 0;
/* Switch the display of W's cursor on or off, according to the value
of ON. */
-#ifndef HAVE_NS
-static
-#endif
void
update_window_cursor (w, on)
struct window *w;
/* EXPORT:
Clear the cursor of window W to background color, and mark the
cursor as not shown. This is used when the text where the cursor
- is is about to be rewritten. */
+ is about to be rewritten. */
void
x_clear_cursor (w)
\f
-/* Find the glyph matrix position of buffer position CHARPOS in window
- *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
- current glyphs must be up to date. If CHARPOS is above window
- start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
- of last line in W. In the row containing CHARPOS, stop before glyphs
- having STOP as object. */
-
-#if 1 /* This is a version of fast_find_position that's more correct
- in the presence of hscrolling, for example. I didn't install
- it right away because the problem fixed is minor, it failed
- in 20.x as well, and I think it's too risky to install
- so near the release of 21.1. 2001-09-25 gerd. */
+/* This function sets the mouse_face_* elements of DPYINFO, assuming
+ the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
+ window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
+ for the overlay or run of text properties specifying the mouse
+ face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
+ before-string and after-string that must also be highlighted.
+ DISPLAY_STRING, if non-nil, is a display string that may cover some
+ or all of the highlighted text. */
-static
-int
-fast_find_position (w, charpos, hpos, vpos, x, y, stop)
- struct window *w;
- EMACS_INT charpos;
- int *hpos, *vpos, *x, *y;
- Lisp_Object stop;
+static void
+mouse_face_from_buffer_pos (Lisp_Object window,
+ Display_Info *dpyinfo,
+ EMACS_INT mouse_charpos,
+ EMACS_INT start_charpos,
+ EMACS_INT end_charpos,
+ Lisp_Object before_string,
+ Lisp_Object after_string,
+ Lisp_Object display_string)
{
- struct glyph_row *row, *first;
+ struct window *w = XWINDOW (window);
+ struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ struct glyph_row *row;
struct glyph *glyph, *end;
- int past_end = 0;
+ EMACS_INT ignore;
+ int x;
+
+ xassert (NILP (display_string) || STRINGP (display_string));
+ xassert (NILP (before_string) || STRINGP (before_string));
+ xassert (NILP (after_string) || STRINGP (after_string));
- first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- if (charpos < MATRIX_ROW_START_CHARPOS (first))
+ /* Find the first highlighted glyph. */
+ if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
{
- *x = first->x;
- *y = first->y;
- *hpos = 0;
- *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
- return 1;
+ dpyinfo->mouse_face_beg_col = 0;
+ dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
+ dpyinfo->mouse_face_beg_x = first->x;
+ dpyinfo->mouse_face_beg_y = first->y;
+ }
+ else
+ {
+ row = row_containing_pos (w, start_charpos, first, NULL, 0);
+ if (row == NULL)
+ row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+
+ /* If the before-string or display-string contains newlines,
+ row_containing_pos skips to its last row. Move back. */
+ if (!NILP (before_string) || !NILP (display_string))
+ {
+ struct glyph_row *prev;
+ while ((prev = row - 1, prev >= first)
+ && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
+ && prev->used[TEXT_AREA] > 0)
+ {
+ struct glyph *beg = prev->glyphs[TEXT_AREA];
+ glyph = beg + prev->used[TEXT_AREA];
+ while (--glyph >= beg && INTEGERP (glyph->object));
+ if (glyph < beg
+ || !(EQ (glyph->object, before_string)
+ || EQ (glyph->object, display_string)))
+ break;
+ row = prev;
+ }
+ }
+
+ glyph = row->glyphs[TEXT_AREA];
+ end = glyph + row->used[TEXT_AREA];
+ x = row->x;
+ dpyinfo->mouse_face_beg_y = row->y;
+ dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
+
+ /* Skip truncation glyphs at the start of the glyph row. */
+ if (row->displays_text_p)
+ for (; glyph < end
+ && INTEGERP (glyph->object)
+ && glyph->charpos < 0;
+ ++glyph)
+ x += glyph->pixel_width;
+
+ /* Scan the glyph row, stopping before BEFORE_STRING or
+ DISPLAY_STRING or START_CHARPOS. */
+ for (; glyph < end
+ && !INTEGERP (glyph->object)
+ && !EQ (glyph->object, before_string)
+ && !EQ (glyph->object, display_string)
+ && !(BUFFERP (glyph->object)
+ && glyph->charpos >= start_charpos);
+ ++glyph)
+ x += glyph->pixel_width;
+
+ dpyinfo->mouse_face_beg_x = x;
+ dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
}
- row = row_containing_pos (w, charpos, first, NULL, 0);
+ /* Find the last highlighted glyph. */
+ row = row_containing_pos (w, end_charpos, first, NULL, 0);
if (row == NULL)
{
row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
- past_end = 1;
+ dpyinfo->mouse_face_past_end = 1;
}
-
- /* If whole rows or last part of a row came from a display overlay,
- row_containing_pos will skip over such rows because their end pos
- equals the start pos of the overlay or interval.
-
- Move back if we have a STOP object and previous row's
- end glyph came from STOP. */
- if (!NILP (stop))
+ else if (!NILP (after_string))
{
- struct glyph_row *prev;
- while ((prev = row - 1, prev >= first)
- && MATRIX_ROW_END_CHARPOS (prev) == charpos
- && prev->used[TEXT_AREA] > 0)
- {
- struct glyph *beg = prev->glyphs[TEXT_AREA];
- glyph = beg + prev->used[TEXT_AREA];
- while (--glyph >= beg
- && INTEGERP (glyph->object));
- if (glyph < beg
- || !EQ (stop, glyph->object))
- break;
- row = prev;
- }
- }
+ /* If the after-string has newlines, advance to its last row. */
+ struct glyph_row *next;
+ struct glyph_row *last
+ = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
- *x = row->x;
- *y = row->y;
- *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+ for (next = row + 1;
+ next <= last
+ && next->used[TEXT_AREA] > 0
+ && EQ (next->glyphs[TEXT_AREA]->object, after_string);
+ ++next)
+ row = next;
+ }
glyph = row->glyphs[TEXT_AREA];
end = glyph + row->used[TEXT_AREA];
+ x = row->x;
+ dpyinfo->mouse_face_end_y = row->y;
+ dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
- /* Skip over glyphs not having an object at the start of the row.
- These are special glyphs like truncation marks on terminal
- frames. */
+ /* Skip truncation glyphs at the start of the row. */
if (row->displays_text_p)
- while (glyph < end
+ for (; glyph < end
&& INTEGERP (glyph->object)
- && !EQ (stop, glyph->object)
- && glyph->charpos < 0)
- {
- *x += glyph->pixel_width;
- ++glyph;
- }
+ && glyph->charpos < 0;
+ ++glyph)
+ x += glyph->pixel_width;
- while (glyph < end
+ /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
+ AFTER_STRING. */
+ for (; glyph < end
&& !INTEGERP (glyph->object)
- && !EQ (stop, glyph->object)
- && (!BUFFERP (glyph->object)
- || glyph->charpos < charpos))
- {
- *x += glyph->pixel_width;
- ++glyph;
- }
-
- *hpos = glyph - row->glyphs[TEXT_AREA];
- return !past_end;
-}
-
-#else /* not 1 */
-
-static int
-fast_find_position (w, pos, hpos, vpos, x, y, stop)
- struct window *w;
- EMACS_INT pos;
- int *hpos, *vpos, *x, *y;
- Lisp_Object stop;
-{
- int i;
- int lastcol;
- int maybe_next_line_p = 0;
- int line_start_position;
- int yb = window_text_bottom_y (w);
- struct glyph_row *row, *best_row;
- int row_vpos, best_row_vpos;
- int current_x;
-
- row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+ && !EQ (glyph->object, after_string)
+ && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
+ ++glyph)
+ x += glyph->pixel_width;
- while (row->y < yb)
+ /* If we found AFTER_STRING, consume it and stop. */
+ if (EQ (glyph->object, after_string))
{
- if (row->used[TEXT_AREA])
- line_start_position = row->glyphs[TEXT_AREA]->charpos;
- else
- line_start_position = 0;
-
- if (line_start_position > pos)
- break;
- /* If the position sought is the end of the buffer,
- don't include the blank lines at the bottom of the window. */
- else if (line_start_position == pos
- && pos == BUF_ZV (XBUFFER (w->buffer)))
- {
- maybe_next_line_p = 1;
- break;
- }
- else if (line_start_position > 0)
- {
- best_row = row;
- best_row_vpos = row_vpos;
- }
-
- if (row->y + row->height >= yb)
- break;
-
- ++row;
- ++row_vpos;
+ for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
+ x += glyph->pixel_width;
}
-
- /* Find the right column within BEST_ROW. */
- lastcol = 0;
- current_x = best_row->x;
- for (i = 0; i < best_row->used[TEXT_AREA]; i++)
+ else
{
- struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
- int charpos = glyph->charpos;
+ /* If there's no after-string, we must check if we overshot,
+ which might be the case if we stopped after a string glyph.
+ That glyph may belong to a before-string or display-string
+ associated with the end position, which must not be
+ highlighted. */
+ Lisp_Object prev_object;
+ int pos;
- if (BUFFERP (glyph->object))
+ while (glyph > row->glyphs[TEXT_AREA])
{
- if (charpos == pos)
- {
- *hpos = i;
- *vpos = best_row_vpos;
- *x = current_x;
- *y = best_row->y;
- return 1;
- }
- else if (charpos > pos)
+ prev_object = (glyph - 1)->object;
+ if (!STRINGP (prev_object) || EQ (prev_object, display_string))
break;
- }
- else if (EQ (glyph->object, stop))
- break;
- if (charpos > 0)
- lastcol = i;
- current_x += glyph->pixel_width;
- }
+ pos = string_buffer_position (w, prev_object, end_charpos);
+ if (pos && pos < end_charpos)
+ break;
- /* If we're looking for the end of the buffer,
- and we didn't find it in the line we scanned,
- use the start of the following line. */
- if (maybe_next_line_p)
- {
- ++best_row;
- ++best_row_vpos;
- lastcol = 0;
- current_x = best_row->x;
+ for (; glyph > row->glyphs[TEXT_AREA]
+ && EQ ((glyph - 1)->object, prev_object);
+ --glyph)
+ x -= (glyph - 1)->pixel_width;
+ }
}
- *vpos = best_row_vpos;
- *hpos = lastcol + 1;
- *x = current_x;
- *y = best_row->y;
- return 0;
+ dpyinfo->mouse_face_end_x = x;
+ dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
+ dpyinfo->mouse_face_window = window;
+ dpyinfo->mouse_face_face_id
+ = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
+ mouse_charpos + 1,
+ !dpyinfo->mouse_face_hidden, -1);
+ show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
}
-#endif /* not 1 */
-
/* Find the position of the glyph for position POS in OBJECT in
window W's current matrix, and return in *X, *Y the pixel
#endif
if (NILP (Vmouse_highlight)
- || !f->glyphs_initialized_p)
+ || !f->glyphs_initialized_p
+ || f->pointer_invisible)
return;
dpyinfo->mouse_face_mouse_x = x;
|| (OVERLAYP (dpyinfo->mouse_face_overlay)
&& mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
{
- /* Find the highest priority overlay that has a mouse-face
- property. */
+ /* Find the highest priority overlay with a mouse-face. */
overlay = Qnil;
for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
{
overlay = overlay_vec[i];
}
- /* If we're actually highlighting the same overlay as
- before, there's no need to do that again. */
- if (!NILP (overlay)
- && EQ (overlay, dpyinfo->mouse_face_overlay))
+ /* If we're highlighting the same overlay as before, there's
+ no need to do that again. */
+ if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
goto check_help_echo;
-
dpyinfo->mouse_face_overlay = overlay;
/* Clear the display of the old active region, if any. */
if (NILP (overlay))
mouse_face = Fget_text_property (position, Qmouse_face, object);
- /* Handle the overlay case. */
- if (!NILP (overlay))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after;
- EMACS_INT ignore;
-
- before = Foverlay_start (overlay);
- after = Foverlay_end (overlay);
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y, Qnil);
-
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y, Qnil);
- dpyinfo->mouse_face_window = window;
-
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
- cursor = No_Cursor;
- }
- /* Handle the text property case. */
- else if (!NILP (mouse_face) && BUFFERP (object))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after, beginning, end;
- EMACS_INT ignore;
-
- beginning = Fmarker_position (w->start);
- end = make_number (BUF_Z (XBUFFER (object))
- - XFASTINT (w->window_end_pos));
- before
- = Fprevious_single_property_change (make_number (pos + 1),
- Qmouse_face,
- object, beginning);
- after
- = Fnext_single_property_change (position, Qmouse_face,
- object, end);
-
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y, Qnil);
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y, Qnil);
- dpyinfo->mouse_face_window = window;
-
- if (BUFFERP (object))
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
- cursor = No_Cursor;
- }
- else if (!NILP (mouse_face) && STRINGP (object))
+ /* Next, compute the bounds of the mouse highlighting and
+ display it. */
+ if (!NILP (mouse_face) && STRINGP (object))
{
+ /* The mouse-highlighting comes from a display string
+ with a mouse-face. */
Lisp_Object b, e;
EMACS_INT ignore;
- b = Fprevious_single_property_change (make_number (pos + 1),
- Qmouse_face,
- object, Qnil);
- e = Fnext_single_property_change (position, Qmouse_face,
- object, Qnil);
+ b = Fprevious_single_property_change
+ (make_number (pos + 1), Qmouse_face, object, Qnil);
+ e = Fnext_single_property_change
+ (position, Qmouse_face, object, Qnil);
if (NILP (b))
b = make_number (0);
if (NILP (e))
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
cursor = No_Cursor;
}
- else if (STRINGP (object) && NILP (mouse_face))
+ else
{
- /* A string which doesn't have mouse-face, but
- the text ``under'' it might have. */
- struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
- int start = MATRIX_ROW_START_CHARPOS (r);
-
- pos = string_buffer_position (w, object, start);
- if (pos > 0)
- mouse_face = get_char_property_and_overlay (make_number (pos),
- Qmouse_face,
- w->buffer,
- &overlay);
- if (!NILP (mouse_face) && !NILP (overlay))
+ /* The mouse-highlighting, if any, comes from an overlay
+ or text property in the buffer. */
+ Lisp_Object buffer, display_string;
+
+ if (STRINGP (object))
{
- Lisp_Object before = Foverlay_start (overlay);
- Lisp_Object after = Foverlay_end (overlay);
- EMACS_INT ignore;
+ /* If we are on a display string with no mouse-face,
+ check if the text under it has one. */
+ struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
+ int start = MATRIX_ROW_START_CHARPOS (r);
+ pos = string_buffer_position (w, object, start);
+ if (pos > 0)
+ {
+ mouse_face = get_char_property_and_overlay
+ (make_number (pos), Qmouse_face, w->buffer, &overlay);
+ buffer = w->buffer;
+ display_string = object;
+ }
+ }
+ else
+ {
+ buffer = object;
+ display_string = Qnil;
+ }
+
+ if (!NILP (mouse_face))
+ {
+ Lisp_Object before, after;
+ Lisp_Object before_string, after_string;
- /* Note that we might not be able to find position
- BEFORE in the glyph matrix if the overlay is
- entirely covered by a `display' property. In
- this case, we overshoot. So let's stop in
- the glyph matrix before glyphs for OBJECT. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y,
- object);
-
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y,
- Qnil);
- dpyinfo->mouse_face_window = window;
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+ if (NILP (overlay))
+ {
+ /* Handle the text property case. */
+ before = Fprevious_single_property_change
+ (make_number (pos + 1), Qmouse_face, buffer,
+ Fmarker_position (w->start));
+ after = Fnext_single_property_change
+ (make_number (pos), Qmouse_face, buffer,
+ make_number (BUF_Z (XBUFFER (buffer))
+ - XFASTINT (w->window_end_pos)));
+ before_string = after_string = Qnil;
+ }
+ else
+ {
+ /* Handle the overlay case. */
+ before = Foverlay_start (overlay);
+ after = Foverlay_end (overlay);
+ before_string = Foverlay_get (overlay, Qbefore_string);
+ after_string = Foverlay_get (overlay, Qafter_string);
+
+ if (!STRINGP (before_string)) before_string = Qnil;
+ if (!STRINGP (after_string)) after_string = Qnil;
+ }
+
+ mouse_face_from_buffer_pos (window, dpyinfo, pos,
+ XFASTINT (before),
+ XFASTINT (after),
+ before_string, after_string,
+ display_string);
cursor = No_Cursor;
}
}
Vmessage_stack = Qnil;
staticpro (&Vmessage_stack);
- Qinhibit_redisplay = intern ("inhibit-redisplay");
+ Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
staticpro (&Qinhibit_redisplay);
message_dolog_marker1 = Fmake_marker ();
defsubr (&Sinvisible_p);
staticpro (&Qmenu_bar_update_hook);
- Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
+ Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
staticpro (&Qoverriding_terminal_local_map);
- Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
+ Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
staticpro (&Qoverriding_local_map);
- Qoverriding_local_map = intern ("overriding-local-map");
+ Qoverriding_local_map = intern_c_string ("overriding-local-map");
staticpro (&Qwindow_scroll_functions);
- Qwindow_scroll_functions = intern ("window-scroll-functions");
+ Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
staticpro (&Qwindow_text_change_functions);
- Qwindow_text_change_functions = intern ("window-text-change-functions");
+ Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
staticpro (&Qredisplay_end_trigger_functions);
- Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
+ Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
staticpro (&Qinhibit_point_motion_hooks);
- Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
+ Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
- Qeval = intern ("eval");
+ Qeval = intern_c_string ("eval");
staticpro (&Qeval);
- QCdata = intern (":data");
+ QCdata = intern_c_string (":data");
staticpro (&QCdata);
- Qdisplay = intern ("display");
+ Qdisplay = intern_c_string ("display");
staticpro (&Qdisplay);
- Qspace_width = intern ("space-width");
+ Qspace_width = intern_c_string ("space-width");
staticpro (&Qspace_width);
- Qraise = intern ("raise");
+ Qraise = intern_c_string ("raise");
staticpro (&Qraise);
- Qslice = intern ("slice");
+ Qslice = intern_c_string ("slice");
staticpro (&Qslice);
- Qspace = intern ("space");
+ Qspace = intern_c_string ("space");
staticpro (&Qspace);
- Qmargin = intern ("margin");
+ Qmargin = intern_c_string ("margin");
staticpro (&Qmargin);
- Qpointer = intern ("pointer");
+ Qpointer = intern_c_string ("pointer");
staticpro (&Qpointer);
- Qleft_margin = intern ("left-margin");
+ Qleft_margin = intern_c_string ("left-margin");
staticpro (&Qleft_margin);
- Qright_margin = intern ("right-margin");
+ Qright_margin = intern_c_string ("right-margin");
staticpro (&Qright_margin);
- Qcenter = intern ("center");
+ Qcenter = intern_c_string ("center");
staticpro (&Qcenter);
- Qline_height = intern ("line-height");
+ Qline_height = intern_c_string ("line-height");
staticpro (&Qline_height);
- QCalign_to = intern (":align-to");
+ QCalign_to = intern_c_string (":align-to");
staticpro (&QCalign_to);
- QCrelative_width = intern (":relative-width");
+ QCrelative_width = intern_c_string (":relative-width");
staticpro (&QCrelative_width);
- QCrelative_height = intern (":relative-height");
+ QCrelative_height = intern_c_string (":relative-height");
staticpro (&QCrelative_height);
- QCeval = intern (":eval");
+ QCeval = intern_c_string (":eval");
staticpro (&QCeval);
- QCpropertize = intern (":propertize");
+ QCpropertize = intern_c_string (":propertize");
staticpro (&QCpropertize);
- QCfile = intern (":file");
+ QCfile = intern_c_string (":file");
staticpro (&QCfile);
- Qfontified = intern ("fontified");
+ Qfontified = intern_c_string ("fontified");
staticpro (&Qfontified);
- Qfontification_functions = intern ("fontification-functions");
+ Qfontification_functions = intern_c_string ("fontification-functions");
staticpro (&Qfontification_functions);
- Qtrailing_whitespace = intern ("trailing-whitespace");
+ Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
staticpro (&Qtrailing_whitespace);
- Qescape_glyph = intern ("escape-glyph");
+ Qescape_glyph = intern_c_string ("escape-glyph");
staticpro (&Qescape_glyph);
- Qnobreak_space = intern ("nobreak-space");
+ Qnobreak_space = intern_c_string ("nobreak-space");
staticpro (&Qnobreak_space);
- Qimage = intern ("image");
+ Qimage = intern_c_string ("image");
staticpro (&Qimage);
- QCmap = intern (":map");
+ QCmap = intern_c_string (":map");
staticpro (&QCmap);
- QCpointer = intern (":pointer");
+ QCpointer = intern_c_string (":pointer");
staticpro (&QCpointer);
- Qrect = intern ("rect");
+ Qrect = intern_c_string ("rect");
staticpro (&Qrect);
- Qcircle = intern ("circle");
+ Qcircle = intern_c_string ("circle");
staticpro (&Qcircle);
- Qpoly = intern ("poly");
+ Qpoly = intern_c_string ("poly");
staticpro (&Qpoly);
- Qmessage_truncate_lines = intern ("message-truncate-lines");
+ Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
staticpro (&Qmessage_truncate_lines);
- Qgrow_only = intern ("grow-only");
+ Qgrow_only = intern_c_string ("grow-only");
staticpro (&Qgrow_only);
- Qinhibit_menubar_update = intern ("inhibit-menubar-update");
+ Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
staticpro (&Qinhibit_menubar_update);
- Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
+ Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
staticpro (&Qinhibit_eval_during_redisplay);
- Qposition = intern ("position");
+ Qposition = intern_c_string ("position");
staticpro (&Qposition);
- Qbuffer_position = intern ("buffer-position");
+ Qbuffer_position = intern_c_string ("buffer-position");
staticpro (&Qbuffer_position);
- Qobject = intern ("object");
+ Qobject = intern_c_string ("object");
staticpro (&Qobject);
- Qbar = intern ("bar");
+ Qbar = intern_c_string ("bar");
staticpro (&Qbar);
- Qhbar = intern ("hbar");
+ Qhbar = intern_c_string ("hbar");
staticpro (&Qhbar);
- Qbox = intern ("box");
+ Qbox = intern_c_string ("box");
staticpro (&Qbox);
- Qhollow = intern ("hollow");
+ Qhollow = intern_c_string ("hollow");
staticpro (&Qhollow);
- Qhand = intern ("hand");
+ Qhand = intern_c_string ("hand");
staticpro (&Qhand);
- Qarrow = intern ("arrow");
+ Qarrow = intern_c_string ("arrow");
staticpro (&Qarrow);
- Qtext = intern ("text");
+ Qtext = intern_c_string ("text");
staticpro (&Qtext);
- Qrisky_local_variable = intern ("risky-local-variable");
+ Qrisky_local_variable = intern_c_string ("risky-local-variable");
staticpro (&Qrisky_local_variable);
- Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
+ Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
staticpro (&Qinhibit_free_realized_faces);
- list_of_error = Fcons (Fcons (intern ("error"),
- Fcons (intern ("void-variable"), Qnil)),
+ 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 ("last-arrow-position");
+ Qlast_arrow_position = intern_c_string ("last-arrow-position");
staticpro (&Qlast_arrow_position);
- Qlast_arrow_string = intern ("last-arrow-string");
+ Qlast_arrow_string = intern_c_string ("last-arrow-string");
staticpro (&Qlast_arrow_string);
- Qoverlay_arrow_string = intern ("overlay-arrow-string");
+ Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
staticpro (&Qoverlay_arrow_string);
- Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
+ Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
staticpro (&Qoverlay_arrow_bitmap);
echo_buffer[0] = echo_buffer[1] = Qnil;
staticpro (&echo_area_buffer[0]);
staticpro (&echo_area_buffer[1]);
- Vmessages_buffer_name = build_string ("*Messages*");
+ Vmessages_buffer_name = make_pure_c_string ("*Messages*");
staticpro (&Vmessages_buffer_name);
mode_line_proptrans_alist = Qnil;
DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
doc: /* String to display as an arrow in non-window frames.
See also `overlay-arrow-position'. */);
- Voverlay_arrow_string = build_string ("=>");
+ Voverlay_arrow_string = make_pure_c_string ("=>");
DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
doc: /* List of variables (symbols) which hold markers for overlay arrows.
The symbols on this list are examined during redisplay to determine
where to display overlay arrows. */);
Voverlay_arrow_variable_list
- = Fcons (intern ("overlay-arrow-position"), Qnil);
+ = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
DEFVAR_INT ("scroll-step", &scroll_step,
doc: /* *The number of lines to try scrolling a window by when point moves out.
DEFVAR_LISP ("truncate-partial-width-windows",
&Vtruncate_partial_width_windows,
- doc: /* Non-nil means truncate lines in windows with less than the frame width.
-For an integer value, truncate lines in each window with less than the
+ doc: /* Non-nil means truncate lines in windows narrower than the frame.
+For an integer value, truncate lines in each window narrower than the
full frame width, provided the window width is less than that integer;
otherwise, respect the value of `truncate-lines'.
-For any other non-nil value, truncate lines in all windows with
-less than the full frame width.
+For any other non-nil value, truncate lines in all windows that do
+not span the full frame width.
A value of nil means to respect the value of `truncate-lines'.
\(see `modify-frame-parameters'). */);
Vicon_title_format
= Vframe_title_format
- = Fcons (intern ("multiple-frames"),
- Fcons (build_string ("%b"),
- Fcons (Fcons (empty_unibyte_string,
- Fcons (intern ("invocation-name"),
- Fcons (build_string ("@"),
- Fcons (intern ("system-name"),
- Qnil)))),
- Qnil)));
+ = pure_cons (intern_c_string ("multiple-frames"),
+ pure_cons (make_pure_c_string ("%b"),
+ pure_cons (pure_cons (empty_unibyte_string,
+ pure_cons (intern_c_string ("invocation-name"),
+ pure_cons (make_pure_c_string ("@"),
+ pure_cons (intern_c_string ("system-name"),
+ Qnil)))),
+ Qnil)));
DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
doc: /* Maximum number of lines to keep in the message log buffer.
DEFVAR_BOOL ("unibyte-display-via-language-environment",
&unibyte_display_via_language_environment,
doc: /* *Non-nil means display unibyte text according to language environment.
-Specifically this means that unibyte non-ASCII characters
+Specifically, this means that raw bytes in the range 160-255 decimal
are displayed by converting them to the equivalent multibyte characters
according to the current language environment. As a result, they are
-displayed according to the current fontset. */);
+displayed according to the current fontset.
+
+Note that this variable affects only how these bytes are displayed,
+but does not change the fact they are interpreted as raw bytes. */);
unibyte_display_via_language_environment = 0;
DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
doc: /* *Non-nil means scroll the display automatically to make point visible. */);
automatic_hscrolling_p = 1;
- Qauto_hscroll_mode = intern ("auto-hscroll-mode");
+ Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
staticpro (&Qauto_hscroll_mode);
DEFVAR_INT ("hscroll-margin", &hscroll_margin,
inhibit_menubar_update = 0;
DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
- doc: /* Prefix added to the beginning of all continuation lines at display-time.
-May be a string, an image, or a stretch-glyph such as used by the
-`display' text-property.
+ doc: /* Prefix prepended to all continuation lines at display time.
+The value may be a string, an image, or a stretch-glyph; it is
+interpreted in the same way as the value of a `display' text property.
-This variable is overridden by any `wrap-prefix' text-property.
+This variable is overridden by any `wrap-prefix' text or overlay
+property.
-To add a prefix to non-continuation lines, use the `line-prefix' variable. */);
+To add a prefix to non-continuation lines, use `line-prefix'. */);
Vwrap_prefix = Qnil;
staticpro (&Qwrap_prefix);
- Qwrap_prefix = intern ("wrap-prefix");
+ Qwrap_prefix = intern_c_string ("wrap-prefix");
Fmake_variable_buffer_local (Qwrap_prefix);
DEFVAR_LISP ("line-prefix", &Vline_prefix,
- doc: /* Prefix added to the beginning of all non-continuation lines at display-time.
-May be a string, an image, or a stretch-glyph such as used by the
-`display' text-property.
+ doc: /* Prefix prepended to all non-continuation lines at display time.
+The value may be a string, an image, or a stretch-glyph; it is
+interpreted in the same way as the value of a `display' text property.
-This variable is overridden by any `line-prefix' text-property.
+This variable is overridden by any `line-prefix' text or overlay
+property.
-To add a prefix to continuation lines, use the `wrap-prefix' variable. */);
+To add a prefix to continuation lines, use `wrap-prefix'. */);
Vline_prefix = Qnil;
staticpro (&Qline_prefix);
- Qline_prefix = intern ("line-prefix");
+ Qline_prefix = intern_c_string ("line-prefix");
Fmake_variable_buffer_local (Qline_prefix);
DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,