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 and 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, drivers expect that) */
206 ulWidth
= WIDTH_BYTES_ALIGN32((ulWidth
<< 3) / cBitsPixel
, cBitsPixel
);
210 /* Calculate width from the bitmap width in pixels */
211 ulWidth
= WIDTH_BYTES_ALIGN32(pso
->sizlBitmap
.cx
, cBitsPixel
);
214 /* Calculate the bitmap size in bytes */
215 pso
->cjBits
= ulWidth
* pso
->sizlBitmap
.cy
;
217 /* Did the caller provide bits? */
220 /* Yes, so let him free it */
221 fjBitmap
|= BMF_DONT_FREE
;
223 else if (pso
->cjBits
)
225 /* We must allocate memory, check what kind */
226 if (fjBitmap
& BMF_USERMEM
)
228 /* User mode memory was requested */
229 pvBits
= EngAllocUserMem(pso
->cjBits
, 0);
233 /* Use a kernel mode section */
234 fjBitmap
|= BMF_KMSECTION
;
235 pvBits
= EngAllocSectionMem(&pvSection
,
236 (fjBitmap
& BMF_NOZEROINIT
) ?
238 pso
->cjBits
, TAG_DIB
);
240 /* Free the section already, but keep the mapping */
241 if (pvBits
) EngFreeSectionMem(pvSection
, NULL
);
244 /* Check for failure */
245 if (!pvBits
) return FALSE
;
248 /* Set pvBits, pvScan0 and lDelta */
249 pso
->pvBits
= pvBits
;
250 if (fjBitmap
& BMF_TOPDOWN
)
252 /* Topdown is the normal way */
253 pso
->pvScan0
= pso
->pvBits
;
254 pso
->lDelta
= ulWidth
;
258 /* Inversed bitmap (bottom up) */
259 pso
->pvScan0
= (PVOID
)((ULONG_PTR
)pso
->pvBits
+ pso
->cjBits
- ulWidth
);
260 pso
->lDelta
= -ulWidth
;
263 pso
->fjBitmap
= fjBitmap
;
281 /* Allocate a surface */
282 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
285 DPRINT1("SURFACE_AllocSurface failed.\n");
289 /* Get the handle for the bitmap */
290 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
292 /* Set the bitmap bits */
293 if (!SURFACE_bSetBitmapBits(psurf
, fl
, lWidth
, pvBits
))
295 /* Bail out if that failed */
296 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
297 SURFACE_FreeSurfaceByHandle(hbmp
);
301 /* Set public ownership */
302 GDIOBJ_SetOwnership(hbmp
, NULL
);
304 /* Unlock the surface and return */
305 SURFACE_UnlockSurface(psurf
);
314 EngCreateDeviceBitmap(
322 /* Allocate a surface */
323 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
329 /* Set the device handle */
330 psurf
->SurfObj
.dhsurf
= dhsurf
;
332 /* Get the handle for the bitmap */
333 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
335 /* Set public ownership */
336 GDIOBJ_SetOwnership(hbmp
, NULL
);
338 /* Unlock the surface and return */
339 SURFACE_UnlockSurface(psurf
);
345 EngCreateDeviceSurface(
353 /* Allocate a surface */
354 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
, sizl
.cx
, sizl
.cy
, iFormat
);
360 /* Set the device handle */
361 psurf
->SurfObj
.dhsurf
= dhsurf
;
363 /* Get the handle for the surface */
364 hsurf
= psurf
->SurfObj
.hsurf
;
366 /* Set public ownership */
367 GDIOBJ_SetOwnership(hsurf
, NULL
);
369 /* Unlock the surface and return */
370 SURFACE_UnlockSurface(psurf
);
385 ppdev
= (PDEVOBJ
*)hdev
;
387 /* Lock the surface */
388 psurf
= SURFACE_LockSurface(hsurf
);
393 pso
= &psurf
->SurfObj
;
395 /* Associate the hdev */
397 pso
->dhpdev
= ppdev
->dhpdev
;
399 /* Hook up specified functions */
400 psurf
->flags
&= ~HOOK_FLAGS
;
401 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
404 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
406 SURFACE_UnlockSurface(psurf
);
427 psurf
= SURFACE_LockSurface(hsurf
);
433 ppdev
= (PDEVOBJ
*)hdev
;
434 pso
= &psurf
->SurfObj
;
435 pso
->dhsurf
= dhsurf
;
436 pso
->lDelta
= lDelta
;
437 pso
->pvScan0
= pvScan0
;
439 /* Associate the hdev */
441 pso
->dhpdev
= ppdev
->dhpdev
;
443 /* Hook up specified functions */
444 psurf
->flags
&= ~HOOK_FLAGS
;
445 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
448 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
450 SURFACE_UnlockSurface(psurf
);
458 EngDeleteSurface(IN HSURF hsurf
)
460 GDIOBJ_SetOwnership(hsurf
, PsGetCurrentProcess());
461 SURFACE_FreeSurfaceByHandle(hsurf
);
474 return FillSolid(pso
, prcl
, iColor
);
481 NtGdiEngLockSurface(IN HSURF hsurf
)
483 return EngLockSurface(hsurf
);
489 EngLockSurface(IN HSURF hsurf
)
491 SURFACE
*psurf
= GDIOBJ_ShareLockObj(hsurf
, GDI_OBJECT_TYPE_BITMAP
);
494 return &psurf
->SurfObj
;
501 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
503 EngUnlockSurface(pso
);
508 EngUnlockSurface(IN SURFOBJ
*pso
)
512 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
513 GDIOBJ_ShareUnlockObjByPtr((POBJ
)psurf
);