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