Reactos
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Native DirectDraw implementation
5 * FILE: win32ss/reactx/ntddraw/d3dkmt.c
6 * PROGRAMER: Sebastian Gasiorek (sebastian.gasiorek@reactos.com)
7 */
8
9#include <win32k.h>
10
11DWORD
12APIENTRY
13NtGdiDdDDICreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc)
14{
15 PSURFACE psurf;
16 HDC hDC;
17
18 const struct d3dddi_format_info
19 {
20 D3DDDIFORMAT format;
21 unsigned int bit_count;
22 DWORD compression;
23 unsigned int palette_size;
24 DWORD mask_r, mask_g, mask_b;
25 } *format = NULL;
26 unsigned int i;
27
28 static const struct d3dddi_format_info format_info[] =
29 {
30 { D3DDDIFMT_R8G8B8, 24, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
31 { D3DDDIFMT_A8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
32 { D3DDDIFMT_X8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
33 { D3DDDIFMT_R5G6B5, 16, BI_BITFIELDS, 0, 0x0000f800, 0x000007e0, 0x0000001f },
34 { D3DDDIFMT_X1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
35 { D3DDDIFMT_A1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
36 { D3DDDIFMT_A4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
37 { D3DDDIFMT_X4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
38 { D3DDDIFMT_P8, 8, BI_RGB, 256, 0x00000000, 0x00000000, 0x00000000 },
39 };
40
41 if (!desc)
42 return STATUS_INVALID_PARAMETER;
43
44 if (!desc->pMemory)
45 return STATUS_INVALID_PARAMETER;
46
47 for (i = 0; i < sizeof(format_info) / sizeof(*format_info); ++i)
48 {
49 if (format_info[i].format == desc->Format)
50 {
51 format = &format_info[i];
52 break;
53 }
54 }
55
56 if (!format)
57 return STATUS_INVALID_PARAMETER;
58
59 if (desc->Width > (UINT_MAX & ~3) / (format->bit_count / 8) ||
60 !desc->Pitch || desc->Pitch < (((desc->Width * format->bit_count + 31) >> 3) & ~3) ||
61 !desc->Height || desc->Height > UINT_MAX / desc->Pitch)
62 {
63 return STATUS_INVALID_PARAMETER;
64 }
65
66 if (!desc->hDeviceDc || !(hDC = NtGdiCreateCompatibleDC(desc->hDeviceDc)))
67 {
68 return STATUS_INVALID_PARAMETER;
69 }
70
71 /* Allocate a surface */
72 psurf = SURFACE_AllocSurface(STYPE_BITMAP,
73 desc->Width,
74 desc->Height,
75 BitmapFormat(format->bit_count, format->compression),
76 BMF_TOPDOWN | BMF_NOZEROINIT,
77 desc->Pitch,
78 0,
79 desc->pMemory);
80
81 /* Mark as API bitmap */
82 psurf->flags |= (DDB_SURFACE | API_BITMAP);
83
84 desc->hDc = hDC;
85 /* Get the handle for the bitmap */
86 desc->hBitmap = (HBITMAP)psurf->SurfObj.hsurf;
87
88 /* Allocate a palette for this surface */
89 if (format->bit_count <= 8)
90 {
91 PPALETTE palette = PALETTE_AllocPalette(PAL_INDEXED, 1 << format->bit_count, NULL, 0, 0, 0);
92 if (palette)
93 {
94 SURFACE_vSetPalette(psurf, palette);
95 PALETTE_ShareUnlockPalette(palette);
96 }
97 }
98
99 /* Unlock the surface and return */
100 SURFACE_UnlockSurface(psurf);
101
102 NtGdiSelectBitmap(desc->hDc, desc->hBitmap);
103
104 return STATUS_SUCCESS;
105}
106
107DWORD
108APIENTRY
109NtGdiDdDDIDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc)
110{
111 if (!desc)
112 return STATUS_INVALID_PARAMETER;
113
114 if (GDI_HANDLE_GET_TYPE(desc->hDc) != GDI_OBJECT_TYPE_DC ||
115 GDI_HANDLE_GET_TYPE(desc->hBitmap) != GDI_OBJECT_TYPE_BITMAP)
116 return STATUS_INVALID_PARAMETER;
117
118 NtGdiDeleteObjectApp(desc->hBitmap);
119 NtGdiDeleteObjectApp(desc->hDc);
120
121 return STATUS_SUCCESS;
122}