cea2f1a13f980a6b080e4f62b7304e0ea11fc8b1
[reactos.git] / reactos / subsys / win32k / misc / driver.c
1 /* $Id: driver.c,v 1.16 2001/03/31 15:35:08 jfilby Exp $
2 *
3 * GDI Driver support routines
4 * (mostly swiped from Wine)
5 *
6 */
7
8 #undef WIN32_LEAN_AND_MEAN
9 #define WIN32_NO_PEHDR
10
11 #include <ddk/ntddk.h>
12 #include <windows.h>
13 #include <win32k/driver.h>
14 #include <wchar.h>
15 #include "../../ntoskrnl/include/internal/module.h"
16 #include <ddk/winddi.h>
17 #include <ddk/ntddvid.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22 typedef struct _GRAPHICS_DRIVER
23 {
24 PWSTR Name;
25 PGD_ENABLEDRIVER EnableDriver;
26 int ReferenceCount;
27 struct _GRAPHICS_DRIVER *Next;
28 } GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
29
30 static PGRAPHICS_DRIVER DriverList;
31 static PGRAPHICS_DRIVER GenericDriver = 0;
32
33 BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
34 {
35 PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
36 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
37 if (!Driver) return FALSE;
38 Driver->ReferenceCount = 0;
39 Driver->EnableDriver = EnableDriver;
40 if (Name)
41 {
42 Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR));
43 wcscpy(Driver->Name, Name);
44 Driver->Next = DriverList;
45 DriverList = Driver;
46 return TRUE;
47 }
48
49 if (GenericDriver != NULL)
50 {
51 ExFreePool(Driver);
52 return FALSE;
53 }
54
55 GenericDriver = Driver;
56 return TRUE;
57 }
58
59 PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
60 {
61 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
62 GRAPHICS_DRIVER *Driver = DriverList;
63 NTSTATUS Status;
64
65 /* First see if the driver hasn't already been loaded */
66 while (Driver && Name)
67 {
68 if (!_wcsicmp( Driver->Name, Name))
69 {
70 return Driver->EnableDriver;
71 }
72 Driver = Driver->Next;
73 }
74
75 /* If not, then load it */
76 RtlInitUnicodeString (&GdiDriverInfo.DriverName, (LPWSTR)Name);
77 Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
78 if (!NT_SUCCESS(Status)) return NULL;
79
80 DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
81 return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
82 }
83
84 BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
85 PDRIVER_FUNCTIONS DF)
86 {
87 int i;
88
89 for (i=0; i<DED->c; i++)
90 {
91 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnablePDEV) DF->EnablePDev = (PGD_ENABLEPDEV)DED->pdrvfn[i].pfn;
92 if(DED->pdrvfn[i].iFunc == INDEX_DrvCompletePDEV) DF->CompletePDev = (PGD_COMPLETEPDEV)DED->pdrvfn[i].pfn;
93 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisablePDEV) DF->DisablePDev = (PGD_DISABLEPDEV)DED->pdrvfn[i].pfn;
94 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnableSurface) DF->EnableSurface = (PGD_ENABLESURFACE)DED->pdrvfn[i].pfn;
95 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisableSurface) DF->DisableSurface = (PGD_DISABLESURFACE)DED->pdrvfn[i].pfn;
96 if(DED->pdrvfn[i].iFunc == INDEX_DrvAssertMode) DF->AssertMode = (PGD_ASSERTMODE)DED->pdrvfn[i].pfn;
97 if(DED->pdrvfn[i].iFunc == INDEX_DrvResetPDEV) DF->ResetPDev = (PGD_RESETPDEV)DED->pdrvfn[i].pfn;
98 if(DED->pdrvfn[i].iFunc == INDEX_DrvCreateDeviceBitmap)
99 DF->CreateDeviceBitmap = (PGD_CREATEDEVICEBITMAP)DED->pdrvfn[i].pfn;
100 if(DED->pdrvfn[i].iFunc == INDEX_DrvDeleteDeviceBitmap)
101 DF->DeleteDeviceBitmap = (PGD_DELETEDEVICEBITMAP)DED->pdrvfn[i].pfn;
102 if(DED->pdrvfn[i].iFunc == INDEX_DrvRealizeBrush) DF->RealizeBrush = (PGD_REALIZEBRUSH)DED->pdrvfn[i].pfn;
103 if(DED->pdrvfn[i].iFunc == INDEX_DrvDitherColor) DF->DitherColor = (PGD_DITHERCOLOR)DED->pdrvfn[i].pfn;
104 if(DED->pdrvfn[i].iFunc == INDEX_DrvStrokePath) DF->StrokePath = (PGD_STROKEPATH)DED->pdrvfn[i].pfn;
105 if(DED->pdrvfn[i].iFunc == INDEX_DrvFillPath) DF->FillPath = (PGD_FILLPATH)DED->pdrvfn[i].pfn;
106 if(DED->pdrvfn[i].iFunc == INDEX_DrvStrokeAndFillPath)
107 DF->StrokeAndFillPath = (PGD_STROKEANDFILLPATH)DED->pdrvfn[i].pfn;
108 if(DED->pdrvfn[i].iFunc == INDEX_DrvPaint) DF->Paint = (PGD_PAINT)DED->pdrvfn[i].pfn;
109 if(DED->pdrvfn[i].iFunc == INDEX_DrvBitBlt) DF->BitBlt = (PGD_BITBLT)DED->pdrvfn[i].pfn;
110 if(DED->pdrvfn[i].iFunc == INDEX_DrvCopyBits) DF->CopyBits = (PGD_COPYBITS)DED->pdrvfn[i].pfn;
111 if(DED->pdrvfn[i].iFunc == INDEX_DrvStretchBlt) DF->StretchBlt = (PGD_STRETCHBLT)DED->pdrvfn[i].pfn;
112 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPalette) DF->SetPalette = (PGD_SETPALETTE)DED->pdrvfn[i].pfn;
113 if(DED->pdrvfn[i].iFunc == INDEX_DrvTextOut) DF->TextOut = (PGD_TEXTOUT)DED->pdrvfn[i].pfn;
114 if(DED->pdrvfn[i].iFunc == INDEX_DrvEscape) DF->Escape = (PGD_ESCAPE)DED->pdrvfn[i].pfn;
115 if(DED->pdrvfn[i].iFunc == INDEX_DrvDrawEscape) DF->DrawEscape = (PGD_DRAWESCAPE)DED->pdrvfn[i].pfn;
116 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFont) DF->QueryFont = (PGD_QUERYFONT)DED->pdrvfn[i].pfn;
117 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontTree) DF->QueryFontTree = (PGD_QUERYFONTTREE)DED->pdrvfn[i].pfn;
118 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontData) DF->QueryFontData = (PGD_QUERYFONTDATA)DED->pdrvfn[i].pfn;
119 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPointerShape) DF->SetPointerShape = (PGD_SETPOINTERSHAPE)DED->pdrvfn[i].pfn;
120 if(DED->pdrvfn[i].iFunc == INDEX_DrvMovePointer) DF->MovePointer = (PGD_MOVEPOINTER)DED->pdrvfn[i].pfn;
121 if(DED->pdrvfn[i].iFunc == INDEX_DrvLineTo) DF->LineTo = (PGD_LINETO)DED->pdrvfn[i].pfn;
122 if(DED->pdrvfn[i].iFunc == INDEX_DrvSendPage) DF->SendPage = (PGD_SENDPAGE)DED->pdrvfn[i].pfn;
123 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartPage) DF->StartPage = (PGD_STARTPAGE)DED->pdrvfn[i].pfn;
124 if(DED->pdrvfn[i].iFunc == INDEX_DrvEndDoc) DF->EndDoc = (PGD_ENDDOC)DED->pdrvfn[i].pfn;
125 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartDoc) DF->StartDoc = (PGD_STARTDOC)DED->pdrvfn[i].pfn;
126 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetGlyphMode) DF->GetGlyphMode = (PGD_GETGLYPHMODE)DED->pdrvfn[i].pfn;
127 if(DED->pdrvfn[i].iFunc == INDEX_DrvSynchronize) DF->Synchronize = (PGD_SYNCHRONIZE)DED->pdrvfn[i].pfn;
128 if(DED->pdrvfn[i].iFunc == INDEX_DrvSaveScreenBits) DF->SaveScreenBits = (PGD_SAVESCREENBITS)DED->pdrvfn[i].pfn;
129 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetModes) DF->GetModes = (PGD_GETMODES)DED->pdrvfn[i].pfn;
130 if(DED->pdrvfn[i].iFunc == INDEX_DrvFree) DF->Free = (PGD_FREE)DED->pdrvfn[i].pfn;
131 if(DED->pdrvfn[i].iFunc == INDEX_DrvDestroyFont) DF->DestroyFont = (PGD_DESTROYFONT)DED->pdrvfn[i].pfn;
132 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontCaps) DF->QueryFontCaps = (PGD_QUERYFONTCAPS)DED->pdrvfn[i].pfn;
133 if(DED->pdrvfn[i].iFunc == INDEX_DrvLoadFontFile) DF->LoadFontFile = (PGD_LOADFONTFILE)DED->pdrvfn[i].pfn;
134 if(DED->pdrvfn[i].iFunc == INDEX_DrvUnloadFontFile) DF->UnloadFontFile = (PGD_UNLOADFONTFILE)DED->pdrvfn[i].pfn;
135 if(DED->pdrvfn[i].iFunc == INDEX_DrvFontManagement) DF->FontManagement = (PGD_FONTMANAGEMENT)DED->pdrvfn[i].pfn;
136 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryTrueTypeTable)
137 DF->QueryTrueTypeTable = (PGD_QUERYTRUETYPETABLE)DED->pdrvfn[i].pfn;
138 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryTrueTypeOutline)
139 DF->QueryTrueTypeOutline = (PGD_QUERYTRUETYPEOUTLINE)DED->pdrvfn[i].pfn;
140 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetTrueTypeFile) DF->GetTrueTypeFile = (PGD_GETTRUETYPEFILE)DED->pdrvfn[i].pfn;
141 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontFile) DF->QueryFontFile = (PGD_QUERYFONTFILE)DED->pdrvfn[i].pfn;
142 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryAdvanceWidths)
143 DF->QueryAdvanceWidths = (PGD_QUERYADVANCEWIDTHS)DED->pdrvfn[i].pfn;
144 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPixelFormat) DF->SetPixelFormat = (PGD_SETPIXELFORMAT)DED->pdrvfn[i].pfn;
145 if(DED->pdrvfn[i].iFunc == INDEX_DrvDescribePixelFormat)
146 DF->DescribePixelFormat = (PGD_DESCRIBEPIXELFORMAT)DED->pdrvfn[i].pfn;
147 if(DED->pdrvfn[i].iFunc == INDEX_DrvSwapBuffers) DF->SwapBuffers = (PGD_SWAPBUFFERS)DED->pdrvfn[i].pfn;
148 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartBanding) DF->StartBanding = (PGD_STARTBANDING)DED->pdrvfn[i].pfn;
149 if(DED->pdrvfn[i].iFunc == INDEX_DrvNextBand) DF->NextBand = (PGD_NEXTBAND)DED->pdrvfn[i].pfn;
150 #if 0
151 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetDirectDrawInfo) DF->GETDIRECTDRAWINFO = (PGD_)DED->pdrvfn[i].pfn;
152 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnableDirectDraw) DF->ENABLEDIRECTDRAW = (PGD_)DED->pdrvfn[i].pfn;
153 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisableDirectDraw) DF->DISABLEDIRECTDRAW = (PGD_)DED->pdrvfn[i].pfn;
154 #endif
155 if(DED->pdrvfn[i].iFunc == INDEX_DrvQuerySpoolType) DF->QuerySpoolType = (PGD_QUERYSPOOLTYPE)DED->pdrvfn[i].pfn;
156 }
157
158 return TRUE;
159 }
160
161 typedef VP_STATUS (*PMP_DRIVERENTRY)(PVOID, PVOID);
162
163 HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
164 {
165 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
166 PWSTR lName;
167 NTSTATUS Status;
168 UNICODE_STRING DeviceName;
169 HANDLE DriverHandle;
170 OBJECT_ATTRIBUTES ObjectAttributes;
171
172 PDRIVER_OBJECT DriverObject;
173 PMP_DRIVERENTRY PMP_DriverEntry;
174
175 /* Phase 1 */
176 RtlInitUnicodeString (&GdiDriverInfo.DriverName, L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
177 Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
178 if (!NT_SUCCESS(Status))
179 return NULL;
180
181 /* Phase 2 */
182 if (Name[0] != '\\')
183 {
184 lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) + 10 * sizeof(WCHAR));
185 wcscpy(lName, L"\\??\\");
186 if (!wcscmp (Name, L"DISPLAY"))
187 {
188 /* FIXME: Read this information from the registry ??? */
189 wcscat(lName, L"DISPLAY1");
190 }
191 else
192 {
193 wcscat(lName, Name);
194 }
195 }
196 else
197 {
198 lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
199 wcscpy(lName, Name);
200 }
201
202 /* Phase 3 */
203 DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
204 if (DriverObject == NULL)
205 {
206 return NULL;
207 }
208 memset(DriverObject, 0, sizeof(DRIVER_OBJECT));
209
210 // We pass the DriverObject to the Miniport driver, which passes it to the VideoPort driver
211 // The VideoPort driver then creates the Device Object
212
213 PMP_DriverEntry = GdiDriverInfo.EntryPoint;
214 PMP_DriverEntry(DriverObject, NULL);
215
216 return DriverObject;
217 }
218
219 BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
220 {
221 PGRAPHICS_DRIVER Driver = NULL;
222
223 if (Name)
224 {
225 if (DriverList != NULL)
226 {
227 if (!_wcsicmp(DriverList->Name, Name))
228 {
229 Driver = DriverList;
230 DriverList = DriverList->Next;
231 }
232 else
233 {
234 Driver = DriverList;
235 while (Driver->Next && _wcsicmp(Driver->Name, Name))
236 {
237 Driver = Driver->Next;
238 }
239 }
240 }
241 }
242 else
243 {
244 if (GenericDriver != NULL)
245 {
246 Driver = GenericDriver;
247 GenericDriver = NULL;
248 }
249 }
250
251 if (Driver != NULL)
252 {
253 ExFreePool(Driver->Name);
254 ExFreePool(Driver);
255
256 return TRUE;
257 }
258 else
259 {
260 return FALSE;
261 }
262 }
263
264 INT DRIVER_ReferenceDriver (LPCWSTR Name)
265 {
266 GRAPHICS_DRIVER *Driver = DriverList;
267
268 while (Driver && Name)
269 {
270 DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
271 if (!_wcsicmp( Driver->Name, Name))
272 {
273 return ++Driver->ReferenceCount;
274 }
275 Driver = Driver->Next;
276 }
277 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
278 assert( GenericDriver != 0 );
279 return ++GenericDriver->ReferenceCount;
280 }
281
282 INT DRIVER_UnreferenceDriver (LPCWSTR Name)
283 {
284 GRAPHICS_DRIVER *Driver = DriverList;
285
286 while (Driver && Name)
287 {
288 DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
289 if (!_wcsicmp( Driver->Name, Name))
290 {
291 return --Driver->ReferenceCount;
292 }
293 Driver = Driver->Next;
294 }
295 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
296 assert( GenericDriver != 0 );
297 return --GenericDriver->ReferenceCount;
298 }