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
nulldrv_AbortDoc( PHYSDEV dev
)
66 static BOOL
nulldrv_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
67 INT xstart
, INT ystart
, INT xend
, INT yend
)
72 static BOOL
nulldrv_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
73 INT xstart
, INT ystart
, INT xend
, INT yend
)
78 static BOOL
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
nulldrv_CreateDC( PHYSDEV
*dev
, LPCWSTR device
, LPCWSTR output
,
85 const DEVMODEW
*devmode
)
87 assert(0); /* should never be called */
91 static BOOL
nulldrv_DeleteDC( PHYSDEV dev
)
93 assert(0); /* should never be called */
97 static BOOL
nulldrv_DeleteObject( PHYSDEV dev
, HGDIOBJ obj
)
102 static BOOL
nulldrv_Ellipse( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
107 static INT
nulldrv_EndDoc( PHYSDEV dev
)
112 static INT
nulldrv_EndPage( PHYSDEV dev
)
117 static BOOL
nulldrv_EnumFonts( PHYSDEV dev
, LOGFONTW
*logfont
, font_enum_proc proc
, LPARAM lParam
)
122 static INT
nulldrv_ExtEscape( PHYSDEV dev
, INT escape
, INT in_size
, const void *in_data
,
123 INT out_size
, void *out_data
)
128 static BOOL
nulldrv_ExtFloodFill( PHYSDEV dev
, INT x
, INT y
, COLORREF color
, UINT type
)
133 static BOOL
nulldrv_FontIsLinked( PHYSDEV dev
)
138 static UINT
nulldrv_GetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
143 static BOOL
nulldrv_GetCharABCWidths( PHYSDEV dev
, UINT first
, UINT count
, WCHAR
*chars
, ABC
*abc
)
148 static BOOL
nulldrv_GetCharABCWidthsI( PHYSDEV dev
, UINT first
, UINT count
, WORD
*indices
, LPABC abc
)
153 static BOOL
nulldrv_GetCharWidth( PHYSDEV dev
, UINT first
, UINT count
,
154 const WCHAR
*chars
, INT
*buffer
)
159 static BOOL
nulldrv_GetCharWidthInfo( PHYSDEV dev
, void *info
)
164 static INT
nulldrv_GetDeviceCaps( PHYSDEV dev
, INT cap
)
170 case DRIVERVERSION
: return 0x4000;
171 case TECHNOLOGY
: return DT_RASDISPLAY
;
172 case HORZSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
), 254,
173 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSX
) * 10 );
174 case VERTSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
), 254,
175 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSY
) * 10 );
178 DC
*dc
= get_nulldrv_dc( dev
);
184 rect
= get_display_rect( dc
->display
);
185 if (!IsRectEmpty( &rect
)) return rect
.right
- rect
.left
;
188 ret
= get_system_metrics( SM_CXSCREEN
);
189 return ret
? ret
: 640;
193 DC
*dc
= get_nulldrv_dc( dev
);
199 rect
= get_display_rect( dc
->display
);
200 if (!IsRectEmpty( &rect
)) return rect
.bottom
- rect
.top
;
203 ret
= get_system_metrics( SM_CYSCREEN
);
204 return ret
? ret
: 480;
208 UNICODE_STRING display
;
211 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
213 dc
= get_nulldrv_dc( dev
);
214 RtlInitUnicodeString( &display
, dc
->display
);
215 return get_display_depth( &display
);
219 case PLANES
: return 1;
220 case NUMBRUSHES
: return -1;
221 case NUMPENS
: return -1;
222 case NUMMARKERS
: return 0;
223 case NUMFONTS
: return 0;
224 case PDEVICESIZE
: return 0;
225 case CURVECAPS
: return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
226 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
227 case LINECAPS
: return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
228 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
229 case POLYGONALCAPS
: return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
230 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
231 case TEXTCAPS
: return (TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
232 TC_CR_ANY
| TC_SF_X_YINDEP
| TC_SA_DOUBLE
| TC_SA_INTEGER
|
233 TC_SA_CONTIN
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
| TC_VA_ABLE
);
234 case CLIPCAPS
: return CP_RECTANGLE
;
235 case RASTERCAPS
: return (RC_BITBLT
| RC_BITMAP64
| RC_GDI20_OUTPUT
| RC_DI_BITMAP
| RC_DIBTODEV
|
236 RC_BIGFONT
| RC_STRETCHBLT
| RC_FLOODFILL
| RC_STRETCHDIB
| RC_DEVBITS
|
237 (NtGdiGetDeviceCaps( dev
->hdc
, SIZEPALETTE
) ? RC_PALETTE
: 0));
238 case ASPECTX
: return 36;
239 case ASPECTY
: return 36;
240 case ASPECTXY
: return (int)(hypot( NtGdiGetDeviceCaps( dev
->hdc
, ASPECTX
),
241 NtGdiGetDeviceCaps( dev
->hdc
, ASPECTY
)) + 0.5);
242 case CAPS1
: return 0;
243 case SIZEPALETTE
: return 0;
244 case NUMRESERVED
: return 20;
245 case PHYSICALWIDTH
: return 0;
246 case PHYSICALHEIGHT
: return 0;
247 case PHYSICALOFFSETX
: return 0;
248 case PHYSICALOFFSETY
: return 0;
249 case SCALINGFACTORX
: return 0;
250 case SCALINGFACTORY
: return 0;
253 UNICODE_STRING display
;
257 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) != DT_RASDISPLAY
)
260 dc
= get_nulldrv_dc( dev
);
262 memset( &devmode
, 0, sizeof(devmode
) );
263 devmode
.dmSize
= sizeof(devmode
);
264 RtlInitUnicodeString( &display
, dc
->display
);
265 if (NtUserEnumDisplaySettings( &display
, ENUM_CURRENT_SETTINGS
, &devmode
, 0 ) &&
266 devmode
.dmDisplayFrequency
)
267 return devmode
.dmDisplayFrequency
;
271 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
273 RECT rect
= get_virtual_screen_rect( 0 );
274 return rect
.right
- rect
.left
;
276 return NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
);
278 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
280 RECT rect
= get_virtual_screen_rect( 0 );
281 return rect
.bottom
- rect
.top
;
283 return NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
);
284 case BLTALIGNMENT
: return 0;
285 case SHADEBLENDCAPS
: return 0;
286 case COLORMGMTCAPS
: return 0;
288 case LOGPIXELSY
: return get_system_dpi();
290 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
291 /* Newer versions of Windows return -1 for 8-bit and higher */
292 return (bpp
> 4) ? -1 : (1 << bpp
);
294 /* The observed correspondence between BITSPIXEL and COLORRES is:
295 * BITSPIXEL: 8 -> COLORRES: 18
296 * BITSPIXEL: 16 -> COLORRES: 16
297 * BITSPIXEL: 24 -> COLORRES: 24
298 * BITSPIXEL: 32 -> COLORRES: 24 */
299 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
300 return (bpp
<= 8) ? 18 : min( 24, bpp
);
302 FIXME("(%p): unsupported capability %d, will return 0\n", dev
->hdc
, cap
);
307 static BOOL
nulldrv_GetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
309 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
313 static DWORD
nulldrv_GetFontData( PHYSDEV dev
, DWORD table
, DWORD offset
, LPVOID buffer
, DWORD length
)
318 static BOOL
nulldrv_GetFontRealizationInfo( PHYSDEV dev
, void *info
)
323 static DWORD
nulldrv_GetFontUnicodeRanges( PHYSDEV dev
, LPGLYPHSET glyphs
)
328 static DWORD
nulldrv_GetGlyphIndices( PHYSDEV dev
, LPCWSTR str
, INT count
, LPWORD indices
, DWORD flags
)
333 static DWORD
nulldrv_GetGlyphOutline( PHYSDEV dev
, UINT ch
, UINT format
, LPGLYPHMETRICS metrics
,
334 DWORD size
, LPVOID buffer
, const MAT2
*mat
)
339 static BOOL
nulldrv_GetICMProfile( PHYSDEV dev
, BOOL allow_default
, LPDWORD size
, LPWSTR filename
)
344 static DWORD
nulldrv_GetImage( PHYSDEV dev
, BITMAPINFO
*info
, struct gdi_image_bits
*bits
,
345 struct bitblt_coords
*src
)
347 return ERROR_NOT_SUPPORTED
;
350 static DWORD
nulldrv_GetKerningPairs( PHYSDEV dev
, DWORD count
, LPKERNINGPAIR pairs
)
355 static UINT
nulldrv_GetOutlineTextMetrics( PHYSDEV dev
, UINT size
, LPOUTLINETEXTMETRICW otm
)
360 static UINT
nulldrv_GetTextCharsetInfo( PHYSDEV dev
, LPFONTSIGNATURE fs
, DWORD flags
)
362 return DEFAULT_CHARSET
;
365 static BOOL
nulldrv_GetTextExtentExPoint( PHYSDEV dev
, LPCWSTR str
, INT count
, INT
*dx
)
370 static BOOL
nulldrv_GetTextExtentExPointI( PHYSDEV dev
, const WORD
*indices
, INT count
, INT
*dx
)
375 static INT
nulldrv_GetTextFace( PHYSDEV dev
, INT size
, LPWSTR name
)
379 DC
*dc
= get_nulldrv_dc( dev
);
381 if (NtGdiExtGetObjectW( dc
->hFont
, sizeof(font
), &font
))
383 ret
= lstrlenW( font
.lfFaceName
) + 1;
386 lstrcpynW( name
, font
.lfFaceName
, size
);
387 ret
= min( size
, ret
);
393 static BOOL
nulldrv_GetTextMetrics( PHYSDEV dev
, TEXTMETRICW
*metrics
)
398 static BOOL
nulldrv_LineTo( PHYSDEV dev
, INT x
, INT y
)
403 static BOOL
nulldrv_MoveTo( PHYSDEV dev
, INT x
, INT y
)
408 static BOOL
nulldrv_PaintRgn( PHYSDEV dev
, HRGN rgn
)
413 static BOOL
nulldrv_PatBlt( PHYSDEV dev
, struct bitblt_coords
*dst
, DWORD rop
)
418 static BOOL
nulldrv_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
419 INT xstart
, INT ystart
, INT xend
, INT yend
)
424 static BOOL
nulldrv_PolyPolygon( PHYSDEV dev
, const POINT
*points
, const INT
*counts
, UINT polygons
)
429 static BOOL
nulldrv_PolyPolyline( PHYSDEV dev
, const POINT
*points
, const DWORD
*counts
, DWORD lines
)
434 static DWORD
nulldrv_PutImage( PHYSDEV dev
, HRGN clip
, BITMAPINFO
*info
,
435 const struct gdi_image_bits
*bits
, struct bitblt_coords
*src
,
436 struct bitblt_coords
*dst
, DWORD rop
)
438 return ERROR_SUCCESS
;
441 static UINT
nulldrv_RealizeDefaultPalette( PHYSDEV dev
)
446 static UINT
nulldrv_RealizePalette( PHYSDEV dev
, HPALETTE palette
, BOOL primary
)
451 static BOOL
nulldrv_Rectangle( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
456 static BOOL
nulldrv_ResetDC( PHYSDEV dev
, const DEVMODEW
*devmode
)
461 static BOOL
nulldrv_RoundRect( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
462 INT ell_width
, INT ell_height
)
467 static HBITMAP
nulldrv_SelectBitmap( PHYSDEV dev
, HBITMAP bitmap
)
472 static HBRUSH
nulldrv_SelectBrush( PHYSDEV dev
, HBRUSH brush
, const struct brush_pattern
*pattern
)
477 static HFONT
nulldrv_SelectFont( PHYSDEV dev
, HFONT font
, UINT
*aa_flags
)
482 static HPEN
nulldrv_SelectPen( PHYSDEV dev
, HPEN pen
, const struct brush_pattern
*pattern
)
487 static COLORREF
nulldrv_SetBkColor( PHYSDEV dev
, COLORREF color
)
492 static UINT
nulldrv_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
497 static COLORREF
nulldrv_SetDCBrushColor( PHYSDEV dev
, COLORREF color
)
502 static COLORREF
nulldrv_SetDCPenColor( PHYSDEV dev
, COLORREF color
)
507 static void nulldrv_SetDeviceClipping( PHYSDEV dev
, HRGN rgn
)
511 static BOOL
nulldrv_SetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
513 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
517 static COLORREF
nulldrv_SetPixel( PHYSDEV dev
, INT x
, INT y
, COLORREF color
)
522 static COLORREF
nulldrv_SetTextColor( PHYSDEV dev
, COLORREF color
)
527 static INT
nulldrv_StartDoc( PHYSDEV dev
, const DOCINFOW
*info
)
532 static INT
nulldrv_StartPage( PHYSDEV dev
)
537 static BOOL
nulldrv_UnrealizePalette( HPALETTE palette
)
542 static NTSTATUS
nulldrv_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
544 return STATUS_PROCEDURE_NOT_FOUND
;
547 static NTSTATUS
nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
549 return STATUS_PROCEDURE_NOT_FOUND
;
552 static NTSTATUS
nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
554 return STATUS_PROCEDURE_NOT_FOUND
;
557 static NTSTATUS
nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
559 return STATUS_PROCEDURE_NOT_FOUND
;
562 static NTSTATUS
nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
564 return STATUS_PROCEDURE_NOT_FOUND
;
567 const struct gdi_dc_funcs null_driver
=
569 nulldrv_AbortDoc
, /* pAbortDoc */
570 nulldrv_AbortPath
, /* pAbortPath */
571 nulldrv_AlphaBlend
, /* pAlphaBlend */
572 nulldrv_AngleArc
, /* pAngleArc */
573 nulldrv_Arc
, /* pArc */
574 nulldrv_ArcTo
, /* pArcTo */
575 nulldrv_BeginPath
, /* pBeginPath */
576 nulldrv_BlendImage
, /* pBlendImage */
577 nulldrv_Chord
, /* pChord */
578 nulldrv_CloseFigure
, /* pCloseFigure */
579 nulldrv_CreateCompatibleDC
, /* pCreateCompatibleDC */
580 nulldrv_CreateDC
, /* pCreateDC */
581 nulldrv_DeleteDC
, /* pDeleteDC */
582 nulldrv_DeleteObject
, /* pDeleteObject */
583 nulldrv_Ellipse
, /* pEllipse */
584 nulldrv_EndDoc
, /* pEndDoc */
585 nulldrv_EndPage
, /* pEndPage */
586 nulldrv_EndPath
, /* pEndPath */
587 nulldrv_EnumFonts
, /* pEnumFonts */
588 nulldrv_ExtEscape
, /* pExtEscape */
589 nulldrv_ExtFloodFill
, /* pExtFloodFill */
590 nulldrv_ExtTextOut
, /* pExtTextOut */
591 nulldrv_FillPath
, /* pFillPath */
592 nulldrv_FillRgn
, /* pFillRgn */
593 nulldrv_FontIsLinked
, /* pFontIsLinked */
594 nulldrv_FrameRgn
, /* pFrameRgn */
595 nulldrv_GetBoundsRect
, /* pGetBoundsRect */
596 nulldrv_GetCharABCWidths
, /* pGetCharABCWidths */
597 nulldrv_GetCharABCWidthsI
, /* pGetCharABCWidthsI */
598 nulldrv_GetCharWidth
, /* pGetCharWidth */
599 nulldrv_GetCharWidthInfo
, /* pGetCharWidthInfo */
600 nulldrv_GetDeviceCaps
, /* pGetDeviceCaps */
601 nulldrv_GetDeviceGammaRamp
, /* pGetDeviceGammaRamp */
602 nulldrv_GetFontData
, /* pGetFontData */
603 nulldrv_GetFontRealizationInfo
, /* pGetFontRealizationInfo */
604 nulldrv_GetFontUnicodeRanges
, /* pGetFontUnicodeRanges */
605 nulldrv_GetGlyphIndices
, /* pGetGlyphIndices */
606 nulldrv_GetGlyphOutline
, /* pGetGlyphOutline */
607 nulldrv_GetICMProfile
, /* pGetICMProfile */
608 nulldrv_GetImage
, /* pGetImage */
609 nulldrv_GetKerningPairs
, /* pGetKerningPairs */
610 nulldrv_GetNearestColor
, /* pGetNearestColor */
611 nulldrv_GetOutlineTextMetrics
, /* pGetOutlineTextMetrics */
612 nulldrv_GetPixel
, /* pGetPixel */
613 nulldrv_GetSystemPaletteEntries
, /* pGetSystemPaletteEntries */
614 nulldrv_GetTextCharsetInfo
, /* pGetTextCharsetInfo */
615 nulldrv_GetTextExtentExPoint
, /* pGetTextExtentExPoint */
616 nulldrv_GetTextExtentExPointI
, /* pGetTextExtentExPointI */
617 nulldrv_GetTextFace
, /* pGetTextFace */
618 nulldrv_GetTextMetrics
, /* pGetTextMetrics */
619 nulldrv_GradientFill
, /* pGradientFill */
620 nulldrv_InvertRgn
, /* pInvertRgn */
621 nulldrv_LineTo
, /* pLineTo */
622 nulldrv_MoveTo
, /* pMoveTo */
623 nulldrv_PaintRgn
, /* pPaintRgn */
624 nulldrv_PatBlt
, /* pPatBlt */
625 nulldrv_Pie
, /* pPie */
626 nulldrv_PolyBezier
, /* pPolyBezier */
627 nulldrv_PolyBezierTo
, /* pPolyBezierTo */
628 nulldrv_PolyDraw
, /* pPolyDraw */
629 nulldrv_PolyPolygon
, /* pPolyPolygon */
630 nulldrv_PolyPolyline
, /* pPolyPolyline */
631 nulldrv_PolylineTo
, /* pPolylineTo */
632 nulldrv_PutImage
, /* pPutImage */
633 nulldrv_RealizeDefaultPalette
, /* pRealizeDefaultPalette */
634 nulldrv_RealizePalette
, /* pRealizePalette */
635 nulldrv_Rectangle
, /* pRectangle */
636 nulldrv_ResetDC
, /* pResetDC */
637 nulldrv_RoundRect
, /* pRoundRect */
638 nulldrv_SelectBitmap
, /* pSelectBitmap */
639 nulldrv_SelectBrush
, /* pSelectBrush */
640 nulldrv_SelectFont
, /* pSelectFont */
641 nulldrv_SelectPen
, /* pSelectPen */
642 nulldrv_SetBkColor
, /* pSetBkColor */
643 nulldrv_SetBoundsRect
, /* pSetBoundsRect */
644 nulldrv_SetDCBrushColor
, /* pSetDCBrushColor */
645 nulldrv_SetDCPenColor
, /* pSetDCPenColor */
646 nulldrv_SetDIBitsToDevice
, /* pSetDIBitsToDevice */
647 nulldrv_SetDeviceClipping
, /* pSetDeviceClipping */
648 nulldrv_SetDeviceGammaRamp
, /* pSetDeviceGammaRamp */
649 nulldrv_SetPixel
, /* pSetPixel */
650 nulldrv_SetTextColor
, /* pSetTextColor */
651 nulldrv_StartDoc
, /* pStartDoc */
652 nulldrv_StartPage
, /* pStartPage */
653 nulldrv_StretchBlt
, /* pStretchBlt */
654 nulldrv_StretchDIBits
, /* pStretchDIBits */
655 nulldrv_StrokeAndFillPath
, /* pStrokeAndFillPath */
656 nulldrv_StrokePath
, /* pStrokePath */
657 nulldrv_UnrealizePalette
, /* pUnrealizePalette */
658 nulldrv_D3DKMTCheckVidPnExclusiveOwnership
, /* pD3DKMTCheckVidPnExclusiveOwnership */
659 nulldrv_D3DKMTCloseAdapter
, /* pD3DKMTCloseAdapter */
660 nulldrv_D3DKMTOpenAdapterFromLuid
, /* pD3DKMTOpenAdapterFromLuid */
661 nulldrv_D3DKMTQueryVideoMemoryInfo
, /* pD3DKMTQueryVideoMemoryInfo */
662 nulldrv_D3DKMTSetVidPnSourceOwner
, /* pD3DKMTSetVidPnSourceOwner */
664 GDI_PRIORITY_NULL_DRV
/* priority */
668 /**********************************************************************
671 * These are fallbacks for entry points that are not implemented in the real driver.
674 static BOOL
nulldrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
679 static void nulldrv_Beep(void)
683 static UINT
nulldrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
685 return ~0; /* use default implementation */
688 static INT
nulldrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
690 return -1; /* use default implementation */
693 static UINT
nulldrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
695 return -1; /* use default implementation */
698 static BOOL
nulldrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
703 static INT
nulldrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
704 int size
, UINT flags
, HKL layout
)
706 return -2; /* use default implementation */
709 static void nulldrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
713 static SHORT
nulldrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
715 return -256; /* use default implementation */
718 static UINT
nulldrv_ImeProcessKey( HIMC himc
, UINT wparam
, UINT lparam
, const BYTE
*state
)
723 static UINT
nulldrv_ImeToAsciiEx( UINT vkey
, UINT vsc
, const BYTE
*state
, COMPOSITIONSTRING
*compstr
, HIMC himc
)
728 static void nulldrv_NotifyIMEStatus( HWND hwnd
, UINT status
)
732 static LRESULT
nulldrv_DesktopWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
734 return default_window_proc( hwnd
, msg
, wparam
, lparam
, FALSE
);
737 static void nulldrv_DestroyCursorIcon( HCURSOR cursor
)
741 static void nulldrv_SetCursor( HWND hwnd
, HCURSOR cursor
)
745 static BOOL
nulldrv_GetCursorPos( LPPOINT pt
)
750 static BOOL
nulldrv_SetCursorPos( INT x
, INT y
)
755 static BOOL
nulldrv_ClipCursor( const RECT
*clip
, BOOL reset
)
760 static void nulldrv_UpdateClipboard(void)
764 static LONG
nulldrv_ChangeDisplaySettings( LPDEVMODEW displays
, LPCWSTR primary_name
, HWND hwnd
,
765 DWORD flags
, LPVOID lparam
)
767 return E_NOTIMPL
; /* use default implementation */
770 static BOOL
nulldrv_GetCurrentDisplaySettings( LPCWSTR name
, BOOL is_primary
, LPDEVMODEW mode
)
772 return FALSE
; /* use default implementation */
775 static INT
nulldrv_GetDisplayDepth( LPCWSTR name
, BOOL is_primary
)
777 return -1; /* use default implementation */
780 static BOOL
nulldrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
785 static BOOL
nulldrv_CreateDesktop( const WCHAR
*name
, UINT width
, UINT height
)
790 static BOOL
nodrv_CreateWindow( HWND hwnd
)
793 HWND parent
= NtUserGetAncestor( hwnd
, GA_PARENT
);
795 /* HWND_MESSAGE windows don't need a graphics driver */
796 if (!parent
|| parent
== UlongToHandle( NtUserGetThreadInfo()->msg_window
)) return TRUE
;
797 if (warned
++) return FALSE
;
799 ERR_(winediag
)( "Application tried to create a window, but no driver could be loaded.\n" );
800 if (driver_load_error
[0]) ERR_(winediag
)( "%s\n", debugstr_w(driver_load_error
) );
804 static BOOL
nulldrv_CreateWindow( HWND hwnd
)
809 static void nulldrv_DestroyWindow( HWND hwnd
)
813 static void nulldrv_FlashWindowEx( FLASHWINFO
*info
)
817 static void nulldrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
818 const RECT
*top_rect
, DWORD flags
)
822 static BOOL
nulldrv_ProcessEvents( DWORD mask
)
827 static void nulldrv_ReleaseDC( HWND hwnd
, HDC hdc
)
831 static BOOL
nulldrv_ScrollDC( HDC hdc
, INT dx
, INT dy
, HRGN update
)
835 NtGdiGetAppClipBox( hdc
, &rect
);
836 return NtGdiBitBlt( hdc
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
837 hdc
, rect
.left
- dx
, rect
.top
- dy
, SRCCOPY
, 0, 0 );
840 static void nulldrv_SetCapture( HWND hwnd
, UINT flags
)
844 static void nulldrv_SetDesktopWindow( HWND hwnd
)
848 static void nulldrv_SetFocus( HWND hwnd
)
852 static void nulldrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
856 static void nulldrv_SetParent( HWND hwnd
, HWND parent
, HWND old_parent
)
860 static void nulldrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
864 static void nulldrv_SetWindowIcon( HWND hwnd
, UINT type
, HICON icon
)
868 static void nulldrv_SetWindowStyle( HWND hwnd
, INT offset
, STYLESTRUCT
*style
)
872 static void nulldrv_SetWindowText( HWND hwnd
, LPCWSTR text
)
876 static UINT
nulldrv_ShowWindow( HWND hwnd
, INT cmd
, RECT
*rect
, UINT swp
)
878 return ~0; /* use default implementation */
881 static LRESULT
nulldrv_SysCommand( HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
886 static BOOL
nulldrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
887 const RECT
*window_rect
)
892 static LRESULT
nulldrv_WindowMessage( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
897 static BOOL
nulldrv_WindowPosChanging( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
898 const RECT
*window_rect
, const RECT
*client_rect
,
899 RECT
*visible_rect
, struct window_surface
**surface
)
904 static void nulldrv_WindowPosChanged( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
905 const RECT
*window_rect
, const RECT
*client_rect
,
906 const RECT
*visible_rect
, const RECT
*valid_rects
,
907 struct window_surface
*surface
)
911 static BOOL
nulldrv_SystemParametersInfo( UINT action
, UINT int_param
, void *ptr_param
, UINT flags
)
916 static const struct vulkan_funcs
*nulldrv_wine_get_vulkan_driver( UINT version
)
921 static struct opengl_funcs
*nulldrv_wine_get_wgl_driver( UINT version
)
926 static void nulldrv_ThreadDetach( void )
930 static const WCHAR guid_key_prefixW
[] =
932 '\\','R','e','g','i','s','t','r','y',
933 '\\','M','a','c','h','i','n','e',
934 '\\','S','y','s','t','e','m',
935 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
936 '\\','C','o','n','t','r','o','l',
937 '\\','V','i','d','e','o','\\','{'
939 static const WCHAR guid_key_suffixW
[] = {'}','\\','0','0','0','0'};
941 static BOOL
load_desktop_driver( HWND hwnd
)
943 static const WCHAR guid_nullW
[] = {'0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-',
944 '0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0',0};
945 WCHAR key
[ARRAYSIZE(guid_key_prefixW
) + 40 + ARRAYSIZE(guid_key_suffixW
)], *ptr
;
947 KEY_VALUE_PARTIAL_INFORMATION
*info
= (void *)buf
;
948 ATOM_BASIC_INFORMATION
*abi
= (ATOM_BASIC_INFORMATION
*)buf
;
954 static const WCHAR prop_nameW
[] =
955 {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_','d','e','v','i','c','e',
956 '_','g','u','i','d',0};
958 user_check_not_lock();
960 asciiz_to_unicode( driver_load_error
, "The explorer process failed to start." ); /* default error */
961 /* wait for graphics driver to be ready */
962 send_message( hwnd
, WM_NULL
, 0, 0 );
964 guid_atom
= HandleToULong( NtUserGetProp( hwnd
, prop_nameW
));
965 memcpy( key
, guid_key_prefixW
, sizeof(guid_key_prefixW
) );
966 ptr
= key
+ ARRAYSIZE(guid_key_prefixW
);
967 if (NtQueryInformationAtom( guid_atom
, AtomBasicInformation
, buf
, sizeof(buf
), NULL
))
969 wcscpy( ptr
, guid_nullW
);
970 ptr
+= ARRAY_SIZE(guid_nullW
) - 1;
974 memcpy( ptr
, abi
->Name
, abi
->NameLength
);
975 ptr
+= abi
->NameLength
/ sizeof(WCHAR
);
977 memcpy( ptr
, guid_key_suffixW
, sizeof(guid_key_suffixW
) );
978 ptr
+= ARRAY_SIZE(guid_key_suffixW
);
980 if (!(hkey
= reg_open_key( NULL
, key
, (ptr
- key
) * sizeof(WCHAR
) ))) return FALSE
;
982 if ((size
= query_reg_ascii_value( hkey
, "GraphicsDriver", info
, sizeof(buf
) )))
984 static const WCHAR nullW
[] = {'n','u','l','l',0};
985 TRACE( "trying driver %s\n", debugstr_wn( (const WCHAR
*)info
->Data
,
986 info
->DataLength
/ sizeof(WCHAR
) ));
987 if (info
->DataLength
!= sizeof(nullW
) || memcmp( info
->Data
, nullW
, sizeof(nullW
) ))
991 ret
= KeUserModeCallback( NtUserLoadDriver
, info
->Data
, info
->DataLength
,
992 &ret_ptr
, &ret_len
);
996 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
1000 else if ((size
= query_reg_ascii_value( hkey
, "DriverError", info
, sizeof(buf
) )))
1002 memcpy( driver_load_error
, info
->Data
, min( info
->DataLength
, sizeof(driver_load_error
) ));
1003 driver_load_error
[ARRAYSIZE(driver_load_error
) - 1] = 0;
1010 /**********************************************************************
1011 * Lazy loading user driver
1013 * Initial driver used before another driver is loaded.
1014 * Each entry point simply loads the real driver and chains to it.
1017 static const struct user_driver_funcs
*load_driver(void)
1019 USEROBJECTFLAGS flags
;
1022 if (!load_desktop_driver( get_desktop_window() ) || user_driver
== &lazy_load_driver
)
1024 winstation
= NtUserGetProcessWindowStation();
1025 if (!NtUserGetObjectInformation( winstation
, UOI_FLAGS
, &flags
, sizeof(flags
), NULL
)
1026 || (flags
.dwFlags
& WSF_VISIBLE
))
1027 null_user_driver
.pCreateWindow
= nodrv_CreateWindow
;
1029 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
1035 /**********************************************************************
1036 * get_display_driver
1038 const struct gdi_dc_funcs
*get_display_driver(void)
1040 if (user_driver
== &lazy_load_driver
) load_driver();
1041 return &user_driver
->dc_funcs
;
1044 static BOOL
loaderdrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
1046 return load_driver()->pActivateKeyboardLayout( layout
, flags
);
1049 static void loaderdrv_Beep(void)
1051 load_driver()->pBeep();
1054 static INT
loaderdrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
1056 return load_driver()->pGetKeyNameText( lparam
, buffer
, size
);
1059 static UINT
loaderdrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
1061 return load_driver()->pGetKeyboardLayoutList( size
, layouts
);
1064 static UINT
loaderdrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
1066 return load_driver()->pMapVirtualKeyEx( code
, type
, layout
);
1069 static INT
loaderdrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
1070 int size
, UINT flags
, HKL layout
)
1072 return load_driver()->pToUnicodeEx( virt
, scan
, state
, str
, size
, flags
, layout
);
1075 static BOOL
loaderdrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1077 return load_driver()->pRegisterHotKey( hwnd
, modifiers
, vk
);
1080 static void loaderdrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1082 load_driver()->pUnregisterHotKey( hwnd
, modifiers
, vk
);
1085 static SHORT
loaderdrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
1087 return load_driver()->pVkKeyScanEx( ch
, layout
);
1090 static UINT
loaderdrv_ImeProcessKey( HIMC himc
, UINT wparam
, UINT lparam
, const BYTE
*state
)
1092 return load_driver()->pImeProcessKey( himc
, wparam
, lparam
, state
);
1095 static UINT
loaderdrv_ImeToAsciiEx( UINT vkey
, UINT vsc
, const BYTE
*state
, COMPOSITIONSTRING
*compstr
, HIMC himc
)
1097 return load_driver()->pImeToAsciiEx( vkey
, vsc
, state
, compstr
, himc
);
1100 static void loaderdrv_NotifyIMEStatus( HWND hwnd
, UINT status
)
1102 return load_driver()->pNotifyIMEStatus( hwnd
, status
);
1105 static LONG
loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays
, LPCWSTR primary_name
, HWND hwnd
,
1106 DWORD flags
, LPVOID lparam
)
1108 return load_driver()->pChangeDisplaySettings( displays
, primary_name
, hwnd
, flags
, lparam
);
1111 static BOOL
loaderdrv_GetCurrentDisplaySettings( LPCWSTR name
, BOOL is_primary
, LPDEVMODEW mode
)
1113 return load_driver()->pGetCurrentDisplaySettings( name
, is_primary
, mode
);
1116 static INT
loaderdrv_GetDisplayDepth( LPCWSTR name
, BOOL is_primary
)
1118 return load_driver()->pGetDisplayDepth( name
, is_primary
);
1121 static void loaderdrv_SetCursor( HWND hwnd
, HCURSOR cursor
)
1123 load_driver()->pSetCursor( hwnd
, cursor
);
1126 static BOOL
loaderdrv_GetCursorPos( POINT
*pt
)
1128 return load_driver()->pGetCursorPos( pt
);
1131 static BOOL
loaderdrv_SetCursorPos( INT x
, INT y
)
1133 return load_driver()->pSetCursorPos( x
, y
);
1136 static BOOL
loaderdrv_ClipCursor( const RECT
*clip
, BOOL reset
)
1138 return load_driver()->pClipCursor( clip
, reset
);
1141 static LRESULT
nulldrv_ClipboardWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1146 static void loaderdrv_UpdateClipboard(void)
1148 load_driver()->pUpdateClipboard();
1151 static BOOL
loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
1153 return load_driver()->pUpdateDisplayDevices( manager
, force
, param
);
1156 static BOOL
loaderdrv_CreateDesktop( const WCHAR
*name
, UINT width
, UINT height
)
1158 return load_driver()->pCreateDesktop( name
, width
, height
);
1161 static BOOL
loaderdrv_CreateWindow( HWND hwnd
)
1163 return load_driver()->pCreateWindow( hwnd
);
1166 static void loaderdrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
1167 const RECT
*top_rect
, DWORD flags
)
1169 load_driver()->pGetDC( hdc
, hwnd
, top_win
, win_rect
, top_rect
, flags
);
1172 static void loaderdrv_FlashWindowEx( FLASHWINFO
*info
)
1174 load_driver()->pFlashWindowEx( info
);
1177 static void loaderdrv_SetDesktopWindow( HWND hwnd
)
1179 load_driver()->pSetDesktopWindow( hwnd
);
1182 static void loaderdrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
1184 load_driver()->pSetLayeredWindowAttributes( hwnd
, key
, alpha
, flags
);
1187 static void loaderdrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
1189 load_driver()->pSetWindowRgn( hwnd
, hrgn
, redraw
);
1192 static BOOL
loaderdrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
1193 const RECT
*window_rect
)
1195 return load_driver()->pUpdateLayeredWindow( hwnd
, info
, window_rect
);
1198 static const struct vulkan_funcs
* loaderdrv_wine_get_vulkan_driver( UINT version
)
1200 return load_driver()->pwine_get_vulkan_driver( version
);
1203 static const struct user_driver_funcs lazy_load_driver
=
1206 /* keyboard functions */
1207 loaderdrv_ActivateKeyboardLayout
,
1209 loaderdrv_GetKeyNameText
,
1210 loaderdrv_GetKeyboardLayoutList
,
1211 loaderdrv_MapVirtualKeyEx
,
1212 loaderdrv_RegisterHotKey
,
1213 loaderdrv_ToUnicodeEx
,
1214 loaderdrv_UnregisterHotKey
,
1215 loaderdrv_VkKeyScanEx
,
1216 loaderdrv_ImeProcessKey
,
1217 loaderdrv_ImeToAsciiEx
,
1218 loaderdrv_NotifyIMEStatus
,
1219 /* cursor/icon functions */
1220 nulldrv_DestroyCursorIcon
,
1221 loaderdrv_SetCursor
,
1222 loaderdrv_GetCursorPos
,
1223 loaderdrv_SetCursorPos
,
1224 loaderdrv_ClipCursor
,
1225 /* clipboard functions */
1226 nulldrv_ClipboardWindowProc
,
1227 loaderdrv_UpdateClipboard
,
1229 loaderdrv_ChangeDisplaySettings
,
1230 loaderdrv_GetCurrentDisplaySettings
,
1231 loaderdrv_GetDisplayDepth
,
1232 loaderdrv_UpdateDisplayDevices
,
1233 /* windowing functions */
1234 loaderdrv_CreateDesktop
,
1235 loaderdrv_CreateWindow
,
1236 nulldrv_DesktopWindowProc
,
1237 nulldrv_DestroyWindow
,
1238 loaderdrv_FlashWindowEx
,
1240 nulldrv_ProcessEvents
,
1244 loaderdrv_SetDesktopWindow
,
1246 loaderdrv_SetLayeredWindowAttributes
,
1248 loaderdrv_SetWindowRgn
,
1249 nulldrv_SetWindowIcon
,
1250 nulldrv_SetWindowStyle
,
1251 nulldrv_SetWindowText
,
1254 loaderdrv_UpdateLayeredWindow
,
1255 nulldrv_WindowMessage
,
1256 nulldrv_WindowPosChanging
,
1257 nulldrv_WindowPosChanged
,
1258 /* system parameters */
1259 nulldrv_SystemParametersInfo
,
1260 /* vulkan support */
1261 loaderdrv_wine_get_vulkan_driver
,
1262 /* opengl support */
1263 nulldrv_wine_get_wgl_driver
,
1264 /* thread management */
1265 nulldrv_ThreadDetach
,
1268 const struct user_driver_funcs
*user_driver
= &lazy_load_driver
;
1270 /******************************************************************************
1271 * __wine_set_user_driver (win32u.so)
1273 void __wine_set_user_driver( const struct user_driver_funcs
*funcs
, UINT version
)
1275 struct user_driver_funcs
*driver
, *prev
;
1277 if (version
!= WINE_GDI_DRIVER_VERSION
)
1279 ERR( "version mismatch, driver wants %u but win32u has %u\n",
1280 version
, WINE_GDI_DRIVER_VERSION
);
1284 driver
= malloc( sizeof(*driver
) );
1285 *driver
= funcs
? *funcs
: null_user_driver
;
1287 #define SET_USER_FUNC(name) \
1288 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
1290 SET_USER_FUNC(ActivateKeyboardLayout
);
1291 SET_USER_FUNC(Beep
);
1292 SET_USER_FUNC(GetKeyNameText
);
1293 SET_USER_FUNC(GetKeyboardLayoutList
);
1294 SET_USER_FUNC(MapVirtualKeyEx
);
1295 SET_USER_FUNC(RegisterHotKey
);
1296 SET_USER_FUNC(ToUnicodeEx
);
1297 SET_USER_FUNC(UnregisterHotKey
);
1298 SET_USER_FUNC(VkKeyScanEx
);
1299 SET_USER_FUNC(ImeProcessKey
);
1300 SET_USER_FUNC(ImeToAsciiEx
);
1301 SET_USER_FUNC(NotifyIMEStatus
);
1302 SET_USER_FUNC(DestroyCursorIcon
);
1303 SET_USER_FUNC(SetCursor
);
1304 SET_USER_FUNC(GetCursorPos
);
1305 SET_USER_FUNC(SetCursorPos
);
1306 SET_USER_FUNC(ClipCursor
);
1307 SET_USER_FUNC(ClipboardWindowProc
);
1308 SET_USER_FUNC(UpdateClipboard
);
1309 SET_USER_FUNC(ChangeDisplaySettings
);
1310 SET_USER_FUNC(GetCurrentDisplaySettings
);
1311 SET_USER_FUNC(GetDisplayDepth
);
1312 SET_USER_FUNC(UpdateDisplayDevices
);
1313 SET_USER_FUNC(CreateDesktop
);
1314 SET_USER_FUNC(CreateWindow
);
1315 SET_USER_FUNC(DesktopWindowProc
);
1316 SET_USER_FUNC(DestroyWindow
);
1317 SET_USER_FUNC(FlashWindowEx
);
1318 SET_USER_FUNC(GetDC
);
1319 SET_USER_FUNC(ProcessEvents
);
1320 SET_USER_FUNC(ReleaseDC
);
1321 SET_USER_FUNC(ScrollDC
);
1322 SET_USER_FUNC(SetCapture
);
1323 SET_USER_FUNC(SetDesktopWindow
);
1324 SET_USER_FUNC(SetFocus
);
1325 SET_USER_FUNC(SetLayeredWindowAttributes
);
1326 SET_USER_FUNC(SetParent
);
1327 SET_USER_FUNC(SetWindowRgn
);
1328 SET_USER_FUNC(SetWindowIcon
);
1329 SET_USER_FUNC(SetWindowStyle
);
1330 SET_USER_FUNC(SetWindowText
);
1331 SET_USER_FUNC(ShowWindow
);
1332 SET_USER_FUNC(SysCommand
);
1333 SET_USER_FUNC(UpdateLayeredWindow
);
1334 SET_USER_FUNC(WindowMessage
);
1335 SET_USER_FUNC(WindowPosChanging
);
1336 SET_USER_FUNC(WindowPosChanged
);
1337 SET_USER_FUNC(SystemParametersInfo
);
1338 SET_USER_FUNC(wine_get_vulkan_driver
);
1339 SET_USER_FUNC(wine_get_wgl_driver
);
1340 SET_USER_FUNC(ThreadDetach
);
1341 #undef SET_USER_FUNC
1343 prev
= InterlockedCompareExchangePointer( (void **)&user_driver
, driver
, (void *)&lazy_load_driver
);
1344 if (prev
!= &lazy_load_driver
)
1346 /* another thread beat us to it */
1352 /******************************************************************************
1353 * NtGdiExtEscape (win32u.@)
1355 * Access capabilities of a particular device that are not available through GDI.
1357 INT WINAPI
NtGdiExtEscape( HDC hdc
, WCHAR
*driver
, int driver_id
, INT escape
, INT input_size
,
1358 const char *input
, INT output_size
, char *output
)
1362 DC
* dc
= get_dc_ptr( hdc
);
1366 physdev
= GET_DC_PHYSDEV( dc
, pExtEscape
);
1367 ret
= physdev
->funcs
->pExtEscape( physdev
, escape
, input_size
, input
, output_size
, output
);
1368 release_dc_ptr( dc
);
1373 /******************************************************************************
1374 * NtGdiDdDDIOpenAdapterFromHdc (win32u.@)
1376 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC
*desc
)
1378 FIXME( "(%p): stub\n", desc
);
1379 return STATUS_NO_MEMORY
;
1382 /******************************************************************************
1383 * NtGdiDdDDIEscape (win32u.@)
1385 NTSTATUS WINAPI
NtGdiDdDDIEscape( const D3DKMT_ESCAPE
*desc
)
1387 FIXME( "(%p): stub\n", desc
);
1388 return STATUS_NO_MEMORY
;
1391 /******************************************************************************
1392 * NtGdiDdDDICloseAdapter (win32u.@)
1394 NTSTATUS WINAPI
NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
1396 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1397 struct d3dkmt_adapter
*adapter
;
1399 TRACE("(%p)\n", desc
);
1401 if (!desc
|| !desc
->hAdapter
)
1402 return STATUS_INVALID_PARAMETER
;
1404 if (get_display_driver()->pD3DKMTCloseAdapter
)
1405 get_display_driver()->pD3DKMTCloseAdapter( desc
);
1407 pthread_mutex_lock( &driver_lock
);
1408 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1410 if (adapter
->handle
== desc
->hAdapter
)
1412 list_remove( &adapter
->entry
);
1414 status
= STATUS_SUCCESS
;
1418 pthread_mutex_unlock( &driver_lock
);
1423 /******************************************************************************
1424 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
1426 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME
*desc
)
1428 D3DKMT_OPENADAPTERFROMLUID desc_luid
;
1431 FIXME( "desc %p stub.\n", desc
);
1433 if (!desc
|| !desc
->pDeviceName
) return STATUS_INVALID_PARAMETER
;
1435 memset( &desc_luid
, 0, sizeof( desc_luid
));
1436 if ((status
= NtGdiDdDDIOpenAdapterFromLuid( &desc_luid
))) return status
;
1438 desc
->AdapterLuid
= desc_luid
.AdapterLuid
;
1439 desc
->hAdapter
= desc_luid
.hAdapter
;
1440 return STATUS_SUCCESS
;
1443 /******************************************************************************
1444 * NtGdiDdDDIOpenAdapterFromLuid (win32u.@)
1446 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
1448 static D3DKMT_HANDLE handle_start
= 0;
1449 struct d3dkmt_adapter
*adapter
;
1451 if (!(adapter
= malloc( sizeof( *adapter
) ))) return STATUS_NO_MEMORY
;
1453 pthread_mutex_lock( &driver_lock
);
1454 desc
->hAdapter
= adapter
->handle
= ++handle_start
;
1455 list_add_tail( &d3dkmt_adapters
, &adapter
->entry
);
1456 pthread_mutex_unlock( &driver_lock
);
1458 if (get_display_driver()->pD3DKMTOpenAdapterFromLuid
)
1459 get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc
);
1461 return STATUS_SUCCESS
;
1464 /******************************************************************************
1465 * NtGdiDdDDICreateDevice (win32u.@)
1467 NTSTATUS WINAPI
NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE
*desc
)
1469 static D3DKMT_HANDLE handle_start
= 0;
1470 struct d3dkmt_adapter
*adapter
;
1471 struct d3dkmt_device
*device
;
1474 TRACE("(%p)\n", desc
);
1477 return STATUS_INVALID_PARAMETER
;
1479 pthread_mutex_lock( &driver_lock
);
1480 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1482 if (adapter
->handle
== desc
->hAdapter
)
1488 pthread_mutex_unlock( &driver_lock
);
1491 return STATUS_INVALID_PARAMETER
;
1493 if (desc
->Flags
.LegacyMode
|| desc
->Flags
.RequestVSync
|| desc
->Flags
.DisableGpuTimeout
)
1494 FIXME("Flags unsupported.\n");
1496 device
= calloc( 1, sizeof( *device
) );
1498 return STATUS_NO_MEMORY
;
1500 pthread_mutex_lock( &driver_lock
);
1501 device
->handle
= ++handle_start
;
1502 list_add_tail( &d3dkmt_devices
, &device
->entry
);
1503 pthread_mutex_unlock( &driver_lock
);
1505 desc
->hDevice
= device
->handle
;
1506 return STATUS_SUCCESS
;
1509 /******************************************************************************
1510 * NtGdiDdDDIDestroyDevice (win32u.@)
1512 NTSTATUS WINAPI
NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE
*desc
)
1514 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1515 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc
;
1516 struct d3dkmt_device
*device
;
1518 TRACE("(%p)\n", desc
);
1520 if (!desc
|| !desc
->hDevice
)
1521 return STATUS_INVALID_PARAMETER
;
1523 pthread_mutex_lock( &driver_lock
);
1524 LIST_FOR_EACH_ENTRY( device
, &d3dkmt_devices
, struct d3dkmt_device
, entry
)
1526 if (device
->handle
== desc
->hDevice
)
1528 memset( &set_owner_desc
, 0, sizeof(set_owner_desc
) );
1529 set_owner_desc
.hDevice
= desc
->hDevice
;
1530 NtGdiDdDDISetVidPnSourceOwner( &set_owner_desc
);
1531 list_remove( &device
->entry
);
1533 status
= STATUS_SUCCESS
;
1537 pthread_mutex_unlock( &driver_lock
);
1542 /******************************************************************************
1543 * NtGdiDdDDIQueryAdapterInfo (win32u.@)
1545 NTSTATUS WINAPI
NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO
*desc
)
1548 return STATUS_INVALID_PARAMETER
;
1550 FIXME("desc %p, type %d stub\n", desc
, desc
->Type
);
1551 return STATUS_NOT_IMPLEMENTED
;
1554 /******************************************************************************
1555 * NtGdiDdDDIQueryStatistics (win32u.@)
1557 NTSTATUS WINAPI
NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS
*stats
)
1559 FIXME("(%p): stub\n", stats
);
1560 return STATUS_SUCCESS
;
1563 /******************************************************************************
1564 * NtGdiDdDDIQueryVideoMemoryInfo (win32u.@)
1566 NTSTATUS WINAPI
NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
1568 OBJECT_BASIC_INFORMATION info
;
1571 TRACE("(%p)\n", desc
);
1573 if (!desc
|| !desc
->hAdapter
||
1574 (desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL
&&
1575 desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL
))
1576 return STATUS_INVALID_PARAMETER
;
1578 /* FIXME: Wine currently doesn't support linked adapters */
1579 if (desc
->PhysicalAdapterIndex
> 0)
1580 return STATUS_INVALID_PARAMETER
;
1582 status
= NtQueryObject(desc
->hProcess
? desc
->hProcess
: GetCurrentProcess(),
1583 ObjectBasicInformation
, &info
, sizeof(info
), NULL
);
1584 if (status
!= STATUS_SUCCESS
)
1586 if (!(info
.GrantedAccess
& PROCESS_QUERY_INFORMATION
))
1587 return STATUS_ACCESS_DENIED
;
1589 if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo
)
1590 return STATUS_PROCEDURE_NOT_FOUND
;
1591 return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc
);
1594 /******************************************************************************
1595 * NtGdiDdDDISetQueuedLimit (win32u.@)
1597 NTSTATUS WINAPI
NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT
*desc
)
1599 FIXME( "(%p): stub\n", desc
);
1600 return STATUS_NOT_IMPLEMENTED
;
1603 /******************************************************************************
1604 * NtGdiDdDDISetVidPnSourceOwner (win32u.@)
1606 NTSTATUS WINAPI
NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
1608 TRACE("(%p)\n", desc
);
1610 if (!get_display_driver()->pD3DKMTSetVidPnSourceOwner
)
1611 return STATUS_PROCEDURE_NOT_FOUND
;
1613 if (!desc
|| !desc
->hDevice
|| (desc
->VidPnSourceCount
&& (!desc
->pType
|| !desc
->pVidPnSourceId
)))
1614 return STATUS_INVALID_PARAMETER
;
1616 /* Store the VidPN source ownership info in the graphics driver because
1617 * the graphics driver needs to change ownership sometimes. For example,
1618 * when a new window is moved to a VidPN source with an exclusive owner,
1619 * such an exclusive owner will be released before showing the new window */
1620 return get_display_driver()->pD3DKMTSetVidPnSourceOwner( desc
);
1623 /******************************************************************************
1624 * NtGdiDdDDICheckVidPnExclusiveOwnership (win32u.@)
1626 NTSTATUS WINAPI
NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
1628 TRACE("(%p)\n", desc
);
1630 if (!get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership
)
1631 return STATUS_PROCEDURE_NOT_FOUND
;
1633 if (!desc
|| !desc
->hAdapter
)
1634 return STATUS_INVALID_PARAMETER
;
1636 return get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership( desc
);