/*
- * 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$
- *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Surace Functions
enum Rle_EscapeCodes
{
- RLE_EOL = 0, /* End of line */
- RLE_END = 1, /* End of bitmap */
- RLE_DELTA = 2 /* Delta */
+ RLE_EOL = 0, /* End of line */
+ RLE_END = 1, /* End of bitmap */
+ RLE_DELTA = 2 /* Delta */
};
INT FASTCALL BitsPerFormat(ULONG Format)
{
- switch(Format)
- {
- case BMF_1BPP: return 1;
- case BMF_4BPP:
- case BMF_4RLE: return 4;
- case BMF_8BPP:
- case BMF_8RLE: return 8;
- case BMF_16BPP: return 16;
- case BMF_24BPP: return 24;
- case BMF_32BPP: return 32;
- default: return 0;
- }
+ 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;
+
+ case BMF_32BPP:
+ return 32;
+
+ default:
+ return 0;
+ }
}
ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
{
- switch(Compression)
- {
- case BI_RGB:
- 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;
- }
- return 0;
-
- case BI_RLE4: return BMF_4RLE;
- case BI_RLE8: return BMF_8RLE;
-
- default: return 0;
- }
+ switch (Compression)
+ {
+ 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;
+ }
+ return 0;
+
+ case BI_RLE4:
+ return BMF_4RLE;
+
+ case BI_RLE8:
+ return BMF_8RLE;
+
+ default:
+ return 0;
+ }
}
BOOL INTERNAL_CALL
-BITMAPOBJ_InitBitsLock(BITMAPOBJ *BitmapObj)
+SURFACE_Cleanup(PVOID ObjectBody)
{
- BitmapObj->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(FAST_MUTEX),
- TAG_BITMAPOBJ);
- if (NULL == BitmapObj->BitsLock)
+ PSURFACE psurf = (PSURFACE)ObjectBody;
+ PVOID pvBits = psurf->SurfObj.pvBits;
+
+ /* If this is an API bitmap, free the bits */
+ if (pvBits != NULL &&
+ (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP))
{
- return FALSE;
+ /* Check if we have a DIB section */
+ if (psurf->hSecure)
+ {
+ // FIXME: IMPLEMENT ME!
+ // MmUnsecureVirtualMemory(psurf->hSecure);
+ if (psurf->hDIBSection)
+ {
+ /* 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?
+ }
+ }
+ else
+ {
+ /* DIB was allocated */
+ EngFreeUserMem(pvBits);
+ }
+ }
+ else
+ {
+ // FIXME: use TAG
+ ExFreePool(psurf->SurfObj.pvBits);
+ }
+
+ if (psurf->hDIBPalette != NULL)
+ {
+ GreDeleteObject(psurf->hDIBPalette);
+ }
}
- ExInitializeFastMutex(BitmapObj->BitsLock);
+ if (NULL != psurf->BitsLock)
+ {
+ ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
+ psurf->BitsLock = NULL;
+ }
- return TRUE;
+ return TRUE;
+}
+
+BOOL INTERNAL_CALL
+SURFACE_InitBitsLock(PSURFACE psurf)
+{
+ psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(FAST_MUTEX),
+ TAG_SURFACE);
+ if (NULL == psurf->BitsLock)
+ {
+ return FALSE;
+ }
+
+ ExInitializeFastMutex(psurf->BitsLock);
+
+ return TRUE;
}
void INTERNAL_CALL
-BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *BitmapObj)
+SURFACE_CleanupBitsLock(PSURFACE psurf)
{
- if (NULL != BitmapObj->BitsLock)
+ if (NULL != psurf->BitsLock)
{
- ExFreePoolWithTag(BitmapObj->BitsLock, TAG_BITMAPOBJ);
- BitmapObj->BitsLock = NULL;
+ ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
+ psurf->BitsLock = NULL;
}
}
/*
* @implemented
*/
-HBITMAP STDCALL
+HBITMAP APIENTRY
EngCreateDeviceBitmap(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
+ IN SIZEL Size,
+ IN ULONG Format)
{
- HBITMAP NewBitmap;
- SURFOBJ *SurfObj;
+ HBITMAP NewBitmap;
+ SURFOBJ *pso;
+
+ NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
+ if (!NewBitmap)
+ {
+ DPRINT1("EngCreateBitmap failed\n");
+ return 0;
+ }
- NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
- if(!NewBitmap)
- {
- DPRINT1("EngCreateBitmap failed\n");
- return 0;
- }
+ pso = EngLockSurface((HSURF)NewBitmap);
+ if (!pso)
+ {
+ DPRINT1("EngLockSurface failed on newly created bitmap!\n");
+ GreDeleteObject(NewBitmap);
+ return NULL;
+ }
- SurfObj = EngLockSurface((HSURF)NewBitmap);
- SurfObj->dhsurf = dhsurf;
- EngUnlockSurface(SurfObj);
+ pso->dhsurf = dhsurf;
+ EngUnlockSurface(pso);
- return NewBitmap;
+ return NewBitmap;
}
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)
- {
- 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++;
- }
- }
- }
+ 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)
+ {
+ 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++;
+ }
+ }
+ }
+ }
}
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)
- {
- length = *bits++;
- 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++;
- 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++;
- }
- }
- }
+ 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)
+ {
+ length = *bits++;
+ 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++;
+ 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++;
+ }
+ }
+ }
+ }
}
HBITMAP FASTCALL
IntCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+ IN LONG Width,
+ IN ULONG Format,
+ IN ULONG Flags,
+ IN PVOID Bits)
{
- HBITMAP NewBitmap;
- SURFOBJ *SurfObj;
- BITMAPOBJ *BitmapObj;
- PVOID UncompressedBits;
- ULONG UncompressedFormat;
+ HBITMAP hbmp;
+ SURFOBJ *pso;
+ PSURFACE psurf;
+ PVOID UncompressedBits;
+ ULONG UncompressedFormat;
- if (Format == 0)
- return 0;
+ if (Format == 0)
+ return 0;
- NewBitmap = BITMAPOBJ_AllocBitmap();
- if (NewBitmap == NULL)
- return 0;
+ psurf = SURFACE_AllocSurfaceWithHandle();
+ if (psurf == NULL)
+ {
+ return 0;
+ }
+ hbmp = psurf->BaseObject.hHmgr;
- BitmapObj = BITMAPOBJ_LockBitmap(NewBitmap);
- if (! BITMAPOBJ_InitBitsLock(BitmapObj))
+ if (! SURFACE_InitBitsLock(psurf))
{
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- BITMAPOBJ_FreeBitmap(NewBitmap);
- return 0;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ return 0;
}
- SurfObj = &BitmapObj->SurfObj;
+ pso = &psurf->SurfObj;
- if (Format == BMF_4RLE)
+ 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);
+ 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)
+ 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);
+ 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);
}
- else
+ else
{
- SurfObj->lDelta = abs(Width);
- SurfObj->cjBits = SurfObj->lDelta * Size.cy;
- UncompressedBits = Bits;
- UncompressedFormat = Format;
+ pso->lDelta = abs(Width);
+ pso->cjBits = pso->lDelta * Size.cy;
+ UncompressedBits = Bits;
+ UncompressedFormat = Format;
}
- if (UncompressedBits != NULL)
+ if (UncompressedBits != NULL)
{
- SurfObj->pvBits = UncompressedBits;
+ pso->pvBits = UncompressedBits;
}
- else
+ else
{
- if (SurfObj->cjBits == 0)
+ if (pso->cjBits == 0)
{
- SurfObj->pvBits = NULL;
+ pso->pvBits = NULL;
}
- else
+ else
{
- if (0 != (Flags & BMF_USERMEM))
+ if (0 != (Flags & BMF_USERMEM))
{
- SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
+ pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
}
- else
+ else
{
- SurfObj->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
- SurfObj->cjBits, 0);
+ pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
+ 0 : FL_ZERO_MEMORY,
+ pso->cjBits, TAG_DIB);
}
- if (SurfObj->pvBits == NULL)
+ if (pso->pvBits == NULL)
{
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- BITMAPOBJ_FreeBitmap(NewBitmap);
- return 0;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
}
}
- }
-
+ }
- if (0 == (Flags & BMF_TOPDOWN))
+ if (0 == (Flags & BMF_TOPDOWN))
{
- SurfObj->pvScan0 = (PVOID) ((ULONG_PTR) SurfObj->pvBits + SurfObj->cjBits - SurfObj->lDelta);
- SurfObj->lDelta = - SurfObj->lDelta;
+ pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
+ pso->lDelta = - pso->lDelta;
}
- else
+ else
+ {
+ pso->pvScan0 = pso->pvBits;
+ }
+
+ 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;
+
+ SURFACE_UnlockSurface(psurf);
+
+ return hbmp;
+}
+
+/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
+typedef struct _DEVBITMAPINFO
+{
+ ULONG Format;
+ ULONG Width;
+ ULONG Height;
+ ULONG Flags;
+ ULONG Size;
+} DEVBITMAPINFO, *PDEVBITMAPINFO;
+
+SURFOBJ*
+FASTCALL
+SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
+ IN PVOID Bits)
+{
+ BOOLEAN Compressed = FALSE;
+ ULONG ScanLine = 0; // Compiler is dumb
+ ULONG Size;
+ SURFOBJ *pso;
+ PSURFACE psurf;
+ SIZEL LocalSize;
+ BOOLEAN AllocatedLocally = FALSE;
+
+ /*
+ * First, check the format so we can get the aligned scanline width.
+ * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
+ * since they are compressed surfaces!
+ */
+ switch (BitmapInfo->Format)
{
- SurfObj->pvScan0 = SurfObj->pvBits;
+ case BMF_1BPP:
+ ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
+ break;
+
+ case BMF_4BPP:
+ ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
+ break;
+
+ case BMF_8BPP:
+ ScanLine = (BitmapInfo->Width + 3) & ~3;
+ break;
+
+ case BMF_16BPP:
+ ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
+ break;
+
+ case BMF_24BPP:
+ ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
+ break;
+
+ case BMF_32BPP:
+ ScanLine = BitmapInfo->Width << 2;
+ break;
+
+ case BMF_8RLE:
+ case BMF_4RLE:
+ case BMF_JPEG:
+ case BMF_PNG:
+ Compressed = TRUE;
+ break;
+
+ default:
+ DPRINT1("Invalid bitmap format\n");
+ return NULL;
}
- 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->iUniq = 0;
+ /* Does the device manage its own surface? */
+ if (!Bits)
+ {
+ /* We need to allocate bits for the caller, figure out the size */
+ if (Compressed)
+ {
+ /* Note: we should not be seeing this scenario from ENGDDI */
+ ASSERT(FALSE);
+ Size = BitmapInfo->Size;
+ }
+ else
+ {
+ /* The height times the bytes for each scanline */
+ Size = BitmapInfo->Height * ScanLine;
+ }
+
+ if (Size)
+ {
+ /* Check for allocation flag */
+ if (BitmapInfo->Flags & BMF_USERMEM)
+ {
+ /* Get the bits from user-mode memory */
+ Bits = EngAllocUserMem(Size, 'mbuG');
+ }
+ else
+ {
+ /* Get kernel bits (zeroed out if requested) */
+ Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
+ Size,
+ TAG_DIB);
+ }
+ AllocatedLocally = TRUE;
+ /* Bail out if that failed */
+ if (!Bits) return NULL;
+ }
+ }
+ else
+ {
+ /* Should not have asked for user memory */
+ ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
+ }
- BitmapObj->flHooks = 0;
- BitmapObj->flFlags = 0;
- BitmapObj->dimension.cx = 0;
- BitmapObj->dimension.cy = 0;
- BitmapObj->dib = NULL;
+ /* Allocate the actual surface object structure */
+ psurf = SURFACE_AllocSurfaceWithHandle();
+ if (!psurf)
+ {
+ if(Bits && AllocatedLocally)
+ {
+ if(BitmapInfo->Flags & BMF_USERMEM)
+ EngFreeUserMem(Bits);
+ else
+ EngFreeMem(Bits);
+ }
+ return NULL;
+ }
- BITMAPOBJ_UnlockBitmap(BitmapObj);
+ /* Lock down the surface */
+ if (!SURFACE_InitBitsLock(psurf))
+ {
+ /* Bail out if that failed */
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr);
+ return NULL;
+ }
- return NewBitmap;
+ /* We should now have our surface object */
+ pso = &psurf->SurfObj;
+
+ /* Save format and flags */
+ pso->iBitmapFormat = BitmapInfo->Format;
+ pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
+
+ /* Save size and type */
+ LocalSize.cy = BitmapInfo->Height;
+ LocalSize.cx = BitmapInfo->Width;
+ pso->sizlBitmap = LocalSize;
+ pso->iType = STYPE_BITMAP;
+
+ /* Device-managed surface, no flags or dimension */
+ pso->dhsurf = 0;
+ pso->dhpdev = NULL;
+ pso->hdev = NULL;
+ psurf->flFlags = 0;
+ psurf->dimension.cx = 0;
+ psurf->dimension.cy = 0;
+ psurf->hSecure = NULL;
+ psurf->hDIBSection = NULL;
+ psurf->flHooks = 0;
+
+ /* Set bits */
+ pso->pvBits = Bits;
+
+ /* Check for bitmap type */
+ if (!Compressed)
+ {
+ /* Number of bits is based on the height times the scanline */
+ pso->cjBits = BitmapInfo->Height * ScanLine;
+ if (BitmapInfo->Flags & BMF_TOPDOWN)
+ {
+ /* For topdown, the base address starts with the bits */
+ pso->pvScan0 = pso->pvBits;
+ pso->lDelta = ScanLine;
+ }
+ else
+ {
+ /* Otherwise we start with the end and go up */
+ pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
+ pso->lDelta = -ScanLine;
+ }
+ }
+ else
+ {
+ /* Compressed surfaces don't have scanlines! */
+ pso->lDelta = 0;
+ pso->cjBits = BitmapInfo->Size;
+
+ /* Check for JPG or PNG */
+ if ((BitmapInfo->Format != BMF_JPEG) && (BitmapInfo->Format != BMF_PNG))
+ {
+ /* Wherever the bit data is */
+ pso->pvScan0 = pso->pvBits;
+ }
+ else
+ {
+ /* Fancy formats don't use a base address */
+ pso->pvScan0 = NULL;
+ ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
+ }
+ }
+
+ /* Finally set the handle and uniq */
+ pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
+ pso->iUniq = 0;
+
+ /* Unlock and return the surface */
+ SURFACE_UnlockSurface(psurf);
+ return pso;
}
/*
* @implemented
*/
-HBITMAP STDCALL
+HBITMAP
+APIENTRY
EngCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+ 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;
-
- GDIOBJ_SetOwnership(GdiHandleTable, NewBitmap, NULL);
-
- return NewBitmap;
+ SURFOBJ* Surface;
+ DEVBITMAPINFO BitmapInfo;
+
+ /* Capture the parameters */
+ BitmapInfo.Format = Format;
+ BitmapInfo.Width = Size.cx;
+ BitmapInfo.Height = Size.cy;
+ BitmapInfo.Flags = Flags;
+
+ /*
+ * If the display driver supports framebuffer access, use the scanline width
+ * to determine the actual width of the bitmap, and convert it to pels instead
+ * of bytes.
+ */
+ if ((Bits) && (Width))
+ {
+ switch (BitmapInfo.Format)
+ {
+ /* Do the conversion for each bit depth we support */
+ case BMF_1BPP:
+ BitmapInfo.Width = Width * 8;
+ break;
+ case BMF_4BPP:
+ BitmapInfo.Width = Width * 2;
+ break;
+ case BMF_8BPP:
+ BitmapInfo.Width = Width;
+ break;
+ case BMF_16BPP:
+ BitmapInfo.Width = Width / 2;
+ break;
+ case BMF_24BPP:
+ BitmapInfo.Width = Width / 3;
+ break;
+ case BMF_32BPP:
+ BitmapInfo.Width = Width / 4;
+ break;
+ }
+ }
+
+ /* Now create the surface */
+ Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
+ if (!Surface) return 0;
+
+ /* Set public ownership and reutrn the handle */
+ GDIOBJ_SetOwnership(Surface->hsurf, NULL);
+ return Surface->hsurf;
}
/*
* @unimplemented
*/
-HSURF STDCALL
+HSURF APIENTRY
EngCreateDeviceSurface(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
+ IN SIZEL Size,
+ IN ULONG Format)
{
- HSURF NewSurface;
- SURFOBJ *SurfObj;
- BITMAPOBJ *BitmapObj;
+ HSURF hsurf;
+ SURFOBJ *pso;
+ PSURFACE psurf;
- NewSurface = (HSURF)BITMAPOBJ_AllocBitmap();
- if (NewSurface == NULL)
- return 0;
+ psurf = SURFACE_AllocSurfaceWithHandle();
+ if (!psurf)
+ {
+ return 0;
+ }
- GDIOBJ_SetOwnership(GdiHandleTable, NewSurface, NULL);
+ hsurf = psurf->BaseObject.hHmgr;
+ GDIOBJ_SetOwnership(hsurf, NULL);
- BitmapObj = BITMAPOBJ_LockBitmap(NewSurface);
- if (! BITMAPOBJ_InitBitsLock(BitmapObj))
+ if (!SURFACE_InitBitsLock(psurf))
{
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- BITMAPOBJ_FreeBitmap(NewSurface);
- return 0;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hsurf);
+ return 0;
}
- SurfObj = &BitmapObj->SurfObj;
+ pso = &psurf->SurfObj;
- SurfObj->dhsurf = dhsurf;
- SurfObj->hsurf = NewSurface;
- SurfObj->sizlBitmap = Size;
- SurfObj->iBitmapFormat = Format;
- SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
- SurfObj->iType = STYPE_DEVICE;
- SurfObj->iUniq = 0;
+ 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;
- BitmapObj->flHooks = 0;
+ psurf->flHooks = 0;
- BITMAPOBJ_UnlockBitmap(BitmapObj);
+ SURFACE_UnlockSurface(psurf);
- return NewSurface;
-}
-
-PFN FASTCALL DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
-{
- ULONG i;
-
- for(i=0; i<DED->c; i++)
- {
- if(DED->pdrvfn[i].iFunc == DriverFunc)
- return DED->pdrvfn[i].pfn;
- }
- return NULL;
+ return hsurf;
}
/*
* @implemented
*/
-BOOL STDCALL
-EngAssociateSurface(IN HSURF Surface,
- IN HDEV Dev,
- IN ULONG Hooks)
+BOOL
+APIENTRY
+EngAssociateSurface(
+ IN HSURF hsurf,
+ IN HDEV hdev,
+ IN FLONG flHooks)
{
- SURFOBJ *SurfObj;
- BITMAPOBJ *BitmapObj;
- GDIDEVICE* Device;
+ SURFOBJ *pso;
+ PSURFACE psurf;
+ PDEVOBJ* ppdev;
- Device = (GDIDEVICE*)Dev;
+ ppdev = (PDEVOBJ*)hdev;
- BitmapObj = BITMAPOBJ_LockBitmap(Surface);
- ASSERT(BitmapObj);
- SurfObj = &BitmapObj->SurfObj;
+ /* Lock the surface */
+ psurf = SURFACE_LockSurface(hsurf);
+ if (!psurf)
+ {
+ return FALSE;
+ }
+ pso = &psurf->SurfObj;
- /* Associate the hdev */
- SurfObj->hdev = Dev;
- SurfObj->dhpdev = Device->PDev;
+ /* Associate the hdev */
+ pso->hdev = hdev;
+ pso->dhpdev = ppdev->dhpdev;
- /* Hook up specified functions */
- BitmapObj->flHooks = Hooks;
+ /* Hook up specified functions */
+ psurf->flHooks = flHooks;
- BITMAPOBJ_UnlockBitmap(BitmapObj);
+ SURFACE_UnlockSurface(psurf);
- return TRUE;
+ return TRUE;
}
/*
* @implemented
*/
-BOOL STDCALL
+BOOL APIENTRY
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)
+ 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;
+ SURFOBJ *pso;
+ PSURFACE psurf;
+ PDEVOBJ* ppdev;
- pso = EngLockSurface(hsurf);
- if (pso == NULL)
- {
- return FALSE;
- }
+ psurf = SURFACE_LockSurface(hsurf);
+ if (psurf == NULL)
+ {
+ return FALSE;
+ }
- if (!EngAssociateSurface(hsurf, hdev, flHooks))
- {
- EngUnlockSurface(pso);
+ ppdev = (PDEVOBJ*)hdev;
+ pso = &psurf->SurfObj;
+ pso->dhsurf = dhsurf;
+ pso->lDelta = lDelta;
+ pso->pvScan0 = pvScan0;
- return FALSE;
- }
+ /* Associate the hdev */
+ pso->hdev = hdev;
+ pso->dhpdev = ppdev->dhpdev;
- pso->dhsurf = dhsurf;
- pso->lDelta = lDelta;
- pso->pvScan0 = pvScan0;
+ /* Hook up specified functions */
+ psurf->flHooks = flHooks;
- EngUnlockSurface(pso);
+ SURFACE_UnlockSurface(psurf);
- return TRUE;
+ return TRUE;
}
/*
* @implemented
*/
-BOOL STDCALL
-EngDeleteSurface(IN HSURF Surface)
+BOOL APIENTRY
+EngDeleteSurface(IN HSURF hsurf)
{
- GDIOBJ_SetOwnership(GdiHandleTable, Surface, PsGetCurrentProcess());
- BITMAPOBJ_FreeBitmap(Surface);
- return TRUE;
+ GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
+ SURFACE_FreeSurfaceByHandle(hsurf);
+ return TRUE;
}
/*
* @implemented
*/
-BOOL STDCALL
-EngEraseSurface(SURFOBJ *Surface,
- RECTL *Rect,
- ULONG iColor)
+BOOL APIENTRY
+EngEraseSurface(SURFOBJ *pso,
+ RECTL *Rect,
+ ULONG iColor)
{
- ASSERT(Surface);
- ASSERT(Rect);
- return FillSolid(Surface, Rect, iColor);
+ ASSERT(pso);
+ ASSERT(Rect);
+ return FillSolid(pso, Rect, iColor);
}
-#define GDIBdyToHdr(body) \
- ((PGDIOBJHDR)(body) - 1)
-
-
/*
* @implemented
*/
-SURFOBJ * STDCALL
-NtGdiEngLockSurface(IN HSURF Surface)
+SURFOBJ * APIENTRY
+NtGdiEngLockSurface(IN HSURF hsurf)
{
- return EngLockSurface(Surface);
+ return EngLockSurface(hsurf);
}
/*
* @implemented
*/
-SURFOBJ * STDCALL
-EngLockSurface(IN HSURF Surface)
+SURFOBJ * APIENTRY
+EngLockSurface(IN HSURF hsurf)
{
- BITMAPOBJ *bmp = GDIOBJ_ShareLockObj(GdiHandleTable, Surface, GDI_OBJECT_TYPE_BITMAP);
+ SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
- if (bmp != NULL)
- return &bmp->SurfObj;
+ if (psurf != NULL)
+ return &psurf->SurfObj;
- return NULL;
+ return NULL;
}
/*
* @implemented
*/
-VOID STDCALL
-NtGdiEngUnlockSurface(IN SURFOBJ *Surface)
+VOID APIENTRY
+NtGdiEngUnlockSurface(IN SURFOBJ *pso)
{
- EngUnlockSurface(Surface);
+ EngUnlockSurface(pso);
}
/*
* @implemented
*/
-VOID STDCALL
-EngUnlockSurface(IN SURFOBJ *Surface)
+VOID APIENTRY
+EngUnlockSurface(IN SURFOBJ *pso)
{
- if (Surface != NULL)
- GDIOBJ_UnlockObjByPtr(GdiHandleTable, Surface);
+ if (pso != NULL)
+ {
+ SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
+ GDIOBJ_ShareUnlockObjByPtr((POBJ)psurf);
+ }
}