On Windows, GdiEntry13 is used by WPF (wpfgfx_v0400.dll) to obtain an IDirect3D9 object via GetProcAddress(gdi32, "GdiEntry13"). WPF expects the return value to be an IDirect3D9 pointer, equivalent to calling Direct3DCreate9(D3D_SDK_VERSION). The previous implementation mapped GdiEntry13 to a stub of DdQueryDisplaySettingsUniqueness that always returned 0, causing WPF to fail to initialize its rendering pipeline and resulting in black or missing windows for all WPF applications running under Wine. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59634 --- dlls/gdi32/dc.c | 36 ++++++++++++++++++++++++++++++++---- include/ddrawgdi.h | 2 +- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index adfcd51..4b453dd 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -2709,15 +2709,43 @@ INT WINAPI NamedEscape( HDC hdc, const WCHAR *driver, INT escape, INT input_size return 0; } +typedef void * (WINAPI *Direct3DCreate9_func)(UINT); +static Direct3DCreate9_func pDirect3DCreate9; + +static BOOL WINAPI init_d3d9( INIT_ONCE *once, void *param, void **context ) +{ + HMODULE d3d9_module = LoadLibraryW( L"d3d9.dll" ); + if (d3d9_module) + pDirect3DCreate9 = (Direct3DCreate9_func)GetProcAddress( d3d9_module, "Direct3DCreate9" ); + if (!pDirect3DCreate9) + WARN( "Failed to load d3d9.dll or find Direct3DCreate9\n" ); + return TRUE; +} + /******************************************************************* * DdQueryDisplaySettingsUniqueness (GDI32.@) * GdiEntry13 + * + * On Windows, GdiEntry13 is used by WPF (wpfgfx_v0400.dll) to obtain + * an IDirect3D9 object. WPF calls GetProcAddress(gdi32, "GdiEntry13") + * and expects the return value to be an IDirect3D9 pointer, equivalent + * to calling Direct3DCreate9(D3D_SDK_VERSION). + * + * The original DdQueryDisplaySettingsUniqueness stub returned 0 (NULL), + * causing WPF to fail to initialize its rendering pipeline. */ -ULONG WINAPI DdQueryDisplaySettingsUniqueness(void) +void * WINAPI DdQueryDisplaySettingsUniqueness(void) { - static int warn_once; - if (!warn_once++) FIXME( "stub\n" ); - return 0; + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + + TRACE( "\n" ); + + InitOnceExecuteOnce( &init_once, init_d3d9, NULL, NULL ); + + if (pDirect3DCreate9) + return pDirect3DCreate9( 32 /* D3D_SDK_VERSION */ ); + + return NULL; } /******************************************************************* diff --git a/include/ddrawgdi.h b/include/ddrawgdi.h index 4b78702..c0893b9 100644 --- a/include/ddrawgdi.h +++ b/include/ddrawgdi.h @@ -27,7 +27,7 @@ extern "C" { #define DdQueryDisplaySettingsUniqueness GdiEntry13 -ULONG APIENTRY DdQueryDisplaySettingsUniqueness(void); +void * APIENTRY DdQueryDisplaySettingsUniqueness(void); #ifdef __cplusplus } -- 2.53.0