update for HEAD-2003091401
[reactos.git] / subsys / win32k / eng / surface.c
1 /*
2  *  ReactOS W32 Subsystem
3  *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4  *
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.
9  *
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.
14  *
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.
18  */
19 /* $Id$
20  * 
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
26  * REVISION HISTORY:
27  *                 3/7/1999: Created
28  *                 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
29  * TESTING TO BE DONE:
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
32  */
33
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>
40 #include "handle.h"
41 #include "../dib/dib.h"
42
43 #define NDEBUG
44 #include <win32k/debug1.h>
45
46 INT FASTCALL BitsPerFormat(ULONG Format)
47 {
48   switch(Format)
49   {
50     case BMF_1BPP: return 1;
51     case BMF_4BPP:
52     case BMF_4RLE: return 4;
53     case BMF_8BPP:
54     case BMF_8RLE: return 8;
55     case BMF_16BPP: return 16;
56     case BMF_24BPP: return 24;
57     case BMF_32BPP: return 32;
58     default: return 0;
59   }
60 }
61
62 ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
63 {
64   switch(Compression)
65   {
66     case BI_RGB:
67       switch(Bits)
68       {
69         case 1: return BMF_1BPP;
70         case 4: return BMF_4BPP;
71         case 8: return BMF_8BPP;
72         case 16: return BMF_16BPP;
73         case 24: return BMF_24BPP;
74         case 32: return BMF_32BPP;
75       }
76
77     case BI_RLE4: return BMF_4RLE;
78     case BI_RLE8: return BMF_8RLE;
79
80     default: return 0;
81   }
82 }
83
84 static VOID Dummy_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
85 {
86   return;
87 }
88
89 static VOID Dummy_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
90 {
91   return;
92 }
93
94 static VOID Dummy_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
95 {
96   return;
97 }
98
99 static BOOLEAN Dummy_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
100                             SURFGDI *DestGDI,  SURFGDI *SourceGDI,
101                             PRECTL  DestRect,  POINTL  *SourcePoint,
102                             PBRUSHOBJ BrushObj, POINTL* BrushOrign,
103                             XLATEOBJ *ColorTranslation, ULONG Rop4)
104 {
105   return FALSE;
106 }
107
108 #define SURF_METHOD(c,n) DIB_##c##_##n
109 #define SET_SURFGDI(c)\
110  SurfGDI->DIB_PutPixel=SURF_METHOD(c,PutPixel);\
111  SurfGDI->DIB_HLine=SURF_METHOD(c,HLine);\
112  SurfGDI->DIB_VLine=SURF_METHOD(c,VLine);\
113  SurfGDI->DIB_BitBlt=SURF_METHOD(c,BitBlt);
114
115 VOID FASTCALL InitializeFuncs(SURFGDI *SurfGDI, ULONG BitmapFormat)
116 {
117   SurfGDI->BitBlt   = NULL;
118   SurfGDI->CopyBits = NULL;
119   SurfGDI->CreateDeviceBitmap = NULL;
120   SurfGDI->SetPalette = NULL;
121   SurfGDI->TransparentBlt = NULL;
122
123   switch(BitmapFormat)
124     {
125     case BMF_1BPP:  SET_SURFGDI(1BPP) break;
126     case BMF_4BPP:  SET_SURFGDI(4BPP) break;
127     case BMF_8BPP:  SET_SURFGDI(8BPP) break;
128     case BMF_16BPP: SET_SURFGDI(16BPP) break;
129     case BMF_24BPP: SET_SURFGDI(24BPP) break;
130     case BMF_32BPP: SET_SURFGDI(32BPP) break;
131     case BMF_4RLE:
132     case BMF_8RLE:
133       /* Not supported yet, fall through to unrecognized case */
134     default:
135       DPRINT1("InitializeFuncs: unsupported DIB format %d\n",
136                BitmapFormat);
137
138       SurfGDI->DIB_PutPixel = Dummy_PutPixel;
139       SurfGDI->DIB_HLine    = Dummy_HLine;
140       SurfGDI->DIB_VLine    = Dummy_VLine;
141       SurfGDI->DIB_BitBlt   = Dummy_BitBlt;
142       break;
143     }
144 }
145
146 /*
147  * @implemented
148  */
149 HBITMAP STDCALL
150 EngCreateDeviceBitmap(IN DHSURF dhsurf,
151                       IN SIZEL Size,
152                       IN ULONG Format)
153 {
154   HBITMAP NewBitmap;
155   SURFOBJ *SurfObj;
156
157   NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
158   SurfObj = (PVOID)AccessUserObject((ULONG)NewBitmap);
159   SurfObj->dhpdev = dhsurf;
160
161   return NewBitmap;
162 }
163
164 /*
165  * @implemented
166  */
167 HBITMAP STDCALL
168 EngCreateBitmap(IN SIZEL Size,
169                 IN LONG Width,
170                 IN ULONG Format,
171                 IN ULONG Flags,
172                 IN PVOID Bits)
173 {
174   HBITMAP NewBitmap;
175   SURFOBJ *SurfObj;
176   SURFGDI *SurfGDI;
177
178   NewBitmap = (PVOID)CreateGDIHandle(sizeof(SURFGDI), sizeof(SURFOBJ));
179   if( !ValidEngHandle( NewBitmap ) )
180         return 0;
181
182   SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewBitmap );
183   SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewBitmap );
184   ASSERT( SurfObj );
185   ASSERT( SurfGDI );
186
187   SurfGDI->BitsPerPixel = BitsPerFormat(Format);
188   SurfObj->lDelta = Width;
189   SurfObj->cjBits = SurfObj->lDelta * Size.cy;
190
191   if(Bits!=NULL)
192   {
193     SurfObj->pvBits = Bits;
194   } else
195   {
196     if(Flags & BMF_USERMEM)
197     {
198       SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
199     } else {
200       if(Flags & BMF_NOZEROINIT)
201       {
202         SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
203       } else {
204         SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
205       }
206     }
207   }
208
209   SurfObj->dhsurf = 0; // device managed surface
210   SurfObj->hsurf  = 0;
211   SurfObj->sizlBitmap = Size;
212   SurfObj->iBitmapFormat = Format;
213   SurfObj->iType = STYPE_BITMAP;
214   SurfObj->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
215   SurfObj->pvScan0 = SurfObj->pvBits;
216
217   InitializeFuncs(SurfGDI, Format);
218
219   // Use flags to determine bitmap type -- TOP_DOWN or whatever
220
221   return NewBitmap;
222 }
223
224 /*
225  * @unimplemented
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 FASTCALL 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 /*
271  * @implemented
272  */
273 BOOL STDCALL
274 EngAssociateSurface(IN HSURF Surface,
275                     IN HDEV Dev,
276                     IN ULONG Hooks)
277 {
278   SURFOBJ *SurfObj;
279   SURFGDI *SurfGDI;
280   GDIDEVICE* Device;
281
282   Device = (GDIDEVICE*)Dev;
283
284   SurfGDI = (PVOID)AccessInternalObject((ULONG)Surface);
285   SurfObj = (PVOID)AccessUserObject((ULONG)Surface);
286
287   // Associate the hdev
288   SurfObj->hdev = Dev;
289
290   // Hook up specified functions
291   if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Device->DriverFunctions.BitBlt;
292   if(Hooks & HOOK_TRANSPARENTBLT)    SurfGDI->TransparentBlt    = Device->DriverFunctions.TransparentBlt;
293   if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = (PFN_StretchBlt)Device->DriverFunctions.StretchBlt;
294   if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Device->DriverFunctions.TextOut;
295   if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Device->DriverFunctions.Paint;
296   if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Device->DriverFunctions.StrokePath;
297   if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Device->DriverFunctions.FillPath;
298   if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Device->DriverFunctions.StrokeAndFillPath;
299   if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Device->DriverFunctions.LineTo;
300   if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Device->DriverFunctions.CopyBits;
301   if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Device->DriverFunctions.Synchronize;
302   if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
303
304   SurfGDI->CreateDeviceBitmap = Device->DriverFunctions.CreateDeviceBitmap;
305   SurfGDI->SetPalette = Device->DriverFunctions.SetPalette;
306   SurfGDI->MovePointer = Device->DriverFunctions.MovePointer;
307   SurfGDI->SetPointerShape = (PFN_SetPointerShape)Device->DriverFunctions.SetPointerShape;
308
309   return TRUE;
310 }
311
312 /*
313  * @implemented
314  */
315 BOOL STDCALL
316 EngDeleteSurface(IN HSURF Surface)
317 {
318   FreeGDIHandle((ULONG)Surface);
319   return TRUE;
320 }
321
322 /*
323  * @implemented
324  */
325 BOOL STDCALL
326 EngEraseSurface(SURFOBJ *Surface,
327                 RECTL *Rect,
328                 ULONG iColor)
329 {
330   return FillSolid(Surface, Rect, iColor);
331 }
332
333 /*
334  * @unimplemented
335  */
336 SURFOBJ * STDCALL
337 EngLockSurface(IN HSURF Surface)
338 {
339   /*
340    * FIXME - don't know if GDIOBJ_LockObj's return value is a SURFOBJ or not...
341    * also, what is HSURF's correct magic #?
342    */
343 #ifdef TODO
344   GDIOBJ_LockObj ( Surface, GDI_OBJECT_TYPE_DONTCARE );
345 #endif
346   return (SURFOBJ*)AccessUserObject((ULONG)Surface);
347 }
348
349 /*
350  * @unimplemented
351  */
352 VOID STDCALL
353 EngUnlockSurface(IN SURFOBJ *Surface)
354 {
355   /*
356    * FIXME what is HSURF's correct magic #?
357    */
358 #ifdef TODO
359   GDIOBJ_UnlockObj ( Surface->hsurf, GDI_OBJECT_TYPE_DONTCARE );
360 #endif
361 }
362 /* EOF */