solv the issue with mouse poiter is hide, do not show the mousepointer when you are...
[reactos.git] / reactos / subsys / win32k / eng / mouse.c
index 5c62925..3bc769c 100644 (file)
-#include <ddk/ntddk.h>
-#include <win32k/dc.h>
-#include "../../drivers/input/include/mouse.h"
-#include "objects.h"
-
-BOOLEAN SafetySwitch = FALSE, SafetySwitch2 = FALSE, MouseEnabled = FALSE;
-LONG mouse_x, mouse_y;
-UINT mouse_width = 0, mouse_height = 0;
-
-INT MouseSafetyOnDrawStart(SURFOBJ *SurfObj, SURFGDI *SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2)
+/*
+ *  ReactOS W32 Subsystem
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$
+ *
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Mouse
+ * FILE:             subsys/win32k/eng/mouse.c
+ * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISION HISTORY:
+ *       06-06-2001  CSH  Created
+ */
+/* INCLUDES ******************************************************************/
+
+#include <w32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+INT INTERNAL_CALL
+MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
+                      LONG HazardY1, LONG HazardX2, LONG HazardY2)
+/*
+ * FUNCTION: Notify the mouse driver that drawing is about to begin in
+ * a rectangle on a particular surface.
+ */
 {
-  RECTL MouseRect;
   LONG tmp;
+  GDIDEVICE *ppdev;
+  GDIPOINTER *pgp;
+
+  ASSERT(SurfObj != NULL);
+
+  ppdev = GDIDEV(SurfObj);
+
+  if(ppdev == NULL)
+    {
+      return(FALSE);
+    }
+
+  pgp = &ppdev->Pointer;
+
+  if (SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+      pgp->Exclude.right == -1)
+    {
+      return(FALSE);
+    }
+
+  if (HazardX1 > HazardX2)
+    {
+      tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp;
+    }
+  if (HazardY1 > HazardY2)
+    {
+      tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
+    }
+
+  if (ppdev->SafetyRemoveLevel != 0)
+    {
+      ppdev->SafetyRemoveCount++;
+      return FALSE;
+    }
+
+ ppdev->SafetyRemoveCount++;
+
+  if (pgp->Exclude.right >= HazardX1
+      && pgp->Exclude.left <= HazardX2
+      && pgp->Exclude.bottom >= HazardY1
+      && pgp->Exclude.top <= HazardY2)
+    {
+      ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
+      if (pgp->MovePointer)
+        pgp->MovePointer(SurfObj, -1, -1, NULL);
+      else
+        EngMovePointer(SurfObj, -1, -1, NULL);
+    }
+
+  return(TRUE);
+}
 
-  if(SurfObj == NULL) return 0;
+INT INTERNAL_CALL
+MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
+/*
+ * FUNCTION: Notify the mouse driver that drawing has finished on a surface.
+ */
+{
+  GDIDEVICE *ppdev;
+  GDIPOINTER *pgp;
+
+  ASSERT(SurfObj != NULL);
+
+  ppdev = GDIDEV(SurfObj);
 
-  if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0;
+  if(ppdev == NULL)
+    {
+      return(FALSE);
+    }
 
-  if(HazardX1 > HazardX2) { tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; }
-  if(HazardY1 > HazardY2) { tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; }
+  pgp = &ppdev->Pointer;
 
-  if( (mouse_x + mouse_width >= HazardX1)  && (mouse_x <= HazardX2) &&
-      (mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2) )
+  if(SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+     pgp->Exclude.right == -1)
   {
-    SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
-    SafetySwitch = TRUE;
+    return FALSE;
   }
 
-  // Mouse is not allowed to move if GDI is busy drawing
-  SafetySwitch2 = TRUE;
+  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 1;
+  return(TRUE);
 }
 
-INT MouseSafetyOnDrawEnd(SURFOBJ *SurfObj, SURFGDI *SurfGDI)
+/* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
+
+VOID INTERNAL_CALL
+IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
 {
-  RECTL MouseRect;
+   GDIPOINTER *pgp;
+   POINTL pt;
 
-  if(SurfObj == NULL) return 0;
+   ASSERT(ppdev);
+   ASSERT(DestSurface);
 
-  if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0;
+   pgp = &ppdev->Pointer;
 
-  if(SafetySwitch == TRUE)
-  {
-    SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
-    SafetySwitch = FALSE;
-  }
+   if (!pgp->Enabled)
+   {
+      return;
+   }
 
-  SafetySwitch2 = FALSE;
+      
 
-  return 1;
+   pgp->Enabled = FALSE;
+
+   pt.x = pgp->Pos.x - pgp->HotSpot.x;
+   pt.y = pgp->Pos.y - pgp->HotSpot.y;
+   
+
+   if (pgp->SaveSurface != NULL)
+   {
+      RECTL DestRect;
+      POINTL SrcPoint;
+      SURFOBJ *SaveSurface;
+      SURFOBJ *MaskSurface;
+
+      DestRect.left = max(pt.x, 0);
+      DestRect.top = max(pt.y, 0);
+      DestRect.right = min(
+         pt.x + pgp->Size.cx,
+         DestSurface->sizlBitmap.cx);
+      DestRect.bottom = min(
+         pt.y + pgp->Size.cy,
+         DestSurface->sizlBitmap.cy);
+
+      SrcPoint.x = max(-pt.x, 0);
+      SrcPoint.y = max(-pt.y, 0);
+
+      if((SaveSurface = EngLockSurface(pgp->SaveSurface)))
+      {
+        if((MaskSurface = EngLockSurface(pgp->MaskSurface)))
+        {
+          IntEngBitBltEx(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
+                         &DestRect, &SrcPoint, &SrcPoint, NULL, NULL,
+                         ROP3_TO_ROP4(SRCCOPY), FALSE);
+          EngUnlockSurface(MaskSurface);
+        }
+        EngUnlockSurface(SaveSurface);
+      }
+   }
 }
 
-VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
+VOID INTERNAL_CALL
+IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
 {
-  ULONG i;
-  LONG mouse_cx = 0, mouse_cy = 0;
-/*  HDC hDC = RetrieveDisplayHDC();
-  PDC dc = DC_HandleToPtr(hDC);
-  PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
-  PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
-  RECTL MouseRect; */
-
-  PDEVICE_OBJECT ClassDeviceObject = NULL;
-  PFILE_OBJECT FileObject = NULL;
-  NTSTATUS status;
-  UNICODE_STRING ClassName;
-  IO_STATUS_BLOCK ioStatus;
-  KEVENT event;
-  PIRP irp;
-
-  // Compile the total mouse movement change
-  for (i=0; i<InputCount; i++)
-  {
-    mouse_cx += Data[i].LastX;
-    mouse_cy += Data[i].LastY;
-  }
+   GDIPOINTER *pgp;
+   SURFOBJ *SaveSurface;
+   POINTL pt;
 
-  if((mouse_cx != 0) || (mouse_cy != 0))
-  {
-    mouse_x += mouse_cx;
-    mouse_y += mouse_cy;
+   ASSERT(ppdev);
+   ASSERT(DestSurface);
 
-    if(mouse_x < 0) mouse_x = 0;
-    if(mouse_y < 0) mouse_y = 0;
-    if(mouse_x > 620) mouse_x = 620;
-    if(mouse_y > 460) mouse_y = 460;
+   pgp = &ppdev->Pointer;
 
-    if((SafetySwitch == FALSE) && (SafetySwitch2 == FALSE)) ;
-/*      SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); */
-  }
+   if (pgp->Enabled)
+   {
+      return;
+   }
+   
+   if (pgp->ShowPointer == 1)
+   {
+      return ;
+   }
+
+
+   pgp->Enabled = TRUE;
+
+   pt.x = pgp->Pos.x - pgp->HotSpot.x;
+   pt.y = pgp->Pos.y - pgp->HotSpot.y;
+
+   /*
+    * Copy the pixels under the cursor to temporary surface.
+    */
+
+   if (pgp->SaveSurface != NULL &&
+       (SaveSurface = EngLockSurface(pgp->SaveSurface)))
+   {
+      RECTL DestRect;
+      POINTL SrcPoint;
+
+      SrcPoint.x = max(pt.x, 0);
+      SrcPoint.y = max(pt.y, 0);
+
+      DestRect.left = SrcPoint.x - pt.x;
+      DestRect.top = SrcPoint.y - pt.y;
+      DestRect.right = min(
+         pgp->Size.cx,
+         DestSurface->sizlBitmap.cx - pt.x);
+      DestRect.bottom = min(
+         pgp->Size.cy,
+         DestSurface->sizlBitmap.cy - pt.y);
+
+      IntEngBitBltEx(SaveSurface, DestSurface, NULL, NULL, NULL,
+                     &DestRect, &SrcPoint, NULL, NULL, NULL,
+                     ROP3_TO_ROP4(SRCCOPY), FALSE);
+      EngUnlockSurface(SaveSurface);
+   }
+
+   /*
+    * Blit the cursor on the screen.
+    */
+
+   {
+      RECTL DestRect;
+      POINTL SrcPoint;
+      SURFOBJ *ColorSurf;
+      SURFOBJ *MaskSurf = NULL;
+
+      DestRect.left = max(pt.x, 0);
+      DestRect.top = max(pt.y, 0);
+      DestRect.right = min(
+         pt.x + pgp->Size.cx,
+         DestSurface->sizlBitmap.cx);
+      DestRect.bottom = min(
+         pt.y + pgp->Size.cy,
+         DestSurface->sizlBitmap.cy);
+
+      SrcPoint.x = max(-pt.x, 0);
+      SrcPoint.y = max(-pt.y, 0);
+
+      if (pgp->MaskSurface)
+        MaskSurf = EngLockSurface(pgp->MaskSurface);
+
+      if (MaskSurf != NULL)
+      {
+        if (pgp->ColorSurface != NULL)
+        {
+           if((ColorSurf = EngLockSurface(pgp->ColorSurface)))
+           {
+             IntEngBitBltEx(DestSurface, ColorSurf, MaskSurf, NULL,
+                            pgp->XlateObject, &DestRect, &SrcPoint, &SrcPoint,
+                            NULL, NULL, R4_MASK, FALSE);
+             EngUnlockSurface(ColorSurf);
+           }
+        }
+        else
+        {
+           IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+                          &DestRect, &SrcPoint, NULL, NULL, NULL,
+                          ROP3_TO_ROP4(SRCAND), FALSE);
+           SrcPoint.y += pgp->Size.cy;
+           IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+                          &DestRect, &SrcPoint, NULL, NULL, NULL,
+                          ROP3_TO_ROP4(SRCINVERT), FALSE);
+        }
+        EngUnlockSurface(MaskSurf);
+      }
+   }
 }
 
-NTSTATUS ConnectMouseClassDriver()
+/*
+ * @implemented
+ */
+
+ULONG STDCALL
+EngSetPointerShape(
+   IN SURFOBJ *pso,
+   IN SURFOBJ *psoMask,
+   IN SURFOBJ *psoColor,
+   IN XLATEOBJ *pxlo,
+   IN LONG xHot,
+   IN LONG yHot,
+   IN LONG x,
+   IN LONG y,
+   IN RECTL *prcl,
+   IN FLONG fl)
 {
-   PDEVICE_OBJECT ClassDeviceObject = NULL;
-   PFILE_OBJECT FileObject = NULL;
-   NTSTATUS status;
-   UNICODE_STRING ClassName = UNICODE_STRING_INITIALIZER(L"\\Device\\MouseClass");
-   IO_STATUS_BLOCK ioStatus;
-   KEVENT event;
-   PIRP irp;
-   GDI_INFORMATION GDIInformation;
+   GDIDEVICE *ppdev;
+   SURFOBJ *TempSurfObj;
+   GDIPOINTER *pgp;
+
+   ASSERT(pso);
 
-   status = IoGetDeviceObjectPointer(&ClassName, FILE_READ_ATTRIBUTES, &FileObject, &ClassDeviceObject);
+   ppdev = GDIDEV(pso);
+   pgp = &ppdev->Pointer;
 
-   if(status != STATUS_SUCCESS)
+   IntHideMousePointer(ppdev, pso);
+
+   if (pgp->ColorSurface != NULL)
    {
-      DbgPrint("Win32k: Could not connect to mouse class driver\n");
-      return status;
+      /* FIXME: Is this really needed? */
+      if((TempSurfObj = EngLockSurface(pgp->ColorSurface)))
+      {
+        EngFreeMem(TempSurfObj->pvBits);
+        TempSurfObj->pvBits = 0;
+        EngUnlockSurface(TempSurfObj);
+      }
+
+      EngDeleteSurface(pgp->ColorSurface);
+      pgp->MaskSurface = NULL;
    }
 
-   // Connect our callback to the class driver
+   if (pgp->MaskSurface != NULL)
+   {
+      /* FIXME: Is this really needed? */
+      if((TempSurfObj = EngLockSurface(pgp->MaskSurface)))
+      {
+        EngFreeMem(TempSurfObj->pvBits);
+        TempSurfObj->pvBits = 0;
+        EngUnlockSurface(TempSurfObj);
+      }
+
+      EngDeleteSurface(pgp->MaskSurface);
+      pgp->MaskSurface = NULL;
+   }
+
+   if (pgp->SaveSurface != NULL)
+   {
+      EngDeleteSurface(pgp->SaveSurface);
+      pgp->SaveSurface = NULL;
+   }
+
+   if (pgp->XlateObject != NULL)
+   {
+      EngDeleteXlate(pgp->XlateObject);
+      pgp->XlateObject = NULL;
+   }
+
+   /*
+    * See if we are being asked to hide the pointer.
+    */
+
+   if (psoMask == NULL)
+   {
+      return SPS_ACCEPT_NOEXCLUDE;
+   }
 
-   KeInitializeEvent(&event, NotificationEvent, FALSE);
+   pgp->HotSpot.x = xHot;
+   pgp->HotSpot.y = yHot;
 
-   GDIInformation.CallBack = MouseGDICallBack;
+   /* Actually this should be set by 'the other side', but it would be
+    * done right after this. It helps IntShowMousePointer. */
+   if (x != -1)
+   {
+     pgp->Pos.x = x;
+     pgp->Pos.y = y;
+   }
 
-   irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
-      ClassDeviceObject, &GDIInformation, sizeof(CLASS_INFORMATION), NULL, 0, TRUE, &event, &ioStatus);
+   pgp->Size.cx = abs(psoMask->lDelta) << 3;
+   pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
 
-   status = IoCallDriver(ClassDeviceObject, irp);
+   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,
+         psoColor->lDelta, psoColor->iBitmapFormat,
+         psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
+   }
+   else
+   {
+      pgp->ColorSurface = NULL;
+   }
 
-   if (status == STATUS_PENDING) {
-      KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
-   } else {
-      ioStatus.Status = status;
+   {
+      SIZEL Size;
+      PBYTE Bits;
+
+      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,
+         psoMask->lDelta, psoMask->iBitmapFormat,
+         psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
    }
 
-   return ioStatus.Status;
+   /*
+    * 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.
+    */
+
+   {
+      LONG lDelta;
+
+      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;
+      }
+
+      pgp->SaveSurface = (HSURF)EngCreateBitmap(
+         pgp->Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
+   }
+
+   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;
 }
+
 /*
-void TestMouse()
+ * @implemented
+ */
+
+VOID STDCALL
+EngMovePointer(
+   IN SURFOBJ *pso,
+   IN LONG x,
+   IN LONG y,
+   IN RECTL *prcl)
 {
-  HDC hDC = RetrieveDisplayHDC();
-  PDC dc = DC_HandleToPtr(hDC);
-  PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
-  PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
-  BOOL txt;
-  int i;
-
-  BRUSHOBJ Brush;
-  HBITMAP hMouseSurf;
-  PSURFOBJ MouseSurf;
-  SIZEL MouseSize;
-  POINTL ZeroPoint;
-  RECTL MouseRect;
-
-  // Draw a test mouse cursor
-  mouse_width  = 16;
-  mouse_height = 16;
-
-  // Draw transparent colored rectangle
-  Brush.iSolidColor = 5;
-  for (i = 0; i < 17; i++)
-    EngLineTo(SurfObj, NULL, &Brush, 0, i, 17, i, NULL, 0);
-
-  // Draw white interior
-  Brush.iSolidColor = 15;
-  for (i = 1; i < 16; i++)
-    EngLineTo(SurfObj, NULL, &Brush, 0, i-1, 16-i, i-1, NULL, 0);
-
-  // Draw black outline
-  Brush.iSolidColor = 0;
-  EngLineTo(SurfObj, NULL, &Brush, 0, 0, 15, 0, NULL, 0);
-  EngLineTo(SurfObj, NULL, &Brush, 0, 16, 15, 0, NULL, 0);
-  EngLineTo(SurfObj, NULL, &Brush, 0, 15, 0, 0, NULL, 0);
-
-  // Create the bitmap for the mouse cursor data
-  MouseSize.cx = 16;
-  MouseSize.cy = 16;
-  hMouseSurf = EngCreateBitmap(MouseSize, 16, BMF_4BPP, 0, NULL);
-  MouseSurf = (PSURFOBJ)AccessUserObject(hMouseSurf);
-
-  // Capture the cursor we drew in the mouse cursor buffer
-  ZeroPoint.x = 0;
-  ZeroPoint.y = 0;
-  MouseRect.top = 0;
-  MouseRect.left = 0;
-  MouseRect.bottom = 16;
-  MouseRect.right = 16;
-  EngBitBlt(MouseSurf, SurfObj, NULL, NULL, NULL, &MouseRect, &ZeroPoint, NULL, NULL, NULL, 0);
-  SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 50, 50, &MouseRect, 0);
-
-  // Connect the mouse class driver to the GDI
-  mouse_x = 50;
-  mouse_y = 50;
-  ConnectMouseClassDriver();
-  MouseEnabled = TRUE;
+   GDIDEVICE *ppdev;
+   GDIPOINTER *pgp;
+
+   ASSERT(pso);
+
+   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;
+
 }
-*/
+
+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 */