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/win3…
==============================================================================
--- 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);