2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: GDI Driver Surace Functions
23 * FILE: subsys/win32k/eng/surface.c
24 * PROGRAMER: Jason Filby
27 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
29 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
30 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
40 RLE_EOL
= 0, /* End of line */
41 RLE_END
= 1, /* End of bitmap */
42 RLE_DELTA
= 2 /* Delta */
45 INT FASTCALL
BitsPerFormat(ULONG Format
)
76 ULONG FASTCALL
BitmapFormat(WORD Bits
, DWORD Compression
)
112 BITMAPOBJ_InitBitsLock(BITMAPOBJ
*BitmapObj
)
114 BitmapObj
->BitsLock
= ExAllocatePoolWithTag(NonPagedPool
,
117 if (NULL
== BitmapObj
->BitsLock
)
122 ExInitializeFastMutex(BitmapObj
->BitsLock
);
128 BITMAPOBJ_CleanupBitsLock(BITMAPOBJ
*BitmapObj
)
130 if (NULL
!= BitmapObj
->BitsLock
)
132 ExFreePoolWithTag(BitmapObj
->BitsLock
, TAG_BITMAPOBJ
);
133 BitmapObj
->BitsLock
= NULL
;
142 EngCreateDeviceBitmap(IN DHSURF dhsurf
,
149 NewBitmap
= EngCreateBitmap(Size
, DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
)), Format
, 0, NULL
);
152 DPRINT1("EngCreateBitmap failed\n");
156 SurfObj
= EngLockSurface((HSURF
)NewBitmap
);
157 SurfObj
->dhsurf
= dhsurf
;
158 EngUnlockSurface(SurfObj
);
163 VOID
Decompress4bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
169 int width
= ((Size
.cx
+1)/2);
170 int height
= Size
.cy
- 1;
171 BYTE
*begin
= CompressedBits
;
172 BYTE
*bits
= CompressedBits
;
176 length
= *bits
++ / 2;
182 if (x
>= width
) break;
183 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
210 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
215 if ((bits
- begin
) & 1)
224 VOID
Decompress8bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
231 int height
= Size
.cy
- 1;
232 BYTE
*begin
= CompressedBits
;
233 BYTE
*bits
= CompressedBits
;
243 if (x
>= width
) break;
244 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
270 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
275 if ((bits
- begin
) & 1)
285 IntCreateBitmap(IN SIZEL Size
,
293 BITMAPOBJ
*BitmapObj
;
294 PVOID UncompressedBits
;
295 ULONG UncompressedFormat
;
300 BitmapObj
= BITMAPOBJ_AllocBitmapWithHandle();
301 if (BitmapObj
== NULL
)
305 NewBitmap
= BitmapObj
->BaseObject
.hHmgr
;
307 if (! BITMAPOBJ_InitBitsLock(BitmapObj
))
309 BITMAPOBJ_UnlockBitmap(BitmapObj
);
310 BITMAPOBJ_FreeBitmapByHandle(NewBitmap
);
313 SurfObj
= &BitmapObj
->SurfObj
;
315 if (Format
== BMF_4RLE
)
317 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_4BPP
));
318 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
319 UncompressedFormat
= BMF_4BPP
;
320 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, TAG_DIB
);
321 Decompress4bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
323 else if (Format
== BMF_8RLE
)
325 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_8BPP
));
326 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
327 UncompressedFormat
= BMF_8BPP
;
328 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, TAG_DIB
);
329 Decompress8bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
333 SurfObj
->lDelta
= abs(Width
);
334 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
335 UncompressedBits
= Bits
;
336 UncompressedFormat
= Format
;
339 if (UncompressedBits
!= NULL
)
341 SurfObj
->pvBits
= UncompressedBits
;
345 if (SurfObj
->cjBits
== 0)
347 SurfObj
->pvBits
= NULL
;
351 if (0 != (Flags
& BMF_USERMEM
))
353 SurfObj
->pvBits
= EngAllocUserMem(SurfObj
->cjBits
, 0);
357 SurfObj
->pvBits
= EngAllocMem(0 != (Flags
& BMF_NOZEROINIT
) ?
359 SurfObj
->cjBits
, TAG_DIB
);
361 if (SurfObj
->pvBits
== NULL
)
363 BITMAPOBJ_UnlockBitmap(BitmapObj
);
364 BITMAPOBJ_FreeBitmapByHandle(NewBitmap
);
370 if (0 == (Flags
& BMF_TOPDOWN
))
372 SurfObj
->pvScan0
= (PVOID
) ((ULONG_PTR
) SurfObj
->pvBits
+ SurfObj
->cjBits
- SurfObj
->lDelta
);
373 SurfObj
->lDelta
= - SurfObj
->lDelta
;
377 SurfObj
->pvScan0
= SurfObj
->pvBits
;
380 SurfObj
->dhsurf
= 0; /* device managed surface */
381 SurfObj
->hsurf
= (HSURF
)NewBitmap
;
382 SurfObj
->dhpdev
= NULL
;
383 SurfObj
->hdev
= NULL
;
384 SurfObj
->sizlBitmap
= Size
;
385 SurfObj
->iBitmapFormat
= UncompressedFormat
;
386 SurfObj
->iType
= STYPE_BITMAP
;
387 SurfObj
->fjBitmap
= Flags
& (BMF_TOPDOWN
| BMF_NOZEROINIT
);
390 BitmapObj
->flHooks
= 0;
391 BitmapObj
->flFlags
= 0;
392 BitmapObj
->dimension
.cx
= 0;
393 BitmapObj
->dimension
.cy
= 0;
394 BitmapObj
->dib
= NULL
;
396 BITMAPOBJ_UnlockBitmap(BitmapObj
);
405 EngCreateBitmap(IN SIZEL Size
,
413 NewBitmap
= IntCreateBitmap(Size
, Width
, Format
, Flags
, Bits
);
417 GDIOBJ_SetOwnership(NewBitmap
, NULL
);
426 EngCreateDeviceSurface(IN DHSURF dhsurf
,
432 BITMAPOBJ
*BitmapObj
;
434 BitmapObj
= BITMAPOBJ_AllocBitmapWithHandle();
440 NewSurface
= BitmapObj
->BaseObject
.hHmgr
;
441 GDIOBJ_SetOwnership(NewSurface
, NULL
);
443 if (!BITMAPOBJ_InitBitsLock(BitmapObj
))
445 BITMAPOBJ_UnlockBitmap(BitmapObj
);
446 BITMAPOBJ_FreeBitmapByHandle(NewSurface
);
449 SurfObj
= &BitmapObj
->SurfObj
;
451 SurfObj
->dhsurf
= dhsurf
;
452 SurfObj
->hsurf
= NewSurface
;
453 SurfObj
->sizlBitmap
= Size
;
454 SurfObj
->iBitmapFormat
= Format
;
455 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
));
456 SurfObj
->iType
= STYPE_DEVICE
;
459 BitmapObj
->flHooks
= 0;
461 BITMAPOBJ_UnlockBitmap(BitmapObj
);
466 PFN FASTCALL
DriverFunction(DRVENABLEDATA
*DED
, ULONG DriverFunc
)
470 for (i
=0; i
<DED
->c
; i
++)
472 if (DED
->pdrvfn
[i
].iFunc
== DriverFunc
)
474 return DED
->pdrvfn
[i
].pfn
;
484 EngAssociateSurface(IN HSURF Surface
,
489 BITMAPOBJ
*BitmapObj
;
492 Device
= (GDIDEVICE
*)Dev
;
494 BitmapObj
= BITMAPOBJ_LockBitmap(Surface
);
496 SurfObj
= &BitmapObj
->SurfObj
;
498 /* Associate the hdev */
500 SurfObj
->dhpdev
= Device
->hPDev
;
502 /* Hook up specified functions */
503 BitmapObj
->flHooks
= Hooks
;
505 BITMAPOBJ_UnlockBitmap(BitmapObj
);
526 pso
= EngLockSurface(hsurf
);
532 if (!EngAssociateSurface(hsurf
, hdev
, flHooks
))
534 EngUnlockSurface(pso
);
539 pso
->dhsurf
= dhsurf
;
540 pso
->lDelta
= lDelta
;
541 pso
->pvScan0
= pvScan0
;
543 EngUnlockSurface(pso
);
552 EngDeleteSurface(IN HSURF Surface
)
554 GDIOBJ_SetOwnership(Surface
, PsGetCurrentProcess());
555 BITMAPOBJ_FreeBitmapByHandle(Surface
);
563 EngEraseSurface(SURFOBJ
*Surface
,
569 return FillSolid(Surface
, Rect
, iColor
);
572 #define GDIBdyToHdr(body) \
573 ((PGDIOBJHDR)(body) - 1)
580 NtGdiEngLockSurface(IN HSURF Surface
)
582 return EngLockSurface(Surface
);
590 EngLockSurface(IN HSURF Surface
)
592 BITMAPOBJ
*bmp
= GDIOBJ_ShareLockObj(Surface
, GDI_OBJECT_TYPE_BITMAP
);
595 return &bmp
->SurfObj
;
605 NtGdiEngUnlockSurface(IN SURFOBJ
*Surface
)
607 EngUnlockSurface(Surface
);
614 EngUnlockSurface(IN SURFOBJ
*Surface
)
618 BITMAPOBJ
*bmp
= CONTAINING_RECORD(Surface
, BITMAPOBJ
, SurfObj
);
619 GDIOBJ_ShareUnlockObjByPtr((POBJ
)bmp
);