xref: /reactos/win32ss/reactx/ntddraw/d3dkmt.c (revision 7f26a396)
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 
11 DWORD
12 APIENTRY
13 NtGdiDdDDICreateDCFromMemory(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 
107 DWORD
108 APIENTRY
109 NtGdiDdDDIDestroyDCFromMemory(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 }
123