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/inc... ============================================================================== --- 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/ntu... ============================================================================== --- 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/obj... ============================================================================== --- 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