branch update for HEAD-2003050101
[reactos.git] / 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 #include "../dib/dib.h"
22
23 #define NDEBUG
24 #include <win32k/debug1.h>
25
26 INT BitsPerFormat(ULONG Format)
27 {
28   switch(Format)
29   {
30     case BMF_1BPP: return 1;
31     case BMF_4BPP:
32     case BMF_4RLE: return 4;
33     case BMF_8BPP:
34     case BMF_8RLE: return 8;
35     case BMF_16BPP: return 16;
36     case BMF_24BPP: return 24;
37     case BMF_32BPP: return 32;
38     default: return 0;
39   }
40 }
41
42 ULONG BitmapFormat(WORD Bits, DWORD Compression)
43 {
44   switch(Compression)
45   {
46     case BI_RGB:
47       switch(Bits)
48       {
49         case 1: return BMF_1BPP;
50         case 4: return BMF_4BPP;
51         case 8: return BMF_8BPP;
52         case 16: return BMF_16BPP;
53         case 24: return BMF_24BPP;
54         case 32: return BMF_32BPP;
55       }
56
57     case BI_RLE4: return BMF_4RLE;
58     case BI_RLE8: return BMF_8RLE;
59
60     default: return 0;
61   }
62 }
63
64 static VOID Dummy_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
65 {
66   return;
67 }
68
69 static VOID Dummy_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
70 {
71   return;
72 }
73
74 static VOID Dummy_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
75 {
76   return;
77 }
78
79 static BOOLEAN Dummy_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
80                             SURFGDI *DestGDI,  SURFGDI *SourceGDI,
81                             PRECTL  DestRect,  POINTL  *SourcePoint,
82                             XLATEOBJ *ColorTranslation)
83 {
84   return FALSE;
85 }
86
87 VOID InitializeFuncs(SURFGDI *SurfGDI, ULONG BitmapFormat)
88 {
89   SurfGDI->BitBlt   = NULL;
90   SurfGDI->CopyBits = NULL;
91   SurfGDI->CreateDeviceBitmap = NULL;
92   SurfGDI->SetPalette = NULL;
93   SurfGDI->TransparentBlt = NULL;
94
95   switch(BitmapFormat)
96     {
97     case BMF_1BPP:
98       SurfGDI->DIB_PutPixel = DIB_1BPP_PutPixel;
99       SurfGDI->DIB_HLine    = DIB_1BPP_HLine;
100       SurfGDI->DIB_VLine    = DIB_1BPP_VLine;
101       SurfGDI->DIB_BitBlt   = DIB_1BPP_BitBlt;
102       break;
103
104     case BMF_4BPP:
105       SurfGDI->DIB_PutPixel = DIB_4BPP_PutPixel;
106       SurfGDI->DIB_HLine    = DIB_4BPP_HLine;
107       SurfGDI->DIB_VLine    = DIB_4BPP_VLine;
108       SurfGDI->DIB_BitBlt   = DIB_4BPP_BitBlt;
109       break;
110
111     case BMF_8BPP:
112       SurfGDI->DIB_PutPixel = DIB_8BPP_PutPixel;
113       SurfGDI->DIB_HLine    = DIB_8BPP_HLine;
114       SurfGDI->DIB_VLine    = DIB_8BPP_VLine;
115       SurfGDI->DIB_BitBlt   = DIB_8BPP_BitBlt;
116       break;
117
118     case BMF_16BPP:
119       SurfGDI->DIB_PutPixel = DIB_16BPP_PutPixel;
120       SurfGDI->DIB_HLine    = DIB_16BPP_HLine;
121       SurfGDI->DIB_VLine    = DIB_16BPP_VLine;
122       SurfGDI->DIB_BitBlt   = DIB_16BPP_BitBlt;
123       break;
124
125     case BMF_24BPP:
126       SurfGDI->DIB_PutPixel = DIB_24BPP_PutPixel;
127       SurfGDI->DIB_HLine    = DIB_24BPP_HLine;
128       SurfGDI->DIB_VLine    = DIB_24BPP_VLine;
129       SurfGDI->DIB_BitBlt   = DIB_24BPP_BitBlt;
130       break;
131
132     case BMF_32BPP:
133       SurfGDI->DIB_PutPixel = DIB_32BPP_PutPixel;
134       SurfGDI->DIB_HLine    = DIB_32BPP_HLine;
135       SurfGDI->DIB_VLine    = DIB_32BPP_VLine;
136       SurfGDI->DIB_BitBlt   = DIB_32BPP_BitBlt;
137       break;
138
139     case BMF_4RLE:
140     case BMF_8RLE:
141       /* Not supported yet, fall through to unrecognized case */
142     default:
143       DPRINT1("InitializeFuncs: unsupported DIB format %d\n",
144                BitmapFormat);
145
146       SurfGDI->DIB_PutPixel = Dummy_PutPixel;
147       SurfGDI->DIB_HLine    = Dummy_HLine;
148       SurfGDI->DIB_VLine    = Dummy_VLine;
149       SurfGDI->DIB_BitBlt   = Dummy_BitBlt;
150       break;
151     }
152 }
153
154 HBITMAP STDCALL
155 EngCreateDeviceBitmap(IN DHSURF dhsurf,
156                       IN SIZEL Size,
157                       IN ULONG Format)
158 {
159   HBITMAP NewBitmap;
160   SURFOBJ *SurfObj;
161
162   NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
163   SurfObj = (PVOID)AccessUserObject((ULONG)NewBitmap);
164   SurfObj->dhpdev = dhsurf;
165
166   return NewBitmap;
167 }
168
169 HBITMAP STDCALL
170 EngCreateBitmap(IN SIZEL Size,
171                 IN LONG Width,
172                 IN ULONG Format,
173                 IN ULONG Flags,
174                 IN PVOID Bits)
175 {
176   HBITMAP NewBitmap;
177   SURFOBJ *SurfObj;
178   SURFGDI *SurfGDI;
179
180
181   NewBitmap = (PVOID)CreateGDIHandle(sizeof(SURFGDI), sizeof(SURFOBJ));
182   if( !ValidEngHandle( NewBitmap ) )
183         return 0;
184
185   SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewBitmap );
186   SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewBitmap );
187   ASSERT( SurfObj );
188   ASSERT( SurfGDI );
189
190   SurfGDI->BitsPerPixel = BitsPerFormat(Format);
191   SurfObj->lDelta = Width;
192   SurfObj->cjBits = SurfObj->lDelta * Size.cy;
193
194   if(Bits!=NULL)
195   {
196     SurfObj->pvBits = Bits;
197   } else
198   {
199     if(Flags & BMF_USERMEM)
200     {
201       SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
202     } else {
203       if(Flags & BMF_NOZEROINIT)
204       {
205         SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
206       } else {
207         SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
208       }
209     }
210   }
211
212   SurfObj->dhsurf = 0; // device managed surface
213   SurfObj->hsurf  = 0;
214   SurfObj->sizlBitmap = Size;
215   SurfObj->iBitmapFormat = Format;
216   SurfObj->iType = STYPE_BITMAP;
217   SurfObj->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
218   SurfObj->pvScan0 = SurfObj->pvBits;
219
220   InitializeFuncs(SurfGDI, Format);
221
222   // Use flags to determine bitmap type -- TOP_DOWN or whatever
223
224   return NewBitmap;
225 }
226
227 HSURF STDCALL
228 EngCreateDeviceSurface(IN DHSURF dhsurf,
229                        IN SIZEL Size,
230                        IN ULONG Format)
231 {
232   HSURF   NewSurface;
233   SURFOBJ *SurfObj;
234   SURFGDI *SurfGDI;
235
236   NewSurface = (HSURF)CreateGDIHandle(sizeof( SURFGDI ), sizeof( SURFOBJ ));
237   if( !ValidEngHandle( NewSurface ) )
238         return 0;
239
240   SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewSurface );
241   SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewSurface );
242   ASSERT( SurfObj );
243   ASSERT( SurfGDI );
244
245   SurfGDI->BitsPerPixel = BitsPerFormat(Format);
246   SurfObj->dhsurf = dhsurf;
247   SurfObj->hsurf  = dhsurf; // FIXME: Is this correct??
248   SurfObj->sizlBitmap = Size;
249   SurfObj->iBitmapFormat = Format;
250   SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
251   SurfObj->iType = STYPE_DEVICE;
252
253   InitializeFuncs(SurfGDI, Format);
254
255   return NewSurface;
256 }
257
258 PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
259 {
260   ULONG i;
261
262   for(i=0; i<DED->c; i++)
263   {
264     if(DED->pdrvfn[i].iFunc == DriverFunc)
265       return DED->pdrvfn[i].pfn;
266   }
267   return NULL;
268 }
269
270 BOOL STDCALL
271 EngAssociateSurface(IN HSURF Surface,
272                     IN HDEV Dev,
273                     IN ULONG Hooks)
274 {
275   SURFOBJ *SurfObj;
276   SURFGDI *SurfGDI;
277   GDIDEVICE* Device;
278
279   Device = (GDIDEVICE*)Dev;
280
281   SurfGDI = (PVOID)AccessInternalObject((ULONG)Surface);
282   SurfObj = (PVOID)AccessUserObject((ULONG)Surface);
283
284   // Associate the hdev
285   SurfObj->hdev = Dev;
286
287   // Hook up specified functions
288   if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Device->DriverFunctions.BitBlt;
289   if(Hooks & HOOK_TRANSPARENTBLT)    SurfGDI->TransparentBlt    = Device->DriverFunctions.TransparentBlt;
290   if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = (PFN_StretchBlt)Device->DriverFunctions.StretchBlt;
291   if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Device->DriverFunctions.TextOut;
292   if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Device->DriverFunctions.Paint;
293   if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Device->DriverFunctions.StrokePath;
294   if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Device->DriverFunctions.FillPath;
295   if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Device->DriverFunctions.StrokeAndFillPath;
296   if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Device->DriverFunctions.LineTo;
297   if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Device->DriverFunctions.CopyBits;
298   if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Device->DriverFunctions.Synchronize;
299   if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
300
301   SurfGDI->CreateDeviceBitmap = Device->DriverFunctions.CreateDeviceBitmap;
302   SurfGDI->SetPalette = Device->DriverFunctions.SetPalette;
303   SurfGDI->MovePointer = Device->DriverFunctions.MovePointer;
304   SurfGDI->SetPointerShape = (PFN_SetPointerShape)Device->DriverFunctions.SetPointerShape;
305
306   return TRUE;
307 }
308
309 BOOL STDCALL
310 EngDeleteSurface(IN HSURF Surface)
311 {
312   FreeGDIHandle((ULONG)Surface);
313   return TRUE;
314 }
315
316 BOOL STDCALL
317 EngEraseSurface(SURFOBJ *Surface,
318                 RECTL *Rect,
319                 ULONG iColor)
320 {
321   return FillSolid(Surface, Rect, iColor);
322 }
323
324 SURFOBJ * STDCALL
325 EngLockSurface(IN HSURF Surface)
326 {
327   // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
328   return (SURFOBJ*)AccessUserObject((ULONG)Surface);
329 }
330
331 VOID STDCALL
332 EngUnlockSurface(IN SURFOBJ *Surface)
333 {
334   // FIXME: Call GDI_UnlockObject
335 }