From 656202640dc8857da0373ba690ea193394352ddb Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 8 Aug 2013 18:51:07 +0400 Subject: [PATCH] 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. --- src/ChangeLog | 26 ++++++++++++++++++ src/dispextern.h | 24 +++++++--------- src/dispnew.c | 44 ++++++++++++++---------------- src/nsterm.m | 9 ++---- src/w32term.c | 22 +++++---------- src/xdisp.c | 71 +++++++++++++++++------------------------------- src/xterm.c | 23 +++++----------- 7 files changed, 98 insertions(+), 121 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6cb69f776f1..caf7b034401 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +2013-08-08 Dmitry Antipov + + 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 Do not reset window modification event counters excessively. diff --git a/src/dispextern.h b/src/dispextern.h index d747700fd66..7a4fa2ea774 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -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 *); diff --git a/src/dispnew.c b/src/dispnew.c index 2708252aa8a..519659a104c 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -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); } diff --git a/src/nsterm.m b/src/nsterm.m index 3672c7656da..56572d5b9f4 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -711,9 +711,9 @@ ns_update_window_begin (struct window *w) -------------------------------------------------------------------------- */ { 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 @@ ns_update_window_end (struct window *w, int cursor_on_p, hlinfo->mouse_face_window = Qnil; } - updated_window = NULL; NSTRACE (update_window_end); } @@ -2084,7 +2083,6 @@ ns_scroll_run (struct window *w, struct run *run) block_input (); - updated_window = w; x_clear_cursor (w); { @@ -2102,12 +2100,11 @@ ns_scroll_run (struct window *w, struct run *run) 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; diff --git a/src/w32term.c b/src/w32term.c index 56793660d90..15812f93ff5 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -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); { diff --git a/src/xdisp.c b/src/xdisp.c index d2dae3406d1..ab625b9d6ec 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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; diff --git a/src/xterm.c b/src/xterm.c index a486242b8c3..6391154961f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -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), -- 2.39.2