-/*
+/*
* PROJECT: ReactOS win32 subsystem
* PURPOSE: Mouse pointer functions
* FILE: subsystems/win32k/eng/mouse.c
*/
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
+BOOL
+APIENTRY
+EngSetPointerTag(
+ IN HDEV hdev,
+ IN SURFOBJ *psoMask,
+ IN SURFOBJ *psoColor,
+ IN XLATEOBJ *pxlo,
+ IN FLONG fl)
+{
+ // This function is obsolete for Windows 2000 and later.
+ // This function is still supported, but always returns FALSE.
+ // www.osr.com/ddk/graphics/gdifncs_4yav.htm
+ return FALSE;
+}
+
/*
* FUNCTION: Notify the mouse driver that drawing is about to begin in
* a rectangle on a particular surface.
*/
INT INTERNAL_CALL
MouseSafetyOnDrawStart(
- SURFOBJ *pso,
+ PPDEVOBJ ppdev,
LONG HazardX1,
LONG HazardY1,
LONG HazardX2,
LONG HazardY2)
{
LONG tmp;
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = GDIDEV(pso);
- if (ppdev == NULL)
- {
- return FALSE;
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
}
if (pgp->Exclude.right >= HazardX1
- && pgp->Exclude.left <= HazardX2
- && pgp->Exclude.bottom >= HazardY1
- && pgp->Exclude.top <= HazardY2)
+ && pgp->Exclude.left <= HazardX2
+ && pgp->Exclude.bottom >= HazardY1
+ && pgp->Exclude.top <= HazardY2)
{
ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
- ppdev->pfnMovePointer(pso, -1, -1, NULL);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj, -1, -1, NULL);
}
return(TRUE);
*/
INT INTERNAL_CALL
MouseSafetyOnDrawEnd(
- SURFOBJ *pso)
+ PPDEVOBJ ppdev)
{
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = (PDEVOBJ*)pso->hdev;
-
- if (ppdev == NULL)
- {
- return(FALSE);
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
return FALSE;
}
- ppdev->pfnMovePointer(pso, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj,
+ gpsi->ptCursor.x,
+ gpsi->ptCursor.y,
+ &pgp->Exclude);
ppdev->SafetyRemoveLevel = 0;
pgp->Enabled = FALSE;
- /* The mouse is hide from ShowCours and it is frist ?? */
- if (pgp->ShowPointer < 0)
- {
- return;
- }
-
if (!pgp->psurfSave)
{
DPRINT1("No SaveSurface!\n");
ptlSave.x = rclDest.left - pt.x;
ptlSave.y = rclDest.top - pt.y;
- IntEngBitBltEx(psoDest,
- &pgp->psurfSave->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclDest,
- &ptlSave,
- &ptlSave,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfSave->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclDest,
+ &ptlSave,
+ &ptlSave,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
}
VOID
pgp->Enabled = TRUE;
- /* Do not blt the pointer, if it is hidden */
- if (pgp->ShowPointer < 0)
- {
- return ;
- }
+ /* Check if we have any mouse pointer */
+ if (!pgp->psurfSave) return;
/* Calculate pointer coordinates */
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
rclPointer.bottom = min(pgp->Size.cy, psoDest->sizlBitmap.cy - pt.y);
/* Copy the pixels under the cursor to temporary surface. */
- IntEngBitBltEx(&pgp->psurfSave->SurfObj,
- psoDest,
- NULL,
- NULL,
- NULL,
- &rclPointer,
- (POINTL*)&rclSurf,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(&pgp->psurfSave->SurfObj,
+ psoDest,
+ NULL,
+ NULL,
+ NULL,
+ &rclPointer,
+ (POINTL*)&rclSurf,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfColor->SurfObj,
- &pgp->psurfMask->SurfObj,
- NULL,
- pgp->XlateObject,
- &rclSurf,
- (POINTL*)&rclPointer,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- R4_MASK,
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
+
+ IntEngBitBlt(psoDest,
+ &pgp->psurfColor->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
else
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- pgp->XlateObject,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCAND),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
rclPointer.top += pgp->Size.cy;
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- pgp->XlateObject,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCINVERT),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
}
{
PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- PBYTE Bits;
- SIZEL Size;
- LONG lDelta;
- HBITMAP hbmp;
+ 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 = WIDTH_BYTES_ALIGN32(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)
+ {
+ 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)
{
- /* FIXME: let GDI allocate/free memory */
- EngFreeMem(pgp->psurfColor->SurfObj.pvBits);
- pgp->psurfColor->SurfObj.pvBits = 0;
-
EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
SURFACE_ShareUnlockSurface(pgp->psurfColor);
pgp->psurfColor = NULL;
}
+ /* Free old mask bitmap */
if (pgp->psurfMask)
{
- /* FIXME: let GDI allocate/free memory */
- EngFreeMem(pgp->psurfMask->SurfObj.pvBits);
- pgp->psurfMask->SurfObj.pvBits = 0;
-
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
SURFACE_ShareUnlockSurface(pgp->psurfMask);
pgp->psurfMask = NULL;
}
- if (pgp->psurfSave != NULL)
+ /* Free old save bitmap */
+ if (pgp->psurfSave)
{
EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr);
SURFACE_ShareUnlockSurface(pgp->psurfSave);
pgp->psurfSave = NULL;
}
- if (pgp->XlateObject != NULL)
- {
- EngDeleteXlate(pgp->XlateObject);
- pgp->XlateObject = NULL;
- }
-
/* See if we are being asked to hide the pointer. */
- if (psoMask == NULL)
+ 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;
+ pgp->Size = sizel;
if (x != -1)
{
ppdev->ptlPointer.x = x;
ppdev->ptlPointer.y = y;
- }
-
- pgp->Size.cx = abs(psoMask->lDelta) << 3;
- pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
-
- if (psoColor != NULL)
- {
- /* FIXME: let GDI allocate/free memory */
- Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE);
- if (Bits == NULL)
- {
- return SPS_ERROR;
- }
-
- memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
-
- hbmp = EngCreateBitmap(pgp->Size,
- psoColor->lDelta,
- psoColor->iBitmapFormat,
- psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN,
- Bits);
-
- pgp->psurfColor = SURFACE_ShareLockSurface(hbmp);
- }
- else
- {
- pgp->psurfColor = NULL;
- }
-
- Size.cx = pgp->Size.cx;
- Size.cy = pgp->Size.cy << 1;
- Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE);
- if (Bits == NULL)
- {
- return SPS_ERROR;
- }
-
- memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
-
- hbmp = EngCreateBitmap(Size,
- psoMask->lDelta,
- psoMask->iBitmapFormat,
- psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN,
- Bits);
-
- pgp->psurfMask = SURFACE_ShareLockSurface(hbmp);
- /* Create an XLATEOBJ that will be used for drawing masks.
- * FIXME: We should get this in pxlo parameter! */
- if (pxlo == NULL)
- {
- HPALETTE BWPalette, DestPalette;
- ULONG BWColors[] = {0, 0xFFFFFF};
-
- BWPalette = EngCreatePalette(PAL_INDEXED, sizeof(BWColors) / sizeof(ULONG),
- BWColors, 0, 0, 0);
-
- DestPalette = ppdev->DevInfo.hpalDefault;
- pgp->XlateObject = IntEngCreateXlate(0, PAL_INDEXED,
- DestPalette, BWPalette);
- EngDeletePalette(BWPalette);
- }
- else
- {
- pgp->XlateObject = pxlo;
- }
-
- /* Create surface for saving the pixels under the cursor. */
- switch (pso->iBitmapFormat)
- {
- case BMF_1BPP:
- lDelta = pgp->Size.cx >> 3;
- break;
- case BMF_4BPP:
- lDelta = pgp->Size.cx >> 1;
- break;
- case BMF_8BPP:
- lDelta = pgp->Size.cx;
- break;
- case BMF_16BPP:
- lDelta = pgp->Size.cx << 1;
- break;
- case BMF_24BPP:
- lDelta = pgp->Size.cx * 3;
- break;
- case BMF_32BPP:
- lDelta = pgp->Size.cx << 2;
- break;
- default:
- lDelta = 0;
- break;
- }
-
- hbmp = EngCreateBitmap(pgp->Size,
- lDelta,
- pso->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT,
- NULL);
-
- pgp->psurfSave = SURFACE_ShareLockSurface(hbmp);
-
- if (x != -1)
- {
IntShowMousePointer(ppdev, pso);
if (prcl != NULL)
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- } else if (prcl != NULL)
+ }
+ else if (prcl != NULL)
+ {
prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
+ }
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;
}
/*
if (prcl != NULL)
{
prcl->left = x - pgp->HotSpot.x;
- prcl->top = y - pgp->HotSpot.x;
+ prcl->top = y - pgp->HotSpot.y;
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- } else if (prcl != NULL)
+ }
+ else if (prcl != NULL)
+ {
prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
-}
-
-VOID APIENTRY
-IntEngMovePointer(
- IN SURFOBJ *pso,
- IN LONG x,
- IN LONG y,
- IN RECTL *prcl)
-{
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
- PPDEVOBJ ppdev = (PPDEVOBJ)pso->hdev;
-
- SURFACE_LockBitmapBits(psurf);
- ppdev->pfnMovePointer(pso, x, y, prcl);
- SURFACE_UnlockBitmapBits(psurf);
+ }
}
ULONG APIENTRY
IN FLONG fl)
{
ULONG ulResult = SPS_DECLINE;
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
PFN_DrvSetPointerShape pfnSetPointerShape;
PPDEVOBJ ppdev = GDIDEV(pso);
pfnSetPointerShape = GDIDEVFUNCS(pso).SetPointerShape;
- SURFACE_LockBitmapBits(psurf);
if (pfnSetPointerShape)
{
ulResult = pfnSetPointerShape(pso,
ppdev->pfnMovePointer = EngMovePointer;
}
- SURFACE_UnlockBitmapBits(psurf);
+ return ulResult;
+}
+
+ULONG
+NTAPI
+GreSetPointerShape(
+ HDC hdc,
+ HBITMAP hbmMask,
+ HBITMAP hbmColor,
+ LONG xHot,
+ LONG yHot,
+ LONG x,
+ LONG y)
+{
+ PDC pdc;
+ PSURFACE psurf, psurfMask, psurfColor;
+ EXLATEOBJ exlo;
+ FLONG fl = 0;
+ ULONG ulResult = 0;
+
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ DPRINT1("Failed to lock the DC.\n");
+ return 0;
+ }
+
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
+ /* We're not sure DC surface is the good one */
+ psurf = pdc->ppdev->pSurface;
+ if (!psurf)
+ {
+ DPRINT1("DC has no surface.\n");
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+ DC_UnlockDc(pdc);
+ return 0;
+ }
+
+ /* Lock the mask bitmap */
+ if (hbmMask)
+ psurfMask = SURFACE_ShareLockSurface(hbmMask);
+ else
+ psurfMask = NULL;
+
+ /* Check for color bitmap */
+ if (hbmColor)
+ {
+ /* We have one, lock it */
+ psurfColor = SURFACE_ShareLockSurface(hbmColor);
+
+ if (psurfColor)
+ {
+ /* Create an XLATEOBJ, no mono support */
+ EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurf->ppal, 0, 0, 0);
+ }
+ }
+ else
+ psurfColor = NULL;
+
+ /* Call the driver or eng function */
+ ulResult = IntEngSetPointerShape(&psurf->SurfObj,
+ psurfMask ? &psurfMask->SurfObj : NULL,
+ psurfColor ? &psurfColor->SurfObj : NULL,
+ psurfColor ? &exlo.xlo : NULL,
+ xHot,
+ yHot,
+ x,
+ y,
+ &pdc->ppdev->Pointer.Exclude,
+ fl | SPS_CHANGE);
+
+ /* Cleanup */
+ if (psurfColor)
+ {
+ EXLATEOBJ_vCleanup(&exlo);
+ SURFACE_ShareUnlockSurface(psurfColor);
+ }
+
+ if (psurfMask)
+ SURFACE_ShareUnlockSurface(psurfMask);
+
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+ /* Return result */
return ulResult;
}
+VOID
+NTAPI
+GreMovePointer(
+ HDC hdc,
+ LONG x,
+ LONG y)
+{
+ PDC pdc;
+ PRECTL prcl;
+
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ DPRINT1("Failed to lock the DC.\n");
+ return;
+ }
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
+
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
+
+ /* Check if we need to move it */
+ if(pdc->ppdev->SafetyRemoveLevel == 0)
+ {
+ /* Store the cursor exclude position in the PDEV */
+ prcl = &pdc->ppdev->Pointer.Exclude;
+
+ /* Call Eng/Drv function */
+ pdc->ppdev->pfnMovePointer(&pdc->ppdev->pSurface->SurfObj, x, y, prcl);
+ }
+
+ /* Release PDEV lock */
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+}
+
+
/* EOF */