[CMAKE]
[reactos.git] / subsystems / win32 / win32k / eng / surface.c
index 5dd6138..fb59ff5 100644 (file)
@@ -3,7 +3,8 @@
  * PROJECT:           ReactOS kernel
  * PURPOSE:           GDI Driver Surace Functions
  * FILE:              subsys/win32k/eng/surface.c
- * PROGRAMER:         Jason Filby
+ * PROGRAMERS:        Jason Filby
+ *                    Timo Kreuzer
  * REVISION HISTORY:
  *                 3/7/1999: Created
  *                 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
  *   refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
-enum Rle_EscapeCodes
-{
-    RLE_EOL   = 0, /* End of line */
-    RLE_END   = 1, /* End of bitmap */
-    RLE_DELTA = 2  /* Delta */
-};
+ULONG giUniqueSurface = 0;
 
-INT FASTCALL BitsPerFormat(ULONG Format)
+UCHAR
+gajBitsPerFormat[11] =
 {
-    switch (Format)
-    {
-        case BMF_1BPP:
-            return 1;
-
-        case BMF_4BPP:
-            /* Fall through */
-        case BMF_4RLE:
-            return 4;
-
-        case BMF_8BPP:
-            /* Fall through */
-        case BMF_8RLE:
-            return 8;
-
-        case BMF_16BPP:
-            return 16;
-
-        case BMF_24BPP:
-            return 24;
+    0, /*  0: unused */
+    1, /*  1: BMF_1BPP */
+    4, /*  2: BMF_4BPP */
+    8, /*  3: BMF_8BPP */
+   16, /*  4: BMF_16BPP */
+   24, /*  5: BMF_24BPP */
+   32, /*  6: BMF_32BPP */
+    4, /*  7: BMF_4RLE */
+    8, /*  8: BMF_8RLE */
+    0, /*  9: BMF_JPEG */
+    0, /* 10: BMF_PNG */
+};
 
-        case BMF_32BPP:
-            return 32;
 
-        default:
-            return 0;
-    }
-}
-
-ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
+ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
 {
-    switch (Compression)
+    switch (iCompression)
     {
         case BI_RGB:
             /* Fall through */
         case BI_BITFIELDS:
-            switch (Bits)
-            {
-                case 1:
-                    return BMF_1BPP;
-                case 4:
-                    return BMF_4BPP;
-                case 8:
-                    return BMF_8BPP;
-                case 16:
-                    return BMF_16BPP;
-                case 24:
-                    return BMF_24BPP;
-                case 32:
-                    return BMF_32BPP;
-            }
+            if (cBits <= 1) return BMF_1BPP;
+            if (cBits <= 4) return BMF_4BPP;
+            if (cBits <= 8) return BMF_8BPP;
+            if (cBits <= 16) return BMF_16BPP;
+            if (cBits <= 24) return BMF_24BPP;
+            if (cBits <= 32) return BMF_32BPP;
             return 0;
 
         case BI_RLE4:
@@ -90,429 +63,305 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
     }
 }
 
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
 SURFACE_Cleanup(PVOID ObjectBody)
 {
     PSURFACE psurf = (PSURFACE)ObjectBody;
     PVOID pvBits = psurf->SurfObj.pvBits;
+    NTSTATUS Status;
 
-    /* If this is an API bitmap, free the bits */
-    if (pvBits != NULL &&
-        (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP))
+    /* Check if the surface has bits */
+    if (pvBits)
     {
-        /* Check if we have a DIB section */
-        if (psurf->hSecure)
+        /* Only bitmaps can have bits */
+        ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
+
+        /* Check if it is a DIB section */
+        if (psurf->hDIBSection)
         {
-            // FIXME: IMPLEMENT ME!
-            // MmUnsecureVirtualMemory(psurf->hSecure);
-            if (psurf->hDIBSection)
+            /* Unsecure the memory */
+            EngUnsecureMem(psurf->hSecure);
+
+            /* Calculate the real start of the section */
+            pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
+
+            /* Unmap the section */
+            Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
+            if (!NT_SUCCESS(Status))
             {
-                /* DIB was created from a section */
-                NTSTATUS Status;
-
-                pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
-                Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits);
-                if (!NT_SUCCESS(Status))
-                {
-                    DPRINT1("Could not unmap section view!\n");
-                    // Should we BugCheck here?
-                }
+                DPRINT1("Could not unmap section view!\n");
+                // Should we BugCheck here?
+                ASSERT(FALSE);
             }
-            else
+        }
+        else if (psurf->SurfObj.fjBitmap & BMF_USERMEM)
+        {
+            /* Bitmap was allocated from usermode memory */
+            EngFreeUserMem(pvBits);
+        }
+        else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION)
+        {
+            /* Bitmap was allocated from a kernel section */
+            if (!EngFreeSectionMem(NULL, pvBits))
             {
-                /* DIB was allocated */
-                EngFreeUserMem(pvBits);
+                DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits);
+                // Should we BugCheck here?
+                ASSERT(FALSE);
             }
         }
-        else
+        else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
         {
-            // FIXME: use TAG
-            ExFreePool(psurf->SurfObj.pvBits);
+            /* HACK: Free RLE decompressed bits */
+            EngFreeMem(pvBits);
         }
-
-        if (psurf->hDIBPalette != NULL)
+        else
         {
-            GreDeleteObject(psurf->hDIBPalette);
+            /* There should be nothing to free */
+            ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
         }
     }
 
-    if (NULL != psurf->BitsLock)
+    /* Free palette */
+    if(psurf->ppal)
     {
-        ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
-        psurf->BitsLock = NULL;
+        PALETTE_ShareUnlockPalette(psurf->ppal);
     }
 
     return TRUE;
 }
 
-BOOL INTERNAL_CALL
-SURFACE_InitBitsLock(PSURFACE psurf)
+
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+    IN ULONG iType,
+    IN ULONG cx,
+    IN ULONG cy,
+    IN ULONG iFormat)
 {
-    psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
-                          sizeof(FAST_MUTEX),
-                          TAG_SURFACE);
-    if (NULL == psurf->BitsLock)
+    PSURFACE psurf;
+    SURFOBJ *pso;
+
+    /* Verify format */
+    if (iFormat < BMF_1BPP || iFormat > BMF_PNG)
     {
-        return FALSE;
+        DPRINT1("Invalid bitmap format: %ld\n", iFormat);
+        return NULL;
     }
 
-    ExInitializeFastMutex(psurf->BitsLock);
-
-    return TRUE;
-}
+    /* Allocate a SURFACE object */
+    psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, sizeof(SURFACE));
 
-void INTERNAL_CALL
-SURFACE_CleanupBitsLock(PSURFACE psurf)
-{
-    if (NULL != psurf->BitsLock)
+    if (psurf)
     {
-        ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
-        psurf->BitsLock = NULL;
+        /* Initialize the basic fields */
+        pso = &psurf->SurfObj;
+        pso->hsurf = psurf->BaseObject.hHmgr;
+        pso->sizlBitmap.cx = cx;
+        pso->sizlBitmap.cy = cy;
+        pso->iBitmapFormat = iFormat;
+        pso->iType = iType;
+        pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface);
+
+        /* Assign a default palette and increment its reference count */
+        psurf->ppal = appalSurfaceDefault[iFormat];
+        GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
     }
-}
 
+    return psurf;
+}
 
-/*
- * @implemented
- */
-HBITMAP APIENTRY
-EngCreateDeviceBitmap(IN DHSURF dhsurf,
-                      IN SIZEL Size,
-                      IN ULONG Format)
+BOOL
+NTAPI
+SURFACE_bSetBitmapBits(
+    IN PSURFACE psurf,
+    IN USHORT fjBitmap,
+    IN ULONG ulWidth,
+    IN PVOID pvBits OPTIONAL)
 {
-    HBITMAP NewBitmap;
-    SURFOBJ *pso;
+    SURFOBJ *pso = &psurf->SurfObj;
+    PVOID pvSection;
+    UCHAR cBitsPixel;
 
-    NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
-    if (!NewBitmap)
-    {
-        DPRINT1("EngCreateBitmap failed\n");
-        return 0;
-    }
+    /* Only bitmaps can have bits */
+    ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
+
+    /* Get bits per pixel from the format */
+    cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
 
-    pso = EngLockSurface((HSURF)NewBitmap);
-    if (!pso)
+    /* Is a width in bytes given? */
+    if (ulWidth)
     {
-        DPRINT1("EngLockSurface failed on newly created bitmap!\n");
-        GreDeleteObject(NewBitmap);
-        return NULL;
+        /* Align the width (Windows compatibility, drivers expect that) */
+        ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel);
     }
+       else
+       {
+        /* Calculate width from the bitmap width in pixels */
+        ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel);
+       }
 
-    pso->dhsurf = dhsurf;
-    EngUnlockSurface(pso);
-
-    return NewBitmap;
-}
+    /* Calculate the bitmap size in bytes */
+    pso->cjBits = ulWidth * pso->sizlBitmap.cy;
 
-VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
-{
-    int x = 0;
-    int y = Size.cy - 1;
-    int c;
-    int length;
-    int width = ((Size.cx+1)/2);
-    int height = Size.cy - 1;
-    BYTE *begin = CompressedBits;
-    BYTE *bits = CompressedBits;
-    BYTE *temp;
-    while (y >= 0)
+    /* Did the caller provide bits? */
+    if (pvBits)
     {
-        length = *bits++ / 2;
-        if (length)
-        {
-            c = *bits++;
-            while (length--)
-            {
-                if (x >= width) break;
-                temp = UncompressedBits + (((height - y) * Delta) + x);
-                x++;
-                *temp = c;
-            }
-        }
-        else
-        {
-            length = *bits++;
-            switch (length)
-            {
-                case RLE_EOL:
-                    x = 0;
-                    y--;
-                    break;
-                case RLE_END:
-                    return;
-                case RLE_DELTA:
-                    x += (*bits++)/2;
-                    y -= (*bits++)/2;
-                    break;
-                default:
-                    length /= 2;
-                    while (length--)
-                    {
-                        c = *bits++;
-                        if (x < width)
-                        {
-                            temp = UncompressedBits + (((height - y) * Delta) + x);
-                            x++;
-                            *temp = c;
-                        }
-                    }
-                    if ((bits - begin) & 1)
-                    {
-                        bits++;
-                    }
-            }
-        }
+        /* Yes, so let him free it */
+        fjBitmap |= BMF_DONT_FREE;
     }
-}
-
-VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
-{
-    int x = 0;
-    int y = Size.cy - 1;
-    int c;
-    int length;
-    int width = Size.cx;
-    int height = Size.cy - 1;
-    BYTE *begin = CompressedBits;
-    BYTE *bits = CompressedBits;
-    BYTE *temp;
-    while (y >= 0)
+    else if (pso->cjBits)
     {
-        length = *bits++;
-        if (length)
+        /* We must allocate memory, check what kind */
+        if (fjBitmap & BMF_USERMEM)
         {
-            c = *bits++;
-            while (length--)
-            {
-                if (x >= width) break;
-                temp = UncompressedBits + (((height - y) * Delta) + x);
-                x++;
-                *temp = c;
-            }
+            /* User mode memory was requested */
+            pvBits = EngAllocUserMem(pso->cjBits, 0);
         }
         else
         {
-            length = *bits++;
-            switch (length)
-            {
-                case RLE_EOL:
-                    x = 0;
-                    y--;
-                    break;
-                case RLE_END:
-                    return;
-                case RLE_DELTA:
-                    x += *bits++;
-                    y -= *bits++;
-                    break;
-                default:
-                    while (length--)
-                    {
-                        c = *bits++;
-                        if (x < width)
-                        {
-                            temp = UncompressedBits + (((height - y) * Delta) + x);
-                            x++;
-                            *temp = c;
-                        }
-                    }
-                    if ((bits - begin) & 1)
-                    {
-                        bits++;
-                    }
-            }
+            /* Use a kernel mode section */
+            fjBitmap |= BMF_KMSECTION;
+            pvBits = EngAllocSectionMem(&pvSection,
+                                        (fjBitmap & BMF_NOZEROINIT) ?
+                                                0 : FL_ZERO_MEMORY,
+                                        pso->cjBits, TAG_DIB);
+
+            /* Free the section already, but keep the mapping */
+            if (pvBits) EngFreeSectionMem(pvSection, NULL);
         }
-    }
-}
-
-HBITMAP FASTCALL
-IntCreateBitmap(IN SIZEL Size,
-                IN LONG Width,
-                IN ULONG Format,
-                IN ULONG Flags,
-                IN PVOID Bits)
-{
-    HBITMAP hbmp;
-    SURFOBJ *pso;
-    PSURFACE psurf;
-    PVOID UncompressedBits;
-    ULONG UncompressedFormat;
-
-    if (Format == 0)
-        return 0;
 
-    psurf = SURFACE_AllocSurfaceWithHandle();
-    if (psurf == NULL)
-    {
-        return 0;
-    }
-    hbmp = psurf->BaseObject.hHmgr;
-
-    if (! SURFACE_InitBitsLock(psurf))
-    {
-        SURFACE_UnlockSurface(psurf);
-        SURFACE_FreeSurfaceByHandle(hbmp);
-        return 0;
+        /* Check for failure */
+        if (!pvBits) return FALSE;
     }
-    pso = &psurf->SurfObj;
 
-    if (Format == BMF_4RLE)
-    {
-        pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
-        pso->cjBits = pso->lDelta * Size.cy;
-        UncompressedFormat = BMF_4BPP;
-        UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
-        Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
-    }
-    else if (Format == BMF_8RLE)
+    /* Set pvBits, pvScan0 and lDelta */
+    pso->pvBits = pvBits;
+    if (fjBitmap & BMF_TOPDOWN)
     {
-        pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
-        pso->cjBits = pso->lDelta * Size.cy;
-        UncompressedFormat = BMF_8BPP;
-        UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
-        Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
+        /* Topdown is the normal way */
+        pso->pvScan0 = pso->pvBits;
+        pso->lDelta = ulWidth;
     }
     else
     {
-        pso->lDelta = abs(Width);
-        pso->cjBits = pso->lDelta * Size.cy;
-        UncompressedBits = Bits;
-        UncompressedFormat = Format;
+        /* Inversed bitmap (bottom up) */
+        pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
+        pso->lDelta = -ulWidth;
     }
 
-    if (UncompressedBits != NULL)
-    {
-        pso->pvBits = UncompressedBits;
-    }
-    else
-    {
-        if (pso->cjBits == 0)
-        {
-            pso->pvBits = NULL;
-        }
-        else
-        {
-            if (0 != (Flags & BMF_USERMEM))
-            {
-                pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
-            }
-            else
-            {
-                pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
-                                                  0 : FL_ZERO_MEMORY,
-                                              pso->cjBits, TAG_DIB);
-            }
-            if (pso->pvBits == NULL)
-            {
-                SURFACE_UnlockSurface(psurf);
-                SURFACE_FreeSurfaceByHandle(hbmp);
-                SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-                return 0;
-            }
-        }
-    }
+    pso->fjBitmap = fjBitmap;
+
+    /* Success */
+    return TRUE;
+}
 
-    if (0 == (Flags & BMF_TOPDOWN))
+HBITMAP
+APIENTRY
+EngCreateBitmap(
+    IN SIZEL sizl,
+    IN LONG lWidth,
+    IN ULONG iFormat,
+    IN ULONG fl,
+    IN PVOID pvBits)
+{
+    PSURFACE psurf;
+    HBITMAP hbmp;
+
+    /* Allocate a surface */
+    psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
+    if (!psurf)
     {
-        pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
-        pso->lDelta = - pso->lDelta;
+        DPRINT1("SURFACE_AllocSurface failed.\n");
+        return NULL;
     }
-    else
+
+    /* Get the handle for the bitmap */
+    hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+    /* Set the bitmap bits */
+    if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
     {
-        pso->pvScan0 = pso->pvBits;
+        /* Bail out if that failed */
+        DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+        GDIOBJ_vDeleteObject(&psurf->BaseObject);
+        return NULL;
     }
 
-    pso->dhsurf = 0; /* device managed surface */
-    pso->hsurf = (HSURF)hbmp;
-    pso->dhpdev = NULL;
-    pso->hdev = NULL;
-    pso->sizlBitmap = Size;
-    pso->iBitmapFormat = UncompressedFormat;
-    pso->iType = STYPE_BITMAP;
-    pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
-    pso->iUniq = 0;
-
-    psurf->flHooks = 0;
-    psurf->flFlags = 0;
-    psurf->dimension.cx = 0;
-    psurf->dimension.cy = 0;
-    
-    psurf->hSecure = NULL;
-    psurf->hDIBSection = NULL;
+    /* Set public ownership */
+    GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
 
+    /* Unlock the surface and return */
     SURFACE_UnlockSurface(psurf);
-
     return hbmp;
 }
 
 /*
  * @implemented
  */
-HBITMAP APIENTRY
-EngCreateBitmap(IN SIZEL Size,
-                IN LONG Width,
-                IN ULONG Format,
-                IN ULONG Flags,
-                IN PVOID Bits)
+HBITMAP
+APIENTRY
+EngCreateDeviceBitmap(
+    IN DHSURF dhsurf,
+    IN SIZEL sizl,
+    IN ULONG iFormat)
 {
-    HBITMAP hNewBitmap;
+    PSURFACE psurf;
+    HBITMAP hbmp;
 
-    hNewBitmap = IntCreateBitmap(Size, Width, Format, Flags, Bits);
-    if ( !hNewBitmap )
+    /* Allocate a surface */
+    psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
+    if (!psurf)
+    {
         return 0;
+    }
+
+    /* Set the device handle */
+    psurf->SurfObj.dhsurf = dhsurf;
 
-    GDIOBJ_SetOwnership(hNewBitmap, NULL);
+    /* Get the handle for the bitmap */
+    hbmp = (HBITMAP)psurf->SurfObj.hsurf;
 
-    return hNewBitmap;
+    /* Set public ownership */
+    GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
+
+    /* Unlock the surface and return */
+    SURFACE_UnlockSurface(psurf);
+    return hbmp;
 }
 
-/*
- * @unimplemented
- */
-HSURF APIENTRY
-EngCreateDeviceSurface(IN DHSURF dhsurf,
-                       IN SIZEL Size,
-                       IN ULONG Format)
+HSURF
+APIENTRY
+EngCreateDeviceSurface(
+    IN DHSURF dhsurf,
+    IN SIZEL sizl,
+    IN ULONG iFormat)
 {
-    HSURF hsurf;
-    SURFOBJ *pso;
     PSURFACE psurf;
+    HSURF hsurf;
 
-    psurf = SURFACE_AllocSurfaceWithHandle();
+    /* Allocate a surface */
+    psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
     if (!psurf)
     {
         return 0;
     }
 
-    hsurf = psurf->BaseObject.hHmgr;
-    GDIOBJ_SetOwnership(hsurf, NULL);
-
-    if (!SURFACE_InitBitsLock(psurf))
-    {
-        SURFACE_UnlockSurface(psurf);
-        SURFACE_FreeSurfaceByHandle(hsurf);
-        return 0;
-    }
-    pso = &psurf->SurfObj;
+    /* Set the device handle */
+    psurf->SurfObj.dhsurf = dhsurf;
 
-    pso->dhsurf = dhsurf;
-    pso->hsurf = hsurf;
-    pso->sizlBitmap = Size;
-    pso->iBitmapFormat = Format;
-    pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
-    pso->iType = STYPE_DEVICE;
-    pso->iUniq = 0;
+    /* Get the handle for the surface */
+    hsurf = psurf->SurfObj.hsurf;
 
-    psurf->flHooks = 0;
+    /* Set public ownership */
+    GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
 
+    /* Unlock the surface and return */
     SURFACE_UnlockSurface(psurf);
-
     return hsurf;
 }
 
-/*
- * @implemented
- */
 BOOL
 APIENTRY
 EngAssociateSurface(
@@ -527,7 +376,7 @@ EngAssociateSurface(
     ppdev = (PDEVOBJ*)hdev;
 
     /* Lock the surface */
-    psurf = SURFACE_LockSurface(hsurf);
+    psurf = SURFACE_ShareLockSurface(hsurf);
     if (!psurf)
     {
         return FALSE;
@@ -539,17 +388,19 @@ EngAssociateSurface(
     pso->dhpdev = ppdev->dhpdev;
 
     /* Hook up specified functions */
-    psurf->flHooks = flHooks;
+    psurf->flags &= ~HOOK_FLAGS;
+    psurf->flags |= (flHooks & HOOK_FLAGS);
 
-    SURFACE_UnlockSurface(psurf);
+    /* Get palette */
+    psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
+
+    SURFACE_ShareUnlockSurface(psurf);
 
     return TRUE;
 }
 
-/*
- * @implemented
- */
-BOOL APIENTRY
+BOOL
+APIENTRY
 EngModifySurface(
     IN HSURF hsurf,
     IN HDEV hdev,
@@ -564,7 +415,7 @@ EngModifySurface(
     PSURFACE psurf;
     PDEVOBJ* ppdev;
 
-    psurf = SURFACE_LockSurface(hsurf);
+    psurf = SURFACE_ShareLockSurface(hsurf);
     if (psurf == NULL)
     {
         return FALSE;
@@ -581,35 +432,45 @@ EngModifySurface(
     pso->dhpdev = ppdev->dhpdev;
 
     /* Hook up specified functions */
-    psurf->flHooks = flHooks;
+    psurf->flags &= ~HOOK_FLAGS;
+    psurf->flags |= (flHooks & HOOK_FLAGS);
 
-    SURFACE_UnlockSurface(psurf);
+    /* Get palette */
+    psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
+
+    SURFACE_ShareUnlockSurface(psurf);
 
     return TRUE;
 }
 
-/*
- * @implemented
- */
-BOOL APIENTRY
+
+BOOL
+APIENTRY
 EngDeleteSurface(IN HSURF hsurf)
 {
-    GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
-    SURFACE_FreeSurfaceByHandle(hsurf);
+    PSURFACE psurf;
+
+    psurf = SURFACE_ShareLockSurface(hsurf);
+    if (!psurf)
+    {
+        DPRINT1("Could not reference surface to delete\n");
+        return FALSE;
+    }
+
+    GDIOBJ_vDeleteObject(&psurf->BaseObject);
     return TRUE;
 }
 
-/*
- * @implemented
- */
-BOOL APIENTRY
-EngEraseSurface(SURFOBJ *pso,
-                RECTL *Rect,
-                ULONG iColor)
+BOOL
+APIENTRY
+EngEraseSurface(
+    SURFOBJ *pso,
+    RECTL *prcl,
+    ULONG iColor)
 {
     ASSERT(pso);
-    ASSERT(Rect);
-    return FillSolid(pso, Rect, iColor);
+    ASSERT(prcl);
+    return FillSolid(pso, prcl, iColor);
 }
 
 /*
@@ -622,42 +483,32 @@ NtGdiEngLockSurface(IN HSURF hsurf)
 }
 
 
-/*
- * @implemented
- */
-SURFOBJ * APIENTRY
+SURFOBJ *
+APIENTRY
 EngLockSurface(IN HSURF hsurf)
 {
-    SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
-
-    if (psurf != NULL)
-        return &psurf->SurfObj;
+    SURFACE *psurf = SURFACE_ShareLockSurface(hsurf);
 
-    return NULL;
+    return psurf ? &psurf->SurfObj : NULL;
 }
 
-
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
 NtGdiEngUnlockSurface(IN SURFOBJ *pso)
 {
-    EngUnlockSurface(pso);
+    UNIMPLEMENTED;
+    ASSERT(FALSE);
 }
 
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
 EngUnlockSurface(IN SURFOBJ *pso)
 {
     if (pso != NULL)
     {
         SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
-        GDIOBJ_ShareUnlockObjByPtr((POBJ)psurf);
+        SURFACE_ShareUnlockSurface(psurf);
     }
 }
 
-
 /* EOF */