UserScrollDC: 2nd try to fix the invalidated region. desk.cpl looks ok now and in my tests all worked like on XP, also fix the returned invalidated rect (don't use NtGdiGetClipBox)

NtUserScrollDC: return the region type
NtUserScrollwindowEx: fix the default clip region

svn path=/trunk/; revision=29903
This commit is contained in:
Timo Kreuzer 2007-10-26 22:08:53 +00:00
parent ec2b9a0991
commit fffc7ba078
3 changed files with 51 additions and 28 deletions

View file

@ -141,6 +141,7 @@ HRGN FASTCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lp
void FASTCALL REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn);
INT FASTCALL UnsafeIntGetRgnBox(PROSRGNDATA Rgn, LPRECT pRect);
BOOL FASTCALL UnsafeIntRectInRegion(PROSRGNDATA Rgn, CONST LPRECT rc);
INT STDCALL IntGdiGetRgnBox(HRGN, LPRECT);
#define UnsafeIntCreateRectRgnIndirect(prc) \
NtGdiCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)

View file

@ -1131,10 +1131,11 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcScroll,
const RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate)
{
PDC pDC;
RECT rcClip, rcSrc, rcDst;
RECT rcScroll, rcClip, rcSrc, rcDst;
INT Result;
IntGdiGetClipBox(hDC, &rcClip);
rcScroll = rcClip;
if (prcClip)
{
IntGdiIntersectRect(&rcClip, &rcClip, prcClip);
@ -1142,6 +1143,7 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcScroll,
if (prcScroll)
{
rcScroll = *prcScroll;
IntGdiIntersectRect(&rcSrc, &rcClip, prcScroll);
}
else
@ -1174,38 +1176,37 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcScroll,
hrgnVisible = pDC->w.hVisRgn; // pDC->w.hGCClipRgn?
DC_UnlockDc(pDC);
/* Begin with the source rect */
/* Begin with the shifted and then clipped scroll rect */
rcDst = rcScroll;
IntGdiOffsetRect(&rcDst, dx, dy);
IntGdiIntersectRect(&rcDst, &rcDst, &rcClip);
if (hrgnUpdate)
{
hrgnOwn = hrgnUpdate;
if (!NtGdiSetRectRgn(hrgnOwn, rcSrc.left, rcSrc.top, rcSrc.right, rcSrc.bottom))
if (!NtGdiSetRectRgn(hrgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom))
{
return ERROR;
}
}
else
{
hrgnOwn = UnsafeIntCreateRectRgnIndirect(&rcSrc);
hrgnOwn = UnsafeIntCreateRectRgnIndirect(&rcDst);
}
/* Substract the dest rect */
hrgnTmp = UnsafeIntCreateRectRgnIndirect(&rcDst);
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
/* Add the source rect */
hrgnTmp = UnsafeIntCreateRectRgnIndirect(&rcSrc);
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
/* Add the part of the dest that wasn't visible in source */
NtGdiSetRectRgn(hrgnTmp, rcSrc.left, rcSrc.top, rcSrc.right, rcSrc.bottom);
Result = NtGdiCombineRgn(hrgnTmp, hrgnTmp, hrgnVisible, RGN_DIFF);
if (Result != NULLREGION && Result != ERROR)
{
NtGdiOffsetRgn(hrgnTmp, dx, dy);
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
}
/* Substract the part of the dest that was visible in source */
NtGdiCombineRgn(hrgnTmp, hrgnTmp, hrgnVisible, RGN_AND);
NtGdiOffsetRgn(hrgnTmp, dx, dy);
Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
NtGdiDeleteObject(hrgnTmp);
if (prcUpdate)
{
NtGdiGetRgnBox(hrgnOwn, prcUpdate);
IntGdiGetRgnBox(hrgnOwn, prcUpdate);
}
if (!hrgnUpdate)
@ -1236,6 +1237,7 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
DECLARE_RETURN(DWORD);
RECT rcScroll, rcClip, rcUpdate;
NTSTATUS Status = STATUS_SUCCESS;
DWORD Result;
DPRINT("Enter NtUserScrollDC\n");
UserEnterExclusive();
@ -1268,13 +1270,14 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
RETURN(FALSE);
}
if (UserScrollDC(hDC, dx, dy,
prcUnsafeScroll? &rcScroll : 0,
prcUnsafeClip? &rcClip : 0, hrgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL) == ERROR)
Result = UserScrollDC(hDC, dx, dy,
prcUnsafeScroll? &rcScroll : 0,
prcUnsafeClip? &rcClip : 0, hrgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL);
if(Result == ERROR)
{
/* FIXME: SetLastError? */
RETURN(FALSE);
RETURN(Result);
}
if (prcUnsafeUpdate)
@ -1296,7 +1299,7 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
}
}
RETURN(TRUE);
RETURN(Result);
CLEANUP:
DPRINT("Leave NtUserScrollDC, ret=%i\n",_ret_);
@ -1336,23 +1339,23 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
}
UserRefObjectCo(Window, &Ref);
IntGetClientRect(Window, &rcScroll);
IntGetClientRect(Window, &rcClip);
_SEH_TRY
{
if (prcUnsafeScroll)
{
ProbeForRead(prcUnsafeScroll, sizeof(*prcUnsafeScroll), 1);
IntGdiIntersectRect(&rcScroll, &rcScroll, prcUnsafeScroll);
IntGdiIntersectRect(&rcScroll, &rcClip, prcUnsafeScroll);
}
else
rcScroll = rcClip;
if (prcUnsafeClip)
{
ProbeForRead(prcUnsafeClip, sizeof(*prcUnsafeClip), 1);
IntGdiIntersectRect(&rcClip, &rcScroll, prcUnsafeClip);
IntGdiIntersectRect(&rcClip, &rcClip, prcUnsafeClip);
}
else
rcClip = rcScroll;
}
_SEH_HANDLE
{

View file

@ -540,7 +540,7 @@ static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION);
}
// FIXME: This seems to be wrong
/***********************************************************************
* REGION_CropAndOffsetRegion
*/
@ -2409,6 +2409,25 @@ NtGdiGetRandomRgn(HDC hDC, HRGN hDest, INT iCode)
return ret;
}
INT STDCALL
IntGdiGetRgnBox(HRGN hRgn,
LPRECT pRect)
{
PROSRGNDATA Rgn;
DWORD ret;
if (!(Rgn = RGNDATA_LockRgn(hRgn)))
{
return ERROR;
}
ret = UnsafeIntGetRgnBox(Rgn, pRect);
RGNDATA_UnlockRgn(Rgn);
return ret;
}
INT STDCALL
NtGdiGetRgnBox(HRGN hRgn,
LPRECT pRect)