Move NtGdiSelectBitmap to dcobjs.c, implement DC_vSelectFillBrush and DC_vSelectLineBrush, use them in IntGdiSelectBrush and IntGdiSelectPen, DC_Cleanup and DC_vCopyState. Should fix leaking brushes/pens on process cleanup.

Remove the flag checks from DC_vUpdateXxxBrush functions.

svn path=/trunk/; revision=40243
This commit is contained in:
Timo Kreuzer
2009-03-26 00:56:46 +00:00
parent cac93ee776
commit 65d9fbc726
5 changed files with 222 additions and 205 deletions
+24 -2
View File
@@ -278,13 +278,35 @@ DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
PSURFACE psurfOld = pdc->dclevel.pSurface;
if (psurfOld)
SURFACE_ShareUnlockSurface(psurfOld);
if (psurfNew)
GDIOBJ_IncrementShareCount((POBJ)psurfNew);
pdc->dclevel.pSurface = psurfNew;
}
VOID
FORCEINLINE
DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill)
{
PBRUSH pbrFillOld = pdc->dclevel.pbrFill;
if (pbrFillOld)
BRUSH_ShareUnlockBrush(pbrFillOld);
if (pbrFill)
GDIOBJ_IncrementShareCount((POBJ)pbrFill);
pdc->dclevel.pbrFill = pbrFill;
}
VOID
FORCEINLINE
DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine)
{
PBRUSH pbrLineOld = pdc->dclevel.pbrLine;
if (pbrLineOld)
BRUSH_ShareUnlockBrush(pbrLineOld);
if (pbrLine)
GDIOBJ_IncrementShareCount((POBJ)pbrLine);
pdc->dclevel.pbrLine = pbrLine;
}
BOOL FASTCALL
IntPrepareDriverIfNeeded();
extern PDEVOBJ PrimarySurface;
@@ -920,115 +920,4 @@ NtGdiGetDCforBitmap(
return hDC;
}
/*
* @implemented
*/
HBITMAP
APIENTRY
NtGdiSelectBitmap(
IN HDC hDC,
IN HBITMAP hBmp)
{
PDC pDC;
PDC_ATTR pdcattr;
HBITMAP hOrgBmp;
PSURFACE psurfBmp, psurfOld;
HRGN hVisRgn;
BOOLEAN bFailed;
PBRUSH pbrush;
if (hDC == NULL || hBmp == NULL) return NULL;
pDC = DC_LockDc(hDC);
if (!pDC)
{
return NULL;
}
pdcattr = pDC->pdcattr;
/* must be memory dc to select bitmap */
if (pDC->dctype != DC_TYPE_MEMORY)
{
DC_UnlockDc(pDC);
return NULL;
}
psurfBmp = SURFACE_LockSurface(hBmp);
if (!psurfBmp)
{
DC_UnlockDc(pDC);
return NULL;
}
/* Get the handle for the old bitmap */
psurfOld = pDC->dclevel.pSurface;
hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
/* FIXME: ros hack */
hOrgBmp = pDC->rosdc.hBitmap;
pDC->rosdc.hBitmap = hBmp;
/* Release the old bitmap, reference the new */
DC_vSelectSurface(pDC, psurfBmp);
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
psurfBmp->hDC = hDC;
// if we're working with a DIB, get the palette
// [fixme: only create if the selected palette is null]
if (psurfBmp->hSecure)
{
// pDC->rosdc.bitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
}
else
{
pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
}
/* FIXME; improve by using a region without a handle and selecting it */
hVisRgn = NtGdiCreateRectRgn(0,
0,
psurfBmp->SurfObj.sizlBitmap.cx,
psurfBmp->SurfObj.sizlBitmap.cy);
/* Release the exclusive lock */
SURFACE_UnlockSurface(psurfBmp);
/* Regenerate the XLATEOBJs. (hack!) */
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
if (pbrush)
{
if (pDC->rosdc.XlateBrush)
{
EngDeleteXlate(pDC->rosdc.XlateBrush);
}
pDC->rosdc.XlateBrush = IntGdiCreateBrushXlate(pDC, pbrush, &bFailed);
BRUSH_UnlockBrush(pbrush);
}
pbrush = PEN_LockPen(pdcattr->hpen);
if (pbrush)
{
if (pDC->rosdc.XlatePen)
{
EngDeleteXlate(pDC->rosdc.XlatePen);
}
pDC->rosdc.XlatePen = IntGdiCreateBrushXlate(pDC, pbrush, &bFailed);
PEN_UnlockPen(pbrush);
}
DC_UnlockDc(pDC);
if (hVisRgn)
{
GdiSelectVisRgn(hDC, hVisRgn);
GreDeleteObject(hVisRgn);
}
return hOrgBmp;
}
/* EOF */
@@ -139,9 +139,16 @@ BOOL INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
PDC pDC = (PDC)ObjectBody;
/* Free driver name (HACK) */
if (pDC->rosdc.DriverName.Buffer)
ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
/* Clean up selected objects */
DC_vSelectSurface(pDC, NULL);
DC_vSelectFillBrush(pDC, NULL);
DC_vSelectLineBrush(pDC, NULL);
return TRUE;
}
+189 -90
View File
@@ -21,46 +21,42 @@ DC_vUpdateFillBrush(PDC pdc)
XLATEOBJ *pxlo;
ULONG iSolidColor;
/* Check if update of eboFill is needed */
if (pdcattr->ulDirty_ & DIRTY_FILL)
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Check if the brush handle has changed */
if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr)
{
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Check if the brush handle has changed */
if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr)
/* Try to lock the new brush */
pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (pbrFill)
{
/* Try to lock the new brush */
pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (pbrFill)
{
/* Unlock old brush, set new brush */
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrFill);
pdc->dclevel.pbrFill = pbrFill;
/* Unlock old brush, set new brush */
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrFill);
pdc->dclevel.pbrFill = pbrFill;
/* Update eboFill, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboFill, pbrFill, pxlo);
}
else
{
/* Invalid brush handle, restore old one */
pdcattr->hbrush = pdc->dclevel.pbrFill->BaseObject.hHmgr;
}
/* Update eboFill, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboFill, pbrFill, pxlo);
}
/* Check for DC brush */
if (pdcattr->hbrush == StockObjects[DC_BRUSH])
else
{
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crPenClr);
/* Update the eboFill's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, iSolidColor);
/* Invalid brush handle, restore old one */
pdcattr->hbrush = pdc->dclevel.pbrFill->BaseObject.hHmgr;
}
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_FILL;
}
/* Check for DC brush */
if (pdcattr->hbrush == StockObjects[DC_BRUSH])
{
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crPenClr);
/* Update the eboFill's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, iSolidColor);
}
/* Clear flags */
pdcattr->ulDirty_ &= ~(DIRTY_FILL | DC_BRUSH_DIRTY);
}
VOID
@@ -72,46 +68,42 @@ DC_vUpdateLineBrush(PDC pdc)
XLATEOBJ *pxlo;
ULONG iSolidColor;
/* Check if update of eboLine is needed */
if (pdcattr->ulDirty_ & DIRTY_LINE)
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Check if the pen handle has changed */
if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr)
{
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Check if the pen handle has changed */
if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr)
/* Try to lock the new pen */
pbrLine = BRUSH_ShareLockBrush(pdcattr->hpen);
if (pbrLine)
{
/* Try to lock the new pen */
pbrLine = BRUSH_ShareLockBrush(pdcattr->hpen);
if (pbrLine)
{
/* Unlock old brush, set new brush */
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrLine);
pdc->dclevel.pbrLine = pbrLine;
/* Unlock old brush, set new brush */
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrLine);
pdc->dclevel.pbrLine = pbrLine;
/* Update eboLine, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboLine, pbrLine, pxlo);
}
else
{
/* Invalid pen handle, restore old one */
pdcattr->hpen = pdc->dclevel.pbrLine->BaseObject.hHmgr;
}
/* Update eboLine, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboLine, pbrLine, pxlo);
}
/* Check for DC pen */
if (pdcattr->hpen == StockObjects[DC_PEN])
else
{
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crPenClr);
/* Update the eboLine's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, iSolidColor);
/* Invalid pen handle, restore old one */
pdcattr->hpen = pdc->dclevel.pbrLine->BaseObject.hHmgr;
}
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_LINE;
}
/* Check for DC pen */
if (pdcattr->hpen == StockObjects[DC_PEN])
{
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crPenClr);
/* Update the eboLine's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, iSolidColor);
}
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_LINE;
}
VOID
@@ -122,21 +114,17 @@ DC_vUpdateTextBrush(PDC pdc)
XLATEOBJ *pxlo;
ULONG iSolidColor;
/* Check if update of eboText is needed */
if (pdcattr->ulDirty_ & DIRTY_TEXT)
{
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crForegroundClr);
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crForegroundClr);
/* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, iSolidColor);
/* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, iSolidColor);
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_TEXT;
}
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_TEXT;
}
VOID
@@ -147,21 +135,17 @@ DC_vUpdateBackgroundBrush(PDC pdc)
XLATEOBJ *pxlo;
ULONG iSolidColor;
/* Check if update of eboBackground is needed */
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
{
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* ROS HACK, should use surf xlate */
pxlo = pdc->rosdc.XlatePen;
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crBackgroundClr);
/* Translate the color to the target format */
iSolidColor = XLATEOBJ_iXlate(pxlo, pdcattr->crBackgroundClr);
/* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, iSolidColor);
/* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, iSolidColor);
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;
}
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;
}
HPALETTE
@@ -232,6 +216,8 @@ IntGdiSelectBrush(
return NULL;
}
DC_vSelectFillBrush(pDC, pbrush);
XlateObj = IntGdiCreateBrushXlate(pDC, pbrush, &bFailed);
BRUSH_UnlockBrush(pbrush);
if(bFailed)
@@ -275,6 +261,8 @@ IntGdiSelectPen(
return NULL;
}
DC_vSelectLineBrush(pDC, pbrushPen);
XlateObj = IntGdiCreateBrushXlate(pDC, pbrushPen, &bFailed);
PEN_UnlockPen(pbrushPen);
if (bFailed)
@@ -352,6 +340,117 @@ NtGdiSelectPen(
return hOrgPen;
}
/*
* @implemented
*/
HBITMAP
APIENTRY
NtGdiSelectBitmap(
IN HDC hDC,
IN HBITMAP hBmp)
{
PDC pDC;
PDC_ATTR pdcattr;
HBITMAP hOrgBmp;
PSURFACE psurfBmp, psurfOld;
HRGN hVisRgn;
BOOLEAN bFailed;
PBRUSH pbrush;
if (hDC == NULL || hBmp == NULL) return NULL;
pDC = DC_LockDc(hDC);
if (!pDC)
{
return NULL;
}
pdcattr = pDC->pdcattr;
/* must be memory dc to select bitmap */
if (pDC->dctype != DC_TYPE_MEMORY)
{
DC_UnlockDc(pDC);
return NULL;
}
psurfBmp = SURFACE_LockSurface(hBmp);
if (!psurfBmp)
{
DC_UnlockDc(pDC);
return NULL;
}
/* Get the handle for the old bitmap */
psurfOld = pDC->dclevel.pSurface;
hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
/* FIXME: ros hack */
hOrgBmp = pDC->rosdc.hBitmap;
pDC->rosdc.hBitmap = hBmp;
/* Release the old bitmap, reference the new */
DC_vSelectSurface(pDC, psurfBmp);
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
psurfBmp->hDC = hDC;
// if we're working with a DIB, get the palette
// [fixme: only create if the selected palette is null]
if (psurfBmp->hSecure)
{
// pDC->rosdc.bitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
}
else
{
pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
}
/* FIXME; improve by using a region without a handle and selecting it */
hVisRgn = NtGdiCreateRectRgn(0,
0,
psurfBmp->SurfObj.sizlBitmap.cx,
psurfBmp->SurfObj.sizlBitmap.cy);
/* Release the exclusive lock */
SURFACE_UnlockSurface(psurfBmp);
/* Regenerate the XLATEOBJs. (hack!) */
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
if (pbrush)
{
if (pDC->rosdc.XlateBrush)
{
EngDeleteXlate(pDC->rosdc.XlateBrush);
}
pDC->rosdc.XlateBrush = IntGdiCreateBrushXlate(pDC, pbrush, &bFailed);
BRUSH_UnlockBrush(pbrush);
}
pbrush = PEN_LockPen(pdcattr->hpen);
if (pbrush)
{
if (pDC->rosdc.XlatePen)
{
EngDeleteXlate(pDC->rosdc.XlatePen);
}
pDC->rosdc.XlatePen = IntGdiCreateBrushXlate(pDC, pbrush, &bFailed);
PEN_UnlockPen(pbrush);
}
DC_UnlockDc(pDC);
if (hVisRgn)
{
GdiSelectVisRgn(hDC, hVisRgn);
GreDeleteObject(hVisRgn);
}
return hOrgBmp;
}
BOOL
APIENTRY
NtGdiSelectClipPath(
@@ -39,12 +39,12 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst)
/* Handle references here correctly */
DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface);
DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
// FIXME: handle refs
pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal;
pdcDst->dclevel.ppal = pdcSrc->dclevel.ppal;
pdcDst->dclevel.pbrFill = pdcSrc->dclevel.pbrFill;
pdcDst->dclevel.pbrLine = pdcSrc->dclevel.pbrLine;
pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt;
/* ROS hacks */