Commit a patch for hide and show mouse. (forget it)
[reactos.git] / reactos / subsys / win32k / eng / mouse.c
index 99ffdeb..9a89616 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: mouse.c,v 1.78 2004/12/12 01:40:36 weiden Exp $
+/* $Id$
  *
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Mouse
  *       06-06-2001  CSH  Created
  */
 /* INCLUDES ******************************************************************/
+
 #include <w32k.h>
 
+#define NDEBUG
+#include <debug.h>
+
 /* FUNCTIONS *****************************************************************/
 
 INT INTERNAL_CALL
@@ -41,20 +45,20 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
   LONG tmp;
   GDIDEVICE *ppdev;
   GDIPOINTER *pgp;
-  POINTL pt;
 
   ASSERT(SurfObj != NULL);
 
   ppdev = GDIDEV(SurfObj);
-  
+
   if(ppdev == NULL)
     {
       return(FALSE);
     }
-  
+
   pgp = &ppdev->Pointer;
 
-  if (SPS_ACCEPT_NOEXCLUDE == pgp->Status)
+  if (SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+      pgp->Exclude.right == -1)
     {
       return(FALSE);
     }
@@ -68,19 +72,20 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
       tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
     }
 
-  pt.x = pgp->Pos.x - pgp->HotSpot.x;
-  pt.y = pgp->Pos.y - pgp->HotSpot.y;
+  if (ppdev->SafetyRemoveLevel != 0)
+    {
+      ppdev->SafetyRemoveCount++;
+      return FALSE;
+    }
+
+ ppdev->SafetyRemoveCount++;
 
-  if (pt.x + pgp->Size.cx >= HazardX1
-      && pt.x <= HazardX2
-      && pt.y + pgp->Size.cy >= HazardY1
-      && pt.y <= HazardY2)
+  if (pgp->Exclude.right >= HazardX1
+      && pgp->Exclude.left <= HazardX2
+      && pgp->Exclude.bottom >= HazardY1
+      && pgp->Exclude.top <= HazardY2)
     {
-      if (0 != pgp->SafetyRemoveCount++)
-        {
-          return FALSE;
-        }
-      pgp->SafetySwitch = TRUE;
+      ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
       if (pgp->MovePointer)
         pgp->MovePointer(SurfObj, -1, -1, NULL);
       else
@@ -102,7 +107,7 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
   ASSERT(SurfObj != NULL);
 
   ppdev = GDIDEV(SurfObj);
-  
+
   if(ppdev == NULL)
     {
       return(FALSE);
@@ -110,24 +115,22 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
 
   pgp = &ppdev->Pointer;
 
-  if(SPS_ACCEPT_NOEXCLUDE == pgp->Status)
+  if(SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+     pgp->Exclude.right == -1)
   {
     return FALSE;
   }
 
-  if (pgp->SafetySwitch)
-    {
-      if (1 < pgp->SafetyRemoveCount--)
-        {
-          /* Someone else removed it too, let them restore it */
-          return FALSE;
-        }
-      if (pgp->MovePointer)
-        pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL);
-      else
-        EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL);
-     pgp->SafetySwitch = FALSE;
-    }
+  if (--ppdev->SafetyRemoveCount >= ppdev->SafetyRemoveLevel)
+   {
+      return FALSE;
+   }
+  if (pgp->MovePointer)
+    pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
+  else
+    EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
+
+  ppdev->SafetyRemoveLevel = 0;
 
   return(TRUE);
 }
@@ -150,15 +153,25 @@ IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
       return;
    }
 
+      
+
    pgp->Enabled = FALSE;
    
-   if(pgp->Pos.x == -1)
+   /*
+    * The mouse is hide from ShowCours and it is frist ?? 
+    */
+   if (pgp->ShowPointer < 0)
    {
-      return;
+     return ;
    }
    
+
+  /*
+   *  Hide the cours
+   */
    pt.x = pgp->Pos.x - pgp->HotSpot.x;
    pt.y = pgp->Pos.y - pgp->HotSpot.y;
+   
 
    if (pgp->SaveSurface != NULL)
    {
@@ -183,8 +196,9 @@ IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
       {
         if((MaskSurface = EngLockSurface(pgp->MaskSurface)))
         {
-          EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
-                    &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY);
+          IntEngBitBltEx(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
+                         &DestRect, &SrcPoint, &SrcPoint, NULL, NULL,
+                         ROP3_TO_ROP4(SRCCOPY), FALSE);
           EngUnlockSurface(MaskSurface);
         }
         EngUnlockSurface(SaveSurface);
@@ -208,9 +222,17 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
    {
       return;
    }
-
+     
    pgp->Enabled = TRUE;
    
+   /*
+    * Do not blt the mouse if it in hide 
+    */
+   if (pgp->ShowPointer < 0)
+   {
+     return ;
+   }
+   
    pt.x = pgp->Pos.x - pgp->HotSpot.x;
    pt.y = pgp->Pos.y - pgp->HotSpot.y;
 
@@ -236,12 +258,14 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
          pgp->Size.cy,
          DestSurface->sizlBitmap.cy - pt.y);
 
-      EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL,
-                &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY);
+      IntEngBitBltEx(SaveSurface, DestSurface, NULL, NULL, NULL,
+                     &DestRect, &SrcPoint, NULL, NULL, NULL,
+                     ROP3_TO_ROP4(SRCCOPY), FALSE);
       EngUnlockSurface(SaveSurface);
    }
 
-   /*
+
+   /*   
     * Blit the cursor on the screen.
     */
 
@@ -249,7 +273,7 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
       RECTL DestRect;
       POINTL SrcPoint;
       SURFOBJ *ColorSurf;
-      SURFOBJ *MaskSurf;
+      SURFOBJ *MaskSurf = NULL;
 
       DestRect.left = max(pt.x, 0);
       DestRect.top = max(pt.y, 0);
@@ -263,25 +287,31 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
       SrcPoint.x = max(-pt.x, 0);
       SrcPoint.y = max(-pt.y, 0);
 
-      MaskSurf = EngLockSurface(pgp->MaskSurface);
+
+      if (pgp->MaskSurface)
+        MaskSurf = EngLockSurface(pgp->MaskSurface);
+
       if (MaskSurf != NULL)
       {
         if (pgp->ColorSurface != NULL)
         {
            if((ColorSurf = EngLockSurface(pgp->ColorSurface)))
            {
-             EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, pgp->XlateObject,
-                       &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC);
-             EngUnlockSurface(ColorSurf);
+                IntEngBitBltEx(DestSurface, ColorSurf, MaskSurf, NULL,
+                            pgp->XlateObject, &DestRect, &SrcPoint, &SrcPoint,
+                            NULL, NULL, R4_MASK, FALSE);
+                EngUnlockSurface(ColorSurf);
            }
         }
         else
-        {
-           EngBitBlt(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
-                     &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND);
+        {         
+           IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+                          &DestRect, &SrcPoint, NULL, NULL, NULL,
+                          ROP3_TO_ROP4(SRCAND), FALSE);
            SrcPoint.y += pgp->Size.cy;
-           EngBitBlt(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
-                     &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT);
+           IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+                          &DestRect, &SrcPoint, NULL, NULL, NULL,
+                          ROP3_TO_ROP4(SRCINVERT), FALSE);         
         }
         EngUnlockSurface(MaskSurf);
       }
@@ -368,25 +398,27 @@ EngSetPointerShape(
    pgp->HotSpot.x = xHot;
    pgp->HotSpot.y = yHot;
 
-   pgp->Pos.x = x;
-   pgp->Pos.y = y;
-   pgp->Size.cx = abs(psoMask->lDelta) << 3;
-   pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
-
-   if (prcl != NULL)
+   /* Actually this should be set by 'the other side', but it would be
+    * done right after this. It helps IntShowMousePointer. */
+   if (x != -1)
    {
-      /* FIXME - right rectangle when x == -1? */
-      prcl->left = pgp->Pos.x - pgp->HotSpot.x;
-      prcl->top = pgp->Pos.y - pgp->HotSpot.x;
-      prcl->right = prcl->left + pgp->Size.cx;
-      prcl->bottom = prcl->top + pgp->Size.cy;
+     pgp->Pos.x = x;
+     pgp->Pos.y = y;
    }
 
+   pgp->Size.cx = abs(psoMask->lDelta) << 3;
+   pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
+
    if (psoColor != NULL)
    {
       PBYTE Bits;
 
       Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE);
+      if (Bits == NULL)
+      {
+          return SPS_ERROR;
+      }
+      
       memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
 
       pgp->ColorSurface = (HSURF)EngCreateBitmap(pgp->Size,
@@ -405,6 +437,11 @@ EngSetPointerShape(
       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);
 
       pgp->MaskSurface = (HSURF)EngCreateBitmap(Size,
@@ -474,7 +511,16 @@ EngSetPointerShape(
    if(x != -1)
    {
      IntShowMousePointer(ppdev, pso);
-   }
+
+     if (prcl != NULL)
+     {
+       prcl->left = x - pgp->HotSpot.x;
+       prcl->top = y - pgp->HotSpot.x;
+       prcl->right = prcl->left + pgp->Size.cx;
+       prcl->bottom = prcl->top + pgp->Size.cy;
+     }
+   } else if (prcl != NULL)
+     prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
 
    return SPS_ACCEPT_EXCLUDE;
 }
@@ -498,26 +544,48 @@ EngMovePointer(
    ppdev = GDIDEV(pso);
 
    ASSERT(ppdev);
-   
+
    pgp = &ppdev->Pointer;
-   
-   
+
    IntHideMousePointer(ppdev, pso);
    if (x != -1)
    {
+     /* Actually this should be set by 'the other side', but it would be
+      * done right after this. It helps IntShowMousePointer. */
      pgp->Pos.x = x;
      pgp->Pos.y = y;
      IntShowMousePointer(ppdev, pso);
-   }
+     if (prcl != NULL)
+     {
+       prcl->left = x - pgp->HotSpot.x;
+       prcl->top = y - pgp->HotSpot.x;
+       prcl->right = prcl->left + pgp->Size.cx;
+       prcl->bottom = prcl->top + pgp->Size.cy;
+     }
+   } else if (prcl != NULL)
+     prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
 
-   if (prcl != NULL)
-   {
-      /* FIXME - right rectangle when x == -1? */
-      prcl->left = pgp->Pos.x - pgp->HotSpot.x;
-      prcl->top = pgp->Pos.y - pgp->HotSpot.x;
-      prcl->right = prcl->left + pgp->Size.cx;
-      prcl->bottom = prcl->top + pgp->Size.cy;
-   }
+}
+
+VOID STDCALL
+IntEngMovePointer(
+   IN SURFOBJ *SurfObj,
+   IN LONG x,
+   IN LONG y,
+   IN RECTL *prcl)
+{
+  BITMAPOBJ *BitmapObj = CONTAINING_RECORD(SurfObj, BITMAPOBJ, SurfObj);
+
+  BITMAPOBJ_LockBitmapBits(BitmapObj);
+  if (GDIDEV(SurfObj)->Pointer.MovePointer)
+    {
+    GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, x, y, prcl);
+    }
+  else
+    {
+    EngMovePointer(SurfObj, x, y, prcl);
+    }
+  BITMAPOBJ_UnlockBitmapBits(BitmapObj);
 }
 
 /* EOF */