From: simon Date: Thu, 17 Mar 2005 20:01:28 +0000 (+0000) Subject: Hung-Te Lin's fix for intermittent WM_PAINT problems. X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/commitdiff_plain/8788a4162555db2ab0b9c6e912ea82e450ac0777 Hung-Te Lin's fix for intermittent WM_PAINT problems. git-svn-id: svn://svn.tartarus.org/sgt/putty@5518 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/windows/window.c b/windows/window.c index 9b810278..3d865e7f 100644 --- a/windows/window.c +++ b/windows/window.c @@ -2367,12 +2367,44 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, RealizePalette(hdc); } + /* + * We have to be careful about term_paint(). It will + * set a bunch of character cells to INVALID and then + * call do_paint(), which will redraw those cells and + * _then mark them as done_. This may not be accurate: + * when painting in WM_PAINT context we are restricted + * to the rectangle which has just been exposed - so if + * that only covers _part_ of a character cell and the + * rest of it was already visible, that remainder will + * not be redrawn at all. Accordingly, we must not + * paint any character cell in a WM_PAINT context which + * already has a pending update due to terminal output. + * The simplest solution to this - and many, many + * thanks to Hung-Te Lin for working all this out - is + * not to do any actual painting at _all_ if there's a + * pending terminal update: just mark the relevant + * character cells as INVALID and wait for the + * scheduled full update to sort it out. + * + * I have a suspicion this isn't the _right_ solution. + * An alternative approach would be to have terminal.c + * separately track what _should_ be on the terminal + * screen and what _is_ on the terminal screen, and + * have two completely different types of redraw (one + * for full updates, which syncs the former with the + * terminal itself, and one for WM_PAINT which syncs + * the latter with the former); yet another possibility + * would be to have the Windows front end do what the + * GTK one already does, and maintain a bitmap of the + * current terminal appearance so that WM_PAINT becomes + * completely trivial. However, this should do for now. + */ term_paint(term, hdc, (p.rcPaint.left-offset_width)/font_width, (p.rcPaint.top-offset_height)/font_height, (p.rcPaint.right-offset_width-1)/font_width, (p.rcPaint.bottom-offset_height-1)/font_height, - TRUE); + !term->window_update_pending); if (p.fErase || p.rcPaint.left < offset_width ||