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); void FASTCALL REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn);
INT FASTCALL UnsafeIntGetRgnBox(PROSRGNDATA Rgn, LPRECT pRect); INT FASTCALL UnsafeIntGetRgnBox(PROSRGNDATA Rgn, LPRECT pRect);
BOOL FASTCALL UnsafeIntRectInRegion(PROSRGNDATA Rgn, CONST LPRECT rc); BOOL FASTCALL UnsafeIntRectInRegion(PROSRGNDATA Rgn, CONST LPRECT rc);
INT STDCALL IntGdiGetRgnBox(HRGN, LPRECT);
#define UnsafeIntCreateRectRgnIndirect(prc) \ #define UnsafeIntCreateRectRgnIndirect(prc) \
NtGdiCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom) 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) const RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate)
{ {
PDC pDC; PDC pDC;
RECT rcClip, rcSrc, rcDst; RECT rcScroll, rcClip, rcSrc, rcDst;
INT Result; INT Result;
IntGdiGetClipBox(hDC, &rcClip); IntGdiGetClipBox(hDC, &rcClip);
rcScroll = rcClip;
if (prcClip) if (prcClip)
{ {
IntGdiIntersectRect(&rcClip, &rcClip, prcClip); IntGdiIntersectRect(&rcClip, &rcClip, prcClip);
@ -1142,6 +1143,7 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcScroll,
if (prcScroll) if (prcScroll)
{ {
rcScroll = *prcScroll;
IntGdiIntersectRect(&rcSrc, &rcClip, prcScroll); IntGdiIntersectRect(&rcSrc, &rcClip, prcScroll);
} }
else else
@ -1174,38 +1176,37 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcScroll,
hrgnVisible = pDC->w.hVisRgn; // pDC->w.hGCClipRgn? hrgnVisible = pDC->w.hVisRgn; // pDC->w.hGCClipRgn?
DC_UnlockDc(pDC); 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) if (hrgnUpdate)
{ {
hrgnOwn = 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; return ERROR;
} }
} }
else else
{ {
hrgnOwn = UnsafeIntCreateRectRgnIndirect(&rcSrc); hrgnOwn = UnsafeIntCreateRectRgnIndirect(&rcDst);
} }
/* Substract the dest rect */ /* Add the source rect */
hrgnTmp = UnsafeIntCreateRectRgnIndirect(&rcDst); hrgnTmp = UnsafeIntCreateRectRgnIndirect(&rcSrc);
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
/* 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); 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); NtGdiDeleteObject(hrgnTmp);
if (prcUpdate) if (prcUpdate)
{ {
NtGdiGetRgnBox(hrgnOwn, prcUpdate); IntGdiGetRgnBox(hrgnOwn, prcUpdate);
} }
if (!hrgnUpdate) if (!hrgnUpdate)
@ -1236,6 +1237,7 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
DECLARE_RETURN(DWORD); DECLARE_RETURN(DWORD);
RECT rcScroll, rcClip, rcUpdate; RECT rcScroll, rcClip, rcUpdate;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DWORD Result;
DPRINT("Enter NtUserScrollDC\n"); DPRINT("Enter NtUserScrollDC\n");
UserEnterExclusive(); UserEnterExclusive();
@ -1268,13 +1270,14 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
RETURN(FALSE); RETURN(FALSE);
} }
if (UserScrollDC(hDC, dx, dy, Result = UserScrollDC(hDC, dx, dy,
prcUnsafeScroll? &rcScroll : 0, prcUnsafeScroll? &rcScroll : 0,
prcUnsafeClip? &rcClip : 0, hrgnUpdate, prcUnsafeClip? &rcClip : 0, hrgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL) == ERROR) prcUnsafeUpdate? &rcUpdate : NULL);
if(Result == ERROR)
{ {
/* FIXME: SetLastError? */ /* FIXME: SetLastError? */
RETURN(FALSE); RETURN(Result);
} }
if (prcUnsafeUpdate) if (prcUnsafeUpdate)
@ -1296,7 +1299,7 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
} }
} }
RETURN(TRUE); RETURN(Result);
CLEANUP: CLEANUP:
DPRINT("Leave NtUserScrollDC, ret=%i\n",_ret_); DPRINT("Leave NtUserScrollDC, ret=%i\n",_ret_);
@ -1336,23 +1339,23 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
} }
UserRefObjectCo(Window, &Ref); UserRefObjectCo(Window, &Ref);
IntGetClientRect(Window, &rcScroll); IntGetClientRect(Window, &rcClip);
_SEH_TRY _SEH_TRY
{ {
if (prcUnsafeScroll) if (prcUnsafeScroll)
{ {
ProbeForRead(prcUnsafeScroll, sizeof(*prcUnsafeScroll), 1); ProbeForRead(prcUnsafeScroll, sizeof(*prcUnsafeScroll), 1);
IntGdiIntersectRect(&rcScroll, &rcScroll, prcUnsafeScroll); IntGdiIntersectRect(&rcScroll, &rcClip, prcUnsafeScroll);
} }
else
rcScroll = rcClip;
if (prcUnsafeClip) if (prcUnsafeClip)
{ {
ProbeForRead(prcUnsafeClip, sizeof(*prcUnsafeClip), 1); ProbeForRead(prcUnsafeClip, sizeof(*prcUnsafeClip), 1);
IntGdiIntersectRect(&rcClip, &rcScroll, prcUnsafeClip); IntGdiIntersectRect(&rcClip, &rcClip, prcUnsafeClip);
} }
else
rcClip = rcScroll;
} }
_SEH_HANDLE _SEH_HANDLE
{ {

View file

@ -540,7 +540,7 @@ static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION); pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION);
} }
// FIXME: This seems to be wrong
/*********************************************************************** /***********************************************************************
* REGION_CropAndOffsetRegion * REGION_CropAndOffsetRegion
*/ */
@ -2409,6 +2409,25 @@ NtGdiGetRandomRgn(HDC hDC, HRGN hDest, INT iCode)
return ret; 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 INT STDCALL
NtGdiGetRgnBox(HRGN hRgn, NtGdiGetRgnBox(HRGN hRgn,
LPRECT pRect) LPRECT pRect)