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