From 8d9fb6331e86c8ecea4ca16e12a1121c4cb6559a Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Sat, 17 Dec 2005 12:24:37 +0100 Subject: [PATCH] x11drv: ScrollDC should not clip output if a clipping rect is not specified. Add a ScrollDC test with NULL clipping rect. Add another set of ScrollDC tests written by Rein Klazes. --- dlls/user/tests/win.c | 55 +++++++++++++++++++++++++++++++++++++++++++ dlls/x11drv/scroll.c | 9 +++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/dlls/user/tests/win.c b/dlls/user/tests/win.c index e1f787be552..447ca34415e 100644 --- a/dlls/user/tests/win.c +++ b/dlls/user/tests/win.c @@ -2923,6 +2923,60 @@ static void test_scroll(void) DestroyWindow( hwnd); } +static void test_scrolldc( HWND parent) +{ + HDC hdc; + HRGN exprgn, tmprgn, hrgn; + RECT rc, rc2, rcu, cliprc; + HWND hwnd1; + COLORREF colr; + + hrgn = CreateRectRgn(0,0,0,0); + + hwnd1 = CreateWindowExA(0, "static", NULL, + WS_CHILD| WS_VISIBLE, + 25, 50, 100, 100, parent, 0, 0, NULL); + ShowWindow( parent, SW_SHOW); + UpdateWindow( parent); + GetClientRect( hwnd1, &rc); + hdc = GetDC( hwnd1); + /* paint the upper half of the window black */ + rc2 = rc; + rc2.bottom = ( rc.top + rc.bottom) /2; + FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH)); + /* clip region is the lower half */ + cliprc=rc; + cliprc.top = (rc.top + rc.bottom) /2; + /* test whether scrolled pixels are properly clipped */ + colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1); + ok ( colr == 0, "pixel should be black, color is %08lx\n", colr); + /* this scroll should not cause any visible changes */ + ScrollDC( hdc, 5, -20, &rc, &cliprc, hrgn, &rcu); + colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1); + ok ( colr == 0, "pixel should be black, color is %08lx\n", colr); + + ScrollDC( hdc, 20, -20, &rc, NULL, hrgn, &rcu); + /*FillRgn(hdc, hrgn, GetStockObject(WHITE_BRUSH));*/ + trace("update rect: %ld,%ld - %ld,%ld\n", + rcu.left, rcu.top, rcu.right, rcu.bottom); + if (winetest_debug > 0) dump_region(hrgn); + SetRect(&rc2, 0, 0, 100, 100); + ok(EqualRect(&rcu, &rc2), "rects do not match (%ld,%ld-%ld,%ld) / (%ld,%ld-%ld,%ld)\n", + rcu.left, rcu.top, rcu.right, rcu.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom); + + exprgn = CreateRectRgn(0, 0, 20, 80); + tmprgn = CreateRectRgn(0, 80, 100, 100); + CombineRgn(exprgn, exprgn, tmprgn, RGN_OR); + if (winetest_debug > 0) dump_region(exprgn); + ok(EqualRgn(exprgn, hrgn), "wrong update region\n"); + + /* clean up */ + DeleteObject(hrgn); + DeleteObject(exprgn); + DeleteObject(tmprgn); + DestroyWindow(hwnd1); +} + static void test_params(void) { HWND hwnd; @@ -3533,6 +3587,7 @@ START_TEST(win) test_validatergn(hwndMain); test_nccalcscroll( hwndMain); test_scrollvalidate( hwndMain); + test_scrolldc( hwndMain); test_scroll(); test_IsWindowUnicode(); test_vis_rgn(hwndMain); diff --git a/dlls/x11drv/scroll.c b/dlls/x11drv/scroll.c index 78144dafe30..e0c2f83ed2e 100644 --- a/dlls/x11drv/scroll.c +++ b/dlls/x11drv/scroll.c @@ -110,7 +110,11 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll, /* Then clip again to get the source rectangle that will remain in the * clipping rect */ rcSrc = rcClip; - IntersectRect( &rcSrc, &rcSrc, &rcClip); + if (lprcClip) + { + OffsetRect( &rcSrc, -dx, -dy); + IntersectRect( &rcSrc, &rcSrc, &rcClip); + } /* now convert to device coordinates */ LPtoDP(hdc, (LPPOINT)&rcSrc, 2); TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc)); @@ -141,7 +145,7 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll, TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect)); BitBlt( hdc, rect.left, rect.top, - rect.right - rect.left, rect.bottom -rect.top, + rect.right - rect.left, rect.bottom - rect.top, hdc, rect.left - dx, rect.top - dy, SRCCOPY); } /* compute the update areas. This is the combined clip rectangle @@ -181,6 +185,7 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll, if( !hrgnUpdate) DeleteObject( hrgn); } + /* restore original clipping region */ SelectClipRgn( hdc, clipRgn); DeleteObject( visrgn); DeleteObject( DstRgn);