2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Surace Functions
5 * FILE: subsys/win32k/eng/surface.c
6 * PROGRAMERS: Jason Filby
10 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
12 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
13 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
21 ULONG giUniqueSurface
= 0;
24 gajBitsPerFormat
[11] =
30 16, /* 4: BMF_16BPP */
31 24, /* 5: BMF_24BPP */
32 32, /* 6: BMF_32BPP */
40 ULONG FASTCALL
BitmapFormat(ULONG cBits
, ULONG iCompression
)
47 if (cBits
<= 1) return BMF_1BPP
;
48 if (cBits
<= 4) return BMF_4BPP
;
49 if (cBits
<= 8) return BMF_8BPP
;
50 if (cBits
<= 16) return BMF_16BPP
;
51 if (cBits
<= 24) return BMF_24BPP
;
52 if (cBits
<= 32) return BMF_32BPP
;
68 SURFACE_Cleanup(PVOID ObjectBody
)
70 PSURFACE psurf
= (PSURFACE
)ObjectBody
;
71 PVOID pvBits
= psurf
->SurfObj
.pvBits
;
74 /* Check if the surface has bits */
77 /* Only bitmaps can have bits */
78 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
80 /* Check if it is a DIB section */
81 if (psurf
->hDIBSection
)
83 /* Unsecure the memory */
84 EngUnsecureMem(psurf
->hSecure
);
86 /* Calculate the real start of the section */
87 pvBits
= (PVOID
)((ULONG_PTR
)pvBits
- psurf
->dwOffset
);
89 /* Unmap the section */
90 Status
= MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits
);
91 if (!NT_SUCCESS(Status
))
93 DPRINT1("Could not unmap section view!\n");
94 // Should we BugCheck here?
98 else if (psurf
->SurfObj
.fjBitmap
& BMF_USERMEM
)
100 /* Bitmap was allocated from usermode memory */
101 EngFreeUserMem(pvBits
);
103 else if (psurf
->SurfObj
.fjBitmap
& BMF_KMSECTION
)
105 /* Bitmap was allocated from a kernel section */
106 if (!EngFreeSectionMem(NULL
, pvBits
))
108 DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits
);
109 // Should we BugCheck here?
113 else if (psurf
->SurfObj
.fjBitmap
& BMF_RLE_HACK
)
115 /* HACK: Free RLE decompressed bits */
120 /* There should be nothing to free */
121 ASSERT(psurf
->SurfObj
.fjBitmap
& BMF_DONT_FREE
);
128 PALETTE_ShareUnlockPalette(psurf
->ppal
);
137 SURFACE_AllocSurface(
147 if (iFormat
< BMF_1BPP
|| iFormat
> BMF_PNG
)
149 DPRINT1("Invalid bitmap format: %ld\n", iFormat
);
153 /* Allocate a SURFACE object */
154 psurf
= (PSURFACE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP
, sizeof(SURFACE
));
158 /* Initialize the basic fields */
159 pso
= &psurf
->SurfObj
;
160 pso
->hsurf
= psurf
->BaseObject
.hHmgr
;
161 pso
->sizlBitmap
.cx
= cx
;
162 pso
->sizlBitmap
.cy
= cy
;
163 pso
->iBitmapFormat
= iFormat
;
165 pso
->iUniq
= InterlockedIncrement((PLONG
)&giUniqueSurface
);
167 /* Assign a default palette and increment its reference count */
168 psurf
->ppal
= appalSurfaceDefault
[iFormat
];
169 GDIOBJ_vReferenceObjectByPointer(&psurf
->ppal
->BaseObject
);
177 SURFACE_bSetBitmapBits(
181 IN PVOID pvBits OPTIONAL
)
183 SURFOBJ
*pso
= &psurf
->SurfObj
;
187 /* Only bitmaps can have bits */
188 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
190 /* Get bits per pixel from the format */
191 cBitsPixel
= gajBitsPerFormat
[pso
->iBitmapFormat
];
193 /* Is a width in bytes given? */
196 /* Align the width (Windows compatibility, drivers expect that) */
197 ulWidth
= WIDTH_BYTES_ALIGN32((ulWidth
<< 3) / cBitsPixel
, cBitsPixel
);
201 /* Calculate width from the bitmap width in pixels */
202 ulWidth
= WIDTH_BYTES_ALIGN32(pso
->sizlBitmap
.cx
, cBitsPixel
);
205 /* Calculate the bitmap size in bytes */
206 pso
->cjBits
= ulWidth
* pso
->sizlBitmap
.cy
;
208 /* Did the caller provide bits? */
211 /* Yes, so let him free it */
212 fjBitmap
|= BMF_DONT_FREE
;
214 else if (pso
->cjBits
)
216 /* We must allocate memory, check what kind */
217 if (fjBitmap
& BMF_USERMEM
)
219 /* User mode memory was requested */
220 pvBits
= EngAllocUserMem(pso
->cjBits
, 0);
224 /* Use a kernel mode section */
225 fjBitmap
|= BMF_KMSECTION
;
226 pvBits
= EngAllocSectionMem(&pvSection
,
227 (fjBitmap
& BMF_NOZEROINIT
) ?
229 pso
->cjBits
, TAG_DIB
);
231 /* Free the section already, but keep the mapping */
232 if (pvBits
) EngFreeSectionMem(pvSection
, NULL
);
235 /* Check for failure */
236 if (!pvBits
) return FALSE
;
239 /* Set pvBits, pvScan0 and lDelta */
240 pso
->pvBits
= pvBits
;
241 if (fjBitmap
& BMF_TOPDOWN
)
243 /* Topdown is the normal way */
244 pso
->pvScan0
= pso
->pvBits
;
245 pso
->lDelta
= ulWidth
;
249 /* Inversed bitmap (bottom up) */
250 pso
->pvScan0
= (PVOID
)((ULONG_PTR
)pso
->pvBits
+ pso
->cjBits
- ulWidth
);
251 pso
->lDelta
= -ulWidth
;
254 pso
->fjBitmap
= fjBitmap
;
272 /* Allocate a surface */
273 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
276 DPRINT1("SURFACE_AllocSurface failed.\n");
280 /* Get the handle for the bitmap */
281 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
283 /* Set the bitmap bits */
284 if (!SURFACE_bSetBitmapBits(psurf
, fl
, lWidth
, pvBits
))
286 /* Bail out if that failed */
287 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
288 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
292 /* Set public ownership */
293 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
295 /* Unlock the surface and return */
296 SURFACE_UnlockSurface(psurf
);
305 EngCreateDeviceBitmap(
313 /* Allocate a surface */
314 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
320 /* Set the device handle */
321 psurf
->SurfObj
.dhsurf
= dhsurf
;
323 /* Get the handle for the bitmap */
324 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
326 /* Set public ownership */
327 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
329 /* Unlock the surface and return */
330 SURFACE_UnlockSurface(psurf
);
336 EngCreateDeviceSurface(
344 /* Allocate a surface */
345 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
, sizl
.cx
, sizl
.cy
, iFormat
);
351 /* Set the device handle */
352 psurf
->SurfObj
.dhsurf
= dhsurf
;
354 /* Get the handle for the surface */
355 hsurf
= psurf
->SurfObj
.hsurf
;
357 /* Set public ownership */
358 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
360 /* Unlock the surface and return */
361 SURFACE_UnlockSurface(psurf
);
376 ppdev
= (PDEVOBJ
*)hdev
;
378 /* Lock the surface */
379 psurf
= SURFACE_ShareLockSurface(hsurf
);
384 pso
= &psurf
->SurfObj
;
386 /* Associate the hdev */
388 pso
->dhpdev
= ppdev
->dhpdev
;
390 /* Hook up specified functions */
391 psurf
->flags
&= ~HOOK_FLAGS
;
392 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
395 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
397 SURFACE_ShareUnlockSurface(psurf
);
418 psurf
= SURFACE_ShareLockSurface(hsurf
);
424 ppdev
= (PDEVOBJ
*)hdev
;
425 pso
= &psurf
->SurfObj
;
426 pso
->dhsurf
= dhsurf
;
427 pso
->lDelta
= lDelta
;
428 pso
->pvScan0
= pvScan0
;
430 /* Associate the hdev */
432 pso
->dhpdev
= ppdev
->dhpdev
;
434 /* Hook up specified functions */
435 psurf
->flags
&= ~HOOK_FLAGS
;
436 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
439 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
441 SURFACE_ShareUnlockSurface(psurf
);
449 EngDeleteSurface(IN HSURF hsurf
)
453 psurf
= SURFACE_ShareLockSurface(hsurf
);
456 DPRINT1("Could not reference surface to delete\n");
460 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
473 return FillSolid(pso
, prcl
, iColor
);
480 NtGdiEngLockSurface(IN HSURF hsurf
)
482 return EngLockSurface(hsurf
);
488 EngLockSurface(IN HSURF hsurf
)
490 SURFACE
*psurf
= SURFACE_ShareLockSurface(hsurf
);
492 return psurf
? &psurf
->SurfObj
: NULL
;
497 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
505 EngUnlockSurface(IN SURFOBJ
*pso
)
509 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
510 SURFACE_ShareUnlockSurface(psurf
);