Author: fireball Date: Sun Aug 2 11:56:44 2009 New Revision: 42332
URL: http://svn.reactos.org/svn/reactos?rev=42332&view=rev Log: - Capture user's buffer using SEH in RosGdiSetDeviceClipping. - Offset combined clipping region by DC and viewport origins, which was the problem preventing its usage. - Remove unneeded stuff from RosGdiSetDcRects. Setting DC rects to fullscreen dimensions is done in usermode.
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c [iso-8859-1] Sun Aug 2 11:56:44 2009 @@ -140,6 +140,9 @@
pNewDC->rcDcRect = pNewDC->rcVport; } + + /* Create an empty combined clipping region */ + pNewDC->CombinedClip = EngCreateClip();
/* Give handle to the caller */ *pdev = hNewDC; @@ -358,22 +361,83 @@ void APIENTRY RosGdiSetDeviceClipping( HDC physDev, UINT count, PRECTL pRects, PRECTL rcBounds ) { PDC pDC; - - /* Get a pointer to the DC */ - pDC = DC_Lock(physDev); + RECTL pStackBuf[8]; + RECTL *pSafeRects = pStackBuf; + RECTL rcSafeBounds; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + /* Get a pointer to the DC */ + pDC = DC_Lock(physDev); + + /* Capture the rects buffer */ + _SEH2_TRY + { + ProbeForRead(pRects, count * sizeof(RECTL), 1); + + /* Use pool allocated buffer if data doesn't fit */ + if (count > sizeof(*pStackBuf) / sizeof(RECTL)) + pSafeRects = ExAllocatePool(PagedPool, sizeof(RECTL) * count); + + /* Copy points data */ + RtlCopyMemory(pSafeRects, pRects, count * sizeof(RECTL)); + + /* Copy bounding rect */ + ProbeForRead(rcBounds, sizeof(RECTL), 1); + rcSafeBounds = *rcBounds; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + if (!NT_SUCCESS(Status)) + { + /* Release the object */ + DC_Unlock(pDC); + + /* Free the buffer if it was allocated */ + if (pSafeRects != pStackBuf) ExFreePool(pSafeRects); + + /* Return failure */ + return; + } + + /* Offset all rects */ + for (i=0; i<count; i++) + { + RECTL_vOffsetRect(&pSafeRects[i], + pDC->rcDcRect.left + pDC->rcVport.left, + pDC->rcDcRect.top + pDC->rcVport.top); + } + + /* Offset bounding rect */ + RECTL_vOffsetRect(&rcSafeBounds, + pDC->rcDcRect.left + pDC->rcVport.left, + pDC->rcDcRect.top + pDC->rcVport.top);
/* Delete old clipping region */ if (pDC->CombinedClip) IntEngDeleteClipRegion(pDC->CombinedClip);
/* Set the clipping object */ - pDC->CombinedClip = IntEngCreateClipRegion(count, pRects, rcBounds); + pDC->CombinedClip = IntEngCreateClipRegion(count, pSafeRects, &rcSafeBounds);
DPRINT("RosGdiSetDeviceClipping() for DC %x, bounding rect (%d,%d)-(%d, %d)\n", - physDev, rcBounds->left, rcBounds->bottom, rcBounds->right, rcBounds->top); - - /* Release the object */ - DC_Unlock(pDC); + physDev, rcSafeBounds.left, rcSafeBounds.top, rcSafeBounds.right, rcSafeBounds.bottom); + + DPRINT("rects: %d\n", count); + for (i=0; i<count; i++) + { + DPRINT("%d: (%d,%d)-(%d, %d)\n", i, pSafeRects[i].left, pSafeRects[i].top, pSafeRects[i].right, pSafeRects[i].bottom); + } + + /* Release the object */ + DC_Unlock(pDC); + + /* Free the buffer if it was allocated */ + if (pSafeRects != pStackBuf) ExFreePool(pSafeRects); }
BOOL APIENTRY RosGdiSetDeviceGammaRamp(HDC physDev, LPVOID ramp) @@ -422,23 +486,11 @@
/* Set DC rectangle */ if (rcDcRect) - { pDC->rcDcRect = *rcDcRect; - -#if 0 - /* Set back to full screen */ - pDC->rcDcRect.top = 0; - pDC->rcDcRect.left = 0; - pDC->rcDcRect.right = pDC->szVportExt.cx; - pDC->rcDcRect.top = pDC->szVportExt.cy; -#endif - }
/* Set viewport rectangle */ if (rcVport) - { pDC->rcVport = *rcVport; - }
/* Release the object */ DC_Unlock(pDC);