reactos/win32ss/reactx/ntddraw/d3dkmt.c

124 lines
3.8 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Native DirectDraw implementation
* FILE: win32ss/reactx/ntddraw/d3dkmt.c
* PROGRAMER: Sebastian Gasiorek (sebastian.gasiorek@reactos.com)
*/
#include <win32k.h>
#include <debug.h>
DWORD
APIENTRY
NtGdiDdDDICreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc)
{
PSURFACE psurf;
HDC hDC;
const struct d3dddi_format_info
{
D3DDDIFORMAT format;
unsigned int bit_count;
DWORD compression;
unsigned int palette_size;
DWORD mask_r, mask_g, mask_b;
} *format = NULL;
unsigned int i;
static const struct d3dddi_format_info format_info[] =
{
{ D3DDDIFMT_R8G8B8, 24, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
{ D3DDDIFMT_A8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
{ D3DDDIFMT_X8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
{ D3DDDIFMT_R5G6B5, 16, BI_BITFIELDS, 0, 0x0000f800, 0x000007e0, 0x0000001f },
{ D3DDDIFMT_X1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
{ D3DDDIFMT_A1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
{ D3DDDIFMT_A4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
{ D3DDDIFMT_X4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
{ D3DDDIFMT_P8, 8, BI_RGB, 256, 0x00000000, 0x00000000, 0x00000000 },
};
if (!desc)
return STATUS_INVALID_PARAMETER;
if (!desc->pMemory)
return STATUS_INVALID_PARAMETER;
for (i = 0; i < sizeof(format_info) / sizeof(*format_info); ++i)
{
if (format_info[i].format == desc->Format)
{
format = &format_info[i];
break;
}
}
if (!format)
return STATUS_INVALID_PARAMETER;
if (desc->Width > (UINT_MAX & ~3) / (format->bit_count / 8) ||
!desc->Pitch || desc->Pitch < (((desc->Width * format->bit_count + 31) >> 3) & ~3) ||
!desc->Height || desc->Height > UINT_MAX / desc->Pitch)
{
return STATUS_INVALID_PARAMETER;
}
if (!desc->hDeviceDc || !(hDC = NtGdiCreateCompatibleDC(desc->hDeviceDc)))
{
return STATUS_INVALID_PARAMETER;
}
/* Allocate a surface */
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
desc->Width,
desc->Height,
BitmapFormat(format->bit_count, format->compression),
BMF_TOPDOWN | BMF_NOZEROINIT,
desc->Pitch,
0,
desc->pMemory);
/* Mark as API bitmap */
psurf->flags |= (DDB_SURFACE | API_BITMAP);
desc->hDc = hDC;
/* Get the handle for the bitmap */
desc->hBitmap = (HBITMAP)psurf->SurfObj.hsurf;
/* Allocate a palette for this surface */
if (format->bit_count <= 8)
{
PPALETTE palette = PALETTE_AllocPalette(PAL_INDEXED, 1 << format->bit_count, NULL, 0, 0, 0);
if (palette)
{
SURFACE_vSetPalette(psurf, palette);
PALETTE_ShareUnlockPalette(palette);
}
}
/* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
NtGdiSelectBitmap(desc->hDc, desc->hBitmap);
return STATUS_SUCCESS;
}
DWORD
APIENTRY
NtGdiDdDDIDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc)
{
if (!desc)
return STATUS_INVALID_PARAMETER;
if (GDI_HANDLE_GET_TYPE(desc->hDc) != GDI_OBJECT_TYPE_DC ||
GDI_HANDLE_GET_TYPE(desc->hBitmap) != GDI_OBJECT_TYPE_BITMAP)
return STATUS_INVALID_PARAMETER;
NtGdiDeleteObjectApp(desc->hBitmap);
NtGdiDeleteObjectApp(desc->hDc);
return STATUS_SUCCESS;
}