/* * 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 #include 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; }