2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
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.
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.
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.
21 * GDI Driver support routines
22 * (mostly swiped from Wine)
31 /* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
32 #undef TRACE_DRV_CALLS
34 typedef struct _GRAPHICS_DRIVER
37 PGD_ENABLEDRIVER EnableDriver
;
39 struct _GRAPHICS_DRIVER
*Next
;
40 } GRAPHICS_DRIVER
, *PGRAPHICS_DRIVER
;
42 static PGRAPHICS_DRIVER DriverList
;
43 static PGRAPHICS_DRIVER GenericDriver
= 0;
45 BOOL
DRIVER_RegisterDriver(LPCWSTR Name
, PGD_ENABLEDRIVER EnableDriver
)
47 PGRAPHICS_DRIVER Driver
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Driver
), TAG_DRIVER
);
48 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name
);
49 if (!Driver
) return FALSE
;
50 Driver
->ReferenceCount
= 0;
51 Driver
->EnableDriver
= EnableDriver
;
54 Driver
->Name
= ExAllocatePoolWithTag(PagedPool
,
55 (wcslen(Name
) + 1) * sizeof(WCHAR
),
57 wcscpy(Driver
->Name
, Name
);
58 Driver
->Next
= DriverList
;
63 if (GenericDriver
!= NULL
)
69 GenericDriver
= Driver
;
73 PGD_ENABLEDRIVER
DRIVER_FindDDIDriver(LPCWSTR Name
)
75 static WCHAR DefaultPath
[] = L
"\\SystemRoot\\System32\\";
76 static WCHAR DefaultExtension
[] = L
".DLL";
77 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo
;
78 GRAPHICS_DRIVER
*Driver
= DriverList
;
82 BOOL PathSeparatorFound
;
87 PathSeparatorFound
= FALSE
;
91 if (L
'\\' == *p
|| L
'/' == *p
)
93 PathSeparatorFound
= TRUE
;
103 Size
= (wcslen(Name
) + 1) * sizeof(WCHAR
);
104 if (! PathSeparatorFound
)
106 Size
+= sizeof(DefaultPath
) - sizeof(WCHAR
);
110 Size
+= sizeof(DefaultExtension
) - sizeof(WCHAR
);
112 FullName
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_DRIVER
);
113 if (NULL
== FullName
)
115 DPRINT1("Out of memory\n");
118 if (PathSeparatorFound
)
124 wcscpy(FullName
, DefaultPath
);
126 wcscat(FullName
, Name
);
129 wcscat(FullName
, DefaultExtension
);
132 /* First see if the driver hasn't already been loaded */
133 while (Driver
&& FullName
)
135 if (!_wcsicmp( Driver
->Name
, FullName
))
137 return Driver
->EnableDriver
;
139 Driver
= Driver
->Next
;
142 /* If not, then load it */
143 RtlInitUnicodeString (&GdiDriverInfo
.DriverName
, (LPWSTR
)FullName
);
144 Status
= ZwSetSystemInformation (SystemLoadGdiDriverInformation
, &GdiDriverInfo
, sizeof(SYSTEM_GDI_DRIVER_INFORMATION
));
145 ExFreePool(FullName
);
146 if (!NT_SUCCESS(Status
)) return NULL
;
148 DRIVER_RegisterDriver( L
"DISPLAY", GdiDriverInfo
.EntryPoint
);
149 return (PGD_ENABLEDRIVER
)GdiDriverInfo
.EntryPoint
;
152 #define BEGIN_FUNCTION_MAP() \
154 for (i = 0; i < DED->c; i++) \
156 switch(DED->pdrvfn[i].iFunc) \
159 #define END_FUNCTION_MAP() \
161 DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
166 #ifdef TRACE_DRV_CALLS
168 typedef struct _TRACEDRVINFO
174 TRACEDRVINFO
, *PTRACEDRVINFO
;
180 " call _FindTraceInfo\n"
187 " mov 8(%eax),%eax\n"
191 #define TRACEDRV_ROUTINE(function) \
192 unsigned TraceDrvIndex##function = INDEX_Drv##function; \
195 "_Trace" #function ":\n" \
196 " movl _TraceDrvIndex" #function ",%eax\n" \
199 extern PVOID Trace##function;
201 TRACEDRV_ROUTINE(EnablePDEV
)
202 TRACEDRV_ROUTINE(CompletePDEV
)
203 TRACEDRV_ROUTINE(DisablePDEV
)
204 TRACEDRV_ROUTINE(EnableSurface
)
205 TRACEDRV_ROUTINE(DisableSurface
)
206 TRACEDRV_ROUTINE(AssertMode
)
207 TRACEDRV_ROUTINE(Offset
)
208 TRACEDRV_ROUTINE(ResetPDEV
)
209 TRACEDRV_ROUTINE(DisableDriver
)
210 TRACEDRV_ROUTINE(CreateDeviceBitmap
)
211 TRACEDRV_ROUTINE(DeleteDeviceBitmap
)
212 TRACEDRV_ROUTINE(RealizeBrush
)
213 TRACEDRV_ROUTINE(DitherColor
)
214 TRACEDRV_ROUTINE(StrokePath
)
215 TRACEDRV_ROUTINE(FillPath
)
216 TRACEDRV_ROUTINE(StrokeAndFillPath
)
217 TRACEDRV_ROUTINE(Paint
)
218 TRACEDRV_ROUTINE(BitBlt
)
219 TRACEDRV_ROUTINE(TransparentBlt
)
220 TRACEDRV_ROUTINE(CopyBits
)
221 TRACEDRV_ROUTINE(StretchBlt
)
222 TRACEDRV_ROUTINE(StretchBltROP
)
223 TRACEDRV_ROUTINE(SetPalette
)
224 TRACEDRV_ROUTINE(TextOut
)
225 TRACEDRV_ROUTINE(Escape
)
226 TRACEDRV_ROUTINE(DrawEscape
)
227 TRACEDRV_ROUTINE(QueryFont
)
228 TRACEDRV_ROUTINE(QueryFontTree
)
229 TRACEDRV_ROUTINE(QueryFontData
)
230 TRACEDRV_ROUTINE(SetPointerShape
)
231 TRACEDRV_ROUTINE(MovePointer
)
232 TRACEDRV_ROUTINE(LineTo
)
233 TRACEDRV_ROUTINE(SendPage
)
234 TRACEDRV_ROUTINE(StartPage
)
235 TRACEDRV_ROUTINE(EndDoc
)
236 TRACEDRV_ROUTINE(StartDoc
)
237 TRACEDRV_ROUTINE(GetGlyphMode
)
238 TRACEDRV_ROUTINE(Synchronize
)
239 TRACEDRV_ROUTINE(SaveScreenBits
)
240 TRACEDRV_ROUTINE(GetModes
)
241 TRACEDRV_ROUTINE(Free
)
242 TRACEDRV_ROUTINE(DestroyFont
)
243 TRACEDRV_ROUTINE(QueryFontCaps
)
244 TRACEDRV_ROUTINE(LoadFontFile
)
245 TRACEDRV_ROUTINE(UnloadFontFile
)
246 TRACEDRV_ROUTINE(FontManagement
)
247 TRACEDRV_ROUTINE(QueryTrueTypeTable
)
248 TRACEDRV_ROUTINE(QueryTrueTypeOutline
)
249 TRACEDRV_ROUTINE(GetTrueTypeFile
)
250 TRACEDRV_ROUTINE(QueryFontFile
)
251 TRACEDRV_ROUTINE(QueryAdvanceWidths
)
252 TRACEDRV_ROUTINE(SetPixelFormat
)
253 TRACEDRV_ROUTINE(DescribePixelFormat
)
254 TRACEDRV_ROUTINE(SwapBuffers
)
255 TRACEDRV_ROUTINE(StartBanding
)
256 TRACEDRV_ROUTINE(NextBand
)
257 TRACEDRV_ROUTINE(GetDirectDrawInfo
)
258 TRACEDRV_ROUTINE(EnableDirectDraw
)
259 TRACEDRV_ROUTINE(DisableDirectDraw
)
260 TRACEDRV_ROUTINE(QuerySpoolType
)
261 TRACEDRV_ROUTINE(GradientFill
)
262 TRACEDRV_ROUTINE(SynchronizeSurface
)
263 TRACEDRV_ROUTINE(AlphaBlend
)
265 #define TRACEDRVINFO_ENTRY(function) \
266 { INDEX_Drv##function, "Drv" #function "\n", NULL }
267 static TRACEDRVINFO TraceDrvInfo
[] =
269 TRACEDRVINFO_ENTRY(EnablePDEV
),
270 TRACEDRVINFO_ENTRY(CompletePDEV
),
271 TRACEDRVINFO_ENTRY(DisablePDEV
),
272 TRACEDRVINFO_ENTRY(EnableSurface
),
273 TRACEDRVINFO_ENTRY(DisableSurface
),
274 TRACEDRVINFO_ENTRY(AssertMode
),
275 TRACEDRVINFO_ENTRY(Offset
),
276 TRACEDRVINFO_ENTRY(ResetPDEV
),
277 TRACEDRVINFO_ENTRY(DisableDriver
),
278 TRACEDRVINFO_ENTRY(CreateDeviceBitmap
),
279 TRACEDRVINFO_ENTRY(DeleteDeviceBitmap
),
280 TRACEDRVINFO_ENTRY(RealizeBrush
),
281 TRACEDRVINFO_ENTRY(DitherColor
),
282 TRACEDRVINFO_ENTRY(StrokePath
),
283 TRACEDRVINFO_ENTRY(FillPath
),
284 TRACEDRVINFO_ENTRY(StrokeAndFillPath
),
285 TRACEDRVINFO_ENTRY(Paint
),
286 TRACEDRVINFO_ENTRY(BitBlt
),
287 TRACEDRVINFO_ENTRY(TransparentBlt
),
288 TRACEDRVINFO_ENTRY(CopyBits
),
289 TRACEDRVINFO_ENTRY(StretchBlt
),
290 TRACEDRVINFO_ENTRY(StretchBltROP
),
291 TRACEDRVINFO_ENTRY(SetPalette
),
292 TRACEDRVINFO_ENTRY(TextOut
),
293 TRACEDRVINFO_ENTRY(Escape
),
294 TRACEDRVINFO_ENTRY(DrawEscape
),
295 TRACEDRVINFO_ENTRY(QueryFont
),
296 TRACEDRVINFO_ENTRY(QueryFontTree
),
297 TRACEDRVINFO_ENTRY(QueryFontData
),
298 TRACEDRVINFO_ENTRY(SetPointerShape
),
299 TRACEDRVINFO_ENTRY(MovePointer
),
300 TRACEDRVINFO_ENTRY(LineTo
),
301 TRACEDRVINFO_ENTRY(SendPage
),
302 TRACEDRVINFO_ENTRY(StartPage
),
303 TRACEDRVINFO_ENTRY(EndDoc
),
304 TRACEDRVINFO_ENTRY(StartDoc
),
305 TRACEDRVINFO_ENTRY(GetGlyphMode
),
306 TRACEDRVINFO_ENTRY(Synchronize
),
307 TRACEDRVINFO_ENTRY(SaveScreenBits
),
308 TRACEDRVINFO_ENTRY(GetModes
),
309 TRACEDRVINFO_ENTRY(Free
),
310 TRACEDRVINFO_ENTRY(DestroyFont
),
311 TRACEDRVINFO_ENTRY(QueryFontCaps
),
312 TRACEDRVINFO_ENTRY(LoadFontFile
),
313 TRACEDRVINFO_ENTRY(UnloadFontFile
),
314 TRACEDRVINFO_ENTRY(FontManagement
),
315 TRACEDRVINFO_ENTRY(QueryTrueTypeTable
),
316 TRACEDRVINFO_ENTRY(QueryTrueTypeOutline
),
317 TRACEDRVINFO_ENTRY(GetTrueTypeFile
),
318 TRACEDRVINFO_ENTRY(QueryFontFile
),
319 TRACEDRVINFO_ENTRY(QueryAdvanceWidths
),
320 TRACEDRVINFO_ENTRY(SetPixelFormat
),
321 TRACEDRVINFO_ENTRY(DescribePixelFormat
),
322 TRACEDRVINFO_ENTRY(SwapBuffers
),
323 TRACEDRVINFO_ENTRY(StartBanding
),
324 TRACEDRVINFO_ENTRY(NextBand
),
325 TRACEDRVINFO_ENTRY(GetDirectDrawInfo
),
326 TRACEDRVINFO_ENTRY(EnableDirectDraw
),
327 TRACEDRVINFO_ENTRY(DisableDirectDraw
),
328 TRACEDRVINFO_ENTRY(QuerySpoolType
),
329 TRACEDRVINFO_ENTRY(GradientFill
),
330 TRACEDRVINFO_ENTRY(SynchronizeSurface
),
331 TRACEDRVINFO_ENTRY(AlphaBlend
)
335 FindTraceInfo(unsigned Index
)
339 for (i
= 0; i
< sizeof(TraceDrvInfo
) / sizeof(TRACEDRVINFO
); i
++)
341 if (TraceDrvInfo
[i
].Index
== Index
)
343 return TraceDrvInfo
+ i
;
350 #define DRIVER_FUNCTION(function) \
351 case INDEX_Drv##function: \
352 FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
353 *(PVOID*)&DF->function = &Trace##function; \
356 #define DRIVER_FUNCTION(function) \
357 case INDEX_Drv##function: \
358 *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
362 BOOL
DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED
,
363 PDRIVER_FUNCTIONS DF
)
365 BEGIN_FUNCTION_MAP();
367 DRIVER_FUNCTION(EnablePDEV
);
368 DRIVER_FUNCTION(CompletePDEV
);
369 DRIVER_FUNCTION(DisablePDEV
);
370 DRIVER_FUNCTION(EnableSurface
);
371 DRIVER_FUNCTION(DisableSurface
);
372 DRIVER_FUNCTION(AssertMode
);
373 DRIVER_FUNCTION(Offset
);
374 DRIVER_FUNCTION(ResetPDEV
);
375 DRIVER_FUNCTION(DisableDriver
);
376 DRIVER_FUNCTION(CreateDeviceBitmap
);
377 DRIVER_FUNCTION(DeleteDeviceBitmap
);
378 DRIVER_FUNCTION(RealizeBrush
);
379 DRIVER_FUNCTION(DitherColor
);
380 DRIVER_FUNCTION(StrokePath
);
381 DRIVER_FUNCTION(FillPath
);
382 DRIVER_FUNCTION(StrokeAndFillPath
);
383 DRIVER_FUNCTION(Paint
);
384 DRIVER_FUNCTION(BitBlt
);
385 DRIVER_FUNCTION(TransparentBlt
);
386 DRIVER_FUNCTION(CopyBits
);
387 DRIVER_FUNCTION(StretchBlt
);
388 DRIVER_FUNCTION(StretchBltROP
);
389 DRIVER_FUNCTION(SetPalette
);
390 DRIVER_FUNCTION(TextOut
);
391 DRIVER_FUNCTION(Escape
);
392 DRIVER_FUNCTION(DrawEscape
);
393 DRIVER_FUNCTION(QueryFont
);
394 DRIVER_FUNCTION(QueryFontTree
);
395 DRIVER_FUNCTION(QueryFontData
);
396 DRIVER_FUNCTION(SetPointerShape
);
397 DRIVER_FUNCTION(MovePointer
);
398 DRIVER_FUNCTION(LineTo
);
399 DRIVER_FUNCTION(SendPage
);
400 DRIVER_FUNCTION(StartPage
);
401 DRIVER_FUNCTION(EndDoc
);
402 DRIVER_FUNCTION(StartDoc
);
403 DRIVER_FUNCTION(GetGlyphMode
);
404 DRIVER_FUNCTION(Synchronize
);
405 DRIVER_FUNCTION(SaveScreenBits
);
406 DRIVER_FUNCTION(GetModes
);
407 DRIVER_FUNCTION(Free
);
408 DRIVER_FUNCTION(DestroyFont
);
409 DRIVER_FUNCTION(QueryFontCaps
);
410 DRIVER_FUNCTION(LoadFontFile
);
411 DRIVER_FUNCTION(UnloadFontFile
);
412 DRIVER_FUNCTION(FontManagement
);
413 DRIVER_FUNCTION(QueryTrueTypeTable
);
414 DRIVER_FUNCTION(QueryTrueTypeOutline
);
415 DRIVER_FUNCTION(GetTrueTypeFile
);
416 DRIVER_FUNCTION(QueryFontFile
);
417 DRIVER_FUNCTION(QueryAdvanceWidths
);
418 DRIVER_FUNCTION(SetPixelFormat
);
419 DRIVER_FUNCTION(DescribePixelFormat
);
420 DRIVER_FUNCTION(SwapBuffers
);
421 DRIVER_FUNCTION(StartBanding
);
422 DRIVER_FUNCTION(NextBand
);
423 DRIVER_FUNCTION(GetDirectDrawInfo
);
424 DRIVER_FUNCTION(EnableDirectDraw
);
425 DRIVER_FUNCTION(DisableDirectDraw
);
426 DRIVER_FUNCTION(QuerySpoolType
);
427 DRIVER_FUNCTION(GradientFill
);
428 DRIVER_FUNCTION(SynchronizeSurface
);
429 DRIVER_FUNCTION(AlphaBlend
);
436 typedef LONG VP_STATUS
;
437 typedef VP_STATUS (STDCALL
*PMP_DRIVERENTRY
)(PVOID
, PVOID
);
439 PFILE_OBJECT
DRIVER_FindMPDriver(ULONG DisplayNumber
)
441 OBJECT_ATTRIBUTES ObjectAttributes
;
442 WCHAR DeviceNameBuffer
[20];
443 UNICODE_STRING DeviceName
;
444 IO_STATUS_BLOCK Iosb
;
445 HANDLE DisplayHandle
;
447 PFILE_OBJECT VideoFileObject
;
449 swprintf(DeviceNameBuffer
, L
"\\??\\DISPLAY%d", DisplayNumber
+ 1);
450 RtlInitUnicodeString(&DeviceName
, DeviceNameBuffer
);
451 InitializeObjectAttributes(&ObjectAttributes
,
456 Status
= ZwOpenFile(&DisplayHandle
,
461 FILE_SYNCHRONOUS_IO_ALERT
);
462 if (NT_SUCCESS(Status
))
464 Status
= ObReferenceObjectByHandle(DisplayHandle
,
465 FILE_READ_DATA
| FILE_WRITE_DATA
,
468 (PVOID
*)&VideoFileObject
,
470 ZwClose(DisplayHandle
);
473 if (!NT_SUCCESS(Status
))
475 DPRINT1("Unable to connect to miniport (Status %lx)\n", Status
);
476 DPRINT1("Perhaps the miniport wasn't loaded?\n");
480 return VideoFileObject
;
484 BOOL
DRIVER_UnregisterDriver(LPCWSTR Name
)
486 PGRAPHICS_DRIVER Driver
= NULL
;
490 if (DriverList
!= NULL
)
492 if (!_wcsicmp(DriverList
->Name
, Name
))
495 DriverList
= DriverList
->Next
;
500 while (Driver
->Next
&& _wcsicmp(Driver
->Name
, Name
))
502 Driver
= Driver
->Next
;
509 if (GenericDriver
!= NULL
)
511 Driver
= GenericDriver
;
512 GenericDriver
= NULL
;
518 ExFreePool(Driver
->Name
);
529 INT
DRIVER_ReferenceDriver (LPCWSTR Name
)
531 GRAPHICS_DRIVER
*Driver
= DriverList
;
533 while (Driver
&& Name
)
535 DPRINT( "Comparing %S to %S\n", Driver
->Name
, Name
);
536 if (!_wcsicmp( Driver
->Name
, Name
))
538 return ++Driver
->ReferenceCount
;
540 Driver
= Driver
->Next
;
542 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name
, GenericDriver
->ReferenceCount
);
543 assert( GenericDriver
!= 0 );
544 return ++GenericDriver
->ReferenceCount
;
547 INT
DRIVER_UnreferenceDriver (LPCWSTR Name
)
549 GRAPHICS_DRIVER
*Driver
= DriverList
;
551 while (Driver
&& Name
)
553 DPRINT( "Comparing %S to %S\n", Driver
->Name
, Name
);
554 if (!_wcsicmp( Driver
->Name
, Name
))
556 return --Driver
->ReferenceCount
;
558 Driver
= Driver
->Next
;
560 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name
, GenericDriver
->ReferenceCount
);
561 assert( GenericDriver
!= 0 );
562 return --GenericDriver
->ReferenceCount
;