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(WORD Bits
, DWORD Compression
)
77 SURFACE_Cleanup(PVOID ObjectBody
)
79 PSURFACE psurf
= (PSURFACE
)ObjectBody
;
80 PVOID pvBits
= psurf
->SurfObj
.pvBits
;
83 /* Check if the surface has bits */
86 /* Only bitmaps can have bits */
87 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
89 /* Check if it is a DIB section */
90 if (psurf
->hDIBSection
)
92 /* Unsecure the memory */
93 EngUnsecureMem(psurf
->hSecure
);
95 /* Calculate the real start of the section */
96 pvBits
= (PVOID
)((ULONG_PTR
)pvBits
- psurf
->dwOffset
);
98 /* Unmap the section */
99 Status
= MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits
);
100 if (!NT_SUCCESS(Status
))
102 DPRINT1("Could not unmap section view!\n");
103 // Should we BugCheck here?
107 else if (psurf
->SurfObj
.fjBitmap
& BMF_USERMEM
)
109 /* Bitmap was allocated from usermode memory */
110 EngFreeUserMem(pvBits
);
112 else if (psurf
->SurfObj
.fjBitmap
& BMF_KMSECTION
)
114 /* Bitmap was allocated from a kernel section */
115 if (!EngFreeSectionMem(NULL
, pvBits
))
117 DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits
);
118 // Should we BugCheck here?
122 else if (psurf
->SurfObj
.fjBitmap
& BMF_RLE_HACK
)
124 /* HACK: Free RLE decompressed bits */
129 /* There should be nothing to free */
130 ASSERT(psurf
->SurfObj
.fjBitmap
& BMF_DONT_FREE
);
137 PALETTE_ShareUnlockPalette(psurf
->ppal
);
146 SURFACE_AllocSurface(
156 if (iFormat
< BMF_1BPP
|| iFormat
> BMF_PNG
)
158 DPRINT1("Invalid bitmap format: %ld\n", iFormat
);
162 /* Allocate a SURFACE object */
163 psurf
= (PSURFACE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP
);
167 /* Initialize the basic fields */
168 pso
= &psurf
->SurfObj
;
169 pso
->hsurf
= psurf
->BaseObject
.hHmgr
;
170 pso
->sizlBitmap
.cx
= cx
;
171 pso
->sizlBitmap
.cy
= cy
;
172 pso
->iBitmapFormat
= iFormat
;
174 pso
->iUniq
= InterlockedIncrement((PLONG
)&giUniqueSurface
);
176 /* Assign a default palette amd increment its reference count */
177 psurf
->ppal
= appalSurfaceDefault
[iFormat
];
178 GDIOBJ_IncrementShareCount(&psurf
->ppal
->BaseObject
);
186 SURFACE_bSetBitmapBits(
190 IN PVOID pvBits OPTIONAL
)
192 SURFOBJ
*pso
= &psurf
->SurfObj
;
196 /* Only bitmaps can have bits */
197 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
199 /* Get bits per pixel from the format */
200 cBitsPixel
= gajBitsPerFormat
[pso
->iBitmapFormat
];
202 /* Is a width in bytes given? */
205 /* Align the width (windows compatibility) */
206 if(psurf
->flags
& DDB_SURFACE
)
208 /* DDB are 16 bits aligned */
209 ulWidth
= BITMAP_GetWidthBytes(pso
->sizlBitmap
.cx
, cBitsPixel
);
213 /* Others are 32 bits aligned */
214 ulWidth
= DIB_GetDIBWidthBytes(pso
->sizlBitmap
.cx
, cBitsPixel
);
219 /* Calculate the bitmap size in bytes */
220 pso
->cjBits
= ulWidth
* pso
->sizlBitmap
.cy
;
222 /* Did the caller provide bits? */
225 /* Yes, so let him free it */
226 fjBitmap
|= BMF_DONT_FREE
;
228 else if (pso
->cjBits
)
230 /* We must allocate memory, check what kind */
231 if (fjBitmap
& BMF_USERMEM
)
233 /* User mode memory was requested */
234 pvBits
= EngAllocUserMem(pso
->cjBits
, 0);
238 /* Use a kernel mode section */
239 fjBitmap
|= BMF_KMSECTION
;
240 pvBits
= EngAllocSectionMem(&pvSection
,
241 (fjBitmap
& BMF_NOZEROINIT
) ?
243 pso
->cjBits
, TAG_DIB
);
245 /* Free the section already, but keep the mapping */
246 if (pvBits
) EngFreeSectionMem(pvSection
, NULL
);
249 /* Check for failure */
250 if (!pvBits
) return FALSE
;
253 /* Set pvBits, pvScan0 and lDelta */
254 pso
->pvBits
= pvBits
;
255 if (fjBitmap
& BMF_TOPDOWN
)
257 /* Topdown is the normal way */
258 pso
->pvScan0
= pso
->pvBits
;
259 pso
->lDelta
= ulWidth
;
263 /* Inversed bitmap (bottom up) */
264 pso
->pvScan0
= (PVOID
)((ULONG_PTR
)pso
->pvBits
+ pso
->cjBits
- ulWidth
);
265 pso
->lDelta
= -ulWidth
;
268 pso
->fjBitmap
= fjBitmap
;
286 /* Allocate a surface */
287 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
290 DPRINT1("SURFACE_AllocSurface failed.\n");
294 /* Get the handle for the bitmap */
295 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
297 /* Set the bitmap bits */
298 if (!SURFACE_bSetBitmapBits(psurf
, fl
, lWidth
, pvBits
))
300 /* Bail out if that failed */
301 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
302 SURFACE_FreeSurfaceByHandle(hbmp
);
306 /* Set public ownership */
307 GDIOBJ_SetOwnership(hbmp
, NULL
);
309 /* Unlock the surface and return */
310 SURFACE_UnlockSurface(psurf
);
319 EngCreateDeviceBitmap(
327 /* Allocate a surface */
328 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
334 /* Set the device handle */
335 psurf
->SurfObj
.dhsurf
= dhsurf
;
337 /* Get the handle for the bitmap */
338 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
340 /* Set public ownership */
341 GDIOBJ_SetOwnership(hbmp
, NULL
);
343 /* Unlock the surface and return */
344 SURFACE_UnlockSurface(psurf
);
350 EngCreateDeviceSurface(
358 /* Allocate a surface */
359 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
, sizl
.cx
, sizl
.cy
, iFormat
);
365 /* Set the device handle */
366 psurf
->SurfObj
.dhsurf
= dhsurf
;
368 /* Get the handle for the surface */
369 hsurf
= psurf
->SurfObj
.hsurf
;
371 /* Set public ownership */
372 GDIOBJ_SetOwnership(hsurf
, NULL
);
374 /* Unlock the surface and return */
375 SURFACE_UnlockSurface(psurf
);
390 ppdev
= (PDEVOBJ
*)hdev
;
392 /* Lock the surface */
393 psurf
= SURFACE_LockSurface(hsurf
);
398 pso
= &psurf
->SurfObj
;
400 /* Associate the hdev */
402 pso
->dhpdev
= ppdev
->dhpdev
;
404 /* Hook up specified functions */
405 psurf
->flags
&= ~HOOK_FLAGS
;
406 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
409 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
411 SURFACE_UnlockSurface(psurf
);
432 psurf
= SURFACE_LockSurface(hsurf
);
438 ppdev
= (PDEVOBJ
*)hdev
;
439 pso
= &psurf
->SurfObj
;
440 pso
->dhsurf
= dhsurf
;
441 pso
->lDelta
= lDelta
;
442 pso
->pvScan0
= pvScan0
;
444 /* Associate the hdev */
446 pso
->dhpdev
= ppdev
->dhpdev
;
448 /* Hook up specified functions */
449 psurf
->flags
&= ~HOOK_FLAGS
;
450 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
453 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
455 SURFACE_UnlockSurface(psurf
);
463 EngDeleteSurface(IN HSURF hsurf
)
465 GDIOBJ_SetOwnership(hsurf
, PsGetCurrentProcess());
466 SURFACE_FreeSurfaceByHandle(hsurf
);
479 return FillSolid(pso
, prcl
, iColor
);
486 NtGdiEngLockSurface(IN HSURF hsurf
)
488 return EngLockSurface(hsurf
);
494 EngLockSurface(IN HSURF hsurf
)
496 SURFACE
*psurf
= GDIOBJ_ShareLockObj(hsurf
, GDI_OBJECT_TYPE_BITMAP
);
499 return &psurf
->SurfObj
;
506 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
508 EngUnlockSurface(pso
);
513 EngUnlockSurface(IN SURFOBJ
*pso
)
517 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
518 GDIOBJ_ShareUnlockObjByPtr((POBJ
)psurf
);