[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / eng / mouse.c
index 399a47c..b2db0e6 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * PROJECT:          ReactOS win32 subsystem
  * PURPOSE:          Mouse pointer functions
  * FILE:             subsystems/win32k/eng/mouse.c
@@ -9,36 +9,45 @@
  */
 /* 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;
 
@@ -68,12 +77,12 @@ MouseSafetyOnDrawStart(
     }
 
     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);
@@ -84,19 +93,12 @@ MouseSafetyOnDrawStart(
  */
 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;
 
@@ -110,7 +112,10 @@ MouseSafetyOnDrawEnd(
         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;
 
@@ -142,12 +147,6 @@ IntHideMousePointer(
 
     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");
@@ -166,18 +165,17 @@ IntHideMousePointer(
     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
@@ -200,11 +198,8 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
 
     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;
@@ -223,64 +218,72 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
     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));
     }
 }
 
@@ -302,169 +305,160 @@ EngSetPointerShape(
 {
     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)
@@ -474,10 +468,24 @@ EngSetPointerShape(
             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;
 }
 
 /*
@@ -512,27 +520,15 @@ EngMovePointer(
         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
@@ -549,13 +545,11 @@ IntEngSetPointerShape(
    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,
@@ -593,9 +587,135 @@ IntEngSetPointerShape(
         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 */