(dumpglyphs): Clear any extra pixel rows below the text.
(x_display_box_cursor): Explicitly clear full height of line. (dumpglyphs): New arg just_foreground. Callers changed. (x_set_window_size): Call XSync. (note_mouse_highlight): Do nothing if buffer has changed.
This commit is contained in:
parent
8fc2766b64
commit
0cdd0c9f3e
1 changed files with 228 additions and 44 deletions
272
src/xterm.c
272
src/xterm.c
|
@ -347,6 +347,7 @@ extern FONT_TYPE *XOpenFont ();
|
|||
|
||||
static void flashback ();
|
||||
static void redraw_previous_char ();
|
||||
static void redraw_following_char ();
|
||||
static unsigned int x_x_to_emacs_modifiers ();
|
||||
|
||||
static void note_mouse_highlight ();
|
||||
|
@ -541,6 +542,8 @@ XTcursor_to (row, col)
|
|||
WINDOW is the x-window to output to. LEFT and TOP are starting coords.
|
||||
HL is 1 if this text is highlighted, 2 if the cursor is on it,
|
||||
3 if should appear in its mouse-face.
|
||||
JUST_FOREGROUND if 1 means draw only the foreground;
|
||||
don't alter the background.
|
||||
|
||||
FONT is the default font to use (for glyphs whose font-code is 0).
|
||||
|
||||
|
@ -555,12 +558,13 @@ XTcursor_to (row, col)
|
|||
/* This is the multi-face code. */
|
||||
|
||||
static void
|
||||
dumpglyphs (f, left, top, gp, n, hl)
|
||||
dumpglyphs (f, left, top, gp, n, hl, just_foreground)
|
||||
struct frame *f;
|
||||
int left, top;
|
||||
register GLYPH *gp; /* Points to first GLYPH. */
|
||||
register int n; /* Number of glyphs to display. */
|
||||
int hl;
|
||||
int just_foreground;
|
||||
{
|
||||
/* Holds characters to be displayed. */
|
||||
char *buf = (char *) alloca (f->width * sizeof (*buf));
|
||||
|
@ -568,6 +572,7 @@ dumpglyphs (f, left, top, gp, n, hl)
|
|||
register int tlen = GLYPH_TABLE_LENGTH;
|
||||
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
|
||||
Window window = FRAME_X_WINDOW (f);
|
||||
int orig_left = left;
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
|
@ -691,8 +696,36 @@ dumpglyphs (f, left, top, gp, n, hl)
|
|||
if ((int) font == FACE_DEFAULT)
|
||||
font = f->display.x->font;
|
||||
|
||||
XDrawImageString (x_current_display, window, gc,
|
||||
left, top + FONT_BASE (font), buf, len);
|
||||
if (just_foreground)
|
||||
XDrawString (x_current_display, window, gc,
|
||||
left, top + FONT_BASE (font), buf, len);
|
||||
else
|
||||
{
|
||||
XDrawImageString (x_current_display, window, gc,
|
||||
left, top + FONT_BASE (font), buf, len);
|
||||
/* Clear the rest of the line's height. */
|
||||
if (f->display.x->line_height != FONT_HEIGHT (font))
|
||||
XClearArea (x_current_display, window, left,
|
||||
top + FONT_HEIGHT (font),
|
||||
FONT_WIDTH (font) * len,
|
||||
/* This is how many pixels of height
|
||||
we have to clear. */
|
||||
f->display.x->line_height - FONT_HEIGHT (font),
|
||||
False);
|
||||
}
|
||||
|
||||
#if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS,
|
||||
which often is not up to date yet. */
|
||||
if (!just_foreground)
|
||||
{
|
||||
if (left == orig_left)
|
||||
redraw_previous_char (f, PIXEL_TO_CHAR_COL (f, left),
|
||||
PIXEL_TO_CHAR_ROW (f, top), hl == 1);
|
||||
if (n == 0)
|
||||
redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)),
|
||||
PIXEL_TO_CHAR_ROW (f, top), hl == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gc_temporary)
|
||||
XFreeGC (x_current_display, gc);
|
||||
|
@ -783,7 +816,7 @@ XTwrite_glyphs (start, len)
|
|||
dumpglyphs (f,
|
||||
CHAR_TO_PIXEL_COL (f, curs_x),
|
||||
CHAR_TO_PIXEL_ROW (f, curs_y),
|
||||
start, len, highlight);
|
||||
start, len, highlight, 0);
|
||||
|
||||
/* If we drew on top of the cursor, note that it is turned off. */
|
||||
if (curs_y == f->phys_cursor_y
|
||||
|
@ -841,7 +874,7 @@ XTclear_end_of_line (first_unused)
|
|||
FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
|
||||
f->display.x->line_height, False);
|
||||
#if 0
|
||||
redraw_previous_char (f, curs_x, curs_y);
|
||||
redraw_previous_char (f, curs_x, curs_y, highlight);
|
||||
#endif
|
||||
#else /* ! defined (HAVE_X11) */
|
||||
XPixSet (FRAME_X_WINDOW (f),
|
||||
|
@ -855,39 +888,6 @@ XTclear_end_of_line (first_unused)
|
|||
UNBLOCK_INPUT;
|
||||
}
|
||||
|
||||
/* Erase the character (if any) at the position just before X, Y in frame F,
|
||||
then redraw it and the character before it.
|
||||
This is necessary when we erase starting at X,
|
||||
in case the character after X overlaps into the one before X.
|
||||
Call this function with input blocked. */
|
||||
|
||||
static void
|
||||
redraw_previous_char (f, x, y)
|
||||
FRAME_PTR f;
|
||||
int x, y;
|
||||
{
|
||||
/* Erase the character before the new ones, in case
|
||||
what was here before overlaps it.
|
||||
Reoutput that character, and the previous character
|
||||
(in case the previous character overlaps it). */
|
||||
if (x > 0)
|
||||
{
|
||||
int start_x = x - 2;
|
||||
if (start_x < 0)
|
||||
start_x = 0;
|
||||
XClearArea (x_current_display, FRAME_X_WINDOW (f),
|
||||
CHAR_TO_PIXEL_COL (f, x - 1),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
FONT_WIDTH (f->display.x->font),
|
||||
f->display.x->line_height, False);
|
||||
|
||||
dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
&FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x],
|
||||
x - start_x, highlight);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
XTclear_frame ()
|
||||
{
|
||||
|
@ -917,6 +917,179 @@ XTclear_frame ()
|
|||
UNBLOCK_INPUT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This currently does not work because FRAME_CURRENT_GLYPHS doesn't
|
||||
always contain the right glyphs to use.
|
||||
|
||||
It also needs to be changed to look at the details of the font and
|
||||
see whether there is really overlap, and do nothing when there is
|
||||
not. This can use font_char_overlap_left and font_char_overlap_right,
|
||||
but just how to use them is not clear. */
|
||||
|
||||
/* Erase the character (if any) at the position just before X, Y in frame F,
|
||||
then redraw it and the character before it.
|
||||
This is necessary when we erase starting at X,
|
||||
in case the character after X overlaps into the one before X.
|
||||
Call this function with input blocked. */
|
||||
|
||||
static void
|
||||
redraw_previous_char (f, x, y, highlight_flag)
|
||||
FRAME_PTR f;
|
||||
int x, y;
|
||||
int highlight_flag;
|
||||
{
|
||||
/* Erase the character before the new ones, in case
|
||||
what was here before overlaps it.
|
||||
Reoutput that character, and the previous character
|
||||
(in case the previous character overlaps it). */
|
||||
if (x > 0)
|
||||
{
|
||||
int start_x = x - 2;
|
||||
if (start_x < 0)
|
||||
start_x = 0;
|
||||
XClearArea (x_current_display, FRAME_X_WINDOW (f),
|
||||
CHAR_TO_PIXEL_COL (f, x - 1),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
FONT_WIDTH (f->display.x->font),
|
||||
f->display.x->line_height, False);
|
||||
|
||||
dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
&FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x],
|
||||
x - start_x, highlight_flag, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase the character (if any) at the position X, Y in frame F,
|
||||
then redraw it and the character after it.
|
||||
This is necessary when we erase endng at X,
|
||||
in case the character after X overlaps into the one before X.
|
||||
Call this function with input blocked. */
|
||||
|
||||
static void
|
||||
redraw_following_char (f, x, y, highlight_flag)
|
||||
FRAME_PTR f;
|
||||
int x, y;
|
||||
int highlight_flag;
|
||||
{
|
||||
int limit = FRAME_CURRENT_GLYPHS (f)->used[y];
|
||||
/* Erase the character after the new ones, in case
|
||||
what was here before overlaps it.
|
||||
Reoutput that character, and the following character
|
||||
(in case the following character overlaps it). */
|
||||
if (x < limit
|
||||
&& FRAME_CURRENT_GLYPHS (f)->glyphs[y][x] != SPACEGLYPH)
|
||||
{
|
||||
int end_x = x + 2;
|
||||
if (end_x > limit)
|
||||
end_x = limit;
|
||||
XClearArea (x_current_display, FRAME_X_WINDOW (f),
|
||||
CHAR_TO_PIXEL_COL (f, x),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
FONT_WIDTH (f->display.x->font),
|
||||
f->display.x->line_height, False);
|
||||
|
||||
dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
&FRAME_CURRENT_GLYPHS (f)->glyphs[y][x],
|
||||
end_x - x, highlight_flag, 1);
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
#if 0 /* Not in use yet */
|
||||
|
||||
/* Return 1 if character C in font F extends past its left edge. */
|
||||
|
||||
static int
|
||||
font_char_overlap_left (font, c)
|
||||
XFontStruct *font;
|
||||
int c;
|
||||
{
|
||||
XCharStruct *s;
|
||||
|
||||
/* Find the bounding-box info for C. */
|
||||
if (font->per_char == 0)
|
||||
s = &font->max_bounds;
|
||||
else
|
||||
{
|
||||
int rowlen = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
|
||||
int row, within;
|
||||
|
||||
/* Decode char into row number (byte 1) and code within row (byte 2). */
|
||||
row = c >> 8;
|
||||
within = c & 0177;
|
||||
if (!(within >= font->min_char_or_byte2
|
||||
&& within <= font->max_char_or_byte2
|
||||
&& row >= font->min_byte1
|
||||
&& row <= font->max_byte1))
|
||||
{
|
||||
/* If char is out of range, try the font's default char instead. */
|
||||
c = font->default_char;
|
||||
row = c >> (INTBITS - 8);
|
||||
within = c & 0177;
|
||||
}
|
||||
if (!(within >= font->min_char_or_byte2
|
||||
&& within <= font->max_char_or_byte2
|
||||
&& row >= font->min_byte1
|
||||
&& row <= font->max_byte1))
|
||||
/* Still out of range means this char does not overlap. */
|
||||
return 0;
|
||||
else
|
||||
/* We found the info for this char. */
|
||||
s = (font->per_char + (within - font->min_char_or_byte2)
|
||||
+ row * rowlen);
|
||||
}
|
||||
|
||||
return (s && s->lbearing < 0);
|
||||
}
|
||||
|
||||
/* Return 1 if character C in font F extends past its right edge. */
|
||||
|
||||
static int
|
||||
font_char_overlap_right (font, c)
|
||||
XFontStruct *font;
|
||||
int c;
|
||||
{
|
||||
XCharStruct *s;
|
||||
|
||||
/* Find the bounding-box info for C. */
|
||||
if (font->per_char == 0)
|
||||
s = &font->max_bounds;
|
||||
else
|
||||
{
|
||||
int rowlen = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
|
||||
int row, within;
|
||||
|
||||
/* Decode char into row number (byte 1) and code within row (byte 2). */
|
||||
row = c >> 8;
|
||||
within = c & 0177;
|
||||
if (!(within >= font->min_char_or_byte2
|
||||
&& within <= font->max_char_or_byte2
|
||||
&& row >= font->min_byte1
|
||||
&& row <= font->max_byte1))
|
||||
{
|
||||
/* If char is out of range, try the font's default char instead. */
|
||||
c = font->default_char;
|
||||
row = c >> (INTBITS - 8);
|
||||
within = c & 0177;
|
||||
}
|
||||
if (!(within >= font->min_char_or_byte2
|
||||
&& within <= font->max_char_or_byte2
|
||||
&& row >= font->min_byte1
|
||||
&& row <= font->max_byte1))
|
||||
/* Still out of range means this char does not overlap. */
|
||||
return 0;
|
||||
else
|
||||
/* We found the info for this char. */
|
||||
s = (font->per_char + (within - font->min_char_or_byte2)
|
||||
+ row * rowlen);
|
||||
}
|
||||
|
||||
return (s && s->rbearing >= s->width);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/* Invert the middle quarter of the frame for .15 sec. */
|
||||
|
||||
/* We use the select system call to do the waiting, so we have to make sure
|
||||
|
@ -1336,7 +1509,7 @@ dumprectangle (f, left, top, cols, rows)
|
|||
CHAR_TO_PIXEL_COL (f, left),
|
||||
CHAR_TO_PIXEL_ROW (f, y),
|
||||
line, min (cols, active_frame->used[y] - left),
|
||||
active_frame->highlight[y]);
|
||||
active_frame->highlight[y], 0);
|
||||
}
|
||||
|
||||
/* Turn the cursor on if we turned it off. */
|
||||
|
@ -1981,9 +2154,11 @@ note_mouse_highlight (f, x, y)
|
|||
if (! EQ (window, mouse_face_window))
|
||||
clear_mouse_face ();
|
||||
|
||||
/* Are we in a window whose display is up to date? */
|
||||
/* Are we in a window whose display is up to date?
|
||||
And verify the buffer's text has not changed. */
|
||||
if (WINDOWP (window) && portion == 0
|
||||
&& EQ (w->window_end_valid, w->buffer))
|
||||
&& EQ (w->window_end_valid, w->buffer)
|
||||
&& w->last_modified == BUF_MODIFF (XBUFFER (w->buffer)))
|
||||
{
|
||||
int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
|
||||
int i, pos;
|
||||
|
@ -2202,7 +2377,7 @@ show_mouse_face (hl)
|
|||
FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column,
|
||||
endcolumn - column,
|
||||
/* Highlight with mouse face if hl > 0. */
|
||||
hl > 0 ? 3 : 0);
|
||||
hl > 0 ? 3 : 0, 0);
|
||||
}
|
||||
|
||||
/* If we turned the cursor off, turn it back on. */
|
||||
|
@ -4275,7 +4450,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
|
|||
dumpglyphs (f,
|
||||
CHAR_TO_PIXEL_COL (f, column),
|
||||
CHAR_TO_PIXEL_ROW (f, row),
|
||||
&glyph, 1, highlight);
|
||||
&glyph, 1, highlight, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4383,6 +4558,14 @@ x_display_box_cursor (f, on)
|
|||
|| (f->display.x->current_cursor != hollow_box_cursor
|
||||
&& (f != x_highlight_frame))))
|
||||
{
|
||||
/* If the font is not as tall as a whole line,
|
||||
we must explicitly clear the line's whole height. */
|
||||
if (FONT_HEIGHT (f->display.x->font) != f->display.x->line_height)
|
||||
XClearArea (x_current_display, FRAME_X_WINDOW (f),
|
||||
CHAR_TO_PIXEL_COL (f, f->phys_cursor_x),
|
||||
CHAR_TO_PIXEL_ROW (f, f->phys_cursor_y),
|
||||
FONT_WIDTH (f->display.x->font),
|
||||
f->display.x->line_height, False);
|
||||
/* Erase the cursor by redrawing the character underneath it. */
|
||||
x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
|
||||
f->phys_cursor_glyph,
|
||||
|
@ -4903,7 +5086,7 @@ x_new_font (f, fontname)
|
|||
else
|
||||
/* If we are setting a new frame's font for the first time,
|
||||
there are no faces yet, so this font's height is the line height. */
|
||||
f->display.x->line_height = FONT_HEIGHT (f);
|
||||
f->display.x->line_height = FONT_HEIGHT (f->display.x->font);
|
||||
|
||||
{
|
||||
Lisp_Object lispy_name;
|
||||
|
@ -5051,6 +5234,7 @@ x_set_window_size (f, change_gravity, cols, rows)
|
|||
#ifdef HAVE_X11
|
||||
x_wm_set_size_hint (f, 0, change_gravity, 0, 0);
|
||||
#endif /* ! defined (HAVE_X11) */
|
||||
XSync (x_current_display, False);
|
||||
XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
|
||||
|
||||
/* Now, strictly speaking, we can't be sure that this is accurate,
|
||||
|
|
Loading…
Add table
Reference in a new issue