Mercurial > emacs
changeset 37540:7ba9dfa3e191
(expose_window): Return int. If W is the window
currently being updated, mark the frame garbaged. Fix
computation of rows intersection the exposed rectangle.
(expose_window_tree): Stop when expose_window returns 0.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Wed, 02 May 2001 13:19:30 +0000 |
parents | 8d13aa9daa13 |
children | d34f1c4da441 |
files | src/xterm.c |
diffstat | 1 files changed, 77 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xterm.c Wed May 02 11:45:00 2001 +0000 +++ b/src/xterm.c Wed May 02 13:19:30 2001 +0000 @@ -459,7 +459,7 @@ XRectangle *)); static void expose_frame P_ ((struct frame *, int, int, int, int)); static void expose_window_tree P_ ((struct window *, XRectangle *)); -static void expose_window P_ ((struct window *, XRectangle *)); +static int expose_window P_ ((struct window *, XRectangle *)); static void expose_area P_ ((struct window *, struct glyph_row *, XRectangle *, enum glyph_row_area)); static void expose_line P_ ((struct window *, struct glyph_row *, @@ -5864,8 +5864,8 @@ expose_window_tree (XWINDOW (w->hchild), r); else if (!NILP (w->vchild)) expose_window_tree (XWINDOW (w->vchild), r); - else - expose_window (w, r); + else if (expose_window (w, r) == 0) + break; w = NILP (w->next) ? NULL : XWINDOW (w->next); } } @@ -5991,88 +5991,96 @@ coordinates in FR are frame-relative. Call this function with input blocked. */ -static void +static int expose_window (w, fr) struct window *w; XRectangle *fr; { struct frame *f = XFRAME (w->frame); - struct glyph_row *row; - int y, yb, cursor_cleared_p; XRectangle wr, r; /* If window is not yet fully initialized, do nothing. This can happen when toolkit scroll bars are used and a window is split. Reconfiguring the scroll bar will generate an expose for a newly created window. */ - if (w->current_matrix == NULL || w == updated_window) - return; - - /* Frame-relative pixel rectangle of W. */ + if (w->current_matrix == NULL) + return 1; + + /* 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) + { + SET_FRAME_GARBAGED (f); + return 0; + } + + /* Frame-relative pixel rectangle of W. */ wr.x = XFASTINT (w->left) * CANON_X_UNIT (f); wr.y = XFASTINT (w->top) * CANON_Y_UNIT (f); wr.width = XFASTINT (w->width) * CANON_X_UNIT (f); wr.height = XFASTINT (w->height) * CANON_Y_UNIT (f); - if (!x_intersect_rectangles (fr, &wr, &r)) - return; - - yb = window_text_bottom_y (w); - - TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", - r.x, r.y, r.width, r.height)); - - /* Convert to window coordinates. */ - r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x); - r.y = FRAME_TO_WINDOW_PIXEL_Y (w, r.y); - - /* Turn off the cursor. */ - if (!w->pseudo_window_p - && x_phys_cursor_in_rect_p (w, &r)) - { - x_clear_cursor (w); - cursor_cleared_p = 1; - } - else - cursor_cleared_p = 0; - - /* Find the first row intersecting the rectangle R. */ - row = w->current_matrix->rows; - y = 0; - while (row->enabled_p - && y < yb - && y + row->height < r.y) - { - y += row->height; - ++row; - } - - /* Display the text in the rectangle, one text line at a time. */ - while (row->enabled_p - && y < yb - && y < r.y + r.height) - { - expose_line (w, row, &r); - y += row->height; - ++row; - } - - /* Display the mode line if there is one. */ - if (WINDOW_WANTS_MODELINE_P (w) - && (row = MATRIX_MODE_LINE_ROW (w->current_matrix), - row->enabled_p) - && row->y < r.y + r.height) - expose_line (w, row, &r); - - if (!w->pseudo_window_p) - { - /* Draw border between windows. */ - x_draw_vertical_border (w); - - /* Turn the cursor on again. */ - if (cursor_cleared_p) - x_update_window_cursor (w, 1); - } + if (x_intersect_rectangles (fr, &wr, &r)) + { + int yb = window_text_bottom_y (w); + struct glyph_row *row; + int cursor_cleared_p; + + TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", + r.x, r.y, r.width, r.height)); + + /* Convert to window coordinates. */ + r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x); + r.y = FRAME_TO_WINDOW_PIXEL_Y (w, r.y); + + /* Turn off the cursor. */ + if (!w->pseudo_window_p + && x_phys_cursor_in_rect_p (w, &r)) + { + x_clear_cursor (w); + cursor_cleared_p = 1; + } + else + cursor_cleared_p = 0; + + /* Find the first row intersecting the rectangle R. */ + for (row = w->current_matrix->rows; + row->enabled_p; + ++row) + { + int y0 = row->y; + int y1 = MATRIX_ROW_BOTTOM_Y (row); + + if ((y0 >= r.y && y0 < r.y + r.height) + || (y1 > r.y && y1 < r.y + r.height) + || (r.y >= y0 && r.y < y1) + || (r.y + r.height > y0 && r.y + r.height < y1)) + expose_line (w, row, &r); + + if (y1 >= yb) + break; + } + + /* Display the mode line if there is one. */ + if (WINDOW_WANTS_MODELINE_P (w) + && (row = MATRIX_MODE_LINE_ROW (w->current_matrix), + row->enabled_p) + && row->y < r.y + r.height) + expose_line (w, row, &r); + + if (!w->pseudo_window_p) + { + /* Draw border between windows. */ + x_draw_vertical_border (w); + + /* Turn the cursor on again. */ + if (cursor_cleared_p) + x_update_window_cursor (w, 1); + } + } + + return 1; }