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