mirror of
https://github.com/reactos/reactos.git
synced 2025-05-14 23:03:53 +00:00
[WIN32K]
Fix another bug in NtGdiSelectBitmap, where selecting the same bitmap a second time, would release the bitmap svn path=/trunk/; revision=55671
This commit is contained in:
parent
04135b7ce4
commit
4c5e2c71ec
1 changed files with 43 additions and 25 deletions
|
@ -261,11 +261,9 @@ NtGdiSelectBitmap(
|
||||||
IN HBITMAP hbmp)
|
IN HBITMAP hbmp)
|
||||||
{
|
{
|
||||||
PDC pdc;
|
PDC pdc;
|
||||||
PDC_ATTR pdcattr;
|
|
||||||
HBITMAP hbmpOld;
|
HBITMAP hbmpOld;
|
||||||
PSURFACE psurfNew, psurfOld;
|
PSURFACE psurfNew, psurfOld;
|
||||||
HRGN hVisRgn;
|
HRGN hVisRgn;
|
||||||
SIZEL sizlBitmap = {1, 1};
|
|
||||||
HDC hdcOld;
|
HDC hdcOld;
|
||||||
ASSERT_NOGDILOCKS();
|
ASSERT_NOGDILOCKS();
|
||||||
|
|
||||||
|
@ -278,7 +276,6 @@ NtGdiSelectBitmap(
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pdcattr = pdc->pdcattr;
|
|
||||||
|
|
||||||
/* Must be a memory dc to select a bitmap */
|
/* Must be a memory dc to select a bitmap */
|
||||||
if (pdc->dctype != DC_TYPE_MEMORY)
|
if (pdc->dctype != DC_TYPE_MEMORY)
|
||||||
|
@ -290,11 +287,35 @@ NtGdiSelectBitmap(
|
||||||
/* Save the old bitmap */
|
/* Save the old bitmap */
|
||||||
psurfOld = pdc->dclevel.pSurface;
|
psurfOld = pdc->dclevel.pSurface;
|
||||||
|
|
||||||
|
/* Check if there is a bitmap selected */
|
||||||
|
if (psurfOld)
|
||||||
|
{
|
||||||
|
/* Get the old bitmap's handle */
|
||||||
|
hbmpOld = psurfOld->BaseObject.hHmgr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use the default bitmap */
|
||||||
|
hbmpOld = StockObjects[DEFAULT_BITMAP];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the new bitmap is already selected */
|
||||||
|
if (hbmp == hbmpOld)
|
||||||
|
{
|
||||||
|
/* Unlock the DC and return the old bitmap */
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
return hbmpOld;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the default bitmap was passed */
|
/* Check if the default bitmap was passed */
|
||||||
if (hbmp == StockObjects[DEFAULT_BITMAP])
|
if (hbmp == StockObjects[DEFAULT_BITMAP])
|
||||||
{
|
{
|
||||||
psurfNew = NULL;
|
psurfNew = NULL;
|
||||||
|
|
||||||
|
/* Default bitmap is 1x1 pixel */
|
||||||
|
pdc->dclevel.sizl.cx = 1;
|
||||||
|
pdc->dclevel.sizl.cy = 1;
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
psurfNew = SURFACE_ShareLockSurface(hbmp);
|
psurfNew = SURFACE_ShareLockSurface(hbmp);
|
||||||
}
|
}
|
||||||
|
@ -308,28 +329,32 @@ NtGdiSelectBitmap(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the bitmp's hdc */
|
/* Set the bitmap's hdc and check if it was set before */
|
||||||
hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
|
hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
|
||||||
if (hdcOld != NULL && hdcOld != hdc)
|
if (hdcOld != NULL)
|
||||||
{
|
{
|
||||||
/* The bitmap is already selected, fail */
|
/* The bitmap is already selected into a different DC */
|
||||||
|
ASSERT(hdcOld != hdc);
|
||||||
|
|
||||||
|
/* Dereference the bitmap, unlock the DC and fail. */
|
||||||
SURFACE_ShareUnlockSurface(psurfNew);
|
SURFACE_ShareUnlockSurface(psurfNew);
|
||||||
DC_UnlockDc(pdc);
|
DC_UnlockDc(pdc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the bitmap size */
|
/* Copy the bitmap size */
|
||||||
sizlBitmap = psurfNew->SurfObj.sizlBitmap;
|
pdc->dclevel.sizl = psurfNew->SurfObj.sizlBitmap;
|
||||||
|
|
||||||
/* Check if the bitmap is a dibsection */
|
/* Check if the bitmap is a dibsection */
|
||||||
if(psurfNew->hSecure)
|
if(psurfNew->hSecure)
|
||||||
{
|
{
|
||||||
/* Set DIBSECTION attribute */
|
/* Set DIBSECTION attribute */
|
||||||
pdcattr->ulDirty_ |= DC_DIBSECTION;
|
pdc->pdcattr->ulDirty_ |= DC_DIBSECTION;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pdcattr->ulDirty_ &= ~DC_DIBSECTION;
|
/* Remove DIBSECTION attribute */
|
||||||
|
pdc->pdcattr->ulDirty_ &= ~DC_DIBSECTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,38 +364,31 @@ NtGdiSelectBitmap(
|
||||||
/* Check if there was a bitmap selected before */
|
/* Check if there was a bitmap selected before */
|
||||||
if (psurfOld)
|
if (psurfOld)
|
||||||
{
|
{
|
||||||
/* Get the old bitmap's handle */
|
/* Reset hdc of the old bitmap, it isn't selected anymore */
|
||||||
hbmpOld = psurfOld->BaseObject.hHmgr;
|
|
||||||
|
|
||||||
/* Reset hdc of the old bitmap,it isn't selected anymore */
|
|
||||||
psurfOld->hdc = NULL;
|
psurfOld->hdc = NULL;
|
||||||
|
|
||||||
/* Dereference the old bitmap */
|
/* Dereference the old bitmap */
|
||||||
SURFACE_ShareUnlockSurface(psurfOld);
|
SURFACE_ShareUnlockSurface(psurfOld);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Return default bitmap */
|
|
||||||
hbmpOld = StockObjects[DEFAULT_BITMAP];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark the dc brushes invalid */
|
/* Mark the dc brushes invalid */
|
||||||
pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
|
pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
|
||||||
|
|
||||||
/* Unlock the DC */
|
|
||||||
DC_UnlockDc(pdc);
|
|
||||||
|
|
||||||
/* FIXME: Improve by using a region without a handle and selecting it */
|
/* FIXME: Improve by using a region without a handle and selecting it */
|
||||||
hVisRgn = IntSysCreateRectRgn( 0,
|
hVisRgn = IntSysCreateRectRgn( 0,
|
||||||
0,
|
0,
|
||||||
sizlBitmap.cx,
|
pdc->dclevel.sizl.cx,
|
||||||
sizlBitmap.cy);
|
pdc->dclevel.sizl.cy);
|
||||||
|
|
||||||
if (hVisRgn)
|
if (hVisRgn)
|
||||||
{
|
{
|
||||||
GdiSelectVisRgn(hdc, hVisRgn);
|
GdiSelectVisRgn(hdc, hVisRgn);
|
||||||
GreDeleteObject(hVisRgn);
|
GreDeleteObject(hVisRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlock the DC */
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
/* Return the old bitmap handle */
|
/* Return the old bitmap handle */
|
||||||
return hbmpOld;
|
return hbmpOld;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue