mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:25:39 +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;
|
pgp->Enabled = TRUE;
|
||||||
|
|
||||||
|
/* Check if we have any mouse pointer */
|
||||||
|
if (!pgp->psurfSave) return;
|
||||||
|
|
||||||
/* Calculate pointer coordinates */
|
/* Calculate pointer coordinates */
|
||||||
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
|
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
|
||||||
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
|
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
|
||||||
|
@ -318,42 +321,117 @@ EngSetPointerShape(
|
||||||
{
|
{
|
||||||
PDEVOBJ *ppdev;
|
PDEVOBJ *ppdev;
|
||||||
GDIPOINTER *pgp;
|
GDIPOINTER *pgp;
|
||||||
LONG lDelta;
|
LONG lDelta = 0;
|
||||||
HBITMAP hbmp;
|
HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL;
|
||||||
RECTL rcl;
|
PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL;
|
||||||
|
RECTL rectl;
|
||||||
|
SIZEL sizel = {0, 0};
|
||||||
|
|
||||||
ASSERT(pso);
|
ASSERT(pso);
|
||||||
|
|
||||||
ppdev = GDIDEV(pso);
|
ppdev = GDIDEV(pso);
|
||||||
pgp = &ppdev->Pointer;
|
pgp = &ppdev->Pointer;
|
||||||
|
|
||||||
|
/* Do we have any bitmap at all? */
|
||||||
|
if (psoColor || psoMask)
|
||||||
|
{
|
||||||
|
/* Get the size of the new pointer */
|
||||||
if (psoColor)
|
if (psoColor)
|
||||||
{
|
{
|
||||||
pgp->Size.cx = psoColor->sizlBitmap.cx;
|
sizel.cx = psoColor->sizlBitmap.cx;
|
||||||
pgp->Size.cy = psoColor->sizlBitmap.cy;
|
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)
|
||||||
|
{
|
||||||
|
/* 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)
|
if (psoMask)
|
||||||
{
|
{
|
||||||
// CHECKME: Is this really required? if we have a color surface,
|
EXLATEOBJ exlo;
|
||||||
// we only need the AND part of the mask.
|
PPALETTE ppal;
|
||||||
/* Check if the sizes match as they should */
|
|
||||||
if (psoMask->sizlBitmap.cx != psoColor->sizlBitmap.cx ||
|
/* Create a bitmap for the mask */
|
||||||
psoMask->sizlBitmap.cy != psoColor->sizlBitmap.cy * 2)
|
hbmMask = EngCreateBitmap(psoMask->sizlBitmap,
|
||||||
{
|
lDelta,
|
||||||
DPRINT("Sizes of mask (%ld,%ld) and color (%ld,%ld) don't match\n",
|
pso->iBitmapFormat,
|
||||||
psoMask->sizlBitmap.cx, psoMask->sizlBitmap.cy,
|
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||||
psoColor->sizlBitmap.cx, psoColor->sizlBitmap.cy);
|
NULL);
|
||||||
// return SPS_ERROR;
|
psurfMask = SURFACE_ShareLockSurface(hbmMask);
|
||||||
}
|
if (!psurfMask) goto failure;
|
||||||
}
|
|
||||||
}
|
/* Initialize an EXLATEOBJ */
|
||||||
else if (psoMask)
|
ppal = PALETTE_LockPalette(ppdev->devinfo.hpalDefault);
|
||||||
{
|
EXLATEOBJ_vInitialize(&exlo,
|
||||||
pgp->Size.cx = psoMask->sizlBitmap.cx;
|
&gpalMono,
|
||||||
pgp->Size.cy = psoMask->sizlBitmap.cy / 2;
|
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);
|
IntHideMousePointer(ppdev, pso);
|
||||||
|
|
||||||
|
/* Free old color bitmap */
|
||||||
if (pgp->psurfColor)
|
if (pgp->psurfColor)
|
||||||
{
|
{
|
||||||
EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
|
EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
|
||||||
|
@ -361,6 +439,7 @@ EngSetPointerShape(
|
||||||
pgp->psurfColor = NULL;
|
pgp->psurfColor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free old mask bitmap */
|
||||||
if (pgp->psurfMask)
|
if (pgp->psurfMask)
|
||||||
{
|
{
|
||||||
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
|
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
|
||||||
|
@ -368,7 +447,8 @@ EngSetPointerShape(
|
||||||
pgp->psurfMask = NULL;
|
pgp->psurfMask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pgp->psurfSave != NULL)
|
/* Free old save bitmap */
|
||||||
|
if (pgp->psurfSave)
|
||||||
{
|
{
|
||||||
EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr);
|
EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr);
|
||||||
SURFACE_ShareUnlockSurface(pgp->psurfSave);
|
SURFACE_ShareUnlockSurface(pgp->psurfSave);
|
||||||
|
@ -378,94 +458,17 @@ EngSetPointerShape(
|
||||||
/* See if we are being asked to hide the pointer. */
|
/* See if we are being asked to hide the pointer. */
|
||||||
if (psoMask == NULL && psoColor == NULL)
|
if (psoMask == NULL && psoColor == NULL)
|
||||||
{
|
{
|
||||||
|
/* We're done */
|
||||||
return SPS_ACCEPT_NOEXCLUDE;
|
return SPS_ACCEPT_NOEXCLUDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now set the new cursor */
|
||||||
|
pgp->psurfColor = psurfColor;
|
||||||
|
pgp->psurfMask = psurfMask;
|
||||||
|
pgp->psurfSave = psurfSave;
|
||||||
pgp->HotSpot.x = xHot;
|
pgp->HotSpot.x = xHot;
|
||||||
pgp->HotSpot.y = yHot;
|
pgp->HotSpot.y = yHot;
|
||||||
|
pgp->Size = sizel;
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x != -1)
|
if (x != -1)
|
||||||
{
|
{
|
||||||
|
@ -488,6 +491,17 @@ EngSetPointerShape(
|
||||||
}
|
}
|
||||||
|
|
||||||
return SPS_ACCEPT_NOEXCLUDE;
|
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…
Add table
Add a link
Reference in a new issue