Redesign redisplay interface to drop global variable updated_window.

Always pass currently updated window as a parameter to update routines.
* dispextern.h (updated_window): Remove declaration.
(struct redisplay_interface): Pass window parameter to
write_glyphs, insert_glyphs, clear_end_of_line, cursor_to
and after_update_window_hook.
(x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to):
Adjust prototypes.
* dispnew.c (updated_window): Remove.
(redraw_overlapped_rows, update_marginal_area, update_text_area)
(update_window_line): Adjust to match redisplay interface changes.
* nsterm.m (ns_update_window_begin, ns_update_window_end)
(ns_scroll_run, ns_after_update_window_line):
* w32term.c (x_update_window_begin, x_update_window_end)
(x_after_update_window_line, x_scroll_run):
* xterm.c (x_update_window_begin, x_update_window_end)
(x_after_update_window_line, x_scroll_run):
* xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
Likewise.  Adjust comments where appropriate.
(x_cursor_to): Simplify because this is always called during window
update (but install debugging check anyway).
(expose_window): Check must_be_updated_p flag to see whether this
function is called during window update.
This commit is contained in:
Dmitry Antipov 2013-08-08 18:51:07 +04:00
parent 04263d23c5
commit 656202640d
7 changed files with 98 additions and 121 deletions

View file

@ -1,3 +1,29 @@
2013-08-08 Dmitry Antipov <dmantipov@yandex.ru>
Redesign redisplay interface to drop global variable updated_window.
Always pass currently updated window as a parameter to update routines.
* dispextern.h (updated_window): Remove declaration.
(struct redisplay_interface): Pass window parameter to
write_glyphs, insert_glyphs, clear_end_of_line, cursor_to
and after_update_window_hook.
(x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to):
Adjust prototypes.
* dispnew.c (updated_window): Remove.
(redraw_overlapped_rows, update_marginal_area, update_text_area)
(update_window_line): Adjust to match redisplay interface changes.
* nsterm.m (ns_update_window_begin, ns_update_window_end)
(ns_scroll_run, ns_after_update_window_line):
* w32term.c (x_update_window_begin, x_update_window_end)
(x_after_update_window_line, x_scroll_run):
* xterm.c (x_update_window_begin, x_update_window_end)
(x_after_update_window_line, x_scroll_run):
* xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
Likewise. Adjust comments where appropriate.
(x_cursor_to): Simplify because this is always called during window
update (but install debugging check anyway).
(expose_window): Check must_be_updated_p flag to see whether this
function is called during window update.
2013-08-08 Dmitry Antipov <dmantipov@yandex.ru>
Do not reset window modification event counters excessively.

View file

@ -1197,11 +1197,6 @@ extern bool fonts_changed_p;
extern struct glyph space_glyph;
/* Window being updated by update_window. This is non-null as long as
update_window has not finished, and null otherwise. */
extern struct window *updated_window;
/* Glyph row and area updated by update_window_line. */
extern struct glyph_row *updated_row;
@ -2718,12 +2713,12 @@ struct redisplay_interface
/* Write or insert LEN glyphs from STRING at the nominal output
position. */
void (*write_glyphs) (struct glyph *string, int len);
void (*insert_glyphs) (struct glyph *start, int len);
void (*write_glyphs) (struct window *w, struct glyph *string, int len);
void (*insert_glyphs) (struct window *w, struct glyph *start, int len);
/* Clear from nominal output position to X. X < 0 means clear
to right end of display. */
void (*clear_end_of_line) (int x);
void (*clear_end_of_line) (struct window *w, int x);
/* Function to call to scroll the display as described by RUN on
window W. */
@ -2732,7 +2727,8 @@ struct redisplay_interface
/* Function to call after a line in a display has been completely
updated. Used to draw truncation marks and alike. DESIRED_ROW
is the desired row which has been updated. */
void (*after_update_window_line_hook) (struct glyph_row *desired_row);
void (*after_update_window_line_hook) (struct window *w,
struct glyph_row *desired_row);
/* Function to call before beginning to update window W in
window-based redisplay. */
@ -2749,7 +2745,7 @@ struct redisplay_interface
/* Move cursor to row/column position VPOS/HPOS, pixel coordinates
Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y
are window-relative pixel positions. */
void (*cursor_to) (int vpos, int hpos, int y, int x);
void (*cursor_to) (struct window *w, int vpos, int hpos, int y, int x);
/* Flush the display of frame F. For X, this is XFlush. */
void (*flush_display) (struct frame *f);
@ -3182,9 +3178,9 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *,
int *, int *);
extern void x_produce_glyphs (struct it *);
extern void x_write_glyphs (struct glyph *, int);
extern void x_insert_glyphs (struct glyph *, int len);
extern void x_clear_end_of_line (int);
extern void x_write_glyphs (struct window *, struct glyph *, int);
extern void x_insert_glyphs (struct window *, struct glyph *, int len);
extern void x_clear_end_of_line (struct window *, int);
extern struct cursor_pos output_cursor;
@ -3200,7 +3196,7 @@ extern void display_and_set_cursor (struct window *,
int, int, int, int, int);
extern void set_output_cursor (struct cursor_pos *);
extern void x_cursor_to (int, int, int, int);
extern void x_cursor_to (struct window *, int, int, int, int);
extern void x_update_cursor (struct frame *, int);
extern void x_clear_cursor (struct window *);

View file

@ -135,10 +135,6 @@ struct frame *last_nonminibuf_frame;
static bool delayed_size_change;
/* Updated window if != 0. Set by update_window. */
struct window *updated_window;
/* Glyph row updated in update_window_line, and area that is updated. */
struct glyph_row *updated_row;
@ -2286,7 +2282,7 @@ check_glyph_memory (void)
screen. We build such a view by constructing a frame matrix from
window matrices in this section.
Windows that must be updated have their must_be_update_p flag set.
Windows that must be updated have their must_be_updated_p flag set.
For all such windows, their desired matrix is made part of the
desired frame matrix. For other windows, their current matrix is
made part of the desired frame matrix.
@ -3243,12 +3239,12 @@ redraw_overlapped_rows (struct window *w, int yb)
{
updated_row = row;
updated_area = area;
FRAME_RIF (f)->cursor_to (i, 0, row->y,
FRAME_RIF (f)->cursor_to (w, i, 0, row->y,
area == TEXT_AREA ? row->x : 0);
if (row->used[area])
FRAME_RIF (f)->write_glyphs (row->glyphs[area],
FRAME_RIF (f)->write_glyphs (w, row->glyphs[area],
row->used[area]);
FRAME_RIF (f)->clear_end_of_line (-1);
FRAME_RIF (f)->clear_end_of_line (w, -1);
}
row->overlapped_p = 0;
@ -3534,10 +3530,10 @@ update_marginal_area (struct window *w, int area, int vpos)
/* Set cursor to start of glyphs, write them, and clear to the end
of the area. I don't think that something more sophisticated is
necessary here, since marginal areas will not be the default. */
rif->cursor_to (vpos, 0, desired_row->y, 0);
rif->cursor_to (w, vpos, 0, desired_row->y, 0);
if (desired_row->used[area])
rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
rif->clear_end_of_line (-1);
rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]);
rif->clear_end_of_line (w, -1);
}
@ -3575,14 +3571,14 @@ update_text_area (struct window *w, int vpos)
&& !(current_row->mode_line_p && vpos > 0))
|| current_row->x != desired_row->x)
{
rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
if (desired_row->used[TEXT_AREA])
rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA],
desired_row->used[TEXT_AREA]);
/* Clear to end of window. */
rif->clear_end_of_line (-1);
rif->clear_end_of_line (w, -1);
changed_p = 1;
/* This erases the cursor. We do this here because
@ -3718,8 +3714,8 @@ update_text_area (struct window *w, int vpos)
break;
}
rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
rif->write_glyphs (start, i - start_hpos);
rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
rif->write_glyphs (w, start, i - start_hpos);
changed_p = 1;
}
}
@ -3727,8 +3723,8 @@ update_text_area (struct window *w, int vpos)
/* Write the rest. */
if (i < desired_row->used[TEXT_AREA])
{
rif->cursor_to (vpos, i, desired_row->y, x);
rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
rif->cursor_to (w, vpos, i, desired_row->y, x);
rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i);
changed_p = 1;
}
@ -3748,9 +3744,9 @@ update_text_area (struct window *w, int vpos)
{
/* If old row extends to the end of the text area, clear. */
if (i >= desired_row->used[TEXT_AREA])
rif->cursor_to (vpos, i, desired_row->y,
rif->cursor_to (w, vpos, i, desired_row->y,
desired_row->pixel_width);
rif->clear_end_of_line (-1);
rif->clear_end_of_line (w, -1);
changed_p = 1;
}
else if (desired_row->pixel_width < current_row->pixel_width)
@ -3760,7 +3756,7 @@ update_text_area (struct window *w, int vpos)
int xlim;
if (i >= desired_row->used[TEXT_AREA])
rif->cursor_to (vpos, i, desired_row->y,
rif->cursor_to (w, vpos, i, desired_row->y,
desired_row->pixel_width);
/* If cursor is displayed at the end of the line, make sure
@ -3778,7 +3774,7 @@ update_text_area (struct window *w, int vpos)
}
else
xlim = current_row->pixel_width;
rif->clear_end_of_line (xlim);
rif->clear_end_of_line (w, xlim);
changed_p = 1;
}
}
@ -3850,7 +3846,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
|| desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
|| (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
!= MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
rif->after_update_window_line_hook (desired_row);
rif->after_update_window_line_hook (w, desired_row);
}
/* Update current_row from desired_row. */
@ -3939,7 +3935,7 @@ set_window_cursor_after_update (struct window *w)
Horizontal position is -1 when cursor is on the left fringe. */
hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
rif->cursor_to (vpos, hpos, cy, cx);
rif->cursor_to (w, vpos, hpos, cy, cx);
}

View file

@ -711,9 +711,9 @@ Free a pool and temporary objects it refers to (callable from C)
-------------------------------------------------------------------------- */
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
NSTRACE (ns_update_window_begin);
updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
@ -770,7 +770,6 @@ Free a pool and temporary objects it refers to (callable from C)
hlinfo->mouse_face_window = Qnil;
}
updated_window = NULL;
NSTRACE (update_window_end);
}
@ -2084,7 +2083,6 @@ Free a pool and temporary objects it refers to (callable from C)
block_input ();
updated_window = w;
x_clear_cursor (w);
{
@ -2102,12 +2100,11 @@ Free a pool and temporary objects it refers to (callable from C)
static void
ns_after_update_window_line (struct glyph_row *desired_row)
ns_after_update_window_line (struct window *w, struct glyph_row *desired_row)
/* --------------------------------------------------------------------------
External (RIF): preparatory to fringe update after text was updated
-------------------------------------------------------------------------- */
{
struct window *w = updated_window;
struct frame *f;
int width, height;

View file

@ -577,8 +577,7 @@ x_update_begin (struct frame *f)
}
/* Start update of window W. Set the global variable updated_window
to the window being updated and set output_cursor to the cursor
/* Start update of window W. Set output_cursor to the cursor
position of W. */
static void
@ -593,7 +592,6 @@ x_update_window_begin (struct window *w)
SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
}
updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
@ -664,7 +662,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
}
/* End update of window W (which is equal to updated_window).
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
display W's cursor if CURSOR_ON_P is non-zero.
@ -714,8 +712,6 @@ x_update_window_end (struct window *w, int cursor_on_p,
{
SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
}
updated_window = NULL;
}
@ -733,9 +729,8 @@ x_update_end (struct frame *f)
}
/* This function is called from various places in xdisp.c whenever a
complete update has been performed. The global variable
updated_window is not available here. */
/* This function is called from various places in xdisp.c
whenever a complete update has been performed. */
static void
w32_frame_up_to_date (struct frame *f)
@ -747,15 +742,13 @@ w32_frame_up_to_date (struct frame *f)
/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
arrow bitmaps, or clear the fringes if no bitmaps are required
before DESIRED_ROW is made current. The window being updated is
found in updated_window. This function is called from
before DESIRED_ROW is made current. This function is called from
update_window_line only if it is known that there are differences
between bitmaps to be drawn between current row and DESIRED_ROW. */
static void
x_after_update_window_line (struct glyph_row *desired_row)
x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
{
struct window *w = updated_window;
struct frame *f;
int width, height;
@ -766,7 +759,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
/* When a window has disappeared, make sure that no rest of
full-width rows stays visible in the internal border. Could
check here if updated_window is the leftmost/rightmost window,
check here if updated window is the leftmost/rightmost window,
but I guess it's not worth doing since vertically split windows
are almost never used, internal border is rarely set, and the
overhead is very small. */
@ -2806,7 +2799,6 @@ x_scroll_run (struct window *w, struct run *run)
block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
x_clear_cursor (w);
{

View file

@ -11385,7 +11385,7 @@ struct cursor_pos output_cursor;
/* EXPORT:
Set the global variable output_cursor to CURSOR. All cursor
positions are relative to updated_window. */
positions are relative to currently updated window. */
void
set_output_cursor (struct cursor_pos *cursor)
@ -11400,41 +11400,24 @@ set_output_cursor (struct cursor_pos *cursor)
/* EXPORT for RIF:
Set a nominal cursor position.
HPOS and VPOS are column/row positions in a window glyph matrix. X
and Y are window text area relative pixel positions.
HPOS and VPOS are column/row positions in a window glyph matrix.
X and Y are window text area relative pixel positions.
If this is done during an update, updated_window will contain the
window that is being updated and the position is the future output
cursor position for that window. If updated_window is null, use
selected_window and display the cursor at the given position. */
This is always done during window update, so the position is the
future output cursor position for currently updated window W.
NOTE: W is used only to check whether this function is called
in a consistent manner via the redisplay interface. */
void
x_cursor_to (int vpos, int hpos, int y, int x)
x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
{
struct window *w;
/* If updated_window is not set, work on selected_window. */
if (updated_window)
w = updated_window;
else
w = XWINDOW (selected_window);
eassert (w);
/* Set the output cursor. */
output_cursor.hpos = hpos;
output_cursor.vpos = vpos;
output_cursor.x = x;
output_cursor.y = y;
/* If not called as part of an update, really display the cursor.
This will also set the cursor position of W. */
if (updated_window == NULL)
{
block_input ();
display_and_set_cursor (w, 1, hpos, vpos, x, y);
if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
unblock_input ();
}
}
#endif /* HAVE_WINDOW_SYSTEM */
@ -25745,16 +25728,15 @@ x_produce_glyphs (struct it *it)
/* EXPORT for RIF:
Output LEN glyphs starting at START at the nominal cursor position.
Advance the nominal cursor over the text. The global variable
updated_window contains the window being updated, updated_row is
the glyph row being updated, and updated_area is the area of that
row being updated. */
updated_row is the glyph row being updated, and updated_area is the
area of that row being updated. */
void
x_write_glyphs (struct glyph *start, int len)
x_write_glyphs (struct window *w, struct glyph *start, int len)
{
int x, hpos, chpos = updated_window->phys_cursor.hpos;
int x, hpos, chpos = w->phys_cursor.hpos;
eassert (updated_window && updated_row);
eassert (updated_row);
/* When the window is hscrolled, cursor hpos can legitimately be out
of bounds, but we draw the cursor at the corresponding window
margin in that case. */
@ -25768,18 +25750,18 @@ x_write_glyphs (struct glyph *start, int len)
/* Write glyphs. */
hpos = start - updated_row->glyphs[updated_area];
x = draw_glyphs (updated_window, output_cursor.x,
x = draw_glyphs (w, output_cursor.x,
updated_row, updated_area,
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
/* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
if (updated_area == TEXT_AREA
&& updated_window->phys_cursor_on_p
&& updated_window->phys_cursor.vpos == output_cursor.vpos
&& w->phys_cursor_on_p
&& w->phys_cursor.vpos == output_cursor.vpos
&& chpos >= hpos
&& chpos < hpos + len)
updated_window->phys_cursor_on_p = 0;
w->phys_cursor_on_p = 0;
unblock_input ();
@ -25793,19 +25775,17 @@ x_write_glyphs (struct glyph *start, int len)
Insert LEN glyphs from START at the nominal cursor position. */
void
x_insert_glyphs (struct glyph *start, int len)
x_insert_glyphs (struct window *w, struct glyph *start, int len)
{
struct frame *f;
struct window *w;
int line_height, shift_by_width, shifted_region_width;
struct glyph_row *row;
struct glyph *glyph;
int frame_x, frame_y;
ptrdiff_t hpos;
eassert (updated_window && updated_row);
eassert (updated_row);
block_input ();
w = updated_window;
f = XFRAME (WINDOW_FRAME (w));
/* Get the height of the line we are in. */
@ -25847,18 +25827,17 @@ x_insert_glyphs (struct glyph *start, int len)
(inclusive) to pixel column TO_X (exclusive). The idea is that
everything from TO_X onward is already erased.
TO_X is a pixel position relative to updated_area of
updated_window. TO_X == -1 means clear to the end of this area. */
TO_X is a pixel position relative to updated_area of currently
updated window W. TO_X == -1 means clear to the end of this area. */
void
x_clear_end_of_line (int to_x)
x_clear_end_of_line (struct window *w, int to_x)
{
struct frame *f;
struct window *w = updated_window;
int max_x, min_y, max_y;
int from_x, from_y, to_y;
eassert (updated_window && updated_row);
eassert (updated_row);
f = XFRAME (w->frame);
if (updated_row->full_width_p)
@ -28820,7 +28799,7 @@ expose_window (struct window *w, XRectangle *fr)
/* When we're currently updating the window, display and current
matrix usually don't agree. Arrange for a thorough display
later. */
if (w == updated_window)
if (w->must_be_updated_p)
{
SET_FRAME_GARBAGED (f);
return 0;

View file

@ -320,7 +320,6 @@ static void x_clip_to_row (struct window *, struct glyph_row *, int, GC);
static void x_flush (struct frame *f);
static void x_update_begin (struct frame *);
static void x_update_window_begin (struct window *);
static void x_after_update_window_line (struct glyph_row *);
static struct scroll_bar *x_window_to_scroll_bar (Display *, Window);
static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
enum scroll_bar_part *,
@ -554,8 +553,7 @@ x_update_begin (struct frame *f)
}
/* Start update of window W. Set the global variable updated_window
to the window being updated and set output_cursor to the cursor
/* Start update of window W. Set output_cursor to the cursor
position of W. */
static void
@ -564,7 +562,6 @@ x_update_window_begin (struct window *w)
struct frame *f = XFRAME (WINDOW_FRAME (w));
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
@ -601,7 +598,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
f->output_data.x->normal_gc, x, y0, x, y1);
}
/* End update of window W (which is equal to updated_window).
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
display W's cursor if CURSOR_ON_P is non-zero.
@ -642,8 +639,6 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt
hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
hlinfo->mouse_face_window = Qnil;
}
updated_window = NULL;
}
@ -664,9 +659,8 @@ x_update_end (struct frame *f)
}
/* This function is called from various places in xdisp.c whenever a
complete update has been performed. The global variable
updated_window is not available here. */
/* This function is called from various places in xdisp.c
whenever a complete update has been performed. */
static void
XTframe_up_to_date (struct frame *f)
@ -678,15 +672,13 @@ XTframe_up_to_date (struct frame *f)
/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
arrow bitmaps, or clear the fringes if no bitmaps are required
before DESIRED_ROW is made current. The window being updated is
found in updated_window. This function It is called from
before DESIRED_ROW is made current. This function is called from
update_window_line only if it is known that there are differences
between bitmaps to be drawn between current row and DESIRED_ROW. */
static void
x_after_update_window_line (struct glyph_row *desired_row)
x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
{
struct window *w = updated_window;
struct frame *f;
int width, height;
@ -697,7 +689,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
/* When a window has disappeared, make sure that no rest of
full-width rows stays visible in the internal border. Could
check here if updated_window is the leftmost/rightmost window,
check here if updated window is the leftmost/rightmost window,
but I guess it's not worth doing since vertically split windows
are almost never used, internal border is rarely set, and the
overhead is very small. */
@ -3323,7 +3315,6 @@ x_scroll_run (struct window *w, struct run *run)
block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
x_clear_cursor (w);
XCopyArea (FRAME_X_DISPLAY (f),