BUGFIX: EngCreateBitmap() - don't call GDIOBJ_SetOwnerShip() with invalid handle
[reactos.git] / reactos / subsys / win32k / eng / surface.c
index 9b6f0c5..952aa01 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: surface.c,v 1.31 2004/02/08 21:37:52 weiden Exp $
+/* $Id: surface.c,v 1.47 2004/12/18 17:12:32 royce Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
  *   refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
  */
-
-#include <ddk/winddi.h>
-#include <win32k/dc.h>
-#include <win32k/gdiobj.h>
-#include <include/dib.h>
-#include <include/object.h>
-#include <include/paint.h>
-#include "handle.h"
-#include "../dib/dib.h"
-
-#define NDEBUG
-#include <win32k/debug1.h>
+#include <w32k.h>
 
 enum Rle_EscapeCodes
 {
@@ -80,6 +69,7 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
         case 24: return BMF_24BPP;
         case 32: return BMF_32BPP;
       }
+      return 0;
 
     case BI_RLE4: return BMF_4RLE;
     case BI_RLE8: return BMF_8RLE;
@@ -88,88 +78,6 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
   }
 }
 
-static VOID Dummy_PutPixel(SURFOBJ* SurfObj, LONG x, LONG y, ULONG c)
-{
-  return;
-}
-
-static ULONG Dummy_GetPixel(SURFOBJ* SurfObj, LONG x, LONG y)
-{
-  return 0;
-}
-
-static VOID Dummy_HLine(SURFOBJ* SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
-{
-  return;
-}
-
-static VOID Dummy_VLine(SURFOBJ* SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
-{
-  return;
-}
-
-static BOOLEAN Dummy_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                            SURFGDI *DestGDI,  SURFGDI *SourceGDI,
-                            RECTL*  DestRect,  POINTL  *SourcePoint,
-                                       BRUSHOBJ* BrushObj, POINTL* BrushOrign,
-                            XLATEOBJ *ColorTranslation, ULONG Rop4)
-{
-  return FALSE;
-}
-
-static BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                                SURFGDI *DestGDI,  SURFGDI *SourceGDI,
-                                RECTL*  DestRect,  RECTL  *SourceRect,
-                                POINTL* MaskOrigin, POINTL* BrushOrign,
-                                XLATEOBJ *ColorTranslation, ULONG Mode)
-{
-  return FALSE;
-}
-
-
-#define SURF_METHOD(c,n) DIB_##c##_##n
-#define SET_SURFGDI(c)\
- SurfGDI->DIB_PutPixel=SURF_METHOD(c,PutPixel);\
- SurfGDI->DIB_GetPixel=SURF_METHOD(c,GetPixel);\
- SurfGDI->DIB_HLine=SURF_METHOD(c,HLine);\
- SurfGDI->DIB_VLine=SURF_METHOD(c,VLine);\
- SurfGDI->DIB_BitBlt=SURF_METHOD(c,BitBlt);\
- SurfGDI->DIB_StretchBlt=SURF_METHOD(c,StretchBlt);
-
-VOID FASTCALL InitializeFuncs(SURFGDI *SurfGDI, ULONG BitmapFormat)
-{
-  SurfGDI->BitBlt   = NULL;
-  SurfGDI->StretchBlt   = NULL;
-  SurfGDI->CopyBits = NULL;
-  SurfGDI->CreateDeviceBitmap = NULL;
-  SurfGDI->SetPalette = NULL;
-  SurfGDI->TransparentBlt = NULL;
-
-  switch(BitmapFormat)
-    {
-    case BMF_1BPP:  SET_SURFGDI(1BPP) break;
-    case BMF_4BPP:  SET_SURFGDI(4BPP) break;
-    case BMF_8BPP:  SET_SURFGDI(8BPP) break;
-    case BMF_16BPP: SET_SURFGDI(16BPP) break;
-    case BMF_24BPP: SET_SURFGDI(24BPP) break;
-    case BMF_32BPP: SET_SURFGDI(32BPP) break;
-    case BMF_4RLE:
-    case BMF_8RLE:
-      /* Not supported yet, fall through to unrecognized case */
-    default:
-      DPRINT1("InitializeFuncs: unsupported DIB format %d\n",
-               BitmapFormat);
-
-      SurfGDI->DIB_PutPixel     = Dummy_PutPixel;
-      SurfGDI->DIB_GetPixel     = Dummy_GetPixel;
-      SurfGDI->DIB_HLine        = Dummy_HLine;
-      SurfGDI->DIB_VLine        = Dummy_VLine;
-      SurfGDI->DIB_BitBlt       = Dummy_BitBlt;
-      SurfGDI->DIB_StretchBlt   = Dummy_StretchBlt;
-      break;
-    }
-}
-
 /*
  * @implemented
  */
@@ -182,8 +90,9 @@ EngCreateDeviceBitmap(IN DHSURF dhsurf,
   SURFOBJ *SurfObj;
 
   NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
-  SurfObj = (PVOID)AccessUserObject((ULONG)NewBitmap);
+  SurfObj = EngLockSurface((HSURF)NewBitmap);
   SurfObj->dhsurf = dhsurf;
+  EngUnlockSurface(SurfObj);
 
   return NewBitmap;
 }
@@ -301,11 +210,8 @@ VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LO
        }
 }
 
-/*
- * @implemented
- */
-HBITMAP STDCALL
-EngCreateBitmap(IN SIZEL Size,
+HBITMAP FASTCALL
+IntCreateBitmap(IN SIZEL Size,
                IN LONG Width,
                IN ULONG Format,
                IN ULONG Flags,
@@ -313,68 +219,123 @@ EngCreateBitmap(IN SIZEL Size,
 {
   HBITMAP NewBitmap;
   SURFOBJ *SurfObj;
-  SURFGDI *SurfGDI;
+  BITMAPOBJ *BitmapObj;
   PVOID UncompressedBits;
   ULONG UncompressedFormat;
 
-  NewBitmap = (PVOID)CreateGDIHandle(sizeof(SURFGDI), sizeof(SURFOBJ));
-  if( !ValidEngHandle( NewBitmap ) )
+  if (Format == 0)
+       return 0;
+
+  NewBitmap = BITMAPOBJ_AllocBitmap();
+  if (NewBitmap == NULL)
        return 0;
 
-  SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewBitmap );
-  SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewBitmap );
-  ASSERT( SurfObj );
-  ASSERT( SurfGDI );
-  SurfGDI->BitsPerPixel = BitsPerFormat(Format);
-  if (Format == BMF_4RLE) {
-         SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
-         SurfObj->cjBits = SurfObj->lDelta * Size.cy;
-         UncompressedFormat = BMF_4BPP;
+  BitmapObj = BITMAPOBJ_LockBitmap(NewBitmap);
+  SurfObj = &BitmapObj->SurfObj;
+
+  if (Format == BMF_4RLE)
+    {
+      SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
+      SurfObj->cjBits = SurfObj->lDelta * Size.cy;
+      UncompressedFormat = BMF_4BPP;
       UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
-         Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, SurfObj->lDelta);
-  } else {
-         if (Format == BMF_8RLE) {
-                 SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
-                 SurfObj->cjBits = SurfObj->lDelta * Size.cy;
-             UncompressedFormat = BMF_8BPP;
-             UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
-                 Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, SurfObj->lDelta);
-         } else {
-  SurfObj->lDelta = Width;
-  SurfObj->cjBits = SurfObj->lDelta * Size.cy;
-                 UncompressedBits = Bits;
-                 UncompressedFormat = Format;
-         }
-  }
-  if(UncompressedBits!=NULL)
-  {
-    SurfObj->pvBits = UncompressedBits;
-  } else
-  {
-    if(Flags & BMF_USERMEM)
+      Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, SurfObj->lDelta);
+    }
+  else if (Format == BMF_8RLE)
     {
-      SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
-    } else {
-      if(Flags & BMF_NOZEROINIT)
-      {
-        SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
-      } else {
-        SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
-      }
+      SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
+      SurfObj->cjBits = SurfObj->lDelta * Size.cy;
+      UncompressedFormat = BMF_8BPP;
+      UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
+      Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, SurfObj->lDelta);
+    }
+  else
+    {
+      SurfObj->lDelta = abs(Width);
+      SurfObj->cjBits = SurfObj->lDelta * Size.cy;
+      UncompressedBits = Bits;
+      UncompressedFormat = Format;
+    }
+
+  if (UncompressedBits != NULL)
+    {
+      SurfObj->pvBits = UncompressedBits;
+    }
+  else
+    {
+      if (SurfObj->cjBits == 0)
+        {
+          SurfObj->pvBits = NULL;
+        }
+      else
+        {
+          if (0 != (Flags & BMF_USERMEM))
+            {
+              SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
+            }
+          else
+            {
+              SurfObj->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
+                                            SurfObj->cjBits, 0);
+            }
+          if (SurfObj->pvBits == NULL)
+            {
+              BITMAPOBJ_UnlockBitmap(NewBitmap);
+              BITMAPOBJ_FreeBitmap(NewBitmap);
+              return 0;
+            }
+        }
+     }
+
+
+  if (0 == (Flags & BMF_TOPDOWN))
+    {
+      SurfObj->pvScan0 = (PVOID) ((ULONG_PTR) SurfObj->pvBits + SurfObj->cjBits - SurfObj->lDelta);
+      SurfObj->lDelta = - SurfObj->lDelta;
+    }
+  else
+    {
+      SurfObj->pvScan0 = SurfObj->pvBits;
     }
-  }
 
-  SurfObj->dhsurf = 0; // device managed surface
-  SurfObj->hsurf  = 0;
+  SurfObj->dhsurf = 0; /* device managed surface */
+  SurfObj->hsurf = (HSURF)NewBitmap;
+  SurfObj->dhpdev = NULL;
+  SurfObj->hdev = NULL;
   SurfObj->sizlBitmap = Size;
   SurfObj->iBitmapFormat = UncompressedFormat;
   SurfObj->iType = STYPE_BITMAP;
   SurfObj->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
-  SurfObj->pvScan0 = SurfObj->pvBits;
+  SurfObj->iUniq = 0;
+
+  BitmapObj->flHooks = 0;
+  BitmapObj->flFlags = 0;
+  BitmapObj->dimension.cx = 0;
+  BitmapObj->dimension.cy = 0;
+  BitmapObj->dib = NULL;
+
+  BITMAPOBJ_UnlockBitmap(NewBitmap);
+
+  return NewBitmap;
+}
 
-  InitializeFuncs(SurfGDI, UncompressedFormat);
+/*
+ * @implemented
+ */
+HBITMAP STDCALL
+EngCreateBitmap(IN SIZEL Size,
+               IN LONG Width,
+               IN ULONG Format,
+               IN ULONG Flags,
+               IN PVOID Bits)
+{
+  HBITMAP NewBitmap;
+  
+  NewBitmap = IntCreateBitmap(Size, Width, Format, Flags, Bits);
+  if ( !NewBitmap )
+         return 0;
 
-  // Use flags to determine bitmap type -- TOP_DOWN or whatever
+  GDIOBJ_SetOwnership(NewBitmap, NULL);
 
   return NewBitmap;
 }
@@ -387,28 +348,30 @@ EngCreateDeviceSurface(IN DHSURF dhsurf,
                       IN SIZEL Size,
                       IN ULONG Format)
 {
-  HSURF   NewSurface;
+  HSURF NewSurface;
   SURFOBJ *SurfObj;
-  SURFGDI *SurfGDI;
+  BITMAPOBJ *BitmapObj;
 
-  NewSurface = (HSURF)CreateGDIHandle(sizeof( SURFGDI ), sizeof( SURFOBJ ));
-  if( !ValidEngHandle( NewSurface ) )
+  NewSurface = (HSURF)BITMAPOBJ_AllocBitmap();
+  if (NewSurface == NULL)
        return 0;
 
-  SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewSurface );
-  SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewSurface );
-  ASSERT( SurfObj );
-  ASSERT( SurfGDI );
+  GDIOBJ_SetOwnership(NewSurface, NULL);
+
+  BitmapObj = BITMAPOBJ_LockBitmap(NewSurface);
+  SurfObj = &BitmapObj->SurfObj;
 
-  SurfGDI->BitsPerPixel = BitsPerFormat(Format);
   SurfObj->dhsurf = dhsurf;
-  SurfObj->hsurf  = (HSURF) dhsurf; // FIXME: Is this correct??
+  SurfObj->hsurf = NewSurface;
   SurfObj->sizlBitmap = Size;
   SurfObj->iBitmapFormat = Format;
   SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
   SurfObj->iType = STYPE_DEVICE;
+  SurfObj->iUniq = 0;
 
-  InitializeFuncs(SurfGDI, Format);
+  BitmapObj->flHooks = 0;
+
+  BITMAPOBJ_UnlockBitmap(NewSurface);
 
   return NewSurface;
 }
@@ -434,50 +397,74 @@ EngAssociateSurface(IN HSURF Surface,
                    IN ULONG Hooks)
 {
   SURFOBJ *SurfObj;
-  SURFGDI *SurfGDI;
+  BITMAPOBJ *BitmapObj;
   GDIDEVICE* Device;
 
   Device = (GDIDEVICE*)Dev;
 
-  SurfGDI = (PVOID)AccessInternalObject((ULONG)Surface);
-  SurfObj = (PVOID)AccessUserObject((ULONG)Surface);
+  BitmapObj = BITMAPOBJ_LockBitmap(Surface);
+  ASSERT(BitmapObj);
+  SurfObj = &BitmapObj->SurfObj;
 
-  // Associate the hdev
+  /* Associate the hdev */
   SurfObj->hdev = Dev;
+  SurfObj->dhpdev = Device->PDev;
+
+  /* Hook up specified functions */
+  BitmapObj->flHooks = Hooks;
 
-  // Hook up specified functions
-  if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Device->DriverFunctions.BitBlt;
-  if(Hooks & HOOK_TRANSPARENTBLT)    SurfGDI->TransparentBlt   = Device->DriverFunctions.TransparentBlt;
-  if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = (PFN_StretchBlt)Device->DriverFunctions.StretchBlt;
-  if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Device->DriverFunctions.TextOut;
-  if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Device->DriverFunctions.Paint;
-  if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Device->DriverFunctions.StrokePath;
-  if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Device->DriverFunctions.FillPath;
-  if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Device->DriverFunctions.StrokeAndFillPath;
-  if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Device->DriverFunctions.LineTo;
-  if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Device->DriverFunctions.CopyBits;
-  if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Device->DriverFunctions.Synchronize;
-  if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
-  if(Hooks & HOOK_GRADIENTFILL)      SurfGDI->GradientFill      = Device->DriverFunctions.GradientFill;
-
-  SurfGDI->CreateDeviceBitmap = Device->DriverFunctions.CreateDeviceBitmap;
-  SurfGDI->SetPalette = Device->DriverFunctions.SetPalette;
-  SurfGDI->MovePointer = Device->DriverFunctions.MovePointer;
-  SurfGDI->SetPointerShape = (PFN_SetPointerShape)Device->DriverFunctions.SetPointerShape;
-
-  SurfGDI->DriverLock = &Device->DriverLock;
+  BITMAPOBJ_UnlockBitmap(Surface);
 
   return TRUE;
 }
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+EngModifySurface(
+   IN HSURF hsurf,
+   IN HDEV hdev,
+   IN FLONG flHooks,
+   IN FLONG flSurface,
+   IN DHSURF dhsurf,
+   OUT VOID *pvScan0,
+   IN LONG lDelta,
+   IN VOID *pvReserved)
+{
+   SURFOBJ *pso;
+
+   pso = EngLockSurface(hsurf);
+   if (pso == NULL)
+   {
+      return FALSE;
+   }
+
+   if (!EngAssociateSurface(hsurf, hdev, flHooks))
+   {
+      EngUnlockSurface(pso);
+
+      return FALSE;
+   }
+
+   pso->dhsurf = dhsurf;
+   pso->lDelta = lDelta;
+   pso->pvScan0 = pvScan0;
+
+   EngUnlockSurface(pso);
+
+   return TRUE;
+}
+
 /*
  * @implemented
  */
 BOOL STDCALL
 EngDeleteSurface(IN HSURF Surface)
 {
-  FreeGDIHandle((ULONG)Surface);
-  return TRUE;
+   GDIOBJ_SetOwnership(Surface, PsGetCurrentProcess());
+   BITMAPOBJ_FreeBitmap(Surface);
+   return TRUE;
 }
 
 /*
@@ -488,36 +475,33 @@ EngEraseSurface(SURFOBJ *Surface,
                RECTL *Rect,
                ULONG iColor)
 {
+  ASSERT(Surface);
+  ASSERT(Rect);
   return FillSolid(Surface, Rect, iColor);
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 SURFOBJ * STDCALL
 EngLockSurface(IN HSURF Surface)
 {
-  /*
-   * FIXME - don't know if GDIOBJ_LockObj's return value is a SURFOBJ or not...
-   * also, what is HSURF's correct magic #?
-   */
-#ifdef TODO
-  GDIOBJ_LockObj ( Surface, GDI_OBJECT_TYPE_DONTCARE );
-#endif
-  return (SURFOBJ*)AccessUserObject((ULONG)Surface);
+  BITMAPOBJ *bmp = (BITMAPOBJ*)BITMAPOBJ_LockBitmap(Surface);
+  if(bmp != NULL)
+  {
+    return &bmp->SurfObj;
+  }
+  
+  return NULL;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 VOID STDCALL
 EngUnlockSurface(IN SURFOBJ *Surface)
 {
-  /*
-   * FIXME what is HSURF's correct magic #?
-   */
-#ifdef TODO
-  GDIOBJ_UnlockObj ( Surface->hsurf, GDI_OBJECT_TYPE_DONTCARE );
-#endif
+  ASSERT (Surface);
+  BITMAPOBJ_UnlockBitmap (Surface->hsurf);
 }
 /* EOF */