Author: tkreuzer
Date: Tue May 25 13:55:04 2010
New Revision: 47350
URL:
http://svn.reactos.org/svn/reactos?rev=47350&view=rev
Log:
[WIN32K]
Refactor NtGdiGradientFill, use 1 SEH block instead of 2, replace IntGdiGradientFill with
GreGradientFill, don't lock the DC in UserDrawCaption.
Modified:
trunk/reactos/subsystems/win32/win32k/include/intgdi.h
trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] Tue May 25
13:55:04 2010
@@ -122,10 +122,15 @@
PULONG PolyCounts,
int Count);
-BOOL FASTCALL IntGdiGradientFill(DC *dc,
+BOOL
+NTAPI
+GreGradientFill(
+ HDC hdc,
PTRIVERTEX pVertex,
- ULONG uVertex,
- PVOID pMesh, ULONG uMesh, ULONG ulMode);
+ ULONG nVertex,
+ PVOID pMesh,
+ ULONG nMesh,
+ ULONG ulMode);
/* DC functions */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] Tue May 25
13:55:04 2010
@@ -1782,7 +1782,6 @@
static GRADIENT_RECT gcap = {0, 1};
TRIVERTEX vert[2];
COLORREF Colors[2];
- PDC pMemDc;
if (Wnd != NULL)
{
@@ -1835,20 +1834,12 @@
vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
vert[1].Alpha = 0;
- pMemDc = DC_LockDc(hMemDc);
- if(!pMemDc)
- {
- DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
- goto cleanup;
- }
-
- if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap,
+ if(!GreGradientFill(hMemDc, vert, 2, &gcap,
1, GRADIENT_FILL_RECT_H))
{
DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
}
- DC_UnlockDc(pMemDc);
} //if(uFlags & DC_GRADIENT)
}
Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Tue May 25
13:55:04 2010
@@ -837,40 +837,36 @@
return ret;
}
-BOOL FASTCALL
-IntGdiGradientFill(
- DC *dc,
+BOOL
+NTAPI
+GreGradientFill(
+ HDC hdc,
PTRIVERTEX pVertex,
- ULONG uVertex,
+ ULONG nVertex,
PVOID pMesh,
- ULONG uMesh,
+ ULONG nMesh,
ULONG ulMode)
{
+ PDC pdc;
SURFACE *psurf;
- PPALETTE PalDestGDI;
+ PPALETTE ppal;
EXLATEOBJ exlo;
- RECTL Extent;
- POINTL DitherOrg;
+ RECTL rclExtent;
+ POINTL ptlDitherOrg;
ULONG i;
- BOOL Ret;
+ BOOL bRet;
HPALETTE hDestPalette;
- ASSERT(dc);
- ASSERT(pVertex);
- ASSERT(uVertex);
- ASSERT(pMesh);
- ASSERT(uMesh);
-
- /* check parameters */
- if (ulMode & GRADIENT_FILL_TRIANGLE)
- {
- PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh;
-
- for (i = 0; i < uMesh; i++, tr++)
+ /* Check parameters */
+ if (ulMode == GRADIENT_FILL_TRIANGLE)
+ {
+ PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;
+
+ for (i = 0; i < nMesh; i++, pTriangle++)
{
- if (tr->Vertex1 >= uVertex ||
- tr->Vertex2 >= uVertex ||
- tr->Vertex3 >= uVertex)
+ if (pTriangle->Vertex1 >= nVertex ||
+ pTriangle->Vertex2 >= nVertex ||
+ pTriangle->Vertex3 >= nVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
@@ -879,10 +875,10 @@
}
else
{
- PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh;
- for (i = 0; i < uMesh; i++, rc++)
+ PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh;
+ for (i = 0; i < nMesh; i++, pRect++)
{
- if (rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex)
+ if (pRect->UpperLeft >= nVertex || pRect->LowerRight >= nVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
@@ -890,56 +886,76 @@
}
}
+ /* Lock the output DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (pdc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(pdc);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
+ }
+
+ psurf = pdc->dclevel.pSurface;
+ if (!psurf)
+ {
+ /* Memory DC with no surface selected */
+ DC_UnlockDc(pdc);
+ return TRUE; // CHECKME
+ }
+
/* calculate extent */
- Extent.left = Extent.right = pVertex->x;
- Extent.top = Extent.bottom = pVertex->y;
- for (i = 0; i < uVertex; i++)
- {
- Extent.left = min(Extent.left, (pVertex + i)->x);
- Extent.right = max(Extent.right, (pVertex + i)->x);
- Extent.top = min(Extent.top, (pVertex + i)->y);
- Extent.bottom = max(Extent.bottom, (pVertex + i)->y);
- }
- IntLPtoDP(dc, (LPPOINT)&Extent, 2);
-
- Extent.left += dc->ptlDCOrig.x;
- Extent.right += dc->ptlDCOrig.x;
- Extent.top += dc->ptlDCOrig.y;
- Extent.bottom += dc->ptlDCOrig.y;
-
- DitherOrg.x = DitherOrg.y = 0;
- IntLPtoDP(dc, (LPPOINT)&DitherOrg, 1);
-
- DitherOrg.x += dc->ptlDCOrig.x;
- DitherOrg.y += dc->ptlDCOrig.y;
-
- psurf = dc->dclevel.pSurface;
- /* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */
- ASSERT(psurf);
+ rclExtent.left = rclExtent.right = pVertex->x;
+ rclExtent.top = rclExtent.bottom = pVertex->y;
+ for (i = 0; i < nVertex; i++)
+ {
+ rclExtent.left = min(rclExtent.left, (pVertex + i)->x);
+ rclExtent.right = max(rclExtent.right, (pVertex + i)->x);
+ rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
+ rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
+ }
+
+ IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);
+ rclExtent.left += pdc->ptlDCOrig.x;
+ rclExtent.right += pdc->ptlDCOrig.x;
+ rclExtent.top += pdc->ptlDCOrig.y;
+ rclExtent.bottom += pdc->ptlDCOrig.y;
+
+ ptlDitherOrg.x = ptlDitherOrg.y = 0;
+ IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
+ ptlDitherOrg.x += pdc->ptlDCOrig.x;
+ ptlDitherOrg.y += pdc->ptlDCOrig.y;
hDestPalette = psurf->hDIBPalette;
if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
- PalDestGDI = PALETTE_LockPalette(hDestPalette);
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0);
-
- Ret = IntEngGradientFill(&psurf->SurfObj,
- dc->rosdc.CombinedClip,
- &exlo.xlo,
- pVertex,
- uVertex,
- pMesh,
- uMesh,
- &Extent,
- &DitherOrg,
- ulMode);
+ ppal = PALETTE_LockPalette(hDestPalette);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0);
+
+ ASSERT(pdc->rosdc.CombinedClip);
+
+ bRet = IntEngGradientFill(&psurf->SurfObj,
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
+ pVertex,
+ nVertex,
+ pMesh,
+ nMesh,
+ &rclExtent,
+ &ptlDitherOrg,
+ ulMode);
EXLATEOBJ_vCleanup(&exlo);
- if (PalDestGDI)
- PALETTE_UnlockPalette(PalDestGDI);
-
- return Ret;
+ if (ppal)
+ PALETTE_UnlockPalette(ppal);
+
+ return bRet;
}
BOOL
@@ -947,33 +963,19 @@
NtGdiGradientFill(
HDC hdc,
PTRIVERTEX pVertex,
- ULONG uVertex,
+ ULONG nVertex,
PVOID pMesh,
- ULONG uMesh,
+ ULONG nMesh,
ULONG ulMode)
{
- DC *dc;
- BOOL Ret;
+ BOOL bRet;
PTRIVERTEX SafeVertex;
PVOID SafeMesh;
- ULONG SizeMesh;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc(hdc);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (dc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
- if (!pVertex || !uVertex || !pMesh || !uMesh)
- {
- DC_UnlockDc(dc);
+ ULONG cbVertex, cbMesh;
+
+ /* Validate parameters */
+ if (!pVertex || !nVertex || !pMesh || !nMesh)
+ {
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
@@ -982,77 +984,55 @@
{
case GRADIENT_FILL_RECT_H:
case GRADIENT_FILL_RECT_V:
- SizeMesh = uMesh * sizeof(GRADIENT_RECT);
+ cbMesh = nMesh * sizeof(GRADIENT_RECT);
break;
case GRADIENT_FILL_TRIANGLE:
- SizeMesh = uMesh * sizeof(TRIVERTEX);
+ cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE);
break;
default:
- DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
+ cbVertex = nVertex * sizeof(TRIVERTEX);
+ if (cbVertex + cbMesh <= cbVertex)
+ {
+ /* Overflow */
+ return FALSE;
+ }
+
+ /* Allocate a kernel mode buffer */
+ SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
+ if (!SafeVertex)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex);
+
+ /* Copy the parameters to kernel mode */
_SEH2_TRY
{
- ProbeForRead(pVertex,
- uVertex * sizeof(TRIVERTEX),
- 1);
- ProbeForRead(pMesh,
- SizeMesh,
- 1);
+ ProbeForRead(pVertex, cbVertex, 1);
+ ProbeForRead(pMesh, cbMesh, 1);
+ RtlCopyMemory(SafeVertex, pVertex, cbVertex);
+ RtlCopyMemory(SafeMesh, pMesh, cbMesh);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
+ ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE;)
}
_SEH2_END;
- if (!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(Status);
- return FALSE;
- }
-
- if (!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) +
SizeMesh, TAG_SHAPE)))
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex);
-
- _SEH2_TRY
- {
- /* pointers were already probed! */
- RtlCopyMemory(SafeVertex,
- pVertex,
- uVertex * sizeof(TRIVERTEX));
- RtlCopyMemory(SafeMesh,
- pMesh,
- SizeMesh);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- if (!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
- SetLastNtError(Status);
- return FALSE;
- }
-
- Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode);
-
- DC_UnlockDc(dc);
- ExFreePool(SafeVertex);
- return Ret;
+ /* Call the internal function */
+ bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode);
+
+ /* Cleanup and return result */
+ ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
+ return bRet;
}
BOOL APIENTRY