676ae553de53fcc83528f23b5466c06621ad70dc
[reactos.git] / reactos / subsys / win32k / eng / surface.c
1 /*
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
7 * REVISION HISTORY:
8 * 3/7/1999: Created
9 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
10 * TESTING TO BE DONE:
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
13 */
14
15 #include <ddk/winddi.h>
16 #include <win32k/dc.h>
17 #include <include/dib.h>
18 #include <include/object.h>
19 #include <include/paint.h>
20 #include "handle.h"
21
22 //#define NDEBUG
23 #include <win32k/debug1.h>
24
25 INT BitsPerFormat(ULONG Format)
26 {
27 switch(Format)
28 {
29 case BMF_1BPP: return 1;
30 case BMF_4BPP:
31 case BMF_4RLE: return 4;
32 case BMF_8BPP:
33 case BMF_8RLE: return 8;
34 case BMF_16BPP: return 16;
35 case BMF_24BPP: return 24;
36 case BMF_32BPP: return 32;
37 default: return 0;
38 }
39 }
40
41 ULONG BitmapFormat(WORD Bits, DWORD Compression)
42 {
43 switch(Compression)
44 {
45 case BI_RGB:
46 switch(Bits)
47 {
48 case 1: return BMF_1BPP;
49 case 4: return BMF_4BPP;
50 case 8: return BMF_8BPP;
51 case 16: return BMF_16BPP;
52 case 24: return BMF_24BPP;
53 case 32: return BMF_32BPP;
54 }
55
56 case BI_RLE4: return BMF_4RLE;
57 case BI_RLE8: return BMF_8RLE;
58
59 default: return 0;
60 }
61 }
62
63 VOID InitializeHooks(SURFGDI *SurfGDI)
64 {
65 SurfGDI->BitBlt = NULL;
66 SurfGDI->CopyBits = NULL;
67 SurfGDI->CreateDeviceBitmap = NULL;
68 SurfGDI->SetPalette = NULL;
69 SurfGDI->TransparentBlt = NULL;
70 }
71
72 HBITMAP STDCALL
73 EngCreateDeviceBitmap(IN DHSURF dhsurf,
74 IN SIZEL Size,
75 IN ULONG Format)
76 {
77 HBITMAP NewBitmap;
78 SURFOBJ *SurfObj;
79
80 NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
81 SurfObj = (PVOID)AccessUserObject((ULONG)NewBitmap);
82 SurfObj->dhpdev = dhsurf;
83
84 return NewBitmap;
85 }
86
87 HBITMAP STDCALL
88 EngCreateBitmap(IN SIZEL Size,
89 IN LONG Width,
90 IN ULONG Format,
91 IN ULONG Flags,
92 IN PVOID Bits)
93 {
94 HBITMAP NewBitmap;
95 SURFOBJ *SurfObj;
96 SURFGDI *SurfGDI;
97
98
99 NewBitmap = (PVOID)CreateGDIHandle(sizeof(SURFGDI), sizeof(SURFOBJ));
100 if( !ValidEngHandle( NewBitmap ) )
101 return 0;
102
103 SurfObj = (SURFOBJ*) AccessUserObject( NewBitmap );
104 SurfGDI = (SURFGDI*) AccessInternalObject( NewBitmap );
105 ASSERT( SurfObj );
106 ASSERT( SurfGDI );
107
108 InitializeHooks(SurfGDI);
109
110 SurfGDI->BitsPerPixel = BitsPerFormat(Format);
111 SurfObj->lDelta = Width;
112 SurfObj->cjBits = SurfObj->lDelta * Size.cy;
113
114 if(Bits!=NULL)
115 {
116 SurfObj->pvBits = Bits;
117 } else
118 {
119 if(Flags & BMF_USERMEM)
120 {
121 SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
122 } else {
123 if(Flags & BMF_NOZEROINIT)
124 {
125 SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
126 } else {
127 SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
128 }
129 }
130 }
131
132 SurfObj->dhsurf = 0; // device managed surface
133 SurfObj->hsurf = 0;
134 SurfObj->sizlBitmap = Size;
135 SurfObj->iBitmapFormat = Format;
136 SurfObj->iType = STYPE_BITMAP;
137
138 // Use flags to determine bitmap type -- TOP_DOWN or whatever
139
140 return NewBitmap;
141 }
142
143 HSURF STDCALL
144 EngCreateDeviceSurface(IN DHSURF dhsurf,
145 IN SIZEL Size,
146 IN ULONG Format)
147 {
148 HSURF NewSurface;
149 SURFOBJ *SurfObj;
150 SURFGDI *SurfGDI;
151
152 NewSurface = (HSURF)CreateGDIHandle(sizeof( SURFGDI ), sizeof( SURFOBJ ));
153 if( !ValidEngHandle( NewSurface ) )
154 return 0;
155
156 SurfObj = (SURFOBJ*) AccessUserObject( NewSurface );
157 SurfGDI = (SURFGDI*) AccessInternalObject( NewSurface );
158 ASSERT( SurfObj );
159 ASSERT( SurfGDI );
160
161 InitializeHooks(SurfGDI);
162
163 SurfGDI->BitsPerPixel = BitsPerFormat(Format);
164 SurfObj->dhsurf = dhsurf;
165 SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
166 SurfObj->sizlBitmap = Size;
167 SurfObj->iBitmapFormat = Format;
168 SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
169 SurfObj->iType = STYPE_DEVICE;
170
171 return NewSurface;
172 }
173
174 PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
175 {
176 ULONG i;
177
178 for(i=0; i<DED->c; i++)
179 {
180 if(DED->pdrvfn[i].iFunc == DriverFunc)
181 return DED->pdrvfn[i].pfn;
182 }
183 return NULL;
184 }
185
186 BOOL STDCALL
187 EngAssociateSurface(IN HSURF Surface,
188 IN HDEV Dev,
189 IN ULONG Hooks)
190 {
191 SURFOBJ *SurfObj;
192 SURFGDI *SurfGDI;
193
194 PDC Dc = (PDC)Dev;
195
196 SurfGDI = (PVOID)AccessInternalObject((ULONG)Surface);
197 SurfObj = (PVOID)AccessUserObject((ULONG)Surface);
198
199 // Associate the hdev
200 SurfObj->hdev = Dev;
201
202 // Hook up specified functions
203 if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
204 if(Hooks & HOOK_TRANSPARENTBLT) SurfGDI->TransparentBlt = Dc->DriverFunctions.TransparentBlt;
205 if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = (PFN_StretchBlt)Dc->DriverFunctions.StretchBlt;
206 if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
207 if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
208 if(Hooks & HOOK_STROKEPATH) SurfGDI->StrokePath = Dc->DriverFunctions.StrokePath;
209 if(Hooks & HOOK_FILLPATH) SurfGDI->FillPath = Dc->DriverFunctions.FillPath;
210 if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
211 if(Hooks & HOOK_LINETO) SurfGDI->LineTo = Dc->DriverFunctions.LineTo;
212 if(Hooks & HOOK_COPYBITS) SurfGDI->CopyBits = Dc->DriverFunctions.CopyBits;
213 if(Hooks & HOOK_SYNCHRONIZE) SurfGDI->Synchronize = Dc->DriverFunctions.Synchronize;
214 if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
215
216 SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
217 SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
218 SurfGDI->MovePointer = Dc->DriverFunctions.MovePointer;
219 SurfGDI->SetPointerShape = (PFN_SetPointerShape)Dc->DriverFunctions.SetPointerShape;
220
221 return TRUE;
222 }
223
224 BOOL STDCALL
225 EngDeleteSurface(IN HSURF Surface)
226 {
227 FreeGDIHandle((ULONG)Surface);
228 return TRUE;
229 }
230
231 BOOL STDCALL
232 EngEraseSurface(SURFOBJ *Surface,
233 RECTL *Rect,
234 ULONG iColor)
235 {
236 return FillSolid(Surface, Rect, iColor);
237 }
238
239 SURFOBJ * STDCALL
240 EngLockSurface(IN HSURF Surface)
241 {
242 // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
243 return (SURFOBJ*)AccessUserObject((ULONG)Surface);
244 }