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 * PROGRAMER: Jason Filby
9 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
11 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
12 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
22 RLE_EOL
= 0, /* End of line */
23 RLE_END
= 1, /* End of bitmap */
24 RLE_DELTA
= 2 /* Delta */
27 INT FASTCALL
BitsPerFormat(ULONG Format
)
58 ULONG FASTCALL
BitmapFormat(WORD Bits
, DWORD Compression
)
94 SURFACE_Cleanup(PVOID ObjectBody
)
96 PSURFACE psurf
= (PSURFACE
)ObjectBody
;
97 PVOID pvBits
= psurf
->SurfObj
.pvBits
;
99 /* If this is an API bitmap, free the bits */
100 if (pvBits
!= NULL
&&
101 (psurf
->flFlags
& BITMAPOBJ_IS_APIBITMAP
))
103 /* Check if we have a DIB section */
106 // FIXME: IMPLEMENT ME!
107 // MmUnsecureVirtualMemory(psurf->hSecure);
108 if (psurf
->hDIBSection
)
110 /* DIB was created from a section */
113 pvBits
= (PVOID
)((ULONG_PTR
)pvBits
- psurf
->dwOffset
);
114 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), pvBits
);
115 if (!NT_SUCCESS(Status
))
117 DPRINT1("Could not unmap section view!\n");
118 // Should we BugCheck here?
123 /* DIB was allocated */
124 EngFreeUserMem(pvBits
);
130 ExFreePool(psurf
->SurfObj
.pvBits
);
133 if (psurf
->hDIBPalette
!= NULL
)
135 NtGdiDeleteObject(psurf
->hDIBPalette
);
139 if (NULL
!= psurf
->BitsLock
)
141 ExFreePoolWithTag(psurf
->BitsLock
, TAG_SURFACE
);
142 psurf
->BitsLock
= NULL
;
149 SURFACE_InitBitsLock(PSURFACE psurf
)
151 psurf
->BitsLock
= ExAllocatePoolWithTag(NonPagedPool
,
154 if (NULL
== psurf
->BitsLock
)
159 ExInitializeFastMutex(psurf
->BitsLock
);
165 SURFACE_CleanupBitsLock(PSURFACE psurf
)
167 if (NULL
!= psurf
->BitsLock
)
169 ExFreePoolWithTag(psurf
->BitsLock
, TAG_SURFACE
);
170 psurf
->BitsLock
= NULL
;
179 EngCreateDeviceBitmap(IN DHSURF dhsurf
,
186 NewBitmap
= EngCreateBitmap(Size
, DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
)), Format
, 0, NULL
);
189 DPRINT1("EngCreateBitmap failed\n");
193 pso
= EngLockSurface((HSURF
)NewBitmap
);
194 pso
->dhsurf
= dhsurf
;
195 EngUnlockSurface(pso
);
200 VOID
Decompress4bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
206 int width
= ((Size
.cx
+1)/2);
207 int height
= Size
.cy
- 1;
208 BYTE
*begin
= CompressedBits
;
209 BYTE
*bits
= CompressedBits
;
213 length
= *bits
++ / 2;
219 if (x
>= width
) break;
220 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
247 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
252 if ((bits
- begin
) & 1)
261 VOID
Decompress8bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
268 int height
= Size
.cy
- 1;
269 BYTE
*begin
= CompressedBits
;
270 BYTE
*bits
= CompressedBits
;
280 if (x
>= width
) break;
281 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
307 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
312 if ((bits
- begin
) & 1)
322 IntCreateBitmap(IN SIZEL Size
,
331 PVOID UncompressedBits
;
332 ULONG UncompressedFormat
;
337 psurf
= SURFACE_AllocSurfaceWithHandle();
342 hbmp
= psurf
->BaseObject
.hHmgr
;
344 if (! SURFACE_InitBitsLock(psurf
))
346 SURFACE_UnlockSurface(psurf
);
347 SURFACE_FreeSurfaceByHandle(hbmp
);
350 pso
= &psurf
->SurfObj
;
352 if (Format
== BMF_4RLE
)
354 pso
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_4BPP
));
355 pso
->cjBits
= pso
->lDelta
* Size
.cy
;
356 UncompressedFormat
= BMF_4BPP
;
357 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, pso
->cjBits
, TAG_DIB
);
358 Decompress4bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, pso
->lDelta
);
360 else if (Format
== BMF_8RLE
)
362 pso
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_8BPP
));
363 pso
->cjBits
= pso
->lDelta
* Size
.cy
;
364 UncompressedFormat
= BMF_8BPP
;
365 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, pso
->cjBits
, TAG_DIB
);
366 Decompress8bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, pso
->lDelta
);
370 pso
->lDelta
= abs(Width
);
371 pso
->cjBits
= pso
->lDelta
* Size
.cy
;
372 UncompressedBits
= Bits
;
373 UncompressedFormat
= Format
;
376 if (UncompressedBits
!= NULL
)
378 pso
->pvBits
= UncompressedBits
;
382 if (pso
->cjBits
== 0)
388 if (0 != (Flags
& BMF_USERMEM
))
390 pso
->pvBits
= EngAllocUserMem(pso
->cjBits
, 0);
394 pso
->pvBits
= EngAllocMem(0 != (Flags
& BMF_NOZEROINIT
) ?
396 pso
->cjBits
, TAG_DIB
);
398 if (pso
->pvBits
== NULL
)
400 SURFACE_UnlockSurface(psurf
);
401 SURFACE_FreeSurfaceByHandle(hbmp
);
402 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
408 if (0 == (Flags
& BMF_TOPDOWN
))
410 pso
->pvScan0
= (PVOID
)((ULONG_PTR
)pso
->pvBits
+ pso
->cjBits
- pso
->lDelta
);
411 pso
->lDelta
= - pso
->lDelta
;
415 pso
->pvScan0
= pso
->pvBits
;
418 pso
->dhsurf
= 0; /* device managed surface */
419 pso
->hsurf
= (HSURF
)hbmp
;
422 pso
->sizlBitmap
= Size
;
423 pso
->iBitmapFormat
= UncompressedFormat
;
424 pso
->iType
= STYPE_BITMAP
;
425 pso
->fjBitmap
= Flags
& (BMF_TOPDOWN
| BMF_NOZEROINIT
);
430 psurf
->dimension
.cx
= 0;
431 psurf
->dimension
.cy
= 0;
433 psurf
->hSecure
= NULL
;
434 psurf
->hDIBSection
= NULL
;
436 SURFACE_UnlockSurface(psurf
);
445 EngCreateBitmap(IN SIZEL Size
,
453 hNewBitmap
= IntCreateBitmap(Size
, Width
, Format
, Flags
, Bits
);
457 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
466 EngCreateDeviceSurface(IN DHSURF dhsurf
,
474 psurf
= SURFACE_AllocSurfaceWithHandle();
480 hsurf
= psurf
->BaseObject
.hHmgr
;
481 GDIOBJ_SetOwnership(hsurf
, NULL
);
483 if (!SURFACE_InitBitsLock(psurf
))
485 SURFACE_UnlockSurface(psurf
);
486 SURFACE_FreeSurfaceByHandle(hsurf
);
489 pso
= &psurf
->SurfObj
;
491 pso
->dhsurf
= dhsurf
;
493 pso
->sizlBitmap
= Size
;
494 pso
->iBitmapFormat
= Format
;
495 pso
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
));
496 pso
->iType
= STYPE_DEVICE
;
501 SURFACE_UnlockSurface(psurf
);
510 EngAssociateSurface(IN HSURF hsurf
,
518 Device
= (PDEVOBJ
*)hdev
;
520 psurf
= SURFACE_LockSurface(hsurf
);
522 pso
= &psurf
->SurfObj
;
524 /* Associate the hdev */
526 pso
->dhpdev
= Device
->hPDev
;
528 /* Hook up specified functions */
529 psurf
->flHooks
= Hooks
;
531 SURFACE_UnlockSurface(psurf
);
552 pso
= EngLockSurface(hsurf
);
558 if (!EngAssociateSurface(hsurf
, hdev
, flHooks
))
560 EngUnlockSurface(pso
);
565 pso
->dhsurf
= dhsurf
;
566 pso
->lDelta
= lDelta
;
567 pso
->pvScan0
= pvScan0
;
569 EngUnlockSurface(pso
);
578 EngDeleteSurface(IN HSURF hsurf
)
580 GDIOBJ_SetOwnership(hsurf
, PsGetCurrentProcess());
581 SURFACE_FreeSurfaceByHandle(hsurf
);
589 EngEraseSurface(SURFOBJ
*pso
,
595 return FillSolid(pso
, Rect
, iColor
);
602 NtGdiEngLockSurface(IN HSURF hsurf
)
604 return EngLockSurface(hsurf
);
612 EngLockSurface(IN HSURF hsurf
)
614 SURFACE
*psurf
= GDIOBJ_ShareLockObj(hsurf
, GDI_OBJECT_TYPE_BITMAP
);
617 return &psurf
->SurfObj
;
627 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
629 EngUnlockSurface(pso
);
636 EngUnlockSurface(IN SURFOBJ
*pso
)
640 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
641 GDIOBJ_ShareUnlockObjByPtr((POBJ
)psurf
);