Exclusively lock surface bits before reading or writing them
Modified: trunk/reactos/include/win32k/bitmaps.h
Modified: trunk/reactos/subsys/win32k/eng/bitblt.c
Modified: trunk/reactos/subsys/win32k/eng/copybits.c
Modified: trunk/reactos/subsys/win32k/eng/gradient.c
Modified: trunk/reactos/subsys/win32k/eng/lineto.c
Modified: trunk/reactos/subsys/win32k/eng/mouse.c
Modified: trunk/reactos/subsys/win32k/eng/paint.c
Modified: trunk/reactos/subsys/win32k/eng/surface.c
Modified: trunk/reactos/subsys/win32k/eng/transblt.c
Modified: trunk/reactos/subsys/win32k/include/inteng.h
Modified: trunk/reactos/subsys/win32k/include/tags.h
Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c
Modified: trunk/reactos/subsys/win32k/ntuser/input.c
Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
Modified: trunk/reactos/subsys/win32k/objects/brush.c
Modified: trunk/reactos/subsys/win32k/objects/fillshap.c
Modified: trunk/reactos/subsys/win32k/objects/line.c
Modified: trunk/reactos/subsys/win32k/objects/polyfill.c
Modified: trunk/reactos/subsys/win32k/objects/region.c
Modified: trunk/reactos/subsys/win32k/objects/text.c

Modified: trunk/reactos/include/win32k/bitmaps.h
--- trunk/reactos/include/win32k/bitmaps.h	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/include/win32k/bitmaps.h	2005-06-20 08:31:48 UTC (rev 16143)
@@ -11,10 +11,12 @@
   SURFOBJ     SurfObj;
   FLONG	      flHooks;
   FLONG       flFlags;
-  SIZE        dimension;   /* For SetBitmapDimension(), do NOT use
-                              to get width/height of bitmap, use
-                              bitmap.bmWidth/bitmap.bmHeight for
-                              that */
+  SIZE        dimension;    /* For SetBitmapDimension(), do NOT use
+                               to get width/height of bitmap, use
+                               bitmap.bmWidth/bitmap.bmHeight for
+                               that */
+  PFAST_MUTEX BitsLock;     /* You need to hold this lock before you touch
+                               the actual bits in the bitmap */
 
   /* For device-independent bitmaps: */
   DIBSECTION *dib;
@@ -34,6 +36,11 @@
 #define  BITMAPOBJ_UnlockBitmap(pBMObj) EngUnlockSurface(&pBMObj->SurfObj)
 BOOL INTERNAL_CALL BITMAP_Cleanup(PVOID ObjectBody);
 
+BOOL INTERNAL_CALL BITMAPOBJ_InitBitsLock(BITMAPOBJ *pBMObj);
+#define BITMAPOBJ_LockBitmapBits(pBMObj) ExAcquireFastMutex((pBMObj)->BitsLock)
+#define BITMAPOBJ_UnlockBitmapBits(pBMObj) ExReleaseFastMutex((pBMObj)->BitsLock)
+void INTERNAL_CALL BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *pBMObj);
+
 INT     FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp);
 HBITMAP FASTCALL BITMAPOBJ_CopyBitmap (HBITMAP  hBitmap);
 INT     FASTCALL DIB_GetDIBWidthBytes (INT  width, INT  depth);

Modified: trunk/reactos/subsys/win32k/eng/bitblt.c
--- trunk/reactos/subsys/win32k/eng/bitblt.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/bitblt.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -526,30 +526,30 @@
 }
 
 BOOL STDCALL
-IntEngBitBlt(BITMAPOBJ *DestObj,
-             BITMAPOBJ *SourceObj,
-             BITMAPOBJ *MaskObj,
-             CLIPOBJ *ClipRegion,
-             XLATEOBJ *ColorTranslation,
-             RECTL *DestRect,
-             POINTL *SourcePoint,
-             POINTL *MaskOrigin,
-             BRUSHOBJ *Brush,
-             POINTL *BrushOrigin,
-             ROP4 Rop4)
+IntEngBitBltEx(SURFOBJ *DestSurf,
+               SURFOBJ *SourceSurf,
+               SURFOBJ *MaskSurf,
+               CLIPOBJ *ClipRegion,
+               XLATEOBJ *ColorTranslation,
+               RECTL *DestRect,
+               POINTL *SourcePoint,
+               POINTL *MaskOrigin,
+               BRUSHOBJ *Brush,
+               POINTL *BrushOrigin,
+               ROP4 Rop4,
+               BOOL RemoveMouse)
 {
   BOOLEAN ret;
   RECTL InputClippedRect;
   RECTL OutputRect;
   POINTL InputPoint;
   BOOLEAN UsesSource;
-  SURFOBJ *DestSurf;
-  SURFOBJ *SourceSurf = SourceObj ? &SourceObj->SurfObj : NULL;
-  SURFOBJ *MaskSurf = MaskObj ? &MaskObj->SurfObj : NULL;
+  BITMAPOBJ *DestObj;
+  BITMAPOBJ *SourceObj = NULL;
 
+  ASSERT(DestSurf);
+  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
   ASSERT(DestObj);
-  DestSurf = &DestObj->SurfObj;
-  ASSERT(DestSurf);
 
   InputClippedRect = *DestRect;
   if (InputClippedRect.right < InputClippedRect.left)
@@ -623,17 +623,27 @@
       OutputRect = InputClippedRect;
     }
 
-  if (UsesSource)
+  if (RemoveMouse)
     {
-    MouseSafetyOnDrawStart(SourceSurf, InputPoint.x, InputPoint.y,
-                           (InputPoint.x + abs(DestRect->right - DestRect->left)),
-			   (InputPoint.y + abs(DestRect->bottom - DestRect->top)));
+    BITMAPOBJ_LockBitmapBits(DestObj);
+
+    if (UsesSource)
+      {
+      if (SourceSurf != DestSurf)
+        {
+        SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
+        BITMAPOBJ_LockBitmapBits(SourceObj);
+        }
+      MouseSafetyOnDrawStart(SourceSurf, InputPoint.x, InputPoint.y,
+                             (InputPoint.x + abs(DestRect->right - DestRect->left)),
+  			   (InputPoint.y + abs(DestRect->bottom - DestRect->top)));
+      }
+    MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
+                           OutputRect.right, OutputRect.bottom);
     }
 
   /* No success yet */
   ret = FALSE;
-  MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
-                         OutputRect.right, OutputRect.bottom);
 
   /* Call the driver's DrvBitBlt if available */
   if (DestObj->flHooks & HOOK_BITBLT)
@@ -651,10 +661,19 @@
                       Rop4);
     }
 
-  MouseSafetyOnDrawEnd(DestSurf);
-  if (UsesSource)
+  if (RemoveMouse)
     {
-    MouseSafetyOnDrawEnd(SourceSurf);
+    MouseSafetyOnDrawEnd(DestSurf);
+    if (UsesSource)
+      {
+      MouseSafetyOnDrawEnd(SourceSurf);
+      if (SourceSurf != DestSurf)
+        {
+        BITMAPOBJ_UnlockBitmapBits(SourceObj);
+        }
+      }
+
+    BITMAPOBJ_UnlockBitmapBits(DestObj);
     }
 
   return ret;
@@ -786,9 +805,9 @@
 }
 
 BOOL STDCALL
-IntEngStretchBlt(BITMAPOBJ *DestObj,
-                 BITMAPOBJ *SourceObj,
-                 BITMAPOBJ *MaskObj,
+IntEngStretchBlt(SURFOBJ *DestSurf,
+                 SURFOBJ *SourceSurf,
+                 SURFOBJ *MaskSurf,
                  CLIPOBJ *ClipRegion,
                  XLATEOBJ *ColorTranslation,
                  RECTL *DestRect,
@@ -801,32 +820,37 @@
   BOOLEAN ret;
   COLORADJUSTMENT ca;
   POINT MaskOrigin;
-  SURFOBJ *DestSurf;
-  SURFOBJ *SourceSurf = SourceObj ? &SourceObj->SurfObj : NULL;
-  SURFOBJ *MaskSurf = MaskObj ? &MaskObj->SurfObj : NULL;
+  BITMAPOBJ *DestObj;
+  BITMAPOBJ *SourceObj = NULL;
 
+  ASSERT(DestSurf);
+  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
   ASSERT(DestObj);
-  DestSurf = &DestObj->SurfObj;
-  ASSERT(DestSurf);
 
   if (pMaskOrigin != NULL)
     {
       MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
     }
 
+  /* No success yet */
+  ret = FALSE;
+  ASSERT(DestRect);
+  BITMAPOBJ_LockBitmapBits(DestObj);
+  MouseSafetyOnDrawStart(DestSurf, DestRect->left, DestRect->top,
+                         DestRect->right, DestRect->bottom);
+
   if (NULL != SourceSurf)
     {
+    SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
     ASSERT(SourceRect);
+    if (SourceSurf != DestSurf)
+      {
+      BITMAPOBJ_LockBitmapBits(SourceObj);
+      }
     MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
                            SourceRect->right, SourceRect->bottom);
     }
 
-  /* No success yet */
-  ret = FALSE;
-  ASSERT(DestRect);
-  MouseSafetyOnDrawStart(DestSurf, DestRect->left, DestRect->top,
-                         DestRect->right, DestRect->bottom);
-
   /* Prepare color adjustment */
 
   /* Call the driver's DrvStretchBlt if available */
@@ -847,11 +871,16 @@
                           &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
     }
 
-  MouseSafetyOnDrawEnd(DestSurf);
   if (NULL != SourceSurf)
     {
     MouseSafetyOnDrawEnd(SourceSurf);
+    if (SourceSurf != DestSurf)
+      {
+      BITMAPOBJ_UnlockBitmapBits(SourceObj);
+      }
     }
+  MouseSafetyOnDrawEnd(DestSurf);
+  BITMAPOBJ_UnlockBitmapBits(DestObj);
 
   return ret;
 }
@@ -1147,7 +1176,7 @@
 }
 
 BOOL STDCALL
-IntEngMaskBlt(SURFOBJ *DestObj,
+IntEngMaskBlt(SURFOBJ *DestSurf,
               SURFOBJ *Mask,
               CLIPOBJ *ClipRegion,
               XLATEOBJ *DestColorTranslation,
@@ -1161,6 +1190,7 @@
   BOOLEAN ret;
   RECTL OutputRect;
   POINTL InputPoint;
+  BITMAPOBJ *DestObj;
 
   ASSERT(Mask);
 
@@ -1187,26 +1217,30 @@
 
   /* No success yet */
   ret = FALSE;
-  ASSERT(DestObj);
-  MouseSafetyOnDrawStart(DestObj, OutputRect.left, OutputRect.top,
+  ASSERT(DestSurf);
+  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
+
+  BITMAPOBJ_LockBitmapBits(DestObj);
+  MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
                          OutputRect.right, OutputRect.bottom);
 
   /* Dummy BitBlt to let driver know that it should flush its changes.
      This should really be done using a call to DrvSynchronizeSurface,
      but the VMware driver doesn't hook that call. */
-  /* FIXME: Remove the typecast! */
-  IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
-               DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+  IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
+                 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
+                 R4_NOOP, FALSE);
 
-  ret = EngMaskBitBlt(DestObj, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
+  ret = EngMaskBitBlt(DestSurf, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
                       &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);
 
   /* Dummy BitBlt to let driver know that something has changed. */
-  /* FIXME: Remove the typecast! */
-  IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
-               DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+  IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
+                 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
+                 R4_NOOP, FALSE);
 
-  MouseSafetyOnDrawEnd(DestObj);
+  MouseSafetyOnDrawEnd(DestSurf);
+  BITMAPOBJ_UnlockBitmapBits(DestObj);
 
   return ret;
 }

Modified: trunk/reactos/subsys/win32k/eng/copybits.c
--- trunk/reactos/subsys/win32k/eng/copybits.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/copybits.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -16,8 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id$
- *
+/*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          GDI EngCopyBits Function
@@ -44,12 +43,21 @@
   RECT_ENUM RectEnum;
   BOOL      EnumMore;
   BLTINFO   BltInfo;
+  BITMAPOBJ *DestObj = NULL;
+  BITMAPOBJ *SourceObj;
 
   ASSERT(Dest != NULL && Source != NULL && DestRect != NULL && SourcePoint != NULL);
 
+  SourceObj = CONTAINING_RECORD(Source, BITMAPOBJ, SurfObj);
+  BITMAPOBJ_LockBitmapBits(SourceObj);
   MouseSafetyOnDrawStart(Source, SourcePoint->x, SourcePoint->y,
                          (SourcePoint->x + abs(DestRect->right - DestRect->left)),
                          (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
+  if (Dest != Source)
+    {
+    DestObj = CONTAINING_RECORD(Dest, BITMAPOBJ, SurfObj);
+    BITMAPOBJ_LockBitmapBits(DestObj);
+    }
   MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
 
   // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
@@ -71,7 +79,12 @@
           Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
 
         MouseSafetyOnDrawEnd(Dest);
+        if (Dest != Source)
+          {
+          BITMAPOBJ_UnlockBitmapBits(DestObj);
+          }
         MouseSafetyOnDrawEnd(Source);
+        BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
         return ret;
       }
@@ -88,20 +101,29 @@
           Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
 
         MouseSafetyOnDrawEnd(Dest);
+        if (Dest != Source)
+          {
+          BITMAPOBJ_UnlockBitmapBits(DestObj);
+          }
         MouseSafetyOnDrawEnd(Source);
+        BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
         return ret;
       }
     }
 
     // If CopyBits wasn't hooked, BitBlt must be
-    /* FIXME: Remove the typecast! */
-    ret = IntEngBitBlt((BITMAPOBJ*)Dest, (BITMAPOBJ*)Source,
+    ret = IntEngBitBlt(Dest, Source,
                        NULL, Clip, ColorTranslation, DestRect, SourcePoint,
                        NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
 
     MouseSafetyOnDrawEnd(Dest);
+    if (Dest != Source)
+      {
+      BITMAPOBJ_UnlockBitmapBits(DestObj);
+      }
     MouseSafetyOnDrawEnd(Source);
+    BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
     return ret;
   }
@@ -130,7 +152,12 @@
         DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
 
         MouseSafetyOnDrawEnd(Dest);
+        if (Dest != Source)
+          {
+          BITMAPOBJ_UnlockBitmapBits(DestObj);
+          }
         MouseSafetyOnDrawEnd(Source);
+        BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
         return(TRUE);
 
@@ -144,7 +171,12 @@
         DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
 
         MouseSafetyOnDrawEnd(Dest);
+        if (Dest != Source)
+          {
+          BITMAPOBJ_UnlockBitmapBits(DestObj);
+          }
         MouseSafetyOnDrawEnd(Source);
+        BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
         return(TRUE);
 
@@ -177,13 +209,23 @@
           } while(EnumMore);
 
           MouseSafetyOnDrawEnd(Dest);
+          if (Dest != Source)
+            {
+            BITMAPOBJ_UnlockBitmapBits(DestObj);
+            }
           MouseSafetyOnDrawEnd(Source);
+          BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
           return(TRUE);
     }
 
   MouseSafetyOnDrawEnd(Dest);
+  if (Dest != Source)
+    {
+    BITMAPOBJ_UnlockBitmapBits(DestObj);
+    }
   MouseSafetyOnDrawEnd(Source);
+  BITMAPOBJ_UnlockBitmapBits(SourceObj);
 
   return FALSE;
 }

Modified: trunk/reactos/subsys/win32k/eng/gradient.c
--- trunk/reactos/subsys/win32k/eng/gradient.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/gradient.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -516,7 +516,7 @@
 
 BOOL STDCALL
 IntEngGradientFill(
-    IN BITMAPOBJ  *pboDest,
+    IN SURFOBJ  *psoDest,
     IN CLIPOBJ  *pco,
     IN XLATEOBJ  *pxlo,
     IN TRIVERTEX  *pVertex,
@@ -528,13 +528,14 @@
     IN ULONG  ulMode)
 {
   BOOL Ret;
-  SURFOBJ *psoDest;
-  ASSERT(pboDest);
+  BITMAPOBJ *pboDest;
+  ASSERT(psoDest);
   ASSERT(pco);
 
-  psoDest = &pboDest->SurfObj;
-  ASSERT(psoDest);
+  pboDest = CONTAINING_RECORD(psoDest, BITMAPOBJ, SurfObj);
+  ASSERT(pboDest);
 
+  BITMAPOBJ_LockBitmapBits(pboDest);
   MouseSafetyOnDrawStart(
 	  psoDest,
 	  pco->rclBounds.left,
@@ -552,5 +553,7 @@
   Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents,
                         pptlDitherOrg, ulMode);
   MouseSafetyOnDrawEnd(psoDest);
+  BITMAPOBJ_UnlockBitmapBits(pboDest);
+
   return Ret;
 }

Modified: trunk/reactos/subsys/win32k/eng/lineto.c
--- trunk/reactos/subsys/win32k/eng/lineto.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/lineto.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -485,7 +485,7 @@
 }
 
 BOOL STDCALL
-IntEngLineTo(BITMAPOBJ *DestObj,
+IntEngLineTo(SURFOBJ *DestSurf,
 	     CLIPOBJ *ClipObj,
 	     BRUSHOBJ *Brush,
 	     LONG x1,
@@ -496,13 +496,13 @@
 	     MIX Mix)
 {
   BOOLEAN ret;
-  SURFOBJ *DestSurf;
+  BITMAPOBJ *DestObj;
   PGDIBRUSHINST GdiBrush;
   RECTL b;
 
+  ASSERT(DestSurf);
+  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
   ASSERT(DestObj);
-  DestSurf = &DestObj->SurfObj;
-  ASSERT(DestSurf);
 
   GdiBrush = CONTAINING_RECORD(
      Brush,
@@ -543,6 +543,8 @@
   b.bottom = max(y1, y2);
   if (b.left == b.right) b.right++;
   if (b.top == b.bottom) b.bottom++;
+
+  BITMAPOBJ_LockBitmapBits(DestObj);
   MouseSafetyOnDrawStart(DestSurf, x1, y1, x2, y2);
 
   if (DestObj->flHooks & HOOK_LINETO)
@@ -565,12 +567,13 @@
     }
 
   MouseSafetyOnDrawEnd(DestSurf);
+  BITMAPOBJ_UnlockBitmapBits(DestObj);
 
   return ret;
 }
 
 BOOL STDCALL
-IntEngPolyline(BITMAPOBJ *DestObj,
+IntEngPolyline(SURFOBJ *DestSurf,
 	       CLIPOBJ *Clip,
 	       BRUSHOBJ *Brush,
 	       CONST LPPOINT  pt,
@@ -588,7 +591,7 @@
       rect.top = min(pt[i-1].y, pt[i].y);
       rect.right = max(pt[i-1].x, pt[i].x);
       rect.bottom = max(pt[i-1].y, pt[i].y);
-      ret = IntEngLineTo(DestObj,
+      ret = IntEngLineTo(DestSurf,
 	                 Clip,
 	                 Brush,
                          pt[i-1].x,

Modified: trunk/reactos/subsys/win32k/eng/mouse.c
--- trunk/reactos/subsys/win32k/eng/mouse.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/mouse.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -177,8 +177,9 @@
       {
         if((MaskSurface = EngLockSurface(pgp->MaskSurface)))
         {
-          EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
-                    &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
+          IntEngBitBltEx(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
+                         &DestRect, &SrcPoint, &SrcPoint, NULL, NULL,
+                         ROP3_TO_ROP4(SRCCOPY), FALSE);
           EngUnlockSurface(MaskSurface);
         }
         EngUnlockSurface(SaveSurface);
@@ -230,8 +231,9 @@
          pgp->Size.cy,
          DestSurface->sizlBitmap.cy - pt.y);
 
-      EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL,
-                &DestRect, &SrcPoint, NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
+      IntEngBitBltEx(SaveSurface, DestSurface, NULL, NULL, NULL,
+                     &DestRect, &SrcPoint, NULL, NULL, NULL,
+                     ROP3_TO_ROP4(SRCCOPY), FALSE);
       EngUnlockSurface(SaveSurface);
    }
 
@@ -266,18 +268,21 @@
         {
            if((ColorSurf = EngLockSurface(pgp->ColorSurface)))
            {
-             EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, pgp->XlateObject,
-                       &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, R4_MASK);
+             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, ROP3_TO_ROP4(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, ROP3_TO_ROP4(SRCINVERT));
+           IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+                          &DestRect, &SrcPoint, NULL, NULL, NULL,
+                          ROP3_TO_ROP4(SRCINVERT), FALSE);
         }
         EngUnlockSurface(MaskSurf);
       }
@@ -523,4 +528,25 @@
 
 }
 
+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 */

Modified: trunk/reactos/subsys/win32k/eng/paint.c
--- trunk/reactos/subsys/win32k/eng/paint.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/paint.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -33,9 +33,12 @@
 {
   LONG y;
   ULONG LineWidth;
+  BITMAPOBJ *BitmapObj;
 
   ASSERT ( Surface );
   ASSERT ( pRect );
+  BitmapObj = CONTAINING_RECORD(Surface, BITMAPOBJ, SurfObj);
+  BITMAPOBJ_LockBitmapBits(BitmapObj);
   MouseSafetyOnDrawStart(Surface, pRect->left, pRect->top, pRect->right, pRect->bottom);
   LineWidth  = pRect->right - pRect->left;
   DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
@@ -45,6 +48,7 @@
       Surface, pRect->left, pRect->right, y, iColor);
   }
   MouseSafetyOnDrawEnd(Surface);
+  BITMAPOBJ_UnlockBitmapBits(BitmapObj);
 
   return TRUE;
 }
@@ -111,13 +115,13 @@
 }
 
 BOOL STDCALL
-IntEngPaint(IN BITMAPOBJ *BitmapObj,
+IntEngPaint(IN SURFOBJ *Surface,
             IN CLIPOBJ *ClipRegion,
             IN BRUSHOBJ *Brush,
             IN POINTL *BrushOrigin,
             IN MIX  Mix)
 {
-  SURFOBJ *Surface = &BitmapObj->SurfObj;
+  BITMAPOBJ *BitmapObj = CONTAINING_RECORD(Surface, BITMAPOBJ, SurfObj);
   BOOL ret;
 
   DPRINT("SurfGDI type: %d\n", Surface->iType);
@@ -125,6 +129,7 @@
   if((Surface->iType!=STYPE_BITMAP) && (BitmapObj->flHooks & HOOK_PAINT))
   {
     // Call the driver's DrvPaint
+    BITMAPOBJ_LockBitmapBits(BitmapObj);
     MouseSafetyOnDrawStart(Surface, ClipRegion->rclBounds.left,
 	                         ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
 							 ClipRegion->rclBounds.bottom);
@@ -132,6 +137,7 @@
     ret = GDIDEVFUNCS(Surface).Paint(
       Surface, ClipRegion, Brush, BrushOrigin, Mix);
     MouseSafetyOnDrawEnd(Surface);
+    BITMAPOBJ_UnlockBitmapBits(BitmapObj);
     return ret;
   }
   return EngPaint( Surface, ClipRegion, Brush, BrushOrigin, Mix );

Modified: trunk/reactos/subsys/win32k/eng/surface.c
--- trunk/reactos/subsys/win32k/eng/surface.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/surface.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -79,6 +79,33 @@
   }
 }
 
+BOOL INTERNAL_CALL
+BITMAPOBJ_InitBitsLock(BITMAPOBJ *BitmapObj)
+{
+  BitmapObj->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
+                                              sizeof(FAST_MUTEX),
+                                              TAG_BITMAPOBJ);
+  if (NULL == BitmapObj->BitsLock)
+    {
+      return FALSE;
+    }
+
+  ExInitializeFastMutex(BitmapObj->BitsLock);
+
+  return TRUE;
+}
+
+void INTERNAL_CALL
+BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *BitmapObj)
+{
+  if (NULL != BitmapObj->BitsLock)
+    {
+      ExFreePoolWithTag(BitmapObj->BitsLock, TAG_BITMAPOBJ);
+      BitmapObj->BitsLock = NULL;
+    }
+}
+
+
 /*
  * @implemented
  */
@@ -232,6 +259,12 @@
 	return 0;
 
   BitmapObj = BITMAPOBJ_LockBitmap(NewBitmap);
+  if (! BITMAPOBJ_InitBitsLock(BitmapObj))
+    {
+      BITMAPOBJ_UnlockBitmap(BitmapObj);
+      BITMAPOBJ_FreeBitmap(NewBitmap);
+      return 0;
+    }
   SurfObj = &BitmapObj->SurfObj;
 
   if (Format == BMF_4RLE)
@@ -357,11 +390,17 @@
   if (NewSurface == NULL)
 	return 0;
 
-  GDIOBJ_SetOwnership(NewSurface, NULL);
-
   BitmapObj = BITMAPOBJ_LockBitmap(NewSurface);
+  if (! BITMAPOBJ_InitBitsLock(BitmapObj))
+    {
+      BITMAPOBJ_UnlockBitmap(BitmapObj);
+      BITMAPOBJ_FreeBitmap(NewSurface);
+      return 0;
+    }
   SurfObj = &BitmapObj->SurfObj;
 
+  GDIOBJ_SetOwnership(NewSurface, NULL);
+
   SurfObj->dhsurf = dhsurf;
   SurfObj->hsurf = NewSurface;
   SurfObj->sizlBitmap = Size;

Modified: trunk/reactos/subsys/win32k/eng/transblt.c
--- trunk/reactos/subsys/win32k/eng/transblt.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/eng/transblt.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -193,8 +193,8 @@
 }
 
 BOOL FASTCALL
-IntEngTransparentBlt(BITMAPOBJ *DestObj,
-                     BITMAPOBJ *SourceObj,
+IntEngTransparentBlt(SURFOBJ *DestSurf,
+                     SURFOBJ *SourceSurf,
                      CLIPOBJ *Clip,
                      XLATEOBJ *ColorTranslation,
                      PRECTL DestRect,
@@ -204,18 +204,18 @@
 {
   BOOL Ret;
   RECTL OutputRect, InputClippedRect;
-  SURFOBJ *DestSurf;
-  SURFOBJ *SourceSurf;
+  BITMAPOBJ *DestObj;
+  BITMAPOBJ *SourceObj;
 
-  ASSERT(DestObj);
-  ASSERT(SourceObj);
+  ASSERT(DestSurf);
+  ASSERT(SourceSurf);
   ASSERT(DestRect);
 
-  DestSurf = &DestObj->SurfObj;
-  SourceSurf = &SourceObj->SurfObj;
+  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
+  SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
 
-  ASSERT(DestSurf);
-  ASSERT(SourceSurf);
+  ASSERT(DestObj);
+  ASSERT(SourceObj);
 
   InputClippedRect = *DestRect;
   if(InputClippedRect.right < InputClippedRect.left)
@@ -249,9 +249,11 @@
 
   if(SourceSurf != DestSurf)
   {
+    BITMAPOBJ_LockBitmapBits(SourceObj);
     MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
                            SourceRect->right, SourceRect->bottom);
   }
+  BITMAPOBJ_LockBitmapBits(DestObj);
   MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
                          OutputRect.right, OutputRect.bottom);
 
@@ -271,9 +273,11 @@
   }
 
   MouseSafetyOnDrawEnd(DestSurf);
+  BITMAPOBJ_UnlockBitmapBits(DestObj);
   if(SourceSurf != DestSurf)
   {
     MouseSafetyOnDrawEnd(SourceSurf);
+    BITMAPOBJ_UnlockBitmapBits(SourceObj);
   }
 
   return Ret;

Modified: trunk/reactos/subsys/win32k/include/inteng.h
--- trunk/reactos/subsys/win32k/include/inteng.h	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/include/inteng.h	2005-06-20 08:31:48 UTC (rev 16143)
@@ -43,7 +43,7 @@
                         PW32PROCESS Win32Process);
 
 BOOL STDCALL
-IntEngLineTo(BITMAPOBJ *Surface,
+IntEngLineTo(SURFOBJ *Surface,
              CLIPOBJ *Clip,
              BRUSHOBJ *Brush,
              LONG x1,
@@ -54,22 +54,29 @@
              MIX mix);
 
 BOOL STDCALL
-IntEngBitBlt(BITMAPOBJ *DestObj,
-	     BITMAPOBJ *SourceObj,
-	     BITMAPOBJ *Mask,
-	     CLIPOBJ *ClipRegion,
-	     XLATEOBJ *ColorTranslation,
-	     RECTL *DestRect,
-	     POINTL *SourcePoint,
-	     POINTL *MaskOrigin,
-	     BRUSHOBJ *Brush,
-	     POINTL *BrushOrigin,
-	     ROP4 rop4);
+IntEngBitBltEx(SURFOBJ *DestObj,
+               SURFOBJ *SourceObj,
+               SURFOBJ *Mask,
+               CLIPOBJ *ClipRegion,
+               XLATEOBJ *ColorTranslation,
+               RECTL *DestRect,
+               POINTL *SourcePoint,
+               POINTL *MaskOrigin,
+               BRUSHOBJ *Brush,
+               POINTL *BrushOrigin,
+               ROP4 Rop4,
+               BOOL RemoveMouse);
+#define IntEngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, \
+                     DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, \
+                     Rop4) \
+        IntEngBitBltEx((DestObj), (SourceObj), (Mask), (ClipRegion), \
+                       (ColorTranslation), (DestRect), (SourcePoint), \
+                       (MaskOrigin), (Brush), (BrushOrigin), (Rop4), TRUE)
 
 BOOL STDCALL
-IntEngStretchBlt(BITMAPOBJ *DestObj,
-                 BITMAPOBJ *SourceObj,
-                 BITMAPOBJ *Mask,
+IntEngStretchBlt(SURFOBJ *DestObj,
+                 SURFOBJ *SourceObj,
+                 SURFOBJ *Mask,
                  CLIPOBJ *ClipRegion,
                  XLATEOBJ *ColorTranslation,
                  RECTL *DestRect,
@@ -80,7 +87,7 @@
                  ULONG Mode);
 
 BOOL STDCALL
-IntEngGradientFill(BITMAPOBJ *psoDest,
+IntEngGradientFill(SURFOBJ *psoDest,
                    CLIPOBJ *pco,
                    XLATEOBJ *pxlo,
                    TRIVERTEX *pVertex,
@@ -109,7 +116,7 @@
                          ULONG BackgroundColor);
 
 BOOL STDCALL
-IntEngPolyline(BITMAPOBJ *DestSurf,
+IntEngPolyline(SURFOBJ *DestSurf,
                CLIPOBJ *Clip,
                BRUSHOBJ *Brush,
                CONST LPPOINT  pt,
@@ -131,8 +138,8 @@
                PRECTL Boundary);
 
 BOOL FASTCALL
-IntEngTransparentBlt(BITMAPOBJ *Dest,
-                     BITMAPOBJ *Source,
+IntEngTransparentBlt(SURFOBJ *Dest,
+                     SURFOBJ *Source,
                      CLIPOBJ *Clip,
                      XLATEOBJ *ColorTranslation,
                      PRECTL DestRect,
@@ -141,10 +148,17 @@
                      ULONG Reserved);
 
 BOOL STDCALL
-IntEngPaint(IN BITMAPOBJ *Surface,
+IntEngPaint(IN SURFOBJ *Surface,
             IN CLIPOBJ *ClipRegion,
             IN BRUSHOBJ *Brush,
             IN POINTL *BrushOrigin,
             IN MIX Mix);
 
+VOID STDCALL
+IntEngMovePointer(IN SURFOBJ *pso,
+                  IN LONG x,
+                  IN LONG y,
+                  IN RECTL *prcl);
+
+
 #endif /* _WIN32K_INTENG_H */

Modified: trunk/reactos/subsys/win32k/include/tags.h
--- trunk/reactos/subsys/win32k/include/tags.h	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/include/tags.h	2005-06-20 08:31:48 UTC (rev 16143)
@@ -51,6 +51,7 @@
 #define TAG_FONTOBJ	TAG('F', 'N', 'T', 'O') /* font object */
 #define TAG_WNDOBJ	TAG('W', 'N', 'D', 'O') /* window object */
 #define TAG_XLATEOBJ	TAG('X', 'L', 'A', 'O') /* xlate object */
+#define TAG_BITMAPOBJ	TAG('B', 'M', 'P', 'O') /* bitmap object */
 
 /* misc */
 #define TAG_DRIVER	TAG('G', 'D', 'R', 'V') /* video drivers */

Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c
--- trunk/reactos/subsys/win32k/ntuser/cursoricon.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/ntuser/cursoricon.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -142,10 +142,7 @@
       if (NULL != CurInfo->CurrentCursorObject && CurInfo->ShowingCursor)
       {
          /* Remove the cursor if it was displayed */
-         if (GDIDEV(SurfObj)->Pointer.MovePointer)
-           GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, -1, -1, &GDIDEV(SurfObj)->Pointer.Exclude);
-         else
-           EngMovePointer(SurfObj, -1, -1, &GDIDEV(SurfObj)->Pointer.Exclude);
+         IntEngMovePointer(SurfObj, -1, -1, &GDIDEV(SurfObj)->Pointer.Exclude);
       }
 
       GDIDEV(SurfObj)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE;
@@ -266,7 +263,7 @@
                          GDIDEV(SurfObj)->Pointer.Pos.y,
                          &(GDIDEV(SurfObj)->Pointer.Exclude),
                          SPS_CHANGE);
-      GDIDEV(SurfObj)->Pointer.MovePointer = EngMovePointer;
+      GDIDEV(SurfObj)->Pointer.MovePointer = NULL;
     }
     else
     {

Modified: trunk/reactos/subsys/win32k/ntuser/input.c
--- trunk/reactos/subsys/win32k/ntuser/input.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/ntuser/input.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -959,12 +959,7 @@
       {
         SurfObj = &BitmapObj->SurfObj;
 
-        if (GDIDEV(SurfObj)->Pointer.MovePointer)
-        {
-          GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, MousePos.x, MousePos.y, &(GDIDEV(SurfObj)->Pointer.Exclude));
-        } else {
-	  EngMovePointer(SurfObj, MousePos.x, MousePos.y, &(GDIDEV(SurfObj)->Pointer.Exclude));
-	}
+        IntEngMovePointer(SurfObj, MousePos.x, MousePos.y, &(GDIDEV(SurfObj)->Pointer.Exclude));
         /* Only now, update the info in the GDIDEVICE, so EngMovePointer can
 	 * use the old values to move the pointer image */
 	GDIDEV(SurfObj)->Pointer.Pos.x = MousePos.x;

Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
--- trunk/reactos/subsys/win32k/objects/bitmaps.c	2005-06-20 07:18:20 UTC (rev 16142)
+++ trunk/reactos/subsys/win32k/objects/bitmaps.c	2005-06-20 08:31:48 UTC (rev 16143)
@@ -213,8 +213,10 @@
 	}
 
 	/* Perform the bitblt operation */
-	Status = IntEngBitBlt(BitmapDest, BitmapSrc, NULL, DCDest->CombinedClip, XlateObj,
-	                      &DestRect, &SourcePoint, NULL, BrushObj ? &BrushInst.BrushObject : NULL,
+	Status = IntEngBitBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, NULL,
+                              DCDest->CombinedClip, XlateObj, &DestRect,
+                              &SourcePoint, NULL,
+                              BrushObj ? &BrushInst.BrushObject : NULL,
 	                      &BrushOrigin, ROP3_TO_ROP4(ROP));
 
 	if (UsesSource && XlateObj != NULL)
@@ -371,7 +373,8 @@
     goto done;
   }
 
-  Ret = IntEngTransparentBlt(BitmapDest, BitmapSrc, DCDest->CombinedClip, XlateObj, &rcDest, &rcSrc,
+  Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
+                             DCDest->CombinedClip, XlateObj, &rcDest, &rcSrc,
                              TransparentColor, 0);
 
 done:
@@ -469,6 +472,12 @@
 		}
 	}
 
+	if (NULL != pBmp->BitsLock)
+	{
+		ExFreePoolWithTag(pBmp->BitsLock, TAG_BITMAPOBJ);
+		pBmp->BitsLock = NULL;
+	}
+
 	return TRUE;
 }
 
@@ -1246,8 +1255,10 @@
 	}
 
 	/* Perform the bitblt operation */
-	Status = IntEngStretchBlt(BitmapDest, BitmapSrc, NULL, DCDest->CombinedClip,
-		XlateObj, &DestRect, &SourceRect, NULL, NULL, NULL, COLORONCOLOR);
+	Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
+                                  NULL, DCDest->CombinedClip, XlateObj,
+                                  &DestRect, &SourceRect, NULL, NULL, NULL,
+                                  COLORONCOLOR);
 
[truncated at 1000 lines; 273 more skipped]