struct it it;
struct text_pos pt;
struct window *w = XWINDOW (selected_window);
+ struct buffer *old_buffer = NULL;
+ Lisp_Object result;
+ if (XBUFFER (w->contents) != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal_1 (XBUFFER (w->contents));
+ }
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
it.vpos = it.current_y = 0;
last_height = 0;
- return make_number (line_bottom_y (&it));
+ result = make_number (line_bottom_y (&it));
+ if (old_buffer)
+ set_buffer_internal_1 (old_buffer);
+
+ return result;
}
/* Return the default pixel height of text lines in window W. The
}
if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
- gx += window_box_left_offset (w, area);
+ {
+ gx += window_box_left_offset (w, area);
+ /* Don't expand over the modeline to make sure the vertical
+ drag cursor is shown early enough. */
+ height = min (height,
+ max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
+ }
}
else
{
gx = (x / width) * width;
y -= gy;
gy += (y / height) * height;
+ if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
+ /* See comment above. */
+ height = min (height,
+ max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
}
break;
gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
? window_box_right_offset (w, RIGHT_MARGIN_AREA)
: window_box_right_offset (w, TEXT_AREA));
- width = WINDOW_RIGHT_FRINGE_WIDTH (w);
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+ && !WINDOW_RIGHTMOST_P (w))
+ if (gx < WINDOW_PIXEL_WIDTH (w) - width)
+ /* Make sure the vertical border can get her own glyph to the
+ right of the one we build here. */
+ width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
+ else
+ width = WINDOW_PIXEL_WIDTH (w) - gx;
+ else
+ width = WINDOW_RIGHT_FRINGE_WIDTH (w);
+
+ goto row_glyph;
+
+ case ON_VERTICAL_BORDER:
+ gx = WINDOW_PIXEL_WIDTH (w) - width;
goto row_glyph;
case ON_SCROLL_BAR:
}
break;
+ case ON_RIGHT_DIVIDER:
+ gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ gy = 0;
+ /* The bottom divider prevails. */
+ height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ goto add_edge;;
+
+ case ON_BOTTOM_DIVIDER:
+ gx = 0;
+ width = WINDOW_PIXEL_WIDTH (w);
+ gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ goto add_edge;
+
default:
;
virtual_glyph:
goto store_rect;
}
+ add_edge:
gx += WINDOW_LEFT_EDGE_X (w);
gy += WINDOW_TOP_EDGE_Y (w);
following. Return the result, or nil if something went
wrong. Prevent redisplay during the evaluation. */
-Lisp_Object
-safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
+static Lisp_Object
+safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
{
Lisp_Object val;
val = Qnil;
else
{
- va_list ap;
ptrdiff_t i;
ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1;
Lisp_Object *args = alloca (nargs * word_size);
args[0] = func;
- va_start (ap, func);
for (i = 1; i < nargs; i++)
args[i] = va_arg (ap, Lisp_Object);
- va_end (ap);
GCPRO1 (args[0]);
gcpro1.nvars = nargs;
specbind (Qinhibit_redisplay, Qt);
+ if (inhibit_quit)
+ specbind (Qinhibit_quit, Qt);
/* Use Qt to ensure debugger does not run,
so there is no possibility of wanting to redisplay. */
val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
return val;
}
+Lisp_Object
+safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
+{
+ Lisp_Object retval;
+ va_list ap;
+
+ va_start (ap, func);
+ retval = safe__call (false, nargs, func, ap);
+ va_end (ap);
+ return retval;
+}
/* Call function FN with one argument ARG.
Return the result, or nil if something went wrong. */
return safe_call (2, fn, arg);
}
+static Lisp_Object
+safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
+{
+ Lisp_Object retval;
+ va_list ap;
+
+ va_start (ap, fn);
+ retval = safe__call (inhibit_quit, 2, fn, ap);
+ va_end (ap);
+ return retval;
+}
+
static Lisp_Object Qeval;
Lisp_Object
safe_eval (Lisp_Object sexpr)
{
- return safe_call1 (Qeval, sexpr);
+ return safe__call1 (false, Qeval, sexpr);
+}
+
+static Lisp_Object
+safe__eval (bool inhibit_quit, Lisp_Object sexpr)
+{
+ return safe__call1 (inhibit_quit, Qeval, sexpr);
}
/* Call function FN with two arguments ARG1 and ARG2.
/* If we have a boxed mode line, make the first character appear
with a left box line. */
face = FACE_FROM_ID (it->f, remapped_base_face_id);
- if (face->box != FACE_NO_BOX)
+ if (face && face->box != FACE_NO_BOX)
it->start_of_box_run_p = true;
}
For strings from wrap-prefix and line-prefix properties,
use the default face, possibly remapped via
Vface_remapping_alist. */
+ /* Note that the fact that we use the face at _buffer_
+ position means that a 'display' property on an overlay
+ string will not inherit the face of that overlay string,
+ but will instead revert to the face of buffer text
+ covered by the overlay. This is visible, e.g., when the
+ overlay specifies a box face, but neither the buffer nor
+ the display string do. This sounds like a design bug,
+ but Emacs always did that since v21.1, so changing that
+ might be a big deal. */
base_face_id = it->string_from_prefix_prop_p
? (!NILP (Vface_remapping_alist)
? lookup_basic_face (it->f, DEFAULT_FACE_ID)
it->object = it->w->contents;
break;
case GET_FROM_STRING:
- it->object = it->string;
+ {
+ struct face *face = FACE_FROM_ID (it->f, it->face_id);
+
+ /* Restore the face_box_p flag, since it could have been
+ overwritten by the face of the object that we just finished
+ displaying. */
+ if (face)
+ it->face_box_p = face->box != FACE_NO_BOX;
+ it->object = it->string;
+ }
break;
case GET_FROM_DISPLAY_VECTOR:
if (it->s)
If this is the last string character displayed, check
the next buffer location. */
else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
- && (it->current.overlay_string_index
- == it->n_overlay_strings - 1))
+ /* n_overlay_strings is unreliable unless
+ overlay_string_index is non-negative. */
+ && ((it->current.overlay_string_index >= 0
+ && (it->current.overlay_string_index
+ == it->n_overlay_strings - 1))
+ /* A string from display property. */
+ || it->from_disp_prop_p))
{
ptrdiff_t ignore;
int next_face_id;
struct text_pos pos = it->current.pos;
- INC_TEXT_POS (pos, it->multibyte_p);
- next_face_id = face_at_buffer_position
- (it->w, CHARPOS (pos), &ignore,
- (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);
+ /* For a string from a display property, the next
+ buffer position is stored in the 'position'
+ member of the iteration stack slot below the
+ current one, see handle_single_display_spec. By
+ contrast, it->current.pos was is not yet updated
+ to point to that buffer position; that will
+ happen in pop_it, after we finish displaying the
+ current string. Note that we already checked
+ above that it->sp is positive, so subtracting one
+ from it is safe. */
+ if (it->from_disp_prop_p)
+ pos = (it->stack + it->sp - 1)->position;
+ else
+ INC_TEXT_POS (pos, it->multibyte_p);
+
+ if (CHARPOS (pos) >= ZV)
+ it->end_of_box_run_p = true;
+ else
+ {
+ next_face_id = face_at_buffer_position
+ (it->w, CHARPOS (pos), &ignore,
+ CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
+ it->end_of_box_run_p
+ = (FACE_FROM_ID (it->f, next_face_id)->box
+ == FACE_NO_BOX);
+ }
}
}
}
void *ppos_data = NULL;
int may_wrap = 0;
enum it_method prev_method = it->method;
- ptrdiff_t prev_pos = IT_CHARPOS (*it);
+ ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
int saw_smaller_pos = prev_pos < to_charpos;
/* Don't produce glyphs in produce_glyphs. */
atx_it.sp = -1;
/* Use ppos_it under bidi reordering to save a copy of IT for the
- position > CHARPOS that is the closest to CHARPOS. We restore
- that position in IT when we have scanned the entire display line
- without finding a match for CHARPOS and all the character
- positions are greater than CHARPOS. */
+ initial position. We restore that position in IT when we have
+ scanned the entire display line without finding a match for
+ TO_CHARPOS and all the character positions are greater than
+ TO_CHARPOS. We then restart the scan from the initial position,
+ and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
+ the closest to TO_CHARPOS. */
if (it->bidi_p)
{
- SAVE_IT (ppos_it, *it, ppos_data);
- SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
- SAVE_IT (ppos_it, *it, ppos_data);
+ {
+ SAVE_IT (ppos_it, *it, ppos_data);
+ closest_pos = IT_CHARPOS (*it);
+ }
+ else
+ closest_pos = ZV;
}
#define BUFFER_POS_REACHED_P() \
}
else
{
- if (it->line_wrap == WORD_WRAP)
+ if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
{
if (IT_DISPLAYING_WHITESPACE (it))
may_wrap = 1;
if (it->bidi_p
&& (op & MOVE_TO_POS)
&& IT_CHARPOS (*it) > to_charpos
- && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
- SAVE_IT (ppos_it, *it, ppos_data);
+ && IT_CHARPOS (*it) < closest_pos)
+ closest_pos = IT_CHARPOS (*it);
continue;
}
doesn't fit on the line, e.g. a wide image. */
it->hpos == 0
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f)))
+ && FRAME_WINDOW_P (it->f)
+ /* When word-wrap is ON and we have a valid
+ wrap point, we don't allow the last glyph
+ to "just barely fit" on the line. */
+ && (it->line_wrap != WORD_WRAP
+ || wrap_it.sp < 0)))
{
++it->hpos;
it->current_x = new_x;
{
if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
{
- if (IT_CHARPOS (ppos_it) < ZV)
+ if (closest_pos < ZV)
{
RESTORE_IT (it, &ppos_it, ppos_data);
+ /* Don't recurse if closest_pos is equal to
+ to_charpos, since we have just tried that. */
+ if (closest_pos != to_charpos)
+ move_it_in_display_line_to (it, closest_pos, -1,
+ MOVE_TO_POS);
result = MOVE_POS_MATCH_OR_ZV;
}
else
if (it->bidi_p
&& (op & MOVE_TO_POS)
&& IT_CHARPOS (*it) >= to_charpos
- && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
- SAVE_IT (ppos_it, *it, ppos_data);
+ && IT_CHARPOS (*it) < closest_pos)
+ closest_pos = IT_CHARPOS (*it);
/* Stop if lines are truncated and IT's current x-position is
past the right edge of the window now. */
&& IT_CHARPOS (*it) > to_charpos))
{
if (it->bidi_p
- && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
- RESTORE_IT (it, &ppos_it, ppos_data);
+ && !BUFFER_POS_REACHED_P ()
+ && !at_eob_p && closest_pos < ZV)
+ {
+ RESTORE_IT (it, &ppos_it, ppos_data);
+ if (closest_pos != to_charpos)
+ move_it_in_display_line_to (it, closest_pos, -1,
+ MOVE_TO_POS);
+ }
result = MOVE_POS_MATCH_OR_ZV;
break;
}
&& !saw_smaller_pos
&& IT_CHARPOS (*it) > to_charpos)
{
- if (IT_CHARPOS (ppos_it) < ZV)
- RESTORE_IT (it, &ppos_it, ppos_data);
+ if (closest_pos < ZV)
+ {
+ RESTORE_IT (it, &ppos_it, ppos_data);
+ if (closest_pos != to_charpos)
+ move_it_in_display_line_to (it, closest_pos, -1,
+ MOVE_TO_POS);
+ }
result = MOVE_POS_MATCH_OR_ZV;
break;
}
ptrdiff_t start_charpos, i;
int nchars_per_row
= (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
+ bool hit_pos_limit = false;
ptrdiff_t pos_limit;
/* Start at the beginning of the screen line containing IT's
pos_limit = BEGV;
else
pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
+
for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
back_to_previous_visible_line_start (it);
+ if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
+ hit_pos_limit = true;
reseat (it, it->current.pos, 1);
/* Move further back if we end up in a string or an image. */
else
bidi_unshelve_cache (it2data, 1);
}
+ else if (hit_pos_limit && pos_limit > BEGV
+ && dvpos < 0 && it2.vpos < -dvpos)
+ {
+ /* If we hit the limit, but still didn't make it far enough
+ back, that means there's a display string with a newline
+ covering a large chunk of text, and that caused
+ back_to_previous_visible_line_start try to go too far.
+ Punish those who commit such atrocities by going back
+ until we've reached DVPOS, after lifting the limit, which
+ could make it slow for very long lines. "If it hurts,
+ don't do that!" */
+ dvpos += it2.vpos;
+ RESTORE_IT (it, it, it2data);
+ for (i = -dvpos; i > 0; --i)
+ {
+ back_to_previous_visible_line_start (it);
+ it->vpos--;
+ }
+ }
else
RESTORE_IT (it, it, it2data);
}
defaults to the maximum accessible position of the buffer. If TO is t,
use the maximum accessible position that is not a newline character.
-The optional argument X_LIMIT, if non-nil, specifies the maximum text
-width that can be returned. X_LIMIT nil or omitted, means to use the
+The optional argument X-LIMIT, if non-nil, specifies the maximum text
+width that can be returned. X-LIMIT nil or omitted, means to use the
pixel-width of WINDOW's body; use this if you do not intend to change
the width of WINDOW. Use the maximum width WINDOW may assume if you
-intend to change WINDOW's width.
+intend to change WINDOW's width. In any case, text whose x-coordinate
+is beyond X-LIMIT is ignored. Since calculating the width of long lines
+can take some time, it's always a good idea to make this argument as
+small as possible; in particular, if the buffer contains long lines that
+shall be truncated anyway.
-The optional argument Y_LIMIT, if non-nil, specifies the maximum text
+The optional argument Y-LIMIT, if non-nil, specifies the maximum text
height that can be returned. Text lines whose y-coordinate is beyond
-Y_LIMIT are ignored. Since calculating the text height of a large
+Y-LIMIT are ignored. Since calculating the text height of a large
buffer can take some time, it makes sense to specify this argument if
the size of the buffer is unknown.
-Optional argument MODE_AND_HEADER_LINE nil or omitted means do not
+Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
include the height of the mode- or header-line of WINDOW in the return
value. If it is either the symbol `mode-line' or `header-line', include
only the height of that line, if present, in the return value. If t,
{
if (m)
{
- /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
- String whose data pointer might be passed to us in M. So
- we use a local copy. */
- char *fmt = xstrdup (m);
+ /* ENCODE_SYSTEM below can GC and/or relocate the
+ Lisp data, so make sure we don't use it here. */
+ eassert (relocatable_string_data_p (m) != 1);
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
+ fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
if (!cursor_in_echo_area)
fprintf (stderr, "\n");
fflush (stderr);
- xfree (fmt);
}
}
else if (INTERACTIVE)
}
}
}
- safe_call1 (Vpre_redisplay_function, windows);
+ safe__call1 (true, Vpre_redisplay_function, windows);
}
/* Update all frame titles based on their buffer names, etc. We do
/* As soon as we've found the exact match for point,
or the first suitable row whose ends_at_zv_p flag
is set, we are done. */
- at_zv_p =
- MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
- if (rv && !at_zv_p
- && w->cursor.hpos >= 0
- && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
- w->cursor.vpos))
+ if (rv)
{
- struct glyph_row *candidate =
- MATRIX_ROW (w->current_matrix, w->cursor.vpos);
- struct glyph *g =
- candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
- ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
-
- exact_match_p =
- (BUFFERP (g->object) && g->charpos == PT)
- || (INTEGERP (g->object)
- && (g->charpos == PT
- || (g->charpos == 0 && endpos - 1 == PT)));
- }
- if (rv && (at_zv_p || exact_match_p))
- {
- rc = CURSOR_MOVEMENT_SUCCESS;
- break;
+ at_zv_p = MATRIX_ROW (w->current_matrix,
+ w->cursor.vpos)->ends_at_zv_p;
+ if (!at_zv_p
+ && w->cursor.hpos >= 0
+ && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
+ w->cursor.vpos))
+ {
+ struct glyph_row *candidate =
+ MATRIX_ROW (w->current_matrix, w->cursor.vpos);
+ struct glyph *g =
+ candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
+ ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
+
+ exact_match_p =
+ (BUFFERP (g->object) && g->charpos == PT)
+ || (INTEGERP (g->object)
+ && (g->charpos == PT
+ || (g->charpos == 0 && endpos - 1 == PT)));
+ }
+ if (at_zv_p || exact_match_p)
+ {
+ rc = CURSOR_MOVEMENT_SUCCESS;
+ break;
+ }
}
if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
break;
return rc;
}
-#if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
-static
-#endif
void
set_vertical_scroll_bar (struct window *w)
{
/* Consider the following case: Window starts at BEGV, there is
invisible, intangible text at BEGV, so that display starts at
some point START > BEGV. It can happen that we are called with
- PT somewhere between BEGV and START. Try to handle that case. */
+ PT somewhere between BEGV and START. Try to handle that case,
+ and similar ones. */
if (w->cursor.vpos < 0)
{
- struct glyph_row *row = w->current_matrix->rows;
- if (row->mode_line_p)
- ++row;
+ /* First, try locating the proper glyph row for PT. */
+ struct glyph_row *row =
+ row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
+
+ /* Sometimes point is at the beginning of invisible text that is
+ before the 1st character displayed in the row. In that case,
+ row_containing_pos fails to find the row, because no glyphs
+ with appropriate buffer positions are present in the row.
+ Therefore, we next try to find the row which shows the 1st
+ position after the invisible text. */
+ if (!row)
+ {
+ Lisp_Object val =
+ get_char_property_and_overlay (make_number (PT), Qinvisible,
+ Qnil, NULL);
+
+ if (TEXT_PROP_MEANS_INVISIBLE (val))
+ {
+ ptrdiff_t alt_pos;
+ Lisp_Object invis_end =
+ Fnext_single_char_property_change (make_number (PT), Qinvisible,
+ Qnil, Qnil);
+
+ if (NATNUMP (invis_end))
+ alt_pos = XFASTINT (invis_end);
+ else
+ alt_pos = ZV;
+ row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
+ NULL, 0);
+ }
+ }
+ /* Finally, fall back on the first row of the window after the
+ header line (if any). This is slightly better than not
+ displaying the cursor at all. */
+ if (!row)
+ {
+ row = w->current_matrix->rows;
+ if (row->mode_line_p)
+ ++row;
+ }
set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
}
truncate_it.current_x = 0;
truncate_it.face_id = DEFAULT_FACE_ID;
truncate_it.glyph_row = &scratch_glyph_row;
+ truncate_it.area = TEXT_AREA;
truncate_it.glyph_row->used[TEXT_AREA] = 0;
CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
truncate_it.object = make_number (0);
move_it_by_lines (&it, -1);
target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
target_is_eol_p = true;
+ /* Under word-wrap, we don't know the x coordinate of
+ the last character displayed on the previous line,
+ which immediately precedes the wrap point. To find
+ out its x coordinate, we try moving to the right
+ margin of the window, which will stop at the wrap
+ point, and then reset target_x to point at the
+ character that precedes the wrap point. This is not
+ needed on GUI frames, because (see below) there we
+ move from the left margin one grapheme cluster at a
+ time, and stop when we hit the wrap point. */
+ if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
+ {
+ void *it_data = NULL;
+ struct it it2;
+
+ SAVE_IT (it2, it, it_data);
+ move_it_in_display_line_to (&it, ZV, target_x,
+ MOVE_TO_POS | MOVE_TO_X);
+ /* If we arrived at target_x, that _is_ the last
+ character on the previous line. */
+ if (it.current_x != target_x)
+ target_x = it.current_x - 1;
+ RESTORE_IT (&it, &it2, it_data);
+ }
}
}
else
new_pos = it.current.pos;
while (it.current_x + it.pixel_width <= target_x
- && rc == MOVE_X_REACHED)
+ && (rc == MOVE_X_REACHED
+ /* Under word-wrap, move_it_in_display_line_to
+ stops at correct coordinates, but sometimes
+ returns MOVE_POS_MATCH_OR_ZV. */
+ || (it.line_wrap == WORD_WRAP
+ && rc == MOVE_POS_MATCH_OR_ZV)))
{
int new_x = it.current_x + it.pixel_width;
if (CONSP (XCDR (elt)))
{
Lisp_Object spec;
- spec = safe_eval (XCAR (XCDR (elt)));
+ spec = safe__eval (true, XCAR (XCDR (elt)));
n += display_mode_element (it, depth, field_width - n,
precision - n, spec, props,
risky);
return decode_mode_spec_buf;
no_value:
{
- char* p = decode_mode_spec_buf;
+ char *p = decode_mode_spec_buf;
int pad = width - 2;
while (pad-- > 0)
*p++ = ' ';
return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
}
- prop = buffer_local_value_1 (prop, it->w->contents);
+ prop = buffer_local_value (prop, it->w->contents);
if (EQ (prop, Qunbound))
prop = Qnil;
}
return OK_PIXELS (pixels);
}
- car = buffer_local_value_1 (car, it->w->contents);
+ car = buffer_local_value (car, it->w->contents);
if (EQ (car, Qunbound))
car = Qnil;
}
#endif
{
eassert (face != NULL);
- PREPARE_FACE_FOR_DISPLAY (f, face);
+ prepare_face_for_display (f, face);
}
return face;
/* Make sure X resources of the face are allocated. */
eassert (face != NULL);
- PREPARE_FACE_FOR_DISPLAY (f, face);
+ prepare_face_for_display (f, face);
if (two_byte_p)
*two_byte_p = 0;
s->ybase += voffset;
/* The case that face->gc == 0 is handled when drawing the glyph
- string by calling PREPARE_FACE_FOR_DISPLAY. */
+ string by calling prepare_face_for_display. */
eassert (s->face);
return glyph - s->row->glyphs[s->area];
}
else
overlap_hl = DRAW_NORMAL_TEXT;
+ if (hl != overlap_hl)
+ clip_head = head;
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;
+ if (clip_head == NULL)
+ clip_head = head;
}
/* Prepend glyph strings for glyphs in front of the first glyph
else
overlap_hl = DRAW_NORMAL_TEXT;
- clip_head = head;
+ if (hl == overlap_hl || clip_head == NULL)
+ clip_head = head;
BUILD_GLYPH_STRINGS (i, start, h, t,
overlap_hl, dummy_x, last_x);
for (s = h; s; s = s->next)
else
overlap_hl = DRAW_NORMAL_TEXT;
+ if (hl != overlap_hl)
+ clip_tail = tail;
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;
+ if (clip_tail == NULL)
+ clip_tail = tail;
}
/* Append glyph strings for glyphs following the last glyph
else
overlap_hl = DRAW_NORMAL_TEXT;
- clip_tail = tail;
+ if (hl == overlap_hl || clip_tail == NULL)
+ clip_tail = tail;
i++; /* We must include the Ith glyph. */
BUILD_GLYPH_STRINGS (end, i, h, t,
overlap_hl, x, last_x);
face = FACE_FROM_ID (it->f, it->face_id);
eassert (face);
/* Make sure X resources of the face is loaded. */
- PREPARE_FACE_FOR_DISPLAY (it->f, face);
+ prepare_face_for_display (it->f, face);
if (it->image_id < 0)
{
{
struct face *face = FACE_FROM_ID (it->f, it->face_id);
font = face->font ? face->font : FRAME_FONT (it->f);
- PREPARE_FACE_FOR_DISPLAY (it->f, face);
+ prepare_face_for_display (it->f, face);
}
#endif
face = FACE_FROM_ID (it->f, face_id);
font = face->font ? face->font : FRAME_FONT (it->f);
- PREPARE_FACE_FOR_DISPLAY (it->f, face);
+ prepare_face_for_display (it->f, face);
if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
{
/* Erase the image of a cursor of window W from the screen. */
-#ifndef HAVE_NTGUI
-static
-#endif
void
erase_phys_cursor (struct window *w)
{
if (/* If window is in the process of being destroyed, don't bother
to do anything. */
w->current_matrix != NULL
- /* Don't update mouse highlight if hidden */
+ /* Don't update mouse highlight if hidden. */
&& (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
/* Recognize when we are called to operate on rows that don't exist
anymore. This can happen when a window is split. */
else if (area == ON_MODE_LINE)
{
Lisp_Object default_help
- = buffer_local_value_1 (Qmode_line_default_help_echo,
- w->contents);
+ = buffer_local_value (Qmode_line_default_help_echo,
+ w->contents);
if (STRINGP (default_help))
{
/* Change the mouse pointer according to what is under it. */
if (FRAME_WINDOW_P (f))
{
+ bool draggable = (! WINDOW_BOTTOMMOST_P (w)
+ || minibuf_level
+ || NILP (Vresize_mini_windows));
+
dpyinfo = FRAME_DISPLAY_INFO (f);
if (STRINGP (string))
{
map = Fget_text_property (pos, Qlocal_map, string);
if (!KEYMAPP (map))
map = Fget_text_property (pos, Qkeymap, string);
- if (!KEYMAPP (map))
+ if (!KEYMAPP (map) && draggable)
cursor = dpyinfo->vertical_scroll_bar_cursor;
}
}
- else
+ else if (draggable)
/* Default mode-line pointer. */
cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
}
help_echo_string = build_string ("drag-mouse-1: resize");
}
else if (part == ON_BOTTOM_DIVIDER)
- {
- cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
- help_echo_string = build_string ("drag-mouse-1: resize");
- }
+ if (! WINDOW_BOTTOMMOST_P (w)
+ || minibuf_level
+ || NILP (Vresize_mini_windows))
+ {
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
+ help_echo_string = build_string ("drag-mouse-1: resize");
+ }
+ else
+ cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
|| part == ON_SCROLL_BAR)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;