migrate substitution keywords to SVN
[reactos.git] / reactos / subsys / win32k / misc / driver.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 * GDI Driver support routines
22 * (mostly swiped from Wine)
23 *
24 */
25
26 #undef WIN32_LEAN_AND_MEAN
27 #define WIN32_NO_PEHDR
28
29 #include <ddk/ntddk.h>
30 #include <windows.h>
31 #include <win32k/driver.h>
32 #include <win32k/misc.h>
33 #include <wchar.h>
34 #include <ddk/winddi.h>
35 #include <ddk/ntapi.h>
36 #include <rosrtl/string.h>
37 #include <include/tags.h>
38
39 #define NDEBUG
40 #include <debug.h>
41
42 typedef struct _GRAPHICS_DRIVER
43 {
44 PWSTR Name;
45 PGD_ENABLEDRIVER EnableDriver;
46 int ReferenceCount;
47 struct _GRAPHICS_DRIVER *Next;
48 } GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
49
50 static PGRAPHICS_DRIVER DriverList;
51 static PGRAPHICS_DRIVER GenericDriver = 0;
52
53 BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
54 {
55 PGRAPHICS_DRIVER Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
56 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
57 if (!Driver) return FALSE;
58 Driver->ReferenceCount = 0;
59 Driver->EnableDriver = EnableDriver;
60 if (Name)
61 {
62 Driver->Name = ExAllocatePoolWithTag(PagedPool,
63 (wcslen(Name) + 1) * sizeof(WCHAR),
64 TAG_DRIVER);
65 wcscpy(Driver->Name, Name);
66 Driver->Next = DriverList;
67 DriverList = Driver;
68 return TRUE;
69 }
70
71 if (GenericDriver != NULL)
72 {
73 ExFreePool(Driver);
74 return FALSE;
75 }
76
77 GenericDriver = Driver;
78 return TRUE;
79 }
80
81 PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
82 {
83 static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
84 static WCHAR DefaultExtension[] = L".DLL";
85 SYSTEM_LOAD_IMAGE GdiDriverInfo;
86 GRAPHICS_DRIVER *Driver = DriverList;
87 NTSTATUS Status;
88 WCHAR *FullName;
89 LPCWSTR p;
90 BOOL PathSeparatorFound;
91 BOOL DotFound;
92 UINT Size;
93
94 DotFound = FALSE;
95 PathSeparatorFound = FALSE;
96 p = Name;
97 while (L'\0' != *p)
98 {
99 if (L'\\' == *p || L'/' == *p)
100 {
101 PathSeparatorFound = TRUE;
102 DotFound = FALSE;
103 }
104 else if (L'.' == *p)
105 {
106 DotFound = TRUE;
107 }
108 p++;
109 }
110
111 Size = (wcslen(Name) + 1) * sizeof(WCHAR);
112 if (! PathSeparatorFound)
113 {
114 Size += sizeof(DefaultPath) - sizeof(WCHAR);
115 }
116 if (! DotFound)
117 {
118 Size += sizeof(DefaultExtension) - sizeof(WCHAR);
119 }
120 FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
121 if (NULL == FullName)
122 {
123 DPRINT1("Out of memory\n");
124 return NULL;
125 }
126 if (PathSeparatorFound)
127 {
128 FullName[0] = L'\0';
129 }
130 else
131 {
132 wcscpy(FullName, DefaultPath);
133 }
134 wcscat(FullName, Name);
135 if (! DotFound)
136 {
137 wcscat(FullName, DefaultExtension);
138 }
139
140 /* First see if the driver hasn't already been loaded */
141 while (Driver && FullName)
142 {
143 if (!_wcsicmp( Driver->Name, FullName))
144 {
145 return Driver->EnableDriver;
146 }
147 Driver = Driver->Next;
148 }
149
150 /* If not, then load it */
151 RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)FullName);
152 Status = ZwSetSystemInformation (SystemLoadImage, &GdiDriverInfo, sizeof(SYSTEM_LOAD_IMAGE));
153 ExFreePool(FullName);
154 if (!NT_SUCCESS(Status)) return NULL;
155
156 DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
157 return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
158 }
159
160 #define BEGIN_FUNCTION_MAP() \
161 ULONG i; \
162 for (i = 0; i < DED->c; i++) \
163 { \
164 switch(DED->pdrvfn[i].iFunc) \
165 {
166
167 #define DRIVER_FUNCTION(function) \
168 case INDEX_Drv##function: \
169 *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
170 break
171
172 #define END_FUNCTION_MAP() \
173 default: \
174 DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
175 break; \
176 } \
177 }
178
179 BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
180 PDRIVER_FUNCTIONS DF)
181 {
182 BEGIN_FUNCTION_MAP();
183
184 DRIVER_FUNCTION(EnablePDEV);
185 DRIVER_FUNCTION(CompletePDEV);
186 DRIVER_FUNCTION(DisablePDEV);
187 DRIVER_FUNCTION(EnableSurface);
188 DRIVER_FUNCTION(DisableSurface);
189 DRIVER_FUNCTION(AssertMode);
190 DRIVER_FUNCTION(ResetPDEV);
191 DRIVER_FUNCTION(CreateDeviceBitmap);
192 DRIVER_FUNCTION(DeleteDeviceBitmap);
193 DRIVER_FUNCTION(RealizeBrush);
194 DRIVER_FUNCTION(DitherColor);
195 DRIVER_FUNCTION(StrokePath);
196 DRIVER_FUNCTION(FillPath);
197 DRIVER_FUNCTION(StrokeAndFillPath);
198 DRIVER_FUNCTION(Paint);
199 DRIVER_FUNCTION(BitBlt);
200 DRIVER_FUNCTION(TransparentBlt);
201 DRIVER_FUNCTION(CopyBits);
202 DRIVER_FUNCTION(StretchBlt);
203 DRIVER_FUNCTION(SetPalette);
204 DRIVER_FUNCTION(TextOut);
205 DRIVER_FUNCTION(Escape);
206 DRIVER_FUNCTION(DrawEscape);
207 DRIVER_FUNCTION(QueryFont);
208 DRIVER_FUNCTION(QueryFontTree);
209 DRIVER_FUNCTION(QueryFontData);
210 DRIVER_FUNCTION(SetPointerShape);
211 DRIVER_FUNCTION(MovePointer);
212 DRIVER_FUNCTION(LineTo);
213 DRIVER_FUNCTION(SendPage);
214 DRIVER_FUNCTION(StartPage);
215 DRIVER_FUNCTION(EndDoc);
216 DRIVER_FUNCTION(StartDoc);
217 DRIVER_FUNCTION(GetGlyphMode);
218 DRIVER_FUNCTION(Synchronize);
219 DRIVER_FUNCTION(SaveScreenBits);
220 DRIVER_FUNCTION(GetModes);
221 DRIVER_FUNCTION(Free);
222 DRIVER_FUNCTION(DestroyFont);
223 DRIVER_FUNCTION(QueryFontCaps);
224 DRIVER_FUNCTION(LoadFontFile);
225 DRIVER_FUNCTION(UnloadFontFile);
226 DRIVER_FUNCTION(FontManagement);
227 DRIVER_FUNCTION(QueryTrueTypeTable);
228 DRIVER_FUNCTION(QueryTrueTypeOutline);
229 DRIVER_FUNCTION(GetTrueTypeFile);
230 DRIVER_FUNCTION(QueryFontFile);
231 DRIVER_FUNCTION(QueryAdvanceWidths);
232 DRIVER_FUNCTION(SetPixelFormat);
233 DRIVER_FUNCTION(DescribePixelFormat);
234 DRIVER_FUNCTION(SwapBuffers);
235 DRIVER_FUNCTION(StartBanding);
236 DRIVER_FUNCTION(NextBand);
237 DRIVER_FUNCTION(GetDirectDrawInfo);
238 DRIVER_FUNCTION(EnableDirectDraw);
239 DRIVER_FUNCTION(DisableDirectDraw);
240 DRIVER_FUNCTION(QuerySpoolType);
241 DRIVER_FUNCTION(GradientFill);
242
243 END_FUNCTION_MAP();
244
245 return TRUE;
246 }
247
248 typedef LONG VP_STATUS;
249 typedef VP_STATUS (STDCALL *PMP_DRIVERENTRY)(PVOID, PVOID);
250
251 PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
252 {
253 OBJECT_ATTRIBUTES ObjectAttributes;
254 WCHAR DeviceNameBuffer[20];
255 UNICODE_STRING DeviceName;
256 IO_STATUS_BLOCK Iosb;
257 HANDLE DisplayHandle;
258 NTSTATUS Status;
259 PFILE_OBJECT VideoFileObject;
260
261 swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
262 RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
263 InitializeObjectAttributes(&ObjectAttributes,
264 &DeviceName,
265 0,
266 NULL,
267 NULL);
268 Status = ZwOpenFile(&DisplayHandle,
269 FILE_ALL_ACCESS,
270 &ObjectAttributes,
271 &Iosb,
272 0,
273 FILE_SYNCHRONOUS_IO_ALERT);
274 if (NT_SUCCESS(Status))
275 {
276 Status = ObReferenceObjectByHandle(DisplayHandle,
277 FILE_READ_DATA | FILE_WRITE_DATA,
278 IoFileObjectType,
279 KernelMode,
280 (PVOID *)&VideoFileObject,
281 NULL);
282 ZwClose(DisplayHandle);
283 }
284
285 if (!NT_SUCCESS(Status))
286 {
287 DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
288 DPRINT1("Perhaps the miniport wasn't loaded?\n");
289 return(NULL);
290 }
291
292 return VideoFileObject;
293 }
294
295
296 BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
297 {
298 PGRAPHICS_DRIVER Driver = NULL;
299
300 if (Name)
301 {
302 if (DriverList != NULL)
303 {
304 if (!_wcsicmp(DriverList->Name, Name))
305 {
306 Driver = DriverList;
307 DriverList = DriverList->Next;
308 }
309 else
310 {
311 Driver = DriverList;
312 while (Driver->Next && _wcsicmp(Driver->Name, Name))
313 {
314 Driver = Driver->Next;
315 }
316 }
317 }
318 }
319 else
320 {
321 if (GenericDriver != NULL)
322 {
323 Driver = GenericDriver;
324 GenericDriver = NULL;
325 }
326 }
327
328 if (Driver != NULL)
329 {
330 ExFreePool(Driver->Name);
331 ExFreePool(Driver);
332
333 return TRUE;
334 }
335 else
336 {
337 return FALSE;
338 }
339 }
340
341 INT DRIVER_ReferenceDriver (LPCWSTR Name)
342 {
343 GRAPHICS_DRIVER *Driver = DriverList;
344
345 while (Driver && Name)
346 {
347 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
348 if (!_wcsicmp( Driver->Name, Name))
349 {
350 return ++Driver->ReferenceCount;
351 }
352 Driver = Driver->Next;
353 }
354 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
355 assert( GenericDriver != 0 );
356 return ++GenericDriver->ReferenceCount;
357 }
358
359 INT DRIVER_UnreferenceDriver (LPCWSTR Name)
360 {
361 GRAPHICS_DRIVER *Driver = DriverList;
362
363 while (Driver && Name)
364 {
365 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
366 if (!_wcsicmp( Driver->Name, Name))
367 {
368 return --Driver->ReferenceCount;
369 }
370 Driver = Driver->Next;
371 }
372 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
373 assert( GenericDriver != 0 );
374 return --GenericDriver->ReferenceCount;
375 }
376 /* EOF */