/* 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 Free Software Foundation, Inc.
+ 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
current_header_line_height = current_mode_line_height = -1;
if (visible_p && XFASTINT (w->hscroll) > 0)
- *x -= XFASTINT (w->hscroll);
+ *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
return visible_p;
}
}
/* EXPORT:
- Return in *R the clipping rectangle for glyph string S. */
+ Return in RECTS[] at most N clipping rectangles for glyph string S.
+ Return the number of stored rectangles. */
-void
-get_glyph_string_clip_rect (s, nr)
+int
+get_glyph_string_clip_rects (s, rects, n)
struct glyph_string *s;
- NativeRectangle *nr;
+ NativeRectangle *rects;
+ int n;
{
XRectangle r;
+ if (n <= 0)
+ return 0;
+
if (s->row->full_width_p)
{
/* Draw full-width. X coordinates are relative to S->w->left_col. */
/* If S draws overlapping rows, it's sufficient to use the top and
bottom of the window for clipping because this glyph string
intentionally draws over other lines. */
- if (s->for_overlaps_p)
+ if (s->for_overlaps)
{
r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
r.height = window_text_bottom_y (s->w) - r.y;
+
+ /* Alas, the above simple strategy does not work for the
+ environments with anti-aliased text: if the same text is
+ drawn onto the same place multiple times, it gets thicker.
+ If the overlap we are processing is for the erased cursor, we
+ take the intersection with the rectagle of the cursor. */
+ if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
+ {
+ XRectangle rc, r_save = r;
+
+ rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
+ rc.y = s->w->phys_cursor.y;
+ rc.width = s->w->phys_cursor_width;
+ rc.height = s->w->phys_cursor_height;
+
+ x_intersect_rectangles (&r_save, &rc, &r);
+ }
}
else
{
}
}
+ if ((s->for_overlaps & OVERLAPS_BOTH) == 0
+ || (s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)
+ {
+#ifdef CONVERT_FROM_XRECT
+ CONVERT_FROM_XRECT (r, *rects);
+#else
+ *rects = r;
+#endif
+ return 1;
+ }
+ else
+ {
+ /* If we are processing overlapping and allowed to return
+ multiple clipping rectangles, we exclude the row of the glyph
+ string from the clipping rectangle. This is to avoid drawing
+ the same text on the environment with anti-aliasing. */
#ifdef CONVERT_FROM_XRECT
- CONVERT_FROM_XRECT (r, *nr);
+ XRectangle rs[2];
#else
- *nr = r;
+ XRectangle *rs = rects;
#endif
+ int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
+
+ if (s->for_overlaps & OVERLAPS_PRED)
+ {
+ rs[i] = r;
+ if (r.y + r.height > row_y)
+ if (r.y < row_y)
+ rs[i].height = row_y - r.y;
+ else
+ rs[i].height = 0;
+ i++;
+ }
+ if (s->for_overlaps & OVERLAPS_SUCC)
+ {
+ rs[i] = r;
+ if (r.y < row_y + s->row->visible_height)
+ if (r.y + r.height > row_y + s->row->visible_height)
+ {
+ rs[i].y = row_y + s->row->visible_height;
+ rs[i].height = r.y + r.height - rs[i].y;
+ }
+ else
+ rs[i].height = 0;
+ i++;
+ }
+
+ n = i;
+#ifdef CONVERT_FROM_XRECT
+ for (i = 0; i < n; i++)
+ CONVERT_FROM_XRECT (rs[i], rects[i]);
+#endif
+ return n;
+ }
+}
+
+/* EXPORT:
+ Return in *NR the clipping rectangle for glyph string S. */
+
+void
+get_glyph_string_clip_rect (s, nr)
+ struct glyph_string *s;
+ NativeRectangle *nr;
+{
+ get_glyph_string_clip_rects (s, nr, 1);
}
return WINDOW_TO_FRAME_PIXEL_Y (w, y);
}
+/*
+ * Remember which glyph the mouse is over.
+ */
+
+void
+remember_mouse_glyph (f, gx, gy, rect)
+ struct frame *f;
+ int gx, gy;
+ NativeRectangle *rect;
+{
+ Lisp_Object window;
+ struct window *w;
+ struct glyph_row *r, *gr, *end_row;
+ enum window_part part;
+ enum glyph_row_area area;
+ int x, y, width, height;
+
+ /* Try to determine frame pixel position and size of the glyph under
+ frame pixel coordinates X/Y on frame F. */
+
+ window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
+ if (NILP (window))
+ {
+ width = FRAME_SMALLEST_CHAR_WIDTH (f);
+ height = FRAME_SMALLEST_FONT_HEIGHT (f);
+ goto virtual_glyph;
+ }
+
+ w = XWINDOW (window);
+ width = WINDOW_FRAME_COLUMN_WIDTH (w);
+ height = WINDOW_FRAME_LINE_HEIGHT (w);
+
+ r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+
+ if (w->pseudo_window_p)
+ {
+ area = TEXT_AREA;
+ part = ON_MODE_LINE; /* Don't adjust margin. */
+ goto text_glyph;
+ }
+
+ switch (part)
+ {
+ case ON_LEFT_MARGIN:
+ area = LEFT_MARGIN_AREA;
+ goto text_glyph;
+
+ case ON_RIGHT_MARGIN:
+ area = RIGHT_MARGIN_AREA;
+ goto text_glyph;
+
+ case ON_HEADER_LINE:
+ case ON_MODE_LINE:
+ gr = (part == ON_HEADER_LINE
+ ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
+ : MATRIX_MODE_LINE_ROW (w->current_matrix));
+ gy = gr->y;
+ area = TEXT_AREA;
+ goto text_glyph_row_found;
+
+ case ON_TEXT:
+ area = TEXT_AREA;
+
+ text_glyph:
+ gr = 0; gy = 0;
+ for (; r <= end_row && r->enabled_p; ++r)
+ if (r->y + r->height > y)
+ {
+ gr = r; gy = r->y;
+ break;
+ }
+
+ text_glyph_row_found:
+ if (gr && gy <= y)
+ {
+ struct glyph *g = gr->glyphs[area];
+ struct glyph *end = g + gr->used[area];
+
+ height = gr->height;
+ for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
+ if (gx + g->pixel_width > x)
+ break;
+
+ if (g < end)
+ {
+ if (g->type == IMAGE_GLYPH)
+ {
+ /* Don't remember when mouse is over image, as
+ image may have hot-spots. */
+ STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
+ return;
+ }
+ width = g->pixel_width;
+ }
+ else
+ {
+ /* Use nominal char spacing at end of line. */
+ x -= gx;
+ gx += (x / width) * width;
+ }
+
+ if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
+ gx += window_box_left_offset (w, area);
+ }
+ else
+ {
+ /* Use nominal line height at end of window. */
+ gx = (x / width) * width;
+ y -= gy;
+ gy += (y / height) * height;
+ }
+ break;
+
+ case ON_LEFT_FRINGE:
+ gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
+ : window_box_right_offset (w, LEFT_MARGIN_AREA));
+ width = WINDOW_LEFT_FRINGE_WIDTH (w);
+ goto row_glyph;
+
+ case ON_RIGHT_FRINGE:
+ 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);
+ goto row_glyph;
+
+ case ON_SCROLL_BAR:
+ gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+ ? 0
+ : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
+ + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? WINDOW_RIGHT_FRINGE_WIDTH (w)
+ : 0)));
+ width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+
+ row_glyph:
+ gr = 0, gy = 0;
+ for (; r <= end_row && r->enabled_p; ++r)
+ if (r->y + r->height > y)
+ {
+ gr = r; gy = r->y;
+ break;
+ }
+
+ if (gr && gy <= y)
+ height = gr->height;
+ else
+ {
+ /* Use nominal line height at end of window. */
+ y -= gy;
+ gy += (y / height) * height;
+ }
+ break;
+
+ default:
+ ;
+ virtual_glyph:
+ /* If there is no glyph under the mouse, then we divide the screen
+ into a grid of the smallest glyph in the frame, and use that
+ as our "glyph". */
+
+ /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
+ round down even for negative values. */
+ if (gx < 0)
+ gx -= width - 1;
+ if (gy < 0)
+ gy -= height - 1;
+
+ gx = (gx / width) * width;
+ gy = (gy / height) * height;
+
+ goto store_rect;
+ }
+
+ gx += WINDOW_LEFT_EDGE_X (w);
+ gy += WINDOW_TOP_EDGE_Y (w);
+
+ store_rect:
+ STORE_NATIVE_RECT (*rect, gx, gy, width, height);
+
+ /* Visible feedback for debugging. */
+#if 0
+#if HAVE_X_WINDOWS
+ XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ f->output_data.x->normal_gc,
+ gx, gy, width, height);
+#endif
+#endif
+}
+
#endif /* HAVE_WINDOW_SYSTEM */
struct it *it;
{
enum prop_handled handled;
- int handle_overlay_change_p = 1;
+ int handle_overlay_change_p;
struct props *p;
it->dpvec = NULL;
it->current.dpvec_index = -1;
+ handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
+ it->ignore_overlay_strings_at_pos_p = 0;
/* Use face of preceding text for ellipsis (if invisible) */
if (it->selective_display_ellipsis_p)
Lisp_Object prop, pos;
enum prop_handled handled = HANDLED_NORMALLY;
+ if (!NILP (Vmemory_full))
+ return handled;
+
/* Get the value of the `fontified' property at IT's current buffer
position. (The `fontified' property doesn't have a special
meaning in strings.) If the value is nil, call functions from
skip starting with next_stop. */
if (invis_p)
IT_CHARPOS (*it) = next_stop;
+
+ /* If there are adjacent invisible texts, don't lose the
+ second one's ellipsis. */
+ if (invis_p == 2)
+ display_ellipsis_p = 1;
}
while (invis_p);
it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
}
else if (display_ellipsis_p)
- setup_for_ellipsis (it, 0);
+ {
+ /* Make sure that the glyphs of the ellipsis will get
+ correct `charpos' values. If we would not update
+ it->position here, the glyphs would belong to the
+ last visible character _before_ the invisible
+ text, which confuses `set_cursor_from_row'.
+
+ We use the last invisible position instead of the
+ first because this way the cursor is always drawn on
+ the first "." of the ellipsis, whenever PT is inside
+ the invisible text. Otherwise the cursor would be
+ placed _after_ the ellipsis when the point is after the
+ first invisible character. */
+ it->position.charpos = IT_CHARPOS (*it) - 1;
+ it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
+ setup_for_ellipsis (it, 0);
+ }
}
}
{
it->method = GET_FROM_STRETCH;
it->object = value;
- it->current.pos = it->position = start_pos;
+ *position = it->position = start_pos;
}
#ifdef HAVE_WINDOW_SYSTEM
else
reseat_at_next_visible_line_start (it, 1);
else if (it->dpvec_char_len > 0)
{
+ if (it->method == GET_FROM_STRING
+ && it->n_overlay_strings > 0)
+ it->ignore_overlay_strings_at_pos_p = 1;
it->len = it->dpvec_char_len;
set_iterator_to_next (it, reseat_p);
}
terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
nonzero, means interpret the contents of M as multibyte. This
function calls low-level routines in order to bypass text property
- hooks, etc. which might not be safe to run. */
+ hooks, etc. which might not be safe to run.
+
+ This may GC (insert may run before/after change hooks),
+ so the buffer M must NOT point to a Lisp string. */
void
message_dolog (m, nbytes, nlflag, multibyte)
out any existing message, and let the mini-buffer text show
through.
- The buffer M must continue to exist until after the echo area gets
- cleared or some other message gets displayed there. This means do
- not pass text that is stored in a Lisp string; do not pass text in
- a buffer that was alloca'd. */
+ This may GC, so the buffer M must NOT point to a Lisp string. */
void
message2 (m, nbytes, multibyte)
If S is not null, set the message to the first LEN bytes of S. LEN
zero means use the whole string. MULTIBYTE_P non-zero means S is
- multibyte. Display the message multibyte in that case. */
+ multibyte. Display the message multibyte in that case.
+
+ Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
+ to t before calling set_message_1 (which calls insert).
+ */
void
set_message (s, string, nbytes, multibyte_p)
static Lisp_Object Vmode_line_unwind_vector;
static Lisp_Object
-format_mode_line_unwind_data (obuf)
+format_mode_line_unwind_data (obuf, save_proptrans)
struct buffer *obuf;
{
Lisp_Object vector;
AREF (vector, 0) = make_number (mode_line_target);
AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
AREF (vector, 2) = mode_line_string_list;
- AREF (vector, 3) = mode_line_proptrans_alist;
+ AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
AREF (vector, 4) = mode_line_string_face;
AREF (vector, 5) = mode_line_string_face_prop;
mode_line_target = XINT (AREF (vector, 0));
mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
mode_line_string_list = AREF (vector, 2);
- mode_line_proptrans_alist = AREF (vector, 3);
+ if (! EQ (AREF (vector, 3), Qt))
+ mode_line_proptrans_alist = AREF (vector, 3);
mode_line_string_face = AREF (vector, 4);
mode_line_string_face_prop = AREF (vector, 5);
mode_line_target so that display_mode_element will output into
mode_line_noprop_buf; then display the title. */
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (current_buffer));
+ format_mode_line_unwind_data (current_buffer, 0));
set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
clear_garbaged_frames ();
/* Build menubar and tool-bar items. */
- prepare_menu_bars ();
+ if (NILP (Vmemory_full))
+ prepare_menu_bars ();
if (windows_or_buffers_changed)
update_mode_lines++;
cursor_row_fully_visible_p (w, force_p, current_matrix_p)
struct window *w;
int force_p;
+ int current_matrix_p;
{
struct glyph_matrix *matrix;
struct glyph_row *row;
this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
if ((w->cursor.y < this_scroll_margin
- && CHARPOS (pos) > BEGV)
+ && CHARPOS (pos) > BEGV
+ && IT_CHARPOS (it) < ZV)
/* rms: considering make_cursor_line_fully_visible_p here
seems to give wrong results. We don't want to recenter
when the last line is partly visible, we want to allow
produce_special_glyphs (it, IT_CONTINUATION);
row->continued_p = 1;
+ it->current_x = x_before;
it->continuation_lines_width += x;
+ extend_face_to_end_of_line (it);
if (nglyphs > 1 && i > 0)
{
it.base_face_id = it.face_id = DEFAULT_FACE_ID;
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (NULL));
+ format_mode_line_unwind_data (NULL, 0));
mode_line_target = MODE_LINE_DISPLAY;
return it.glyph_row->height;
}
+/* Move element ELT in LIST to the front of LIST.
+ Return the updated list. */
+
+static Lisp_Object
+move_elt_to_front (elt, list)
+ Lisp_Object elt, list;
+{
+ register Lisp_Object tail, prev;
+ register Lisp_Object tem;
+
+ tail = list;
+ prev = Qnil;
+ while (CONSP (tail))
+ {
+ tem = XCAR (tail);
+
+ if (EQ (elt, tem))
+ {
+ /* Splice out the link TAIL. */
+ if (NILP (prev))
+ list = XCDR (tail);
+ else
+ Fsetcdr (prev, XCDR (tail));
+
+ /* Now make it the first. */
+ Fsetcdr (tail, list);
+ return tail;
+ }
+ else
+ prev = tail;
+ tail = XCDR (tail);
+ QUIT;
+ }
+
+ /* Not found--return unchanged LIST. */
+ return list;
+}
+
/* Contribute ELT to the mode line for window IT->w. How it
translates into text depends on its data type.
unsigned char c;
int offset = 0;
- if (!NILP (props) || risky)
+ if (SCHARS (elt) > 0
+ && (!NILP (props) || risky))
{
Lisp_Object oprops, aelt;
oprops = Ftext_properties_at (make_number (0), elt);
aelt = Fassoc (elt, mode_line_proptrans_alist);
if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
{
- mode_line_proptrans_alist
- = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
+ /* AELT is what we want. Move it to the front
+ without consing. */
elt = XCAR (aelt);
+ mode_line_proptrans_alist
+ = move_elt_to_front (aelt, mode_line_proptrans_alist);
}
else
{
Lisp_Object tem;
+ /* If AELT has the wrong props, it is useless.
+ so get rid of it. */
+ if (! NILP (aelt))
+ mode_line_proptrans_alist
+ = Fdelq (aelt, mode_line_proptrans_alist);
+
elt = Fcopy_sequence (elt);
Fset_text_properties (make_number (0), Flength (elt),
props, elt);
if (XBUFFER (buffer) != current_buffer)
old_buffer = current_buffer;
+ /* Save things including mode_line_proptrans_alist,
+ and set that to nil so that we don't alter the outer value. */
record_unwind_protect (unwind_format_mode_line,
- format_mode_line_unwind_data (old_buffer));
+ format_mode_line_unwind_data (old_buffer, 1));
+ mode_line_proptrans_alist = Qnil;
if (old_buffer)
set_buffer_internal_1 (XBUFFER (buffer));
return decode_mode_spec_buf;
}
+ case 'e':
+#ifndef SYSTEM_MALLOC
+ {
+ if (NILP (Vmemory_full))
+ return "";
+ else
+ return "!MEM FULL! ";
+ }
+#else
+ return "";
+#endif
+
case 'F':
/* %F displays the frame name. */
if (!NILP (f->title))
FACES is an array of faces for all components of this composition.
S->gidx is the index of the first component for S.
- OVERLAPS_P non-zero means S should draw the foreground only, and
- use its physical height for clipping.
+
+ OVERLAPS non-zero means S should draw the foreground only, and use
+ its physical height for clipping. See also draw_glyphs.
Value is the index of a component not in S. */
static int
-fill_composite_glyph_string (s, faces, overlaps_p)
+fill_composite_glyph_string (s, faces, overlaps)
struct glyph_string *s;
struct face **faces;
- int overlaps_p;
+ int overlaps;
{
int i;
xassert (s);
- s->for_overlaps_p = overlaps_p;
+ s->for_overlaps = overlaps;
s->face = faces[s->gidx];
s->font = s->face->font;
FACE_ID is the face id of the string. START is the index of the
first glyph to consider, END is the index of the last + 1.
- OVERLAPS_P non-zero means S should draw the foreground only, and
- use its physical height for clipping.
+ OVERLAPS non-zero means S should draw the foreground only, and use
+ its physical height for clipping. See also draw_glyphs.
Value is the index of the first glyph not in S. */
static int
-fill_glyph_string (s, face_id, start, end, overlaps_p)
+fill_glyph_string (s, face_id, start, end, overlaps)
struct glyph_string *s;
int face_id;
- int start, end, overlaps_p;
+ int start, end, overlaps;
{
struct glyph *glyph, *last;
int voffset;
xassert (s->nchars == 0);
xassert (start >= 0 && end > start);
- s->for_overlaps_p = overlaps_p,
+ s->for_overlaps = overlaps,
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
voffset = glyph->voffset;
{
/* If the face of this glyph string has to be drawn to the end of
the drawing area, set S->extends_to_end_of_line_p. */
- struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
if (start == s->row->used[s->area]
&& s->area == TEXT_AREA
- && ((s->hl == DRAW_NORMAL_TEXT
- && (s->row->fill_line_p
- || s->face->background != default_face->background
- || s->face->stipple != default_face->stipple
- || s->row->mouse_face_p))
- || s->hl == DRAW_MOUSE_FACE
- || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
- && s->row->fill_line_p)))
- s->extends_to_end_of_line_p = 1;
+ && ((s->row->fill_line_p
+ && (s->hl == DRAW_NORMAL_TEXT
+ || s->hl == DRAW_IMAGE_RAISED
+ || s->hl == DRAW_IMAGE_SUNKEN))
+ || s->hl == DRAW_MOUSE_FACE))
+ s->extends_to_end_of_line_p = 1;
/* If S extends its face to the end of the line, set its
background_width to the distance to the right edge of the drawing
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
append_glyph_string (&HEAD, &TAIL, s); \
s->x = (X); \
- START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
+ START = fill_glyph_string (s, face_id, START, END, overlaps); \
} \
while (0)
if (n == 0) \
first_s = s; \
\
- n = fill_composite_glyph_string (s, faces, overlaps_p); \
+ n = fill_composite_glyph_string (s, faces, overlaps); \
} \
\
++START; \
DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
DRAW_IMAGE_RAISED draw an image with a raised relief around it
- If OVERLAPS_P is non-zero, draw only the foreground of characters
- and clip to the physical height of ROW.
+ If OVERLAPS is non-zero, draw only the foreground of characters and
+ clip to the physical height of ROW. Non-zero value also defines
+ the overlapping part to be drawn:
+
+ OVERLAPS_PRED overlap with preceding rows
+ OVERLAPS_SUCC overlap with succeeding rows
+ OVERLAPS_BOTH overlap with both preceding/succeeding rows
+ OVERLAPS_ERASED_CURSOR overlap with erased cursor area
Value is the x-position reached, relative to AREA of W. */
static int
-draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
+draw_glyphs (w, x, row, area, start, end, hl, overlaps)
struct window *w;
int x;
struct glyph_row *row;
enum glyph_row_area area;
int start, end;
enum draw_glyphs_face hl;
- int overlaps_p;
+ int overlaps;
{
struct glyph_string *head, *tail;
struct glyph_string *s;
/* If there are any glyphs with lbearing < 0 or rbearing > width in
the row, redraw some glyphs in front or following the glyph
strings built above. */
- if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
+ if (head && !overlaps && row->contains_overlapping_glyphs_p)
{
int dummy_x = 0;
struct glyph_string *h, *t;
/* When drawing overlapping rows, only the glyph strings'
foreground is drawn, which doesn't erase a cursor
completely. */
- && !overlaps_p)
+ && !overlaps)
{
int x0 = clip_head ? clip_head->x : (head ? head->x : x);
int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
else
ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
+ if (width > 0 && !it->truncate_lines_p
+ && it->current_x + width > it->last_visible_x)
+ width = it->last_visible_x - it->current_x - 1;
+
if (width > 0 && height > 0 && it->glyph_row)
{
Lisp_Object object = it->stack[it->sp - 1].string;
/* RIF:
Produce glyphs/get display metrics for the display element IT is
- loaded with. See the description of struct display_iterator in
- dispextern.h for an overview of struct display_iterator. */
+ loaded with. See the description of struct it in dispextern.h
+ for an overview of struct it. */
void
x_produce_glyphs (it)
{
if (w == XWINDOW (echo_area_window))
{
- *width = FRAME_CURSOR_WIDTH (f);
- return FRAME_DESIRED_CURSOR (f);
+ if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
+ {
+ *width = FRAME_CURSOR_WIDTH (f);
+ return FRAME_DESIRED_CURSOR (f);
+ }
+ else
+ return get_specified_cursor_type (b->cursor_type, width);
}
*active_cursor = 0;
/* Use cursor-in-non-selected-windows for non-selected window or frame. */
if (non_selected)
{
- alt_cursor = XBUFFER (w->buffer)->cursor_in_non_selected_windows;
+ alt_cursor = b->cursor_in_non_selected_windows;
return get_specified_cursor_type (alt_cursor, width);
}
#ifdef HAVE_WINDOW_SYSTEM
/* EXPORT for RIF:
- Fix the display of area AREA of overlapping row ROW in window W. */
+ Fix the display of area AREA of overlapping row ROW in window W
+ with respect to the overlapping part OVERLAPS. */
void
-x_fix_overlapping_area (w, row, area)
+x_fix_overlapping_area (w, row, area, overlaps)
struct window *w;
struct glyph_row *row;
enum glyph_row_area area;
+ int overlaps;
{
int i, x;
draw_glyphs (w, start_x, row, area,
start, i,
- DRAW_NORMAL_TEXT, 1);
+ DRAW_NORMAL_TEXT, overlaps);
}
else
{
are redrawn. */
else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
{
+ w->phys_cursor_width = x1 - w->phys_cursor.x;
+
if (row > w->current_matrix->rows
&& MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
- x_fix_overlapping_area (w, row - 1, TEXT_AREA);
+ x_fix_overlapping_area (w, row - 1, TEXT_AREA,
+ OVERLAPS_ERASED_CURSOR);
if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
&& MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
- x_fix_overlapping_area (w, row + 1, TEXT_AREA);
+ x_fix_overlapping_area (w, row + 1, TEXT_AREA,
+ OVERLAPS_ERASED_CURSOR);
}
}
}
if (row == last)
end_hpos = dpyinfo->mouse_face_end_col;
else
- end_hpos = row->used[TEXT_AREA];
+ {
+ end_hpos = row->used[TEXT_AREA];
+ if (draw == DRAW_NORMAL_TEXT)
+ row->fill_line_p = 1; /* Clear to end of line */
+ }
if (end_hpos > start_hpos)
{
xassert (row->enabled_p && !row->mode_line_p);
if (row->used[LEFT_MARGIN_AREA])
- x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+ x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
if (row->used[TEXT_AREA])
- x_fix_overlapping_area (w, row, TEXT_AREA);
+ x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
if (row->used[RIGHT_MARGIN_AREA])
- x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+ x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
}
}
Each element has the form (ON-STATE . OFF-STATE). Whenever the
`cursor-type' frame-parameter or variable equals ON-STATE,
comparing using `equal', Emacs uses OFF-STATE to specify
-how to blink it off. */);
+how to blink it off. ON-STATE and OFF-STATE are values for
+the `cursor-type' frame parameter.
+
+If a frame's ON-STATE has no entry in this list,
+the frame's other specifications determine how to blink the cursor off. */);
Vblink_cursor_alist = Qnil;
DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,