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>
+
+ 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.
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;
/* 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. */
/* 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. */
/* 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);
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;
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 *);
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;
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.
{
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;
/* 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);
}
&& !(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
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;
}
}
/* 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;
}
{
/* 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)
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
}
else
xlim = current_row->pixel_width;
- rif->clear_end_of_line (xlim);
+ rif->clear_end_of_line (w, xlim);
changed_p = 1;
}
}
|| 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. */
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);
}
-------------------------------------------------------------------------- */
{
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 ();
hlinfo->mouse_face_window = Qnil;
}
- updated_window = NULL;
NSTRACE (update_window_end);
}
block_input ();
- updated_window = w;
x_clear_cursor (w);
{
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;
}
-/* 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
SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
}
- updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
}
-/* 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.
{
SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
}
-
- updated_window = NULL;
}
}
-/* 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)
/* 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;
/* 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. */
block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
- updated_window = w;
x_clear_cursor (w);
{
/* 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)
/* 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 */
/* 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. */
/* 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 ();
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. */
(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)
/* 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;
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 *,
}
-/* 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
struct frame *f = XFRAME (WINDOW_FRAME (w));
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
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.
hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
hlinfo->mouse_face_window = Qnil;
}
-
- updated_window = NULL;
}
}
-/* 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)
/* 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;
/* 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. */
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),