mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 01:23:00 +00:00
[WIN32K]
- merge r47350, slightly modified to get it the yarotows way svn path=/branches/reactos-yarotows/; revision=47366
This commit is contained in:
parent
a37321ad04
commit
5ba3469f7b
3 changed files with 107 additions and 144 deletions
|
@ -122,10 +122,15 @@ IntGdiPolyPolygon(DC *dc,
|
||||||
PULONG PolyCounts,
|
PULONG PolyCounts,
|
||||||
int Count);
|
int Count);
|
||||||
|
|
||||||
BOOL FASTCALL IntGdiGradientFill(DC *dc,
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
GreGradientFill(
|
||||||
|
HDC hdc,
|
||||||
PTRIVERTEX pVertex,
|
PTRIVERTEX pVertex,
|
||||||
ULONG uVertex,
|
ULONG nVertex,
|
||||||
PVOID pMesh, ULONG uMesh, ULONG ulMode);
|
PVOID pMesh,
|
||||||
|
ULONG nMesh,
|
||||||
|
ULONG ulMode);
|
||||||
|
|
||||||
/* DC functions */
|
/* DC functions */
|
||||||
|
|
||||||
|
|
|
@ -1782,7 +1782,6 @@ BOOL UserDrawCaption(
|
||||||
static GRADIENT_RECT gcap = {0, 1};
|
static GRADIENT_RECT gcap = {0, 1};
|
||||||
TRIVERTEX vert[2];
|
TRIVERTEX vert[2];
|
||||||
COLORREF Colors[2];
|
COLORREF Colors[2];
|
||||||
PDC pMemDc;
|
|
||||||
|
|
||||||
if (Wnd != NULL)
|
if (Wnd != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1835,21 +1834,12 @@ BOOL UserDrawCaption(
|
||||||
vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
|
vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
|
||||||
vert[1].Alpha = 0;
|
vert[1].Alpha = 0;
|
||||||
|
|
||||||
pMemDc = DC_LockDc(hMemDc);
|
if(!GreGradientFill(hMemDc, vert, 2, &gcap,
|
||||||
if(!pMemDc)
|
|
||||||
{
|
|
||||||
DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There is no need to call DC_vPrepareDCsForBlit for memory DC */
|
|
||||||
if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap,
|
|
||||||
1, GRADIENT_FILL_RECT_H))
|
1, GRADIENT_FILL_RECT_H))
|
||||||
{
|
{
|
||||||
DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
|
DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
DC_UnlockDc(pMemDc);
|
|
||||||
} //if(uFlags & DC_GRADIENT)
|
} //if(uFlags & DC_GRADIENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -856,39 +856,34 @@ NtGdiRoundRect(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL
|
||||||
IntGdiGradientFill(
|
NTAPI
|
||||||
DC *dc,
|
GreGradientFill(
|
||||||
|
HDC hdc,
|
||||||
PTRIVERTEX pVertex,
|
PTRIVERTEX pVertex,
|
||||||
ULONG uVertex,
|
ULONG nVertex,
|
||||||
PVOID pMesh,
|
PVOID pMesh,
|
||||||
ULONG uMesh,
|
ULONG nMesh,
|
||||||
ULONG ulMode)
|
ULONG ulMode)
|
||||||
{
|
{
|
||||||
|
PDC pdc;
|
||||||
SURFACE *psurf;
|
SURFACE *psurf;
|
||||||
PPALETTE PalDestGDI;
|
|
||||||
EXLATEOBJ exlo;
|
EXLATEOBJ exlo;
|
||||||
RECTL Extent;
|
RECTL rclExtent;
|
||||||
POINTL DitherOrg;
|
POINTL ptlDitherOrg;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
BOOL Ret;
|
BOOL bRet;
|
||||||
|
|
||||||
ASSERT(dc);
|
|
||||||
ASSERT(pVertex);
|
|
||||||
ASSERT(uVertex);
|
|
||||||
ASSERT(pMesh);
|
|
||||||
ASSERT(uMesh);
|
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if (ulMode & GRADIENT_FILL_TRIANGLE)
|
if (ulMode & GRADIENT_FILL_TRIANGLE)
|
||||||
{
|
{
|
||||||
PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh;
|
PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;
|
||||||
|
|
||||||
for (i = 0; i < uMesh; i++, tr++)
|
for (i = 0; i < nMesh; i++, pTriangle++)
|
||||||
{
|
{
|
||||||
if (tr->Vertex1 >= uVertex ||
|
if (pTriangle->Vertex1 >= nVertex ||
|
||||||
tr->Vertex2 >= uVertex ||
|
pTriangle->Vertex2 >= nVertex ||
|
||||||
tr->Vertex3 >= uVertex)
|
pTriangle->Vertex3 >= nVertex)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -897,10 +892,10 @@ IntGdiGradientFill(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh;
|
PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh;
|
||||||
for (i = 0; i < uMesh; i++, rc++)
|
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);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -908,61 +903,74 @@ IntGdiGradientFill(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
/* calculate extent */
|
||||||
Extent.left = Extent.right = pVertex->x;
|
rclExtent.left = rclExtent.right = pVertex->x;
|
||||||
Extent.top = Extent.bottom = pVertex->y;
|
rclExtent.top = rclExtent.bottom = pVertex->y;
|
||||||
for (i = 0; i < uVertex; i++)
|
for (i = 0; i < nVertex; i++)
|
||||||
{
|
{
|
||||||
Extent.left = min(Extent.left, (pVertex + i)->x);
|
rclExtent.left = min(rclExtent.left, (pVertex + i)->x);
|
||||||
Extent.right = max(Extent.right, (pVertex + i)->x);
|
rclExtent.right = max(rclExtent.right, (pVertex + i)->x);
|
||||||
Extent.top = min(Extent.top, (pVertex + i)->y);
|
rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
|
||||||
Extent.bottom = max(Extent.bottom, (pVertex + i)->y);
|
rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
|
||||||
}
|
}
|
||||||
IntLPtoDP(dc, (LPPOINT)&Extent, 2);
|
IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);
|
||||||
|
|
||||||
Extent.left += dc->ptlDCOrig.x;
|
rclExtent.left += pdc->ptlDCOrig.x;
|
||||||
Extent.right += dc->ptlDCOrig.x;
|
rclExtent.right += pdc->ptlDCOrig.x;
|
||||||
Extent.top += dc->ptlDCOrig.y;
|
rclExtent.top += pdc->ptlDCOrig.y;
|
||||||
Extent.bottom += dc->ptlDCOrig.y;
|
rclExtent.bottom += pdc->ptlDCOrig.y;
|
||||||
|
|
||||||
DitherOrg.x = DitherOrg.y = 0;
|
ptlDitherOrg.x = ptlDitherOrg.y = 0;
|
||||||
IntLPtoDP(dc, (LPPOINT)&DitherOrg, 1);
|
IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
|
||||||
|
|
||||||
DitherOrg.x += dc->ptlDCOrig.x;
|
ptlDitherOrg.x += pdc->ptlDCOrig.x;
|
||||||
DitherOrg.y += dc->ptlDCOrig.y;
|
ptlDitherOrg.y += pdc->ptlDCOrig.y;
|
||||||
|
|
||||||
psurf = dc->dclevel.pSurface;
|
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
|
||||||
/* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */
|
|
||||||
ASSERT(psurf);
|
|
||||||
|
|
||||||
if (psurf->ppal)
|
ASSERT(pdc->rosdc.CombinedClip);
|
||||||
{
|
|
||||||
PalDestGDI = psurf->ppal;
|
|
||||||
GDIOBJ_IncrementShareCount(&PalDestGDI->BaseObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Destination palette obtained from the hDC
|
|
||||||
PalDestGDI = PALETTE_ShareLockPalette(dc->ppdev->devinfo.hpalDefault);
|
|
||||||
|
|
||||||
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0);
|
DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
|
||||||
|
|
||||||
Ret = IntEngGradientFill(&psurf->SurfObj,
|
bRet = IntEngGradientFill(&psurf->SurfObj,
|
||||||
dc->rosdc.CombinedClip,
|
pdc->rosdc.CombinedClip,
|
||||||
&exlo.xlo,
|
&exlo.xlo,
|
||||||
pVertex,
|
pVertex,
|
||||||
uVertex,
|
nVertex,
|
||||||
pMesh,
|
pMesh,
|
||||||
uMesh,
|
nMesh,
|
||||||
&Extent,
|
&rclExtent,
|
||||||
&DitherOrg,
|
&ptlDitherOrg,
|
||||||
ulMode);
|
ulMode);
|
||||||
|
|
||||||
EXLATEOBJ_vCleanup(&exlo);
|
EXLATEOBJ_vCleanup(&exlo);
|
||||||
|
DC_vFinishBlit(pdc, NULL);
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
if (PalDestGDI)
|
return bRet;
|
||||||
PALETTE_ShareUnlockPalette(PalDestGDI);
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -970,33 +978,19 @@ APIENTRY
|
||||||
NtGdiGradientFill(
|
NtGdiGradientFill(
|
||||||
HDC hdc,
|
HDC hdc,
|
||||||
PTRIVERTEX pVertex,
|
PTRIVERTEX pVertex,
|
||||||
ULONG uVertex,
|
ULONG nVertex,
|
||||||
PVOID pMesh,
|
PVOID pMesh,
|
||||||
ULONG uMesh,
|
ULONG nMesh,
|
||||||
ULONG ulMode)
|
ULONG ulMode)
|
||||||
{
|
{
|
||||||
DC *dc;
|
BOOL bRet;
|
||||||
BOOL Ret;
|
|
||||||
PTRIVERTEX SafeVertex;
|
PTRIVERTEX SafeVertex;
|
||||||
PVOID SafeMesh;
|
PVOID SafeMesh;
|
||||||
ULONG SizeMesh;
|
ULONG cbVertex, cbMesh;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
dc = DC_LockDc(hdc);
|
/* Validate parameters */
|
||||||
if (!dc)
|
if (!pVertex || !nVertex || !pMesh || !nMesh)
|
||||||
{
|
{
|
||||||
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);
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1005,81 +999,55 @@ NtGdiGradientFill(
|
||||||
{
|
{
|
||||||
case GRADIENT_FILL_RECT_H:
|
case GRADIENT_FILL_RECT_H:
|
||||||
case GRADIENT_FILL_RECT_V:
|
case GRADIENT_FILL_RECT_V:
|
||||||
SizeMesh = uMesh * sizeof(GRADIENT_RECT);
|
cbMesh = nMesh * sizeof(GRADIENT_RECT);
|
||||||
break;
|
break;
|
||||||
case GRADIENT_FILL_TRIANGLE:
|
case GRADIENT_FILL_TRIANGLE:
|
||||||
SizeMesh = uMesh * sizeof(TRIVERTEX);
|
cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DC_UnlockDc(dc);
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_SEH2_TRY
|
cbVertex = nVertex * sizeof(TRIVERTEX) ;
|
||||||
|
if(cbVertex + cbMesh <= cbVertex)
|
||||||
{
|
{
|
||||||
ProbeForRead(pVertex,
|
/* Overflow */
|
||||||
uVertex * sizeof(TRIVERTEX),
|
return FALSE ;
|
||||||
1);
|
|
||||||
ProbeForRead(pMesh,
|
|
||||||
SizeMesh,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
Status = _SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
SetLastWin32Error(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE)))
|
/* Allocate a kernel mode buffer */
|
||||||
|
SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
|
||||||
|
if(!SafeVertex)
|
||||||
{
|
{
|
||||||
DC_UnlockDc(dc);
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex);
|
SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex);
|
||||||
|
|
||||||
|
/* Copy the parameters to kernel mode */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* pointers were already probed! */
|
ProbeForRead(pVertex, cbVertex, 1);
|
||||||
RtlCopyMemory(SafeVertex,
|
ProbeForRead(pMesh, cbMesh, 1);
|
||||||
pVertex,
|
RtlCopyMemory(SafeVertex, pVertex, cbVertex);
|
||||||
uVertex * sizeof(TRIVERTEX));
|
RtlCopyMemory(SafeMesh, pMesh, cbMesh);
|
||||||
RtlCopyMemory(SafeMesh,
|
|
||||||
pMesh,
|
|
||||||
SizeMesh);
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
Status = _SEH2_GetExceptionCode();
|
ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
|
||||||
|
SetLastNtError(_SEH2_GetExceptionCode());
|
||||||
|
_SEH2_YIELD(return FALSE;)
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
/* Call the internal function */
|
||||||
{
|
bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode);
|
||||||
DC_UnlockDc(dc);
|
|
||||||
ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
|
/* Cleanup and return result */
|
||||||
NULL, dc->rosdc.CombinedClip->rclBounds);
|
ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
|
||||||
|
return bRet;
|
||||||
Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode);
|
|
||||||
|
|
||||||
DC_vFinishBlit(dc, NULL) ;
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
ExFreePool(SafeVertex);
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL APIENTRY
|
BOOL APIENTRY
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue