3ec09671d6fda42aac7fb235563447270e253a62
[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
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   GDIDEVICE* Device;
194
195   Device = (GDIDEVICE*)Dev;
196
197   SurfGDI = (PVOID)AccessInternalObject((ULONG)Surface);
198   SurfObj = (PVOID)AccessUserObject((ULONG)Surface);
199
200   // Associate the hdev
201   SurfObj->hdev = Dev;
202
203   // Hook up specified functions
204   if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Device->DriverFunctions.BitBlt;
205   if(Hooks & HOOK_TRANSPARENTBLT)    SurfGDI->TransparentBlt    = Device->DriverFunctions.TransparentBlt;
206   if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = (PFN_StretchBlt)Device->DriverFunctions.StretchBlt;
207   if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Device->DriverFunctions.TextOut;
208   if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Device->DriverFunctions.Paint;
209   if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Device->DriverFunctions.StrokePath;
210   if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Device->DriverFunctions.FillPath;
211   if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Device->DriverFunctions.StrokeAndFillPath;
212   if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Device->DriverFunctions.LineTo;
213   if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Device->DriverFunctions.CopyBits;
214   if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Device->DriverFunctions.Synchronize;
215   if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
216
217   SurfGDI->CreateDeviceBitmap = Device->DriverFunctions.CreateDeviceBitmap;
218   SurfGDI->SetPalette = Device->DriverFunctions.SetPalette;
219   SurfGDI->MovePointer = Device->DriverFunctions.MovePointer;
220   SurfGDI->SetPointerShape = (PFN_SetPointerShape)Device->DriverFunctions.SetPointerShape;
221
222   return TRUE;
223 }
224
225 BOOL STDCALL
226 EngDeleteSurface(IN HSURF Surface)
227 {
228   FreeGDIHandle((ULONG)Surface);
229   return TRUE;
230 }
231
232 BOOL STDCALL
233 EngEraseSurface(SURFOBJ *Surface,
234                 RECTL *Rect,
235                 ULONG iColor)
236 {
237   return FillSolid(Surface, Rect, iColor);
238 }
239
240 SURFOBJ * STDCALL
241 EngLockSurface(IN HSURF Surface)
242 {
243   // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
244   return (SURFOBJ*)AccessUserObject((ULONG)Surface);
245 }