Author: tkreuzer
Date: Fri Aug 27 10:57:54 2010
New Revision: 48630
URL:
http://svn.reactos.org/svn/reactos?rev=48630&view=rev
Log:
[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.
Modified:
trunk/reactos/subsystems/win32/win32k/eng/mouse.c
Modified: trunk/reactos/subsystems/win32/win32k/eng/mouse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/mouse.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/mouse.c [iso-8859-1] Fri Aug 27 10:57:54
2010
@@ -208,6 +208,9 @@
}
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;
@@ -318,42 +321,117 @@
{
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 @@
pgp->psurfColor = NULL;
}
+ /* Free old mask bitmap */
if (pgp->psurfMask)
{
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
@@ -368,7 +447,8 @@
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 @@
/* 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 @@
}
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;
}
/*