mirror of
https://github.com/reactos/reactos.git
synced 2025-05-30 22:49:12 +00:00
[WIN32K]
- Rework EngSetPointerShape, to first allocate the neccessary surfaces, before deleting the old ones. Also check in IntShowMousePointer if a saving surface is present. This way a failure to allocate a surface will not result in a crash, but keep the old mouse pointer. See issue #5402 for more details. svn path=/trunk/; revision=48630
This commit is contained in:
parent
cb6ae2faab
commit
3a325683bc
1 changed files with 122 additions and 108 deletions
|
@ -209,6 +209,9 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
|
|||
|
||||
pgp->Enabled = TRUE;
|
||||
|
||||
/* Check if we have any mouse pointer */
|
||||
if (!pgp->psurfSave) return;
|
||||
|
||||
/* Calculate pointer coordinates */
|
||||
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
|
||||
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
|
||||
|
@ -318,42 +321,117 @@ EngSetPointerShape(
|
|||
{
|
||||
PDEVOBJ *ppdev;
|
||||
GDIPOINTER *pgp;
|
||||
LONG lDelta;
|
||||
HBITMAP hbmp;
|
||||
RECTL rcl;
|
||||
LONG lDelta = 0;
|
||||
HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL;
|
||||
PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL;
|
||||
RECTL rectl;
|
||||
SIZEL sizel = {0, 0};
|
||||
|
||||
ASSERT(pso);
|
||||
|
||||
ppdev = GDIDEV(pso);
|
||||
pgp = &ppdev->Pointer;
|
||||
|
||||
/* Do we have any bitmap at all? */
|
||||
if (psoColor || psoMask)
|
||||
{
|
||||
/* Get the size of the new pointer */
|
||||
if (psoColor)
|
||||
{
|
||||
sizel.cx = psoColor->sizlBitmap.cx;
|
||||
sizel.cy = psoColor->sizlBitmap.cy;
|
||||
}
|
||||
else// if (psoMask)
|
||||
{
|
||||
sizel.cx = psoMask->sizlBitmap.cx;
|
||||
sizel.cy = psoMask->sizlBitmap.cy / 2;
|
||||
}
|
||||
|
||||
rectl.left = 0;
|
||||
rectl.top = 0;
|
||||
rectl.right = sizel.cx;
|
||||
rectl.bottom = sizel.cy;
|
||||
|
||||
/* Calculate lDelta for our surfaces. */
|
||||
lDelta = DIB_GetDIBWidthBytes(sizel.cx,
|
||||
BitsPerFormat(pso->iBitmapFormat));
|
||||
|
||||
/* Create a bitmap for saving the pixels under the cursor. */
|
||||
hbmSave = EngCreateBitmap(sizel,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
psurfSave = SURFACE_ShareLockSurface(hbmSave);
|
||||
if (!psurfSave) goto failure;
|
||||
}
|
||||
|
||||
if (psoColor)
|
||||
{
|
||||
pgp->Size.cx = psoColor->sizlBitmap.cx;
|
||||
pgp->Size.cy = psoColor->sizlBitmap.cy;
|
||||
if (psoMask)
|
||||
{
|
||||
// CHECKME: Is this really required? if we have a color surface,
|
||||
// we only need the AND part of the mask.
|
||||
/* Check if the sizes match as they should */
|
||||
if (psoMask->sizlBitmap.cx != psoColor->sizlBitmap.cx ||
|
||||
psoMask->sizlBitmap.cy != psoColor->sizlBitmap.cy * 2)
|
||||
{
|
||||
DPRINT("Sizes of mask (%ld,%ld) and color (%ld,%ld) don't match\n",
|
||||
psoMask->sizlBitmap.cx, psoMask->sizlBitmap.cy,
|
||||
psoColor->sizlBitmap.cx, psoColor->sizlBitmap.cy);
|
||||
// return SPS_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (psoMask)
|
||||
{
|
||||
pgp->Size.cx = psoMask->sizlBitmap.cx;
|
||||
pgp->Size.cy = psoMask->sizlBitmap.cy / 2;
|
||||
/* Color bitmap must have the same format as the dest surface */
|
||||
if (psoColor->iBitmapFormat != pso->iBitmapFormat) goto failure;
|
||||
|
||||
/* Create a bitmap to copy the color bitmap to */
|
||||
hbmColor = EngCreateBitmap(psoColor->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
psurfColor = SURFACE_ShareLockSurface(hbmColor);
|
||||
if (!psurfColor) goto failure;
|
||||
|
||||
/* Now copy the given bitmap */
|
||||
rectl.bottom = psoColor->sizlBitmap.cy;
|
||||
IntEngCopyBits(&psurfColor->SurfObj,
|
||||
psoColor,
|
||||
NULL,
|
||||
pxlo,
|
||||
&rectl,
|
||||
(POINTL*)&rectl);
|
||||
}
|
||||
|
||||
/* Create a mask surface */
|
||||
if (psoMask)
|
||||
{
|
||||
EXLATEOBJ exlo;
|
||||
PPALETTE ppal;
|
||||
|
||||
/* Create a bitmap for the mask */
|
||||
hbmMask = EngCreateBitmap(psoMask->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
psurfMask = SURFACE_ShareLockSurface(hbmMask);
|
||||
if (!psurfMask) goto failure;
|
||||
|
||||
/* Initialize an EXLATEOBJ */
|
||||
ppal = PALETTE_LockPalette(ppdev->devinfo.hpalDefault);
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
&gpalMono,
|
||||
ppal,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
|
||||
/* Copy the mask bitmap */
|
||||
rectl.bottom = psoMask->sizlBitmap.cy;
|
||||
IntEngCopyBits(&psurfMask->SurfObj,
|
||||
psoMask,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rectl,
|
||||
(POINTL*)&rectl);
|
||||
|
||||
/* Cleanup */
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
if (ppal) PALETTE_UnlockPalette(ppal);
|
||||
}
|
||||
|
||||
/* Hide mouse pointer */
|
||||
IntHideMousePointer(ppdev, pso);
|
||||
|
||||
/* Free old color bitmap */
|
||||
if (pgp->psurfColor)
|
||||
{
|
||||
EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
|
||||
|
@ -361,6 +439,7 @@ EngSetPointerShape(
|
|||
pgp->psurfColor = NULL;
|
||||
}
|
||||
|
||||
/* Free old mask bitmap */
|
||||
if (pgp->psurfMask)
|
||||
{
|
||||
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
|
||||
|
@ -368,7 +447,8 @@ EngSetPointerShape(
|
|||
pgp->psurfMask = NULL;
|
||||
}
|
||||
|
||||
if (pgp->psurfSave != NULL)
|
||||
/* Free old save bitmap */
|
||||
if (pgp->psurfSave)
|
||||
{
|
||||
EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr);
|
||||
SURFACE_ShareUnlockSurface(pgp->psurfSave);
|
||||
|
@ -378,94 +458,17 @@ EngSetPointerShape(
|
|||
/* See if we are being asked to hide the pointer. */
|
||||
if (psoMask == NULL && psoColor == NULL)
|
||||
{
|
||||
/* We're done */
|
||||
return SPS_ACCEPT_NOEXCLUDE;
|
||||
}
|
||||
|
||||
/* Now set the new cursor */
|
||||
pgp->psurfColor = psurfColor;
|
||||
pgp->psurfMask = psurfMask;
|
||||
pgp->psurfSave = psurfSave;
|
||||
pgp->HotSpot.x = xHot;
|
||||
pgp->HotSpot.y = yHot;
|
||||
|
||||
/* Calculate lDelta for our surfaces. */
|
||||
lDelta = DIB_GetDIBWidthBytes(pgp->Size.cx,
|
||||
BitsPerFormat(pso->iBitmapFormat));
|
||||
|
||||
rcl.left = 0;
|
||||
rcl.top = 0;
|
||||
rcl.right = pgp->Size.cx;
|
||||
rcl.bottom = pgp->Size.cy;
|
||||
|
||||
/* Create surface for saving the pixels under the cursor. */
|
||||
hbmp = EngCreateBitmap(pgp->Size,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
pgp->psurfSave = SURFACE_ShareLockSurface(hbmp);
|
||||
|
||||
/* Create a mask surface */
|
||||
if (psoMask)
|
||||
{
|
||||
EXLATEOBJ exlo;
|
||||
PPALETTE ppal;
|
||||
|
||||
hbmp = EngCreateBitmap(psoMask->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
pgp->psurfMask = SURFACE_ShareLockSurface(hbmp);
|
||||
|
||||
if(pgp->psurfMask)
|
||||
{
|
||||
ppal = PALETTE_LockPalette(ppdev->devinfo.hpalDefault);
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
&gpalMono,
|
||||
ppal,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
|
||||
rcl.bottom = psoMask->sizlBitmap.cy;
|
||||
IntEngCopyBits(&pgp->psurfMask->SurfObj,
|
||||
psoMask,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
if (ppal)
|
||||
PALETTE_UnlockPalette(ppal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pgp->psurfMask = NULL;
|
||||
}
|
||||
|
||||
/* Create a color surface */
|
||||
if (psoColor)
|
||||
{
|
||||
hbmp = EngCreateBitmap(psoColor->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
pgp->psurfColor = SURFACE_ShareLockSurface(hbmp);
|
||||
if (pgp->psurfColor)
|
||||
{
|
||||
rcl.bottom = psoColor->sizlBitmap.cy;
|
||||
IntEngCopyBits(&pgp->psurfColor->SurfObj,
|
||||
psoColor,
|
||||
NULL,
|
||||
pxlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pgp->psurfColor = NULL;
|
||||
}
|
||||
pgp->Size = sizel;
|
||||
|
||||
if (x != -1)
|
||||
{
|
||||
|
@ -488,6 +491,17 @@ EngSetPointerShape(
|
|||
}
|
||||
|
||||
return SPS_ACCEPT_NOEXCLUDE;
|
||||
|
||||
failure:
|
||||
/* Cleanup surfaces */
|
||||
if (hbmMask) EngDeleteSurface(hbmMask);
|
||||
if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if (hbmColor) EngDeleteSurface(hbmColor);
|
||||
if (psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
if (hbmSave) EngDeleteSurface(hbmSave);
|
||||
if (psurfSave) SURFACE_ShareUnlockSurface(psurfSave);
|
||||
|
||||
return SPS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue