2 * Graphics driver management functions
4 * Copyright 1994 Bob Amstadt
5 * Copyright 1996, 2001 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #define WIN32_NO_STATUS
31 #include "ntgdi_private.h"
32 #include "ntuser_private.h"
33 #include "wine/winbase16.h"
34 #include "wine/list.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(driver
);
38 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
42 D3DKMT_HANDLE handle
; /* Kernel mode graphics adapter handle */
43 struct list entry
; /* List entry */
48 D3DKMT_HANDLE handle
; /* Kernel mode graphics device handle*/
49 struct list entry
; /* List entry */
52 static const struct user_driver_funcs lazy_load_driver
;
53 static struct user_driver_funcs null_user_driver
;
55 static struct list d3dkmt_adapters
= LIST_INIT( d3dkmt_adapters
);
56 static struct list d3dkmt_devices
= LIST_INIT( d3dkmt_devices
);
58 static pthread_mutex_t driver_lock
= PTHREAD_MUTEX_INITIALIZER
;
59 static WCHAR driver_load_error
[80];
61 static INT CDECL
nulldrv_AbortDoc( PHYSDEV dev
)
66 static BOOL CDECL
nulldrv_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
67 INT xstart
, INT ystart
, INT xend
, INT yend
)
72 static BOOL CDECL
nulldrv_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
73 INT xstart
, INT ystart
, INT xend
, INT yend
)
78 static BOOL CDECL
nulldrv_CreateCompatibleDC( PHYSDEV orig
, PHYSDEV
*pdev
)
80 if (!user_driver
->dc_funcs
.pCreateCompatibleDC
) return TRUE
;
81 return user_driver
->dc_funcs
.pCreateCompatibleDC( NULL
, pdev
);
84 static BOOL CDECL
nulldrv_CreateDC( PHYSDEV
*dev
, LPCWSTR device
, LPCWSTR output
,
85 const DEVMODEW
*devmode
)
87 assert(0); /* should never be called */
91 static BOOL CDECL
nulldrv_DeleteDC( PHYSDEV dev
)
93 assert(0); /* should never be called */
97 static BOOL CDECL
nulldrv_DeleteObject( PHYSDEV dev
, HGDIOBJ obj
)
102 static BOOL CDECL
nulldrv_Ellipse( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
107 static INT CDECL
nulldrv_EndDoc( PHYSDEV dev
)
112 static INT CDECL
nulldrv_EndPage( PHYSDEV dev
)
117 static BOOL CDECL
nulldrv_EnumFonts( PHYSDEV dev
, LOGFONTW
*logfont
, FONTENUMPROCW proc
, LPARAM lParam
)
122 static INT CDECL
nulldrv_ExtEscape( PHYSDEV dev
, INT escape
, INT in_size
, const void *in_data
,
123 INT out_size
, void *out_data
)
128 static BOOL CDECL
nulldrv_ExtFloodFill( PHYSDEV dev
, INT x
, INT y
, COLORREF color
, UINT type
)
133 static BOOL CDECL
nulldrv_FontIsLinked( PHYSDEV dev
)
138 static UINT CDECL
nulldrv_GetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
143 static BOOL CDECL
nulldrv_GetCharABCWidths( PHYSDEV dev
, UINT first
, UINT count
,
144 WCHAR
*chars
, ABC
*abc
)
149 static BOOL CDECL
nulldrv_GetCharABCWidthsI( PHYSDEV dev
, UINT first
, UINT count
, WORD
*indices
, LPABC abc
)
154 static BOOL CDECL
nulldrv_GetCharWidth( PHYSDEV dev
, UINT first
, UINT count
,
155 const WCHAR
*chars
, INT
*buffer
)
160 static BOOL CDECL
nulldrv_GetCharWidthInfo( PHYSDEV dev
, void *info
)
165 static INT CDECL
nulldrv_GetDeviceCaps( PHYSDEV dev
, INT cap
)
171 case DRIVERVERSION
: return 0x4000;
172 case TECHNOLOGY
: return DT_RASDISPLAY
;
173 case HORZSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
), 254,
174 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSX
) * 10 );
175 case VERTSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
), 254,
176 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSY
) * 10 );
179 DC
*dc
= get_nulldrv_dc( dev
);
185 rect
= get_display_rect( dc
->display
);
186 if (!IsRectEmpty( &rect
)) return rect
.right
- rect
.left
;
189 ret
= get_system_metrics( SM_CXSCREEN
);
190 return ret
? ret
: 640;
194 DC
*dc
= get_nulldrv_dc( dev
);
200 rect
= get_display_rect( dc
->display
);
201 if (!IsRectEmpty( &rect
)) return rect
.bottom
- rect
.top
;
204 ret
= get_system_metrics( SM_CYSCREEN
);
205 return ret
? ret
: 480;
209 UNICODE_STRING display
;
213 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
215 dc
= get_nulldrv_dc( dev
);
216 memset( &devmode
, 0, sizeof(devmode
) );
217 devmode
.dmSize
= sizeof(devmode
);
218 RtlInitUnicodeString( &display
, dc
->display
);
219 if (NtUserEnumDisplaySettings( &display
, ENUM_CURRENT_SETTINGS
, &devmode
, 0 ) &&
220 (devmode
.dmFields
& DM_BITSPERPEL
) && devmode
.dmBitsPerPel
)
221 return devmode
.dmBitsPerPel
;
225 case PLANES
: return 1;
226 case NUMBRUSHES
: return -1;
227 case NUMPENS
: return -1;
228 case NUMMARKERS
: return 0;
229 case NUMFONTS
: return 0;
230 case PDEVICESIZE
: return 0;
231 case CURVECAPS
: return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
232 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
233 case LINECAPS
: return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
234 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
235 case POLYGONALCAPS
: return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
236 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
237 case TEXTCAPS
: return (TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
238 TC_CR_ANY
| TC_SF_X_YINDEP
| TC_SA_DOUBLE
| TC_SA_INTEGER
|
239 TC_SA_CONTIN
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
| TC_VA_ABLE
);
240 case CLIPCAPS
: return CP_RECTANGLE
;
241 case RASTERCAPS
: return (RC_BITBLT
| RC_BITMAP64
| RC_GDI20_OUTPUT
| RC_DI_BITMAP
| RC_DIBTODEV
|
242 RC_BIGFONT
| RC_STRETCHBLT
| RC_FLOODFILL
| RC_STRETCHDIB
| RC_DEVBITS
|
243 (NtGdiGetDeviceCaps( dev
->hdc
, SIZEPALETTE
) ? RC_PALETTE
: 0));
244 case ASPECTX
: return 36;
245 case ASPECTY
: return 36;
246 case ASPECTXY
: return (int)(hypot( NtGdiGetDeviceCaps( dev
->hdc
, ASPECTX
),
247 NtGdiGetDeviceCaps( dev
->hdc
, ASPECTY
)) + 0.5);
248 case CAPS1
: return 0;
249 case SIZEPALETTE
: return 0;
250 case NUMRESERVED
: return 20;
251 case PHYSICALWIDTH
: return 0;
252 case PHYSICALHEIGHT
: return 0;
253 case PHYSICALOFFSETX
: return 0;
254 case PHYSICALOFFSETY
: return 0;
255 case SCALINGFACTORX
: return 0;
256 case SCALINGFACTORY
: return 0;
259 UNICODE_STRING display
;
263 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) != DT_RASDISPLAY
)
266 dc
= get_nulldrv_dc( dev
);
268 memset( &devmode
, 0, sizeof(devmode
) );
269 devmode
.dmSize
= sizeof(devmode
);
270 RtlInitUnicodeString( &display
, dc
->display
);
271 if (NtUserEnumDisplaySettings( &display
, ENUM_CURRENT_SETTINGS
, &devmode
, 0 ) &&
272 devmode
.dmDisplayFrequency
)
273 return devmode
.dmDisplayFrequency
;
277 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
279 RECT rect
= get_virtual_screen_rect( 0 );
280 return rect
.right
- rect
.left
;
282 return NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
);
284 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
286 RECT rect
= get_virtual_screen_rect( 0 );
287 return rect
.bottom
- rect
.top
;
289 return NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
);
290 case BLTALIGNMENT
: return 0;
291 case SHADEBLENDCAPS
: return 0;
292 case COLORMGMTCAPS
: return 0;
294 case LOGPIXELSY
: return get_system_dpi();
296 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
297 /* Newer versions of Windows return -1 for 8-bit and higher */
298 return (bpp
> 4) ? -1 : (1 << bpp
);
300 /* The observed correspondence between BITSPIXEL and COLORRES is:
301 * BITSPIXEL: 8 -> COLORRES: 18
302 * BITSPIXEL: 16 -> COLORRES: 16
303 * BITSPIXEL: 24 -> COLORRES: 24
304 * BITSPIXEL: 32 -> COLORRES: 24 */
305 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
306 return (bpp
<= 8) ? 18 : min( 24, bpp
);
308 FIXME("(%p): unsupported capability %d, will return 0\n", dev
->hdc
, cap
);
313 static BOOL CDECL
nulldrv_GetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
315 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
319 static DWORD CDECL
nulldrv_GetFontData( PHYSDEV dev
, DWORD table
, DWORD offset
, LPVOID buffer
, DWORD length
)
324 static BOOL CDECL
nulldrv_GetFontRealizationInfo( PHYSDEV dev
, void *info
)
329 static DWORD CDECL
nulldrv_GetFontUnicodeRanges( PHYSDEV dev
, LPGLYPHSET glyphs
)
334 static DWORD CDECL
nulldrv_GetGlyphIndices( PHYSDEV dev
, LPCWSTR str
, INT count
, LPWORD indices
, DWORD flags
)
339 static DWORD CDECL
nulldrv_GetGlyphOutline( PHYSDEV dev
, UINT ch
, UINT format
, LPGLYPHMETRICS metrics
,
340 DWORD size
, LPVOID buffer
, const MAT2
*mat
)
345 static BOOL CDECL
nulldrv_GetICMProfile( PHYSDEV dev
, BOOL allow_default
, LPDWORD size
, LPWSTR filename
)
350 static DWORD CDECL
nulldrv_GetImage( PHYSDEV dev
, BITMAPINFO
*info
, struct gdi_image_bits
*bits
,
351 struct bitblt_coords
*src
)
353 return ERROR_NOT_SUPPORTED
;
356 static DWORD CDECL
nulldrv_GetKerningPairs( PHYSDEV dev
, DWORD count
, LPKERNINGPAIR pairs
)
361 static UINT CDECL
nulldrv_GetOutlineTextMetrics( PHYSDEV dev
, UINT size
, LPOUTLINETEXTMETRICW otm
)
366 static UINT CDECL
nulldrv_GetTextCharsetInfo( PHYSDEV dev
, LPFONTSIGNATURE fs
, DWORD flags
)
368 return DEFAULT_CHARSET
;
371 static BOOL CDECL
nulldrv_GetTextExtentExPoint( PHYSDEV dev
, LPCWSTR str
, INT count
, INT
*dx
)
376 static BOOL CDECL
nulldrv_GetTextExtentExPointI( PHYSDEV dev
, const WORD
*indices
, INT count
, INT
*dx
)
381 static INT CDECL
nulldrv_GetTextFace( PHYSDEV dev
, INT size
, LPWSTR name
)
385 DC
*dc
= get_nulldrv_dc( dev
);
387 if (NtGdiExtGetObjectW( dc
->hFont
, sizeof(font
), &font
))
389 ret
= lstrlenW( font
.lfFaceName
) + 1;
392 lstrcpynW( name
, font
.lfFaceName
, size
);
393 ret
= min( size
, ret
);
399 static BOOL CDECL
nulldrv_GetTextMetrics( PHYSDEV dev
, TEXTMETRICW
*metrics
)
404 static BOOL CDECL
nulldrv_LineTo( PHYSDEV dev
, INT x
, INT y
)
409 static BOOL CDECL
nulldrv_MoveTo( PHYSDEV dev
, INT x
, INT y
)
414 static BOOL CDECL
nulldrv_PaintRgn( PHYSDEV dev
, HRGN rgn
)
419 static BOOL CDECL
nulldrv_PatBlt( PHYSDEV dev
, struct bitblt_coords
*dst
, DWORD rop
)
424 static BOOL CDECL
nulldrv_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
425 INT xstart
, INT ystart
, INT xend
, INT yend
)
430 static BOOL CDECL
nulldrv_PolyPolygon( PHYSDEV dev
, const POINT
*points
, const INT
*counts
, UINT polygons
)
435 static BOOL CDECL
nulldrv_PolyPolyline( PHYSDEV dev
, const POINT
*points
, const DWORD
*counts
, DWORD lines
)
440 static DWORD CDECL
nulldrv_PutImage( PHYSDEV dev
, HRGN clip
, BITMAPINFO
*info
,
441 const struct gdi_image_bits
*bits
, struct bitblt_coords
*src
,
442 struct bitblt_coords
*dst
, DWORD rop
)
444 return ERROR_SUCCESS
;
447 static UINT CDECL
nulldrv_RealizeDefaultPalette( PHYSDEV dev
)
452 static UINT CDECL
nulldrv_RealizePalette( PHYSDEV dev
, HPALETTE palette
, BOOL primary
)
457 static BOOL CDECL
nulldrv_Rectangle( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
462 static BOOL CDECL
nulldrv_ResetDC( PHYSDEV dev
, const DEVMODEW
*devmode
)
467 static BOOL CDECL
nulldrv_RoundRect( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
468 INT ell_width
, INT ell_height
)
473 static HBITMAP CDECL
nulldrv_SelectBitmap( PHYSDEV dev
, HBITMAP bitmap
)
478 static HBRUSH CDECL
nulldrv_SelectBrush( PHYSDEV dev
, HBRUSH brush
, const struct brush_pattern
*pattern
)
483 static HFONT CDECL
nulldrv_SelectFont( PHYSDEV dev
, HFONT font
, UINT
*aa_flags
)
488 static HPEN CDECL
nulldrv_SelectPen( PHYSDEV dev
, HPEN pen
, const struct brush_pattern
*pattern
)
493 static COLORREF CDECL
nulldrv_SetBkColor( PHYSDEV dev
, COLORREF color
)
498 static UINT CDECL
nulldrv_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
503 static COLORREF CDECL
nulldrv_SetDCBrushColor( PHYSDEV dev
, COLORREF color
)
508 static COLORREF CDECL
nulldrv_SetDCPenColor( PHYSDEV dev
, COLORREF color
)
513 static void CDECL
nulldrv_SetDeviceClipping( PHYSDEV dev
, HRGN rgn
)
517 static BOOL CDECL
nulldrv_SetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
519 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
523 static COLORREF CDECL
nulldrv_SetPixel( PHYSDEV dev
, INT x
, INT y
, COLORREF color
)
528 static COLORREF CDECL
nulldrv_SetTextColor( PHYSDEV dev
, COLORREF color
)
533 static INT CDECL
nulldrv_StartDoc( PHYSDEV dev
, const DOCINFOW
*info
)
538 static INT CDECL
nulldrv_StartPage( PHYSDEV dev
)
543 static BOOL CDECL
nulldrv_UnrealizePalette( HPALETTE palette
)
548 static NTSTATUS CDECL
nulldrv_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
550 return STATUS_PROCEDURE_NOT_FOUND
;
553 static NTSTATUS CDECL
nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
555 return STATUS_PROCEDURE_NOT_FOUND
;
558 static NTSTATUS CDECL
nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
560 return STATUS_PROCEDURE_NOT_FOUND
;
563 static NTSTATUS CDECL
nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
565 return STATUS_PROCEDURE_NOT_FOUND
;
568 static NTSTATUS CDECL
nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
570 return STATUS_PROCEDURE_NOT_FOUND
;
573 const struct gdi_dc_funcs null_driver
=
575 nulldrv_AbortDoc
, /* pAbortDoc */
576 nulldrv_AbortPath
, /* pAbortPath */
577 nulldrv_AlphaBlend
, /* pAlphaBlend */
578 nulldrv_AngleArc
, /* pAngleArc */
579 nulldrv_Arc
, /* pArc */
580 nulldrv_ArcTo
, /* pArcTo */
581 nulldrv_BeginPath
, /* pBeginPath */
582 nulldrv_BlendImage
, /* pBlendImage */
583 nulldrv_Chord
, /* pChord */
584 nulldrv_CloseFigure
, /* pCloseFigure */
585 nulldrv_CreateCompatibleDC
, /* pCreateCompatibleDC */
586 nulldrv_CreateDC
, /* pCreateDC */
587 nulldrv_DeleteDC
, /* pDeleteDC */
588 nulldrv_DeleteObject
, /* pDeleteObject */
589 nulldrv_Ellipse
, /* pEllipse */
590 nulldrv_EndDoc
, /* pEndDoc */
591 nulldrv_EndPage
, /* pEndPage */
592 nulldrv_EndPath
, /* pEndPath */
593 nulldrv_EnumFonts
, /* pEnumFonts */
594 nulldrv_ExtEscape
, /* pExtEscape */
595 nulldrv_ExtFloodFill
, /* pExtFloodFill */
596 nulldrv_ExtTextOut
, /* pExtTextOut */
597 nulldrv_FillPath
, /* pFillPath */
598 nulldrv_FillRgn
, /* pFillRgn */
599 nulldrv_FontIsLinked
, /* pFontIsLinked */
600 nulldrv_FrameRgn
, /* pFrameRgn */
601 nulldrv_GetBoundsRect
, /* pGetBoundsRect */
602 nulldrv_GetCharABCWidths
, /* pGetCharABCWidths */
603 nulldrv_GetCharABCWidthsI
, /* pGetCharABCWidthsI */
604 nulldrv_GetCharWidth
, /* pGetCharWidth */
605 nulldrv_GetCharWidthInfo
, /* pGetCharWidthInfo */
606 nulldrv_GetDeviceCaps
, /* pGetDeviceCaps */
607 nulldrv_GetDeviceGammaRamp
, /* pGetDeviceGammaRamp */
608 nulldrv_GetFontData
, /* pGetFontData */
609 nulldrv_GetFontRealizationInfo
, /* pGetFontRealizationInfo */
610 nulldrv_GetFontUnicodeRanges
, /* pGetFontUnicodeRanges */
611 nulldrv_GetGlyphIndices
, /* pGetGlyphIndices */
612 nulldrv_GetGlyphOutline
, /* pGetGlyphOutline */
613 nulldrv_GetICMProfile
, /* pGetICMProfile */
614 nulldrv_GetImage
, /* pGetImage */
615 nulldrv_GetKerningPairs
, /* pGetKerningPairs */
616 nulldrv_GetNearestColor
, /* pGetNearestColor */
617 nulldrv_GetOutlineTextMetrics
, /* pGetOutlineTextMetrics */
618 nulldrv_GetPixel
, /* pGetPixel */
619 nulldrv_GetSystemPaletteEntries
, /* pGetSystemPaletteEntries */
620 nulldrv_GetTextCharsetInfo
, /* pGetTextCharsetInfo */
621 nulldrv_GetTextExtentExPoint
, /* pGetTextExtentExPoint */
622 nulldrv_GetTextExtentExPointI
, /* pGetTextExtentExPointI */
623 nulldrv_GetTextFace
, /* pGetTextFace */
624 nulldrv_GetTextMetrics
, /* pGetTextMetrics */
625 nulldrv_GradientFill
, /* pGradientFill */
626 nulldrv_InvertRgn
, /* pInvertRgn */
627 nulldrv_LineTo
, /* pLineTo */
628 nulldrv_MoveTo
, /* pMoveTo */
629 nulldrv_PaintRgn
, /* pPaintRgn */
630 nulldrv_PatBlt
, /* pPatBlt */
631 nulldrv_Pie
, /* pPie */
632 nulldrv_PolyBezier
, /* pPolyBezier */
633 nulldrv_PolyBezierTo
, /* pPolyBezierTo */
634 nulldrv_PolyDraw
, /* pPolyDraw */
635 nulldrv_PolyPolygon
, /* pPolyPolygon */
636 nulldrv_PolyPolyline
, /* pPolyPolyline */
637 nulldrv_PolylineTo
, /* pPolylineTo */
638 nulldrv_PutImage
, /* pPutImage */
639 nulldrv_RealizeDefaultPalette
, /* pRealizeDefaultPalette */
640 nulldrv_RealizePalette
, /* pRealizePalette */
641 nulldrv_Rectangle
, /* pRectangle */
642 nulldrv_ResetDC
, /* pResetDC */
643 nulldrv_RoundRect
, /* pRoundRect */
644 nulldrv_SelectBitmap
, /* pSelectBitmap */
645 nulldrv_SelectBrush
, /* pSelectBrush */
646 nulldrv_SelectFont
, /* pSelectFont */
647 nulldrv_SelectPen
, /* pSelectPen */
648 nulldrv_SetBkColor
, /* pSetBkColor */
649 nulldrv_SetBoundsRect
, /* pSetBoundsRect */
650 nulldrv_SetDCBrushColor
, /* pSetDCBrushColor */
651 nulldrv_SetDCPenColor
, /* pSetDCPenColor */
652 nulldrv_SetDIBitsToDevice
, /* pSetDIBitsToDevice */
653 nulldrv_SetDeviceClipping
, /* pSetDeviceClipping */
654 nulldrv_SetDeviceGammaRamp
, /* pSetDeviceGammaRamp */
655 nulldrv_SetPixel
, /* pSetPixel */
656 nulldrv_SetTextColor
, /* pSetTextColor */
657 nulldrv_StartDoc
, /* pStartDoc */
658 nulldrv_StartPage
, /* pStartPage */
659 nulldrv_StretchBlt
, /* pStretchBlt */
660 nulldrv_StretchDIBits
, /* pStretchDIBits */
661 nulldrv_StrokeAndFillPath
, /* pStrokeAndFillPath */
662 nulldrv_StrokePath
, /* pStrokePath */
663 nulldrv_UnrealizePalette
, /* pUnrealizePalette */
664 nulldrv_D3DKMTCheckVidPnExclusiveOwnership
, /* pD3DKMTCheckVidPnExclusiveOwnership */
665 nulldrv_D3DKMTCloseAdapter
, /* pD3DKMTCloseAdapter */
666 nulldrv_D3DKMTOpenAdapterFromLuid
, /* pD3DKMTOpenAdapterFromLuid */
667 nulldrv_D3DKMTQueryVideoMemoryInfo
, /* pD3DKMTQueryVideoMemoryInfo */
668 nulldrv_D3DKMTSetVidPnSourceOwner
, /* pD3DKMTSetVidPnSourceOwner */
670 GDI_PRIORITY_NULL_DRV
/* priority */
674 /**********************************************************************
677 * These are fallbacks for entry points that are not implemented in the real driver.
680 static BOOL
nulldrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
685 static void nulldrv_Beep(void)
689 static UINT
nulldrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
691 return ~0; /* use default implementation */
694 static INT
nulldrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
696 return -1; /* use default implementation */
699 static UINT
nulldrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
701 return -1; /* use default implementation */
704 static BOOL
nulldrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
709 static INT
nulldrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
710 int size
, UINT flags
, HKL layout
)
712 return -2; /* use default implementation */
715 static void nulldrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
719 static SHORT
nulldrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
721 return -256; /* use default implementation */
724 static LRESULT
nulldrv_DesktopWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
726 return default_window_proc( hwnd
, msg
, wparam
, lparam
, FALSE
);
729 static void nulldrv_DestroyCursorIcon( HCURSOR cursor
)
733 static void nulldrv_SetCursor( HCURSOR cursor
)
737 static BOOL
nulldrv_GetCursorPos( LPPOINT pt
)
742 static BOOL
nulldrv_SetCursorPos( INT x
, INT y
)
747 static BOOL
nulldrv_ClipCursor( LPCRECT clip
)
752 static void nulldrv_UpdateClipboard(void)
756 static LONG
nulldrv_ChangeDisplaySettings( LPDEVMODEW displays
, HWND hwnd
,
757 DWORD flags
, LPVOID lparam
)
759 return DISP_CHANGE_FAILED
;
762 static BOOL
nulldrv_EnumDisplaySettingsEx( LPCWSTR name
, DWORD num
, LPDEVMODEW mode
, DWORD flags
)
767 static BOOL
nulldrv_GetCurrentDisplaySettings( LPCWSTR name
, LPDEVMODEW mode
)
772 static BOOL
nulldrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
777 static BOOL
nulldrv_CreateDesktopWindow( HWND hwnd
)
782 static BOOL
nodrv_CreateWindow( HWND hwnd
)
785 HWND parent
= NtUserGetAncestor( hwnd
, GA_PARENT
);
787 /* HWND_MESSAGE windows don't need a graphics driver */
788 if (!parent
|| parent
== UlongToHandle( NtUserGetThreadInfo()->msg_window
)) return TRUE
;
789 if (warned
++) return FALSE
;
791 ERR_(winediag
)( "Application tried to create a window, but no driver could be loaded.\n" );
792 if (driver_load_error
[0]) ERR_(winediag
)( "%s\n", debugstr_w(driver_load_error
) );
796 static BOOL
nulldrv_CreateWindow( HWND hwnd
)
801 static void nulldrv_DestroyWindow( HWND hwnd
)
805 static void nulldrv_FlashWindowEx( FLASHWINFO
*info
)
809 static void nulldrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
810 const RECT
*top_rect
, DWORD flags
)
814 static NTSTATUS
nulldrv_MsgWaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
815 const LARGE_INTEGER
*timeout
,
816 DWORD mask
, DWORD flags
)
818 if (!count
&& timeout
&& !timeout
->QuadPart
) return WAIT_TIMEOUT
;
819 return NtWaitForMultipleObjects( count
, handles
, !(flags
& MWMO_WAITALL
),
820 !!(flags
& MWMO_ALERTABLE
), timeout
);
823 static void nulldrv_ReleaseDC( HWND hwnd
, HDC hdc
)
827 static BOOL
nulldrv_ScrollDC( HDC hdc
, INT dx
, INT dy
, HRGN update
)
831 NtGdiGetAppClipBox( hdc
, &rect
);
832 return NtGdiBitBlt( hdc
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
833 hdc
, rect
.left
- dx
, rect
.top
- dy
, SRCCOPY
, 0, 0 );
836 static void nulldrv_SetCapture( HWND hwnd
, UINT flags
)
840 static void nulldrv_SetFocus( HWND hwnd
)
844 static void nulldrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
848 static void nulldrv_SetParent( HWND hwnd
, HWND parent
, HWND old_parent
)
852 static void nulldrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
856 static void nulldrv_SetWindowIcon( HWND hwnd
, UINT type
, HICON icon
)
860 static void nulldrv_SetWindowStyle( HWND hwnd
, INT offset
, STYLESTRUCT
*style
)
864 static void nulldrv_SetWindowText( HWND hwnd
, LPCWSTR text
)
868 static UINT
nulldrv_ShowWindow( HWND hwnd
, INT cmd
, RECT
*rect
, UINT swp
)
870 return ~0; /* use default implementation */
873 static LRESULT
nulldrv_SysCommand( HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
878 static BOOL
nulldrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
879 const RECT
*window_rect
)
884 static LRESULT
nulldrv_WindowMessage( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
889 static BOOL
nulldrv_WindowPosChanging( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
890 const RECT
*window_rect
, const RECT
*client_rect
,
891 RECT
*visible_rect
, struct window_surface
**surface
)
896 static void nulldrv_WindowPosChanged( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
897 const RECT
*window_rect
, const RECT
*client_rect
,
898 const RECT
*visible_rect
, const RECT
*valid_rects
,
899 struct window_surface
*surface
)
903 static BOOL
nulldrv_SystemParametersInfo( UINT action
, UINT int_param
, void *ptr_param
, UINT flags
)
908 static const struct vulkan_funcs
*nulldrv_wine_get_vulkan_driver( UINT version
)
913 static struct opengl_funcs
*nulldrv_wine_get_wgl_driver( UINT version
)
918 static void nulldrv_ThreadDetach( void )
922 static const WCHAR guid_key_prefixW
[] =
924 '\\','R','e','g','i','s','t','r','y',
925 '\\','M','a','c','h','i','n','e',
926 '\\','S','y','s','t','e','m',
927 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
928 '\\','C','o','n','t','r','o','l',
929 '\\','V','i','d','e','o','\\','{'
931 static const WCHAR guid_key_suffixW
[] = {'}','\\','0','0','0','0'};
933 static BOOL
load_desktop_driver( HWND hwnd
)
935 WCHAR key
[ARRAYSIZE(guid_key_prefixW
) + 40 + ARRAYSIZE(guid_key_suffixW
)], *ptr
;
937 KEY_VALUE_PARTIAL_INFORMATION
*info
= (void *)buf
;
938 ATOM_BASIC_INFORMATION
*abi
= (ATOM_BASIC_INFORMATION
*)buf
;
944 static const WCHAR prop_nameW
[] =
945 {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_','d','e','v','i','c','e',
946 '_','g','u','i','d',0};
948 user_check_not_lock();
950 asciiz_to_unicode( driver_load_error
, "The explorer process failed to start." ); /* default error */
951 /* wait for graphics driver to be ready */
952 send_message( hwnd
, WM_NULL
, 0, 0 );
954 guid_atom
= HandleToULong( NtUserGetProp( hwnd
, prop_nameW
));
955 memcpy( key
, guid_key_prefixW
, sizeof(guid_key_prefixW
) );
956 ptr
= key
+ ARRAYSIZE(guid_key_prefixW
);
957 if (NtQueryInformationAtom( guid_atom
, AtomBasicInformation
, buf
, sizeof(buf
), NULL
))
959 memcpy( ptr
, abi
->Name
, abi
->NameLength
);
960 ptr
+= abi
->NameLength
/ sizeof(WCHAR
);
961 memcpy( ptr
, guid_key_suffixW
, sizeof(guid_key_suffixW
) );
962 ptr
+= ARRAY_SIZE(guid_key_suffixW
);
964 if (!(hkey
= reg_open_key( NULL
, key
, (ptr
- key
) * sizeof(WCHAR
) ))) return FALSE
;
966 if ((size
= query_reg_ascii_value( hkey
, "GraphicsDriver", info
, sizeof(buf
) )))
968 static const WCHAR nullW
[] = {'n','u','l','l',0};
969 TRACE( "trying driver %s\n", debugstr_wn( (const WCHAR
*)info
->Data
,
970 info
->DataLength
/ sizeof(WCHAR
) ));
971 if (info
->DataLength
!= sizeof(nullW
) || memcmp( info
->Data
, nullW
, sizeof(nullW
) ))
975 ret
= KeUserModeCallback( NtUserLoadDriver
, info
->Data
, info
->DataLength
,
976 &ret_ptr
, &ret_len
);
980 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
984 else if ((size
= query_reg_ascii_value( hkey
, "DriverError", info
, sizeof(buf
) )))
986 memcpy( driver_load_error
, info
->Data
, min( info
->DataLength
, sizeof(driver_load_error
) ));
987 driver_load_error
[ARRAYSIZE(driver_load_error
) - 1] = 0;
994 /**********************************************************************
995 * Lazy loading user driver
997 * Initial driver used before another driver is loaded.
998 * Each entry point simply loads the real driver and chains to it.
1001 static const struct user_driver_funcs
*load_driver(void)
1003 USEROBJECTFLAGS flags
;
1006 if (!load_desktop_driver( get_desktop_window() ) || user_driver
== &lazy_load_driver
)
1008 winstation
= NtUserGetProcessWindowStation();
1009 if (!NtUserGetObjectInformation( winstation
, UOI_FLAGS
, &flags
, sizeof(flags
), NULL
)
1010 || (flags
.dwFlags
& WSF_VISIBLE
))
1011 null_user_driver
.pCreateWindow
= nodrv_CreateWindow
;
1013 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
1019 /**********************************************************************
1020 * get_display_driver
1022 const struct gdi_dc_funcs
*get_display_driver(void)
1024 if (user_driver
== &lazy_load_driver
) load_driver();
1025 return &user_driver
->dc_funcs
;
1028 static BOOL
loaderdrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
1030 return load_driver()->pActivateKeyboardLayout( layout
, flags
);
1033 static void loaderdrv_Beep(void)
1035 load_driver()->pBeep();
1038 static INT
loaderdrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
1040 return load_driver()->pGetKeyNameText( lparam
, buffer
, size
);
1043 static UINT
loaderdrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
1045 return load_driver()->pGetKeyboardLayoutList( size
, layouts
);
1048 static UINT
loaderdrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
1050 return load_driver()->pMapVirtualKeyEx( code
, type
, layout
);
1053 static INT
loaderdrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
1054 int size
, UINT flags
, HKL layout
)
1056 return load_driver()->pToUnicodeEx( virt
, scan
, state
, str
, size
, flags
, layout
);
1059 static BOOL
loaderdrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1061 return load_driver()->pRegisterHotKey( hwnd
, modifiers
, vk
);
1064 static void loaderdrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1066 load_driver()->pUnregisterHotKey( hwnd
, modifiers
, vk
);
1069 static SHORT
loaderdrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
1071 return load_driver()->pVkKeyScanEx( ch
, layout
);
1074 static LONG
loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays
, HWND hwnd
,
1075 DWORD flags
, LPVOID lparam
)
1077 return load_driver()->pChangeDisplaySettings( displays
, hwnd
, flags
, lparam
);
1080 static BOOL
loaderdrv_EnumDisplaySettingsEx( LPCWSTR name
, DWORD num
, LPDEVMODEW mode
, DWORD flags
)
1082 return load_driver()->pEnumDisplaySettingsEx( name
, num
, mode
, flags
);
1085 static BOOL
loaderdrv_GetCurrentDisplaySettings( LPCWSTR name
, LPDEVMODEW mode
)
1087 return load_driver()->pGetCurrentDisplaySettings( name
, mode
);
1090 static void loaderdrv_SetCursor( HCURSOR cursor
)
1092 load_driver()->pSetCursor( cursor
);
1095 static BOOL
loaderdrv_GetCursorPos( POINT
*pt
)
1097 return load_driver()->pGetCursorPos( pt
);
1100 static BOOL
loaderdrv_SetCursorPos( INT x
, INT y
)
1102 return load_driver()->pSetCursorPos( x
, y
);
1105 static BOOL
loaderdrv_ClipCursor( const RECT
*clip
)
1107 return load_driver()->pClipCursor( clip
);
1110 static LRESULT
nulldrv_ClipboardWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1115 static void loaderdrv_UpdateClipboard(void)
1117 load_driver()->pUpdateClipboard();
1120 static BOOL
loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
1122 return load_driver()->pUpdateDisplayDevices( manager
, force
, param
);
1125 static BOOL
loaderdrv_CreateDesktopWindow( HWND hwnd
)
1127 return load_driver()->pCreateDesktopWindow( hwnd
);
1130 static BOOL
loaderdrv_CreateWindow( HWND hwnd
)
1132 return load_driver()->pCreateWindow( hwnd
);
1135 static void loaderdrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
1136 const RECT
*top_rect
, DWORD flags
)
1138 load_driver()->pGetDC( hdc
, hwnd
, top_win
, win_rect
, top_rect
, flags
);
1141 static void loaderdrv_FlashWindowEx( FLASHWINFO
*info
)
1143 load_driver()->pFlashWindowEx( info
);
1146 static void loaderdrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
1148 load_driver()->pSetLayeredWindowAttributes( hwnd
, key
, alpha
, flags
);
1151 static void loaderdrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
1153 load_driver()->pSetWindowRgn( hwnd
, hrgn
, redraw
);
1156 static BOOL
loaderdrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
1157 const RECT
*window_rect
)
1159 return load_driver()->pUpdateLayeredWindow( hwnd
, info
, window_rect
);
1162 static const struct vulkan_funcs
* loaderdrv_wine_get_vulkan_driver( UINT version
)
1164 return load_driver()->pwine_get_vulkan_driver( version
);
1167 static const struct user_driver_funcs lazy_load_driver
=
1170 /* keyboard functions */
1171 loaderdrv_ActivateKeyboardLayout
,
1173 loaderdrv_GetKeyNameText
,
1174 loaderdrv_GetKeyboardLayoutList
,
1175 loaderdrv_MapVirtualKeyEx
,
1176 loaderdrv_RegisterHotKey
,
1177 loaderdrv_ToUnicodeEx
,
1178 loaderdrv_UnregisterHotKey
,
1179 loaderdrv_VkKeyScanEx
,
1180 /* cursor/icon functions */
1181 nulldrv_DestroyCursorIcon
,
1182 loaderdrv_SetCursor
,
1183 loaderdrv_GetCursorPos
,
1184 loaderdrv_SetCursorPos
,
1185 loaderdrv_ClipCursor
,
1186 /* clipboard functions */
1187 nulldrv_ClipboardWindowProc
,
1188 loaderdrv_UpdateClipboard
,
1190 loaderdrv_ChangeDisplaySettings
,
1191 loaderdrv_EnumDisplaySettingsEx
,
1192 loaderdrv_GetCurrentDisplaySettings
,
1193 loaderdrv_UpdateDisplayDevices
,
1194 /* windowing functions */
1195 loaderdrv_CreateDesktopWindow
,
1196 loaderdrv_CreateWindow
,
1197 nulldrv_DesktopWindowProc
,
1198 nulldrv_DestroyWindow
,
1199 loaderdrv_FlashWindowEx
,
1201 nulldrv_MsgWaitForMultipleObjectsEx
,
1206 loaderdrv_SetLayeredWindowAttributes
,
1208 loaderdrv_SetWindowRgn
,
1209 nulldrv_SetWindowIcon
,
1210 nulldrv_SetWindowStyle
,
1211 nulldrv_SetWindowText
,
1214 loaderdrv_UpdateLayeredWindow
,
1215 nulldrv_WindowMessage
,
1216 nulldrv_WindowPosChanging
,
1217 nulldrv_WindowPosChanged
,
1218 /* system parameters */
1219 nulldrv_SystemParametersInfo
,
1220 /* vulkan support */
1221 loaderdrv_wine_get_vulkan_driver
,
1222 /* opengl support */
1223 nulldrv_wine_get_wgl_driver
,
1224 /* thread management */
1225 nulldrv_ThreadDetach
,
1228 const struct user_driver_funcs
*user_driver
= &lazy_load_driver
;
1230 /******************************************************************************
1231 * __wine_set_user_driver (win32u.so)
1233 void __wine_set_user_driver( const struct user_driver_funcs
*funcs
, UINT version
)
1235 struct user_driver_funcs
*driver
, *prev
;
1237 if (version
!= WINE_GDI_DRIVER_VERSION
)
1239 ERR( "version mismatch, driver wants %u but win32u has %u\n",
1240 version
, WINE_GDI_DRIVER_VERSION
);
1244 driver
= malloc( sizeof(*driver
) );
1247 #define SET_USER_FUNC(name) \
1248 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
1250 SET_USER_FUNC(ActivateKeyboardLayout
);
1251 SET_USER_FUNC(Beep
);
1252 SET_USER_FUNC(GetKeyNameText
);
1253 SET_USER_FUNC(GetKeyboardLayoutList
);
1254 SET_USER_FUNC(MapVirtualKeyEx
);
1255 SET_USER_FUNC(RegisterHotKey
);
1256 SET_USER_FUNC(ToUnicodeEx
);
1257 SET_USER_FUNC(UnregisterHotKey
);
1258 SET_USER_FUNC(VkKeyScanEx
);
1259 SET_USER_FUNC(DestroyCursorIcon
);
1260 SET_USER_FUNC(SetCursor
);
1261 SET_USER_FUNC(GetCursorPos
);
1262 SET_USER_FUNC(SetCursorPos
);
1263 SET_USER_FUNC(ClipCursor
);
1264 SET_USER_FUNC(ClipboardWindowProc
);
1265 SET_USER_FUNC(UpdateClipboard
);
1266 SET_USER_FUNC(ChangeDisplaySettings
);
1267 SET_USER_FUNC(EnumDisplaySettingsEx
);
1268 SET_USER_FUNC(GetCurrentDisplaySettings
);
1269 SET_USER_FUNC(UpdateDisplayDevices
);
1270 SET_USER_FUNC(CreateDesktopWindow
);
1271 SET_USER_FUNC(CreateWindow
);
1272 SET_USER_FUNC(DesktopWindowProc
);
1273 SET_USER_FUNC(DestroyWindow
);
1274 SET_USER_FUNC(FlashWindowEx
);
1275 SET_USER_FUNC(GetDC
);
1276 SET_USER_FUNC(MsgWaitForMultipleObjectsEx
);
1277 SET_USER_FUNC(ReleaseDC
);
1278 SET_USER_FUNC(ScrollDC
);
1279 SET_USER_FUNC(SetCapture
);
1280 SET_USER_FUNC(SetFocus
);
1281 SET_USER_FUNC(SetLayeredWindowAttributes
);
1282 SET_USER_FUNC(SetParent
);
1283 SET_USER_FUNC(SetWindowRgn
);
1284 SET_USER_FUNC(SetWindowIcon
);
1285 SET_USER_FUNC(SetWindowStyle
);
1286 SET_USER_FUNC(SetWindowText
);
1287 SET_USER_FUNC(ShowWindow
);
1288 SET_USER_FUNC(SysCommand
);
1289 SET_USER_FUNC(UpdateLayeredWindow
);
1290 SET_USER_FUNC(WindowMessage
);
1291 SET_USER_FUNC(WindowPosChanging
);
1292 SET_USER_FUNC(WindowPosChanged
);
1293 SET_USER_FUNC(SystemParametersInfo
);
1294 SET_USER_FUNC(wine_get_vulkan_driver
);
1295 SET_USER_FUNC(wine_get_wgl_driver
);
1296 SET_USER_FUNC(ThreadDetach
);
1297 #undef SET_USER_FUNC
1299 prev
= InterlockedCompareExchangePointer( (void **)&user_driver
, driver
, (void *)&lazy_load_driver
);
1300 if (prev
!= &lazy_load_driver
)
1302 /* another thread beat us to it */
1308 /******************************************************************************
1309 * NtGdiExtEscape (win32u.@)
1311 * Access capabilities of a particular device that are not available through GDI.
1313 INT WINAPI
NtGdiExtEscape( HDC hdc
, WCHAR
*driver
, int driver_id
, INT escape
, INT input_size
,
1314 const char *input
, INT output_size
, char *output
)
1318 DC
* dc
= get_dc_ptr( hdc
);
1322 physdev
= GET_DC_PHYSDEV( dc
, pExtEscape
);
1323 ret
= physdev
->funcs
->pExtEscape( physdev
, escape
, input_size
, input
, output_size
, output
);
1324 release_dc_ptr( dc
);
1329 /******************************************************************************
1330 * NtGdiDdDDIOpenAdapterFromHdc (win32u.@)
1332 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC
*desc
)
1334 FIXME( "(%p): stub\n", desc
);
1335 return STATUS_NO_MEMORY
;
1338 /******************************************************************************
1339 * NtGdiDdDDIEscape (win32u.@)
1341 NTSTATUS WINAPI
NtGdiDdDDIEscape( const D3DKMT_ESCAPE
*desc
)
1343 FIXME( "(%p): stub\n", desc
);
1344 return STATUS_NO_MEMORY
;
1347 /******************************************************************************
1348 * NtGdiDdDDICloseAdapter (win32u.@)
1350 NTSTATUS WINAPI
NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
1352 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1353 struct d3dkmt_adapter
*adapter
;
1355 TRACE("(%p)\n", desc
);
1357 if (!desc
|| !desc
->hAdapter
)
1358 return STATUS_INVALID_PARAMETER
;
1360 if (get_display_driver()->pD3DKMTCloseAdapter
)
1361 get_display_driver()->pD3DKMTCloseAdapter( desc
);
1363 pthread_mutex_lock( &driver_lock
);
1364 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1366 if (adapter
->handle
== desc
->hAdapter
)
1368 list_remove( &adapter
->entry
);
1370 status
= STATUS_SUCCESS
;
1374 pthread_mutex_unlock( &driver_lock
);
1379 /******************************************************************************
1380 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
1382 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME
*desc
)
1384 D3DKMT_OPENADAPTERFROMLUID desc_luid
;
1387 FIXME( "desc %p stub.\n", desc
);
1389 if (!desc
|| !desc
->pDeviceName
) return STATUS_INVALID_PARAMETER
;
1391 memset( &desc_luid
, 0, sizeof( desc_luid
));
1392 if ((status
= NtGdiDdDDIOpenAdapterFromLuid( &desc_luid
))) return status
;
1394 desc
->AdapterLuid
= desc_luid
.AdapterLuid
;
1395 desc
->hAdapter
= desc_luid
.hAdapter
;
1396 return STATUS_SUCCESS
;
1399 /******************************************************************************
1400 * NtGdiDdDDIOpenAdapterFromLuid (win32u.@)
1402 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
1404 static D3DKMT_HANDLE handle_start
= 0;
1405 struct d3dkmt_adapter
*adapter
;
1407 if (!(adapter
= malloc( sizeof( *adapter
) ))) return STATUS_NO_MEMORY
;
1409 pthread_mutex_lock( &driver_lock
);
1410 desc
->hAdapter
= adapter
->handle
= ++handle_start
;
1411 list_add_tail( &d3dkmt_adapters
, &adapter
->entry
);
1412 pthread_mutex_unlock( &driver_lock
);
1414 if (get_display_driver()->pD3DKMTOpenAdapterFromLuid
)
1415 get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc
);
1417 return STATUS_SUCCESS
;
1420 /******************************************************************************
1421 * NtGdiDdDDICreateDevice (win32u.@)
1423 NTSTATUS WINAPI
NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE
*desc
)
1425 static D3DKMT_HANDLE handle_start
= 0;
1426 struct d3dkmt_adapter
*adapter
;
1427 struct d3dkmt_device
*device
;
1430 TRACE("(%p)\n", desc
);
1433 return STATUS_INVALID_PARAMETER
;
1435 pthread_mutex_lock( &driver_lock
);
1436 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1438 if (adapter
->handle
== desc
->hAdapter
)
1444 pthread_mutex_unlock( &driver_lock
);
1447 return STATUS_INVALID_PARAMETER
;
1449 if (desc
->Flags
.LegacyMode
|| desc
->Flags
.RequestVSync
|| desc
->Flags
.DisableGpuTimeout
)
1450 FIXME("Flags unsupported.\n");
1452 device
= calloc( 1, sizeof( *device
) );
1454 return STATUS_NO_MEMORY
;
1456 pthread_mutex_lock( &driver_lock
);
1457 device
->handle
= ++handle_start
;
1458 list_add_tail( &d3dkmt_devices
, &device
->entry
);
1459 pthread_mutex_unlock( &driver_lock
);
1461 desc
->hDevice
= device
->handle
;
1462 return STATUS_SUCCESS
;
1465 /******************************************************************************
1466 * NtGdiDdDDIDestroyDevice (win32u.@)
1468 NTSTATUS WINAPI
NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE
*desc
)
1470 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1471 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc
;
1472 struct d3dkmt_device
*device
;
1474 TRACE("(%p)\n", desc
);
1476 if (!desc
|| !desc
->hDevice
)
1477 return STATUS_INVALID_PARAMETER
;
1479 pthread_mutex_lock( &driver_lock
);
1480 LIST_FOR_EACH_ENTRY( device
, &d3dkmt_devices
, struct d3dkmt_device
, entry
)
1482 if (device
->handle
== desc
->hDevice
)
1484 memset( &set_owner_desc
, 0, sizeof(set_owner_desc
) );
1485 set_owner_desc
.hDevice
= desc
->hDevice
;
1486 NtGdiDdDDISetVidPnSourceOwner( &set_owner_desc
);
1487 list_remove( &device
->entry
);
1489 status
= STATUS_SUCCESS
;
1493 pthread_mutex_unlock( &driver_lock
);
1498 /******************************************************************************
1499 * NtGdiDdDDIQueryStatistics (win32u.@)
1501 NTSTATUS WINAPI
NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS
*stats
)
1503 FIXME("(%p): stub\n", stats
);
1504 return STATUS_SUCCESS
;
1507 /******************************************************************************
1508 * NtGdiDdDDIQueryVideoMemoryInfo (win32u.@)
1510 NTSTATUS WINAPI
NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
1512 OBJECT_BASIC_INFORMATION info
;
1515 TRACE("(%p)\n", desc
);
1517 if (!desc
|| !desc
->hAdapter
||
1518 (desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL
&&
1519 desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL
))
1520 return STATUS_INVALID_PARAMETER
;
1522 /* FIXME: Wine currently doesn't support linked adapters */
1523 if (desc
->PhysicalAdapterIndex
> 0)
1524 return STATUS_INVALID_PARAMETER
;
1526 status
= NtQueryObject(desc
->hProcess
? desc
->hProcess
: GetCurrentProcess(),
1527 ObjectBasicInformation
, &info
, sizeof(info
), NULL
);
1528 if (status
!= STATUS_SUCCESS
)
1530 if (!(info
.GrantedAccess
& PROCESS_QUERY_INFORMATION
))
1531 return STATUS_ACCESS_DENIED
;
1533 if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo
)
1534 return STATUS_PROCEDURE_NOT_FOUND
;
1535 return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc
);
1538 /******************************************************************************
1539 * NtGdiDdDDISetQueuedLimit (win32u.@)
1541 NTSTATUS WINAPI
NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT
*desc
)
1543 FIXME( "(%p): stub\n", desc
);
1544 return STATUS_NOT_IMPLEMENTED
;
1547 /******************************************************************************
1548 * NtGdiDdDDISetVidPnSourceOwner (win32u.@)
1550 NTSTATUS WINAPI
NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
1552 TRACE("(%p)\n", desc
);
1554 if (!get_display_driver()->pD3DKMTSetVidPnSourceOwner
)
1555 return STATUS_PROCEDURE_NOT_FOUND
;
1557 if (!desc
|| !desc
->hDevice
|| (desc
->VidPnSourceCount
&& (!desc
->pType
|| !desc
->pVidPnSourceId
)))
1558 return STATUS_INVALID_PARAMETER
;
1560 /* Store the VidPN source ownership info in the graphics driver because
1561 * the graphics driver needs to change ownership sometimes. For example,
1562 * when a new window is moved to a VidPN source with an exclusive owner,
1563 * such an exclusive owner will be released before showing the new window */
1564 return get_display_driver()->pD3DKMTSetVidPnSourceOwner( desc
);
1567 /******************************************************************************
1568 * NtGdiDdDDICheckVidPnExclusiveOwnership (win32u.@)
1570 NTSTATUS WINAPI
NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
1572 TRACE("(%p)\n", desc
);
1574 if (!get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership
)
1575 return STATUS_PROCEDURE_NOT_FOUND
;
1577 if (!desc
|| !desc
->hAdapter
)
1578 return STATUS_INVALID_PARAMETER
;
1580 return get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership( desc
);