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.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: GDI Driver Surace Functions
24 * FILE: subsys/win32k/eng/surface.c
25 * PROGRAMER: Jason Filby
28 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
30 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
31 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
41 RLE_EOL
= 0, /* End of line */
42 RLE_END
= 1, /* End of bitmap */
43 RLE_DELTA
= 2 /* Delta */
46 INT FASTCALL
BitsPerFormat(ULONG Format
)
50 case BMF_1BPP
: return 1;
52 case BMF_4RLE
: return 4;
54 case BMF_8RLE
: return 8;
55 case BMF_16BPP
: return 16;
56 case BMF_24BPP
: return 24;
57 case BMF_32BPP
: return 32;
62 ULONG FASTCALL
BitmapFormat(WORD Bits
, DWORD Compression
)
70 case 1: return BMF_1BPP
;
71 case 4: return BMF_4BPP
;
72 case 8: return BMF_8BPP
;
73 case 16: return BMF_16BPP
;
74 case 24: return BMF_24BPP
;
75 case 32: return BMF_32BPP
;
79 case BI_RLE4
: return BMF_4RLE
;
80 case BI_RLE8
: return BMF_8RLE
;
87 BITMAPOBJ_InitBitsLock(BITMAPOBJ
*BitmapObj
)
89 BitmapObj
->BitsLock
= ExAllocatePoolWithTag(NonPagedPool
,
92 if (NULL
== BitmapObj
->BitsLock
)
97 ExInitializeFastMutex(BitmapObj
->BitsLock
);
103 BITMAPOBJ_CleanupBitsLock(BITMAPOBJ
*BitmapObj
)
105 if (NULL
!= BitmapObj
->BitsLock
)
107 ExFreePoolWithTag(BitmapObj
->BitsLock
, TAG_BITMAPOBJ
);
108 BitmapObj
->BitsLock
= NULL
;
117 EngCreateDeviceBitmap(IN DHSURF dhsurf
,
124 NewBitmap
= EngCreateBitmap(Size
, DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
)), Format
, 0, NULL
);
127 DPRINT1("EngCreateBitmap failed\n");
131 SurfObj
= EngLockSurface((HSURF
)NewBitmap
);
132 SurfObj
->dhsurf
= dhsurf
;
133 EngUnlockSurface(SurfObj
);
138 VOID
Decompress4bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
144 int width
= ((Size
.cx
+1)/2);
145 int height
= Size
.cy
- 1;
146 BYTE
*begin
= CompressedBits
;
147 BYTE
*bits
= CompressedBits
;
151 length
= *bits
++ / 2;
157 if (x
>= width
) break;
158 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
183 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
188 if ((bits
- begin
) & 1)
195 VOID
Decompress8bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
202 int height
= Size
.cy
- 1;
203 BYTE
*begin
= CompressedBits
;
204 BYTE
*bits
= CompressedBits
;
214 if (x
>= width
) break;
215 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
239 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
244 if ((bits
- begin
) & 1)
252 IntCreateBitmap(IN SIZEL Size
,
260 BITMAPOBJ
*BitmapObj
;
261 PVOID UncompressedBits
;
262 ULONG UncompressedFormat
;
267 NewBitmap
= BITMAPOBJ_AllocBitmap();
268 if (NewBitmap
== NULL
)
271 BitmapObj
= BITMAPOBJ_LockBitmap(NewBitmap
);
272 if (! BITMAPOBJ_InitBitsLock(BitmapObj
))
274 BITMAPOBJ_UnlockBitmap(BitmapObj
);
275 BITMAPOBJ_FreeBitmap(NewBitmap
);
278 SurfObj
= &BitmapObj
->SurfObj
;
280 if (Format
== BMF_4RLE
)
282 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_4BPP
));
283 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
284 UncompressedFormat
= BMF_4BPP
;
285 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, 0);
286 Decompress4bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
288 else if (Format
== BMF_8RLE
)
290 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_8BPP
));
291 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
292 UncompressedFormat
= BMF_8BPP
;
293 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, 0);
294 Decompress8bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
298 SurfObj
->lDelta
= abs(Width
);
299 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
300 UncompressedBits
= Bits
;
301 UncompressedFormat
= Format
;
304 if (UncompressedBits
!= NULL
)
306 SurfObj
->pvBits
= UncompressedBits
;
310 if (SurfObj
->cjBits
== 0)
312 SurfObj
->pvBits
= NULL
;
316 if (0 != (Flags
& BMF_USERMEM
))
318 SurfObj
->pvBits
= EngAllocUserMem(SurfObj
->cjBits
, 0);
322 SurfObj
->pvBits
= EngAllocMem(0 != (Flags
& BMF_NOZEROINIT
) ? 0 : FL_ZERO_MEMORY
,
325 if (SurfObj
->pvBits
== NULL
)
327 BITMAPOBJ_UnlockBitmap(BitmapObj
);
328 BITMAPOBJ_FreeBitmap(NewBitmap
);
335 if (0 == (Flags
& BMF_TOPDOWN
))
337 SurfObj
->pvScan0
= (PVOID
) ((ULONG_PTR
) SurfObj
->pvBits
+ SurfObj
->cjBits
- SurfObj
->lDelta
);
338 SurfObj
->lDelta
= - SurfObj
->lDelta
;
342 SurfObj
->pvScan0
= SurfObj
->pvBits
;
345 SurfObj
->dhsurf
= 0; /* device managed surface */
346 SurfObj
->hsurf
= (HSURF
)NewBitmap
;
347 SurfObj
->dhpdev
= NULL
;
348 SurfObj
->hdev
= NULL
;
349 SurfObj
->sizlBitmap
= Size
;
350 SurfObj
->iBitmapFormat
= UncompressedFormat
;
351 SurfObj
->iType
= STYPE_BITMAP
;
352 SurfObj
->fjBitmap
= Flags
& (BMF_TOPDOWN
| BMF_NOZEROINIT
);
355 BitmapObj
->flHooks
= 0;
356 BitmapObj
->flFlags
= 0;
357 BitmapObj
->dimension
.cx
= 0;
358 BitmapObj
->dimension
.cy
= 0;
359 BitmapObj
->dib
= NULL
;
361 BITMAPOBJ_UnlockBitmap(BitmapObj
);
370 EngCreateBitmap(IN SIZEL Size
,
378 NewBitmap
= IntCreateBitmap(Size
, Width
, Format
, Flags
, Bits
);
382 GDIOBJ_SetOwnership(GdiHandleTable
, NewBitmap
, NULL
);
391 EngCreateDeviceSurface(IN DHSURF dhsurf
,
397 BITMAPOBJ
*BitmapObj
;
399 NewSurface
= (HSURF
)BITMAPOBJ_AllocBitmap();
400 if (NewSurface
== NULL
)
403 GDIOBJ_SetOwnership(GdiHandleTable
, NewSurface
, NULL
);
405 BitmapObj
= BITMAPOBJ_LockBitmap(NewSurface
);
406 if (! BITMAPOBJ_InitBitsLock(BitmapObj
))
408 BITMAPOBJ_UnlockBitmap(BitmapObj
);
409 BITMAPOBJ_FreeBitmap(NewSurface
);
412 SurfObj
= &BitmapObj
->SurfObj
;
414 SurfObj
->dhsurf
= dhsurf
;
415 SurfObj
->hsurf
= NewSurface
;
416 SurfObj
->sizlBitmap
= Size
;
417 SurfObj
->iBitmapFormat
= Format
;
418 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
));
419 SurfObj
->iType
= STYPE_DEVICE
;
422 BitmapObj
->flHooks
= 0;
424 BITMAPOBJ_UnlockBitmap(BitmapObj
);
429 PFN FASTCALL
DriverFunction(DRVENABLEDATA
*DED
, ULONG DriverFunc
)
433 for(i
=0; i
<DED
->c
; i
++)
435 if(DED
->pdrvfn
[i
].iFunc
== DriverFunc
)
436 return DED
->pdrvfn
[i
].pfn
;
445 EngAssociateSurface(IN HSURF Surface
,
450 BITMAPOBJ
*BitmapObj
;
453 Device
= (GDIDEVICE
*)Dev
;
455 BitmapObj
= BITMAPOBJ_LockBitmap(Surface
);
457 SurfObj
= &BitmapObj
->SurfObj
;
459 /* Associate the hdev */
461 SurfObj
->dhpdev
= Device
->PDev
;
463 /* Hook up specified functions */
464 BitmapObj
->flHooks
= Hooks
;
466 BITMAPOBJ_UnlockBitmap(BitmapObj
);
487 pso
= EngLockSurface(hsurf
);
493 if (!EngAssociateSurface(hsurf
, hdev
, flHooks
))
495 EngUnlockSurface(pso
);
500 pso
->dhsurf
= dhsurf
;
501 pso
->lDelta
= lDelta
;
502 pso
->pvScan0
= pvScan0
;
504 EngUnlockSurface(pso
);
513 EngDeleteSurface(IN HSURF Surface
)
515 GDIOBJ_SetOwnership(GdiHandleTable
, Surface
, PsGetCurrentProcess());
516 BITMAPOBJ_FreeBitmap(Surface
);
524 EngEraseSurface(SURFOBJ
*Surface
,
530 return FillSolid(Surface
, Rect
, iColor
);
533 #define GDIBdyToHdr(body) \
534 ((PGDIOBJHDR)(body) - 1)
540 EngLockSurface(IN HSURF Surface
)
542 BITMAPOBJ
*bmp
= GDIOBJ_ShareLockObj(GdiHandleTable
, Surface
, GDI_OBJECT_TYPE_BITMAP
);
545 return &bmp
->SurfObj
;
554 EngUnlockSurface(IN SURFOBJ
*Surface
)
557 GDIOBJ_UnlockObjByPtr(GdiHandleTable
, Surface
);