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
35 typedef struct _GRAPHICS_DRIVER
38 PGD_ENABLEDRIVER EnableDriver
;
40 struct _GRAPHICS_DRIVER
*Next
;
41 } GRAPHICS_DRIVER
, *PGRAPHICS_DRIVER
;
43 static PGRAPHICS_DRIVER DriverList
;
44 static PGRAPHICS_DRIVER GenericDriver
= NULL
;
46 BOOL
DRIVER_RegisterDriver(LPCWSTR Name
, PGD_ENABLEDRIVER EnableDriver
)
48 PGRAPHICS_DRIVER Driver
;
50 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name
);
52 if (GenericDriver
!= NULL
)
56 Driver
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Driver
), TAG_DRIVER
);
57 if (!Driver
) return FALSE
;
58 Driver
->ReferenceCount
= 0;
59 Driver
->EnableDriver
= EnableDriver
;
62 Driver
->Name
= ExAllocatePoolWithTag(PagedPool
,
63 (wcslen(Name
) + 1) * sizeof(WCHAR
),
65 if (Driver
->Name
== NULL
)
67 DPRINT1("Out of memory\n");
68 ExFreePoolWithTag(Driver
, TAG_DRIVER
);
72 wcscpy(Driver
->Name
, Name
);
73 Driver
->Next
= DriverList
;
78 GenericDriver
= Driver
;
82 PGD_ENABLEDRIVER
DRIVER_FindExistingDDIDriver(LPCWSTR Name
)
84 GRAPHICS_DRIVER
*Driver
= DriverList
;
85 while (Driver
&& Name
)
87 if (!_wcsicmp(Driver
->Name
, Name
))
89 return Driver
->EnableDriver
;
91 Driver
= Driver
->Next
;
97 PGD_ENABLEDRIVER
DRIVER_FindDDIDriver(LPCWSTR Name
)
99 static WCHAR DefaultPath
[] = L
"\\SystemRoot\\System32\\";
100 static WCHAR DefaultExtension
[] = L
".DLL";
101 PGD_ENABLEDRIVER ExistingDriver
;
102 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo
;
106 BOOL PathSeparatorFound
;
111 PathSeparatorFound
= FALSE
;
115 if (L
'\\' == *p
|| L
'/' == *p
)
117 PathSeparatorFound
= TRUE
;
127 Size
= (wcslen(Name
) + 1) * sizeof(WCHAR
);
128 if (! PathSeparatorFound
)
130 Size
+= sizeof(DefaultPath
) - sizeof(WCHAR
);
134 Size
+= sizeof(DefaultExtension
) - sizeof(WCHAR
);
136 FullName
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_DRIVER
);
137 if (NULL
== FullName
)
139 DPRINT1("Out of memory\n");
142 if (PathSeparatorFound
)
148 wcscpy(FullName
, DefaultPath
);
150 wcscat(FullName
, Name
);
153 wcscat(FullName
, DefaultExtension
);
156 /* First see if the driver hasn't already been loaded */
157 ExistingDriver
= DRIVER_FindExistingDDIDriver(FullName
);
160 ExFreePoolWithTag(FullName
, TAG_DRIVER
);
161 return ExistingDriver
;
164 /* If not, then load it */
165 RtlInitUnicodeString (&GdiDriverInfo
.DriverName
, FullName
);
166 Status
= ZwSetSystemInformation (SystemLoadGdiDriverInformation
, &GdiDriverInfo
, sizeof(SYSTEM_GDI_DRIVER_INFORMATION
));
168 if (!NT_SUCCESS(Status
))
170 ExFreePool(FullName
);
174 DRIVER_RegisterDriver( L
"DISPLAY", GdiDriverInfo
.EntryPoint
);
175 DRIVER_RegisterDriver( FullName
, GdiDriverInfo
.EntryPoint
);
176 ExFreePoolWithTag(FullName
, TAG_DRIVER
);
177 return (PGD_ENABLEDRIVER
)GdiDriverInfo
.EntryPoint
;
180 #define BEGIN_FUNCTION_MAP() \
182 for (i = 0; i < DED->c; i++) \
184 switch(DED->pdrvfn[i].iFunc) \
187 #define END_FUNCTION_MAP() \
189 DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
194 #ifdef TRACE_DRV_CALLS
196 typedef struct _TRACEDRVINFO
202 TRACEDRVINFO
, *PTRACEDRVINFO
;
208 " call _FindTraceInfo\n"
215 " mov 8(%eax),%eax\n"
219 #define TRACEDRV_ROUTINE(function) \
220 unsigned TraceDrvIndex##function = INDEX_Drv##function; \
223 "_Trace" #function ":\n" \
224 " movl _TraceDrvIndex" #function ",%eax\n" \
227 extern PVOID Trace##function;
229 TRACEDRV_ROUTINE(EnablePDEV
)
230 TRACEDRV_ROUTINE(CompletePDEV
)
231 TRACEDRV_ROUTINE(DisablePDEV
)
232 TRACEDRV_ROUTINE(EnableSurface
)
233 TRACEDRV_ROUTINE(DisableSurface
)
234 TRACEDRV_ROUTINE(AssertMode
)
235 TRACEDRV_ROUTINE(Offset
)
236 TRACEDRV_ROUTINE(ResetPDEV
)
237 TRACEDRV_ROUTINE(DisableDriver
)
238 TRACEDRV_ROUTINE(CreateDeviceBitmap
)
239 TRACEDRV_ROUTINE(DeleteDeviceBitmap
)
240 TRACEDRV_ROUTINE(RealizeBrush
)
241 TRACEDRV_ROUTINE(DitherColor
)
242 TRACEDRV_ROUTINE(StrokePath
)
243 TRACEDRV_ROUTINE(FillPath
)
244 TRACEDRV_ROUTINE(StrokeAndFillPath
)
245 TRACEDRV_ROUTINE(Paint
)
246 TRACEDRV_ROUTINE(BitBlt
)
247 TRACEDRV_ROUTINE(TransparentBlt
)
248 TRACEDRV_ROUTINE(CopyBits
)
249 TRACEDRV_ROUTINE(StretchBlt
)
250 TRACEDRV_ROUTINE(StretchBltROP
)
251 TRACEDRV_ROUTINE(SetPalette
)
252 TRACEDRV_ROUTINE(TextOut
)
253 TRACEDRV_ROUTINE(Escape
)
254 TRACEDRV_ROUTINE(DrawEscape
)
255 TRACEDRV_ROUTINE(QueryFont
)
256 TRACEDRV_ROUTINE(QueryFontTree
)
257 TRACEDRV_ROUTINE(QueryFontData
)
258 TRACEDRV_ROUTINE(SetPointerShape
)
259 TRACEDRV_ROUTINE(MovePointer
)
260 TRACEDRV_ROUTINE(LineTo
)
261 TRACEDRV_ROUTINE(SendPage
)
262 TRACEDRV_ROUTINE(StartPage
)
263 TRACEDRV_ROUTINE(EndDoc
)
264 TRACEDRV_ROUTINE(StartDoc
)
265 TRACEDRV_ROUTINE(GetGlyphMode
)
266 TRACEDRV_ROUTINE(Synchronize
)
267 TRACEDRV_ROUTINE(SaveScreenBits
)
268 TRACEDRV_ROUTINE(GetModes
)
269 TRACEDRV_ROUTINE(Free
)
270 TRACEDRV_ROUTINE(DestroyFont
)
271 TRACEDRV_ROUTINE(QueryFontCaps
)
272 TRACEDRV_ROUTINE(LoadFontFile
)
273 TRACEDRV_ROUTINE(UnloadFontFile
)
274 TRACEDRV_ROUTINE(FontManagement
)
275 TRACEDRV_ROUTINE(QueryTrueTypeTable
)
276 TRACEDRV_ROUTINE(QueryTrueTypeOutline
)
277 TRACEDRV_ROUTINE(GetTrueTypeFile
)
278 TRACEDRV_ROUTINE(QueryFontFile
)
279 TRACEDRV_ROUTINE(QueryAdvanceWidths
)
280 TRACEDRV_ROUTINE(SetPixelFormat
)
281 TRACEDRV_ROUTINE(DescribePixelFormat
)
282 TRACEDRV_ROUTINE(SwapBuffers
)
283 TRACEDRV_ROUTINE(StartBanding
)
284 TRACEDRV_ROUTINE(NextBand
)
285 TRACEDRV_ROUTINE(GetDirectDrawInfo
)
286 TRACEDRV_ROUTINE(EnableDirectDraw
)
287 TRACEDRV_ROUTINE(DisableDirectDraw
)
288 TRACEDRV_ROUTINE(QuerySpoolType
)
289 TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp
)
290 TRACEDRV_ROUTINE(GradientFill
)
291 TRACEDRV_ROUTINE(SynchronizeSurface
)
292 TRACEDRV_ROUTINE(AlphaBlend
)
294 #define TRACEDRVINFO_ENTRY(function) \
295 { INDEX_Drv##function, "Drv" #function "\n", NULL }
296 static TRACEDRVINFO TraceDrvInfo
[] =
298 TRACEDRVINFO_ENTRY(EnablePDEV
),
299 TRACEDRVINFO_ENTRY(CompletePDEV
),
300 TRACEDRVINFO_ENTRY(DisablePDEV
),
301 TRACEDRVINFO_ENTRY(EnableSurface
),
302 TRACEDRVINFO_ENTRY(DisableSurface
),
303 TRACEDRVINFO_ENTRY(AssertMode
),
304 TRACEDRVINFO_ENTRY(Offset
),
305 TRACEDRVINFO_ENTRY(ResetPDEV
),
306 TRACEDRVINFO_ENTRY(DisableDriver
),
307 TRACEDRVINFO_ENTRY(CreateDeviceBitmap
),
308 TRACEDRVINFO_ENTRY(DeleteDeviceBitmap
),
309 TRACEDRVINFO_ENTRY(RealizeBrush
),
310 TRACEDRVINFO_ENTRY(DitherColor
),
311 TRACEDRVINFO_ENTRY(StrokePath
),
312 TRACEDRVINFO_ENTRY(FillPath
),
313 TRACEDRVINFO_ENTRY(StrokeAndFillPath
),
314 TRACEDRVINFO_ENTRY(Paint
),
315 TRACEDRVINFO_ENTRY(BitBlt
),
316 TRACEDRVINFO_ENTRY(TransparentBlt
),
317 TRACEDRVINFO_ENTRY(CopyBits
),
318 TRACEDRVINFO_ENTRY(StretchBlt
),
319 TRACEDRVINFO_ENTRY(StretchBltROP
),
320 TRACEDRVINFO_ENTRY(SetPalette
),
321 TRACEDRVINFO_ENTRY(TextOut
),
322 TRACEDRVINFO_ENTRY(Escape
),
323 TRACEDRVINFO_ENTRY(DrawEscape
),
324 TRACEDRVINFO_ENTRY(QueryFont
),
325 TRACEDRVINFO_ENTRY(QueryFontTree
),
326 TRACEDRVINFO_ENTRY(QueryFontData
),
327 TRACEDRVINFO_ENTRY(SetPointerShape
),
328 TRACEDRVINFO_ENTRY(MovePointer
),
329 TRACEDRVINFO_ENTRY(LineTo
),
330 TRACEDRVINFO_ENTRY(SendPage
),
331 TRACEDRVINFO_ENTRY(StartPage
),
332 TRACEDRVINFO_ENTRY(EndDoc
),
333 TRACEDRVINFO_ENTRY(StartDoc
),
334 TRACEDRVINFO_ENTRY(GetGlyphMode
),
335 TRACEDRVINFO_ENTRY(Synchronize
),
336 TRACEDRVINFO_ENTRY(SaveScreenBits
),
337 TRACEDRVINFO_ENTRY(GetModes
),
338 TRACEDRVINFO_ENTRY(Free
),
339 TRACEDRVINFO_ENTRY(DestroyFont
),
340 TRACEDRVINFO_ENTRY(QueryFontCaps
),
341 TRACEDRVINFO_ENTRY(LoadFontFile
),
342 TRACEDRVINFO_ENTRY(UnloadFontFile
),
343 TRACEDRVINFO_ENTRY(FontManagement
),
344 TRACEDRVINFO_ENTRY(QueryTrueTypeTable
),
345 TRACEDRVINFO_ENTRY(QueryTrueTypeOutline
),
346 TRACEDRVINFO_ENTRY(GetTrueTypeFile
),
347 TRACEDRVINFO_ENTRY(QueryFontFile
),
348 TRACEDRVINFO_ENTRY(QueryAdvanceWidths
),
349 TRACEDRVINFO_ENTRY(SetPixelFormat
),
350 TRACEDRVINFO_ENTRY(DescribePixelFormat
),
351 TRACEDRVINFO_ENTRY(SwapBuffers
),
352 TRACEDRVINFO_ENTRY(StartBanding
),
353 TRACEDRVINFO_ENTRY(NextBand
),
354 TRACEDRVINFO_ENTRY(GetDirectDrawInfo
),
355 TRACEDRVINFO_ENTRY(EnableDirectDraw
),
356 TRACEDRVINFO_ENTRY(DisableDirectDraw
),
357 TRACEDRVINFO_ENTRY(QuerySpoolType
),
358 TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp
),
359 TRACEDRVINFO_ENTRY(GradientFill
),
360 TRACEDRVINFO_ENTRY(SynchronizeSurface
),
361 TRACEDRVINFO_ENTRY(AlphaBlend
)
365 FindTraceInfo(unsigned Index
)
369 for (i
= 0; i
< sizeof(TraceDrvInfo
) / sizeof(TRACEDRVINFO
); i
++)
371 if (TraceDrvInfo
[i
].Index
== Index
)
373 return TraceDrvInfo
+ i
;
380 #define DRIVER_FUNCTION(function) \
381 case INDEX_Drv##function: \
382 FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
383 *(PVOID*)&DF->function = &Trace##function; \
386 #define DRIVER_FUNCTION(function) \
387 case INDEX_Drv##function: \
388 *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
392 BOOL
DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED
,
393 PDRIVER_FUNCTIONS DF
)
395 BEGIN_FUNCTION_MAP();
396 DRIVER_FUNCTION(EnablePDEV
);
397 DRIVER_FUNCTION(CompletePDEV
);
398 DRIVER_FUNCTION(DisablePDEV
);
399 DRIVER_FUNCTION(EnableSurface
);
400 DRIVER_FUNCTION(DisableSurface
);
401 DRIVER_FUNCTION(AssertMode
);
402 DRIVER_FUNCTION(Offset
);
403 DRIVER_FUNCTION(ResetPDEV
);
404 DRIVER_FUNCTION(DisableDriver
);
405 DRIVER_FUNCTION(Unknown1
);
406 DRIVER_FUNCTION(CreateDeviceBitmap
);
407 DRIVER_FUNCTION(DeleteDeviceBitmap
);
408 DRIVER_FUNCTION(RealizeBrush
);
409 DRIVER_FUNCTION(DitherColor
);
410 DRIVER_FUNCTION(StrokePath
);
411 DRIVER_FUNCTION(FillPath
);
412 DRIVER_FUNCTION(StrokeAndFillPath
);
413 DRIVER_FUNCTION(Paint
);
414 DRIVER_FUNCTION(BitBlt
);
415 DRIVER_FUNCTION(CopyBits
);
416 DRIVER_FUNCTION(StretchBlt
);
417 DRIVER_FUNCTION(Unknown2
);
418 DRIVER_FUNCTION(SetPalette
);
419 DRIVER_FUNCTION(TextOut
);
420 DRIVER_FUNCTION(Escape
);
421 DRIVER_FUNCTION(DrawEscape
);
422 DRIVER_FUNCTION(QueryFont
);
423 DRIVER_FUNCTION(QueryFontTree
);
424 DRIVER_FUNCTION(QueryFontData
);
425 DRIVER_FUNCTION(SetPointerShape
);
426 DRIVER_FUNCTION(MovePointer
);
427 DRIVER_FUNCTION(LineTo
);
428 DRIVER_FUNCTION(SendPage
);
429 DRIVER_FUNCTION(StartPage
);
430 DRIVER_FUNCTION(EndDoc
);
431 DRIVER_FUNCTION(StartDoc
);
432 DRIVER_FUNCTION(Unknown3
);
433 DRIVER_FUNCTION(GetGlyphMode
);
434 DRIVER_FUNCTION(Synchronize
);
435 DRIVER_FUNCTION(Unknown4
);
436 DRIVER_FUNCTION(SaveScreenBits
);
437 DRIVER_FUNCTION(GetModes
);
438 DRIVER_FUNCTION(Free
);
439 DRIVER_FUNCTION(DestroyFont
);
440 DRIVER_FUNCTION(QueryFontCaps
);
441 DRIVER_FUNCTION(LoadFontFile
);
442 DRIVER_FUNCTION(UnloadFontFile
);
443 DRIVER_FUNCTION(FontManagement
);
444 DRIVER_FUNCTION(QueryTrueTypeTable
);
445 DRIVER_FUNCTION(QueryTrueTypeOutline
);
446 DRIVER_FUNCTION(GetTrueTypeFile
);
447 DRIVER_FUNCTION(QueryFontFile
);
448 DRIVER_FUNCTION(QueryAdvanceWidths
);
449 DRIVER_FUNCTION(SetPixelFormat
);
450 DRIVER_FUNCTION(DescribePixelFormat
);
451 DRIVER_FUNCTION(SwapBuffers
);
452 DRIVER_FUNCTION(StartBanding
);
453 DRIVER_FUNCTION(NextBand
);
454 DRIVER_FUNCTION(GetDirectDrawInfo
);
455 DRIVER_FUNCTION(EnableDirectDraw
);
456 DRIVER_FUNCTION(DisableDirectDraw
);
457 DRIVER_FUNCTION(QuerySpoolType
);
458 DRIVER_FUNCTION(Unknown5
);
459 DRIVER_FUNCTION(IcmCreateColorTransform
);
460 DRIVER_FUNCTION(IcmDeleteColorTransform
);
461 DRIVER_FUNCTION(IcmCheckBitmapBits
);
462 DRIVER_FUNCTION(IcmSetDeviceGammaRamp
);
463 DRIVER_FUNCTION(GradientFill
);
464 DRIVER_FUNCTION(StretchBltROP
);
465 DRIVER_FUNCTION(PlgBlt
);
466 DRIVER_FUNCTION(AlphaBlend
);
467 DRIVER_FUNCTION(SynthesizeFont
);
468 DRIVER_FUNCTION(GetSynthesizedFontFiles
);
469 DRIVER_FUNCTION(TransparentBlt
);
470 DRIVER_FUNCTION(QueryPerBandInfo
);
471 DRIVER_FUNCTION(QueryDeviceSupport
);
472 DRIVER_FUNCTION(Reserved1
);
473 DRIVER_FUNCTION(Reserved2
);
474 DRIVER_FUNCTION(Reserved3
);
475 DRIVER_FUNCTION(Reserved4
);
476 DRIVER_FUNCTION(Reserved5
);
477 DRIVER_FUNCTION(Reserved6
);
478 DRIVER_FUNCTION(Reserved7
);
479 DRIVER_FUNCTION(Reserved8
);
480 DRIVER_FUNCTION(DeriveSurface
);
481 DRIVER_FUNCTION(QueryGlyphAttrs
);
482 DRIVER_FUNCTION(Notify
);
483 DRIVER_FUNCTION(SynchronizeSurface
);
484 DRIVER_FUNCTION(ResetDevice
);
485 DRIVER_FUNCTION(Reserved9
);
486 DRIVER_FUNCTION(Reserved10
);
487 DRIVER_FUNCTION(Reserved11
);
493 typedef LONG VP_STATUS
;
494 typedef VP_STATUS (STDCALL
*PMP_DRIVERENTRY
)(PVOID
, PVOID
);
496 PFILE_OBJECT
DRIVER_FindMPDriver(ULONG DisplayNumber
)
498 OBJECT_ATTRIBUTES ObjectAttributes
;
499 WCHAR DeviceNameBuffer
[20];
500 UNICODE_STRING DeviceName
;
501 IO_STATUS_BLOCK Iosb
;
502 HANDLE DisplayHandle
;
504 PFILE_OBJECT VideoFileObject
;
506 swprintf(DeviceNameBuffer
, L
"\\??\\DISPLAY%d", DisplayNumber
+ 1);
507 RtlInitUnicodeString(&DeviceName
, DeviceNameBuffer
);
508 InitializeObjectAttributes(&ObjectAttributes
,
513 Status
= ZwOpenFile(&DisplayHandle
,
518 FILE_SYNCHRONOUS_IO_ALERT
);
519 if (NT_SUCCESS(Status
))
521 Status
= ObReferenceObjectByHandle(DisplayHandle
,
522 FILE_READ_DATA
| FILE_WRITE_DATA
,
525 (PVOID
*)&VideoFileObject
,
527 ZwClose(DisplayHandle
);
530 if (!NT_SUCCESS(Status
))
532 DPRINT1("Unable to connect to miniport (Status %lx)\n", Status
);
533 DPRINT1("Perhaps the miniport wasn't loaded?\n");
537 return VideoFileObject
;
541 BOOL
DRIVER_UnregisterDriver(LPCWSTR Name
)
543 PGRAPHICS_DRIVER Driver
= NULL
;
547 if (DriverList
!= NULL
)
549 if (!_wcsicmp(DriverList
->Name
, Name
))
552 DriverList
= DriverList
->Next
;
557 while (Driver
->Next
&& _wcsicmp(Driver
->Name
, Name
))
559 Driver
= Driver
->Next
;
566 if (GenericDriver
!= NULL
)
568 Driver
= GenericDriver
;
569 GenericDriver
= NULL
;
575 ExFreePool(Driver
->Name
);
586 INT
DRIVER_ReferenceDriver (LPCWSTR Name
)
588 GRAPHICS_DRIVER
*Driver
= DriverList
;
590 while (Driver
&& Name
)
592 DPRINT( "Comparing %S to %S\n", Driver
->Name
, Name
);
593 if (!_wcsicmp( Driver
->Name
, Name
))
595 return ++Driver
->ReferenceCount
;
597 Driver
= Driver
->Next
;
599 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name
, GenericDriver
->ReferenceCount
);
600 assert( GenericDriver
!= 0 );
601 return ++GenericDriver
->ReferenceCount
;
604 INT
DRIVER_UnreferenceDriver (LPCWSTR Name
)
606 GRAPHICS_DRIVER
*Driver
= DriverList
;
608 while (Driver
&& Name
)
610 DPRINT( "Comparing %S to %S\n", Driver
->Name
, Name
);
611 if (!_wcsicmp( Driver
->Name
, Name
))
613 return --Driver
->ReferenceCount
;
615 Driver
= Driver
->Next
;
617 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name
, GenericDriver
->ReferenceCount
);
618 assert( GenericDriver
!= 0 );
619 return --GenericDriver
->ReferenceCount
;