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.
19 /* $Id: surface.c,v 1.35 2004/03/20 17:33:10 navaraf Exp $
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
34 #include <ddk/winddi.h>
35 #include <win32k/dc.h>
36 #include <win32k/gdiobj.h>
37 #include <include/dib.h>
38 #include <include/object.h>
39 #include <include/paint.h>
41 #include "../dib/dib.h"
44 #include <win32k/debug1.h>
48 RLE_EOL
= 0, /* End of line */
49 RLE_END
= 1, /* End of bitmap */
50 RLE_DELTA
= 2 /* Delta */
53 INT FASTCALL
BitsPerFormat(ULONG Format
)
57 case BMF_1BPP
: return 1;
59 case BMF_4RLE
: return 4;
61 case BMF_8RLE
: return 8;
62 case BMF_16BPP
: return 16;
63 case BMF_24BPP
: return 24;
64 case BMF_32BPP
: return 32;
69 ULONG FASTCALL
BitmapFormat(WORD Bits
, DWORD Compression
)
76 case 1: return BMF_1BPP
;
77 case 4: return BMF_4BPP
;
78 case 8: return BMF_8BPP
;
79 case 16: return BMF_16BPP
;
80 case 24: return BMF_24BPP
;
81 case 32: return BMF_32BPP
;
84 case BI_RLE4
: return BMF_4RLE
;
85 case BI_RLE8
: return BMF_8RLE
;
91 static VOID
Dummy_PutPixel(SURFOBJ
* SurfObj
, LONG x
, LONG y
, ULONG c
)
96 static ULONG
Dummy_GetPixel(SURFOBJ
* SurfObj
, LONG x
, LONG y
)
101 static VOID
Dummy_HLine(SURFOBJ
* SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
106 static VOID
Dummy_VLine(SURFOBJ
* SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
111 static BOOLEAN
Dummy_BitBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
112 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
113 RECTL
* DestRect
, POINTL
*SourcePoint
,
114 BRUSHOBJ
* BrushObj
, POINTL
* BrushOrign
,
115 XLATEOBJ
*ColorTranslation
, ULONG Rop4
)
120 static BOOLEAN
Dummy_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
121 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
122 RECTL
* DestRect
, RECTL
*SourceRect
,
123 POINTL
* MaskOrigin
, POINTL
* BrushOrign
,
124 XLATEOBJ
*ColorTranslation
, ULONG Mode
)
130 #define SURF_METHOD(c,n) DIB_##c##_##n
131 #define SET_SURFGDI(c)\
132 SurfGDI->DIB_PutPixel=SURF_METHOD(c,PutPixel);\
133 SurfGDI->DIB_GetPixel=SURF_METHOD(c,GetPixel);\
134 SurfGDI->DIB_HLine=SURF_METHOD(c,HLine);\
135 SurfGDI->DIB_VLine=SURF_METHOD(c,VLine);\
136 SurfGDI->DIB_BitBlt=SURF_METHOD(c,BitBlt);\
137 SurfGDI->DIB_StretchBlt=SURF_METHOD(c,StretchBlt);
139 VOID FASTCALL
InitializeFuncs(SURFGDI
*SurfGDI
, ULONG BitmapFormat
)
141 SurfGDI
->BitBlt
= NULL
;
142 SurfGDI
->StretchBlt
= NULL
;
143 SurfGDI
->CopyBits
= NULL
;
144 SurfGDI
->CreateDeviceBitmap
= NULL
;
145 SurfGDI
->SetPalette
= NULL
;
146 SurfGDI
->TransparentBlt
= NULL
;
150 case BMF_1BPP
: SET_SURFGDI(1BPP
) break;
151 case BMF_4BPP
: SET_SURFGDI(4BPP
) break;
152 case BMF_8BPP
: SET_SURFGDI(8BPP
) break;
153 case BMF_16BPP
: SET_SURFGDI(16BPP
) break;
154 case BMF_24BPP
: SET_SURFGDI(24BPP
) break;
155 case BMF_32BPP
: SET_SURFGDI(32BPP
) break;
158 /* Not supported yet, fall through to unrecognized case */
160 DPRINT1("InitializeFuncs: unsupported DIB format %d\n",
163 SurfGDI
->DIB_PutPixel
= Dummy_PutPixel
;
164 SurfGDI
->DIB_GetPixel
= Dummy_GetPixel
;
165 SurfGDI
->DIB_HLine
= Dummy_HLine
;
166 SurfGDI
->DIB_VLine
= Dummy_VLine
;
167 SurfGDI
->DIB_BitBlt
= Dummy_BitBlt
;
168 SurfGDI
->DIB_StretchBlt
= Dummy_StretchBlt
;
177 EngCreateDeviceBitmap(IN DHSURF dhsurf
,
184 NewBitmap
= EngCreateBitmap(Size
, DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
)), Format
, 0, NULL
);
185 SurfObj
= (PVOID
)AccessUserObject((ULONG
)NewBitmap
);
186 SurfObj
->dhsurf
= dhsurf
;
191 VOID
Decompress4bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
197 int width
= ((Size
.cx
+1)/2);
198 int height
= Size
.cy
- 1;
199 BYTE
*begin
= CompressedBits
;
200 BYTE
*bits
= CompressedBits
;
204 length
= *bits
++ / 2;
210 if (x
>= width
) break;
211 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
236 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
241 if ((bits
- begin
) & 1)
248 VOID
Decompress8bpp(SIZEL Size
, BYTE
*CompressedBits
, BYTE
*UncompressedBits
, LONG Delta
)
255 int height
= Size
.cy
- 1;
256 BYTE
*begin
= CompressedBits
;
257 BYTE
*bits
= CompressedBits
;
267 if (x
>= width
) break;
268 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
292 temp
= UncompressedBits
+ (((height
- y
) * Delta
) + x
);
297 if ((bits
- begin
) & 1)
308 EngCreateBitmap(IN SIZEL Size
,
317 PVOID UncompressedBits
;
318 ULONG UncompressedFormat
;
320 NewBitmap
= (PVOID
)CreateGDIHandle(sizeof(SURFGDI
), sizeof(SURFOBJ
));
321 if( !ValidEngHandle( NewBitmap
) )
324 SurfObj
= (SURFOBJ
*) AccessUserObject( (ULONG
) NewBitmap
);
325 SurfGDI
= (SURFGDI
*) AccessInternalObject( (ULONG
) NewBitmap
);
328 SurfGDI
->BitsPerPixel
= BitsPerFormat(Format
);
329 if (Format
== BMF_4RLE
) {
330 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_4BPP
));
331 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
332 UncompressedFormat
= BMF_4BPP
;
333 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, 0);
334 Decompress4bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
336 if (Format
== BMF_8RLE
) {
337 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(BMF_8BPP
));
338 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
339 UncompressedFormat
= BMF_8BPP
;
340 UncompressedBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, 0);
341 Decompress8bpp(Size
, (BYTE
*)Bits
, (BYTE
*)UncompressedBits
, SurfObj
->lDelta
);
343 SurfObj
->lDelta
= Width
;
344 SurfObj
->cjBits
= SurfObj
->lDelta
* Size
.cy
;
345 UncompressedBits
= Bits
;
346 UncompressedFormat
= Format
;
349 if(UncompressedBits
!=NULL
)
351 SurfObj
->pvBits
= UncompressedBits
;
354 if (SurfObj
->cjBits
== 0)
356 SurfObj
->pvBits
= NULL
;
360 if(Flags
& BMF_USERMEM
)
362 SurfObj
->pvBits
= EngAllocUserMem(SurfObj
->cjBits
, 0);
364 if(Flags
& BMF_NOZEROINIT
)
366 SurfObj
->pvBits
= EngAllocMem(0, SurfObj
->cjBits
, 0);
368 SurfObj
->pvBits
= EngAllocMem(FL_ZERO_MEMORY
, SurfObj
->cjBits
, 0);
374 SurfObj
->dhsurf
= 0; // device managed surface
376 SurfObj
->dhpdev
= NULL
;
377 SurfObj
->hdev
= NULL
;
378 SurfObj
->sizlBitmap
= Size
;
379 SurfObj
->iBitmapFormat
= UncompressedFormat
;
380 SurfObj
->iType
= STYPE_BITMAP
;
381 SurfObj
->fjBitmap
= Flags
& (BMF_TOPDOWN
| BMF_NOZEROINIT
);
382 SurfObj
->pvScan0
= SurfObj
->pvBits
;
385 InitializeFuncs(SurfGDI
, UncompressedFormat
);
387 // Use flags to determine bitmap type -- TOP_DOWN or whatever
396 EngCreateDeviceSurface(IN DHSURF dhsurf
,
404 NewSurface
= (HSURF
)CreateGDIHandle(sizeof( SURFGDI
), sizeof( SURFOBJ
));
405 if( !ValidEngHandle( NewSurface
) )
408 SurfObj
= (SURFOBJ
*) AccessUserObject( (ULONG
) NewSurface
);
409 SurfGDI
= (SURFGDI
*) AccessInternalObject( (ULONG
) NewSurface
);
413 SurfGDI
->BitsPerPixel
= BitsPerFormat(Format
);
414 SurfObj
->dhsurf
= dhsurf
;
415 SurfObj
->hsurf
= (HSURF
) dhsurf
; // FIXME: Is this correct??
416 SurfObj
->sizlBitmap
= Size
;
417 SurfObj
->iBitmapFormat
= Format
;
418 SurfObj
->lDelta
= DIB_GetDIBWidthBytes(Size
.cx
, BitsPerFormat(Format
));
419 SurfObj
->iType
= STYPE_DEVICE
;
422 InitializeFuncs(SurfGDI
, Format
);
427 PFN FASTCALL
DriverFunction(DRVENABLEDATA
*DED
, ULONG DriverFunc
)
431 for(i
=0; i
<DED
->c
; i
++)
433 if(DED
->pdrvfn
[i
].iFunc
== DriverFunc
)
434 return DED
->pdrvfn
[i
].pfn
;
443 EngAssociateSurface(IN HSURF Surface
,
451 Device
= (GDIDEVICE
*)Dev
;
453 SurfGDI
= (PVOID
)AccessInternalObject((ULONG
)Surface
);
454 SurfObj
= (PVOID
)AccessUserObject((ULONG
)Surface
);
456 // Associate the hdev
458 SurfObj
->dhpdev
= Device
->PDev
;
460 // Hook up specified functions
461 if(Hooks
& HOOK_BITBLT
) SurfGDI
->BitBlt
= Device
->DriverFunctions
.BitBlt
;
462 if(Hooks
& HOOK_TRANSPARENTBLT
) SurfGDI
->TransparentBlt
= Device
->DriverFunctions
.TransparentBlt
;
463 if(Hooks
& HOOK_STRETCHBLT
) SurfGDI
->StretchBlt
= (PFN_StretchBlt
)Device
->DriverFunctions
.StretchBlt
;
464 if(Hooks
& HOOK_TEXTOUT
) SurfGDI
->TextOut
= Device
->DriverFunctions
.TextOut
;
465 if(Hooks
& HOOK_PAINT
) SurfGDI
->Paint
= Device
->DriverFunctions
.Paint
;
466 if(Hooks
& HOOK_STROKEPATH
) SurfGDI
->StrokePath
= Device
->DriverFunctions
.StrokePath
;
467 if(Hooks
& HOOK_FILLPATH
) SurfGDI
->FillPath
= Device
->DriverFunctions
.FillPath
;
468 if(Hooks
& HOOK_STROKEANDFILLPATH
) SurfGDI
->StrokeAndFillPath
= Device
->DriverFunctions
.StrokeAndFillPath
;
469 if(Hooks
& HOOK_LINETO
) SurfGDI
->LineTo
= Device
->DriverFunctions
.LineTo
;
470 if(Hooks
& HOOK_COPYBITS
) SurfGDI
->CopyBits
= Device
->DriverFunctions
.CopyBits
;
471 if(Hooks
& HOOK_SYNCHRONIZE
) SurfGDI
->Synchronize
= Device
->DriverFunctions
.Synchronize
;
472 if(Hooks
& HOOK_SYNCHRONIZEACCESS
) SurfGDI
->SynchronizeAccess
= TRUE
;
473 if(Hooks
& HOOK_GRADIENTFILL
) SurfGDI
->GradientFill
= Device
->DriverFunctions
.GradientFill
;
475 SurfGDI
->CreateDeviceBitmap
= Device
->DriverFunctions
.CreateDeviceBitmap
;
476 SurfGDI
->SetPalette
= Device
->DriverFunctions
.SetPalette
;
477 SurfGDI
->MovePointer
= Device
->DriverFunctions
.MovePointer
;
478 SurfGDI
->SetPointerShape
= (PFN_SetPointerShape
)Device
->DriverFunctions
.SetPointerShape
;
480 SurfGDI
->DriverLock
= &Device
->DriverLock
;
501 pso
= EngLockSurface(hsurf
);
507 if (!EngAssociateSurface(hsurf
, hdev
, flHooks
))
509 EngUnlockSurface(pso
);
514 pso
->dhsurf
= dhsurf
;
515 pso
->lDelta
= lDelta
;
516 pso
->pvScan0
= pvScan0
;
518 EngUnlockSurface(pso
);
527 EngDeleteSurface(IN HSURF Surface
)
529 FreeGDIHandle((ULONG
)Surface
);
537 EngEraseSurface(SURFOBJ
*Surface
,
541 return FillSolid(Surface
, Rect
, iColor
);
548 EngLockSurface(IN HSURF Surface
)
551 * FIXME - don't know if GDIOBJ_LockObj's return value is a SURFOBJ or not...
552 * also, what is HSURF's correct magic #?
555 GDIOBJ_LockObj ( Surface
, GDI_OBJECT_TYPE_DONTCARE
);
557 return (SURFOBJ
*)AccessUserObject((ULONG
)Surface
);
564 EngUnlockSurface(IN SURFOBJ
*Surface
)
567 * FIXME what is HSURF's correct magic #?
570 GDIOBJ_UnlockObj ( Surface
->hsurf
, GDI_OBJECT_TYPE_DONTCARE
);