user32: Allow using null driver as a normal graphics driver.

When explicitly requested by config, Wine will use null driver in the
same way as we allow using it for invisible winstations.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-02-11 20:45:27 +01:00 committed by Alexandre Julliard
parent c2679945dd
commit beaef92010
2 changed files with 26 additions and 17 deletions

View File

@ -41,7 +41,7 @@ static char driver_load_error[80];
static BOOL CDECL nodrv_CreateWindow( HWND hwnd ); static BOOL CDECL nodrv_CreateWindow( HWND hwnd );
static HMODULE load_desktop_driver( HWND hwnd ) static BOOL load_desktop_driver( HWND hwnd, HMODULE *module )
{ {
static const WCHAR display_device_guid_propW[] = { static const WCHAR display_device_guid_propW[] = {
'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_', '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
@ -53,7 +53,8 @@ static HMODULE load_desktop_driver( HWND hwnd )
'V','i','d','e','o','\\','{',0}; 'V','i','d','e','o','\\','{',0};
static const WCHAR displayW[] = {'}','\\','0','0','0','0',0}; static const WCHAR displayW[] = {'}','\\','0','0','0','0',0};
static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0}; static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
HMODULE ret = 0; static const WCHAR nullW[] = {'n','u','l','l',0};
BOOL ret = FALSE;
HKEY hkey; HKEY hkey;
DWORD size; DWORD size;
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
@ -76,8 +77,9 @@ static HMODULE load_desktop_driver( HWND hwnd )
size = sizeof(path); size = sizeof(path);
if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size ))
{ {
if (!(ret = LoadLibraryW( path ))) ERR( "failed to load %s\n", debugstr_w(path) ); ret = !strcmpW( path, nullW ) || (*module = LoadLibraryW( path ));
TRACE( "%s %p\n", debugstr_w(path), ret ); if (!ret) ERR( "failed to load %s\n", debugstr_w(path) );
TRACE( "%s %p\n", debugstr_w(path), *module );
} }
else else
{ {
@ -98,8 +100,17 @@ static const USER_DRIVER *load_driver(void)
driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) ); driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) );
*driver = null_driver; *driver = null_driver;
graphics_driver = load_desktop_driver( GetDesktopWindow() ); if (!load_desktop_driver( GetDesktopWindow(), &graphics_driver ))
if (graphics_driver) {
USEROBJECTFLAGS flags;
HWINSTA winstation;
winstation = GetProcessWindowStation();
if (!GetUserObjectInformationA(winstation, UOI_FLAGS, &flags, sizeof(flags), NULL)
|| (flags.dwFlags & WSF_VISIBLE))
driver->pCreateWindow = nodrv_CreateWindow;
}
else if (graphics_driver)
{ {
#define GET_USER_FUNC(name) \ #define GET_USER_FUNC(name) \
do { if ((ptr = GetProcAddress( graphics_driver, #name ))) driver->p##name = ptr; } while(0) do { if ((ptr = GetProcAddress( graphics_driver, #name ))) driver->p##name = ptr; } while(0)
@ -153,16 +164,6 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC(ThreadDetach); GET_USER_FUNC(ThreadDetach);
#undef GET_USER_FUNC #undef GET_USER_FUNC
} }
else
{
USEROBJECTFLAGS flags;
HWINSTA winstation;
winstation = GetProcessWindowStation();
if (!GetUserObjectInformationA(winstation, UOI_FLAGS, &flags, sizeof(flags), NULL)
|| (flags.dwFlags & WSF_VISIBLE))
driver->pCreateWindow = nodrv_CreateWindow;
}
prev = InterlockedCompareExchangePointer( (void **)&USER_Driver, driver, &lazy_load_driver ); prev = InterlockedCompareExchangePointer( (void **)&USER_Driver, driver, &lazy_load_driver );
if (prev != &lazy_load_driver) if (prev != &lazy_load_driver)

View File

@ -766,6 +766,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
WCHAR buffer[MAX_PATH], libname[32], *name, *next; WCHAR buffer[MAX_PATH], libname[32], *name, *next;
WCHAR key[ARRAY_SIZE( device_keyW ) + 39]; WCHAR key[ARRAY_SIZE( device_keyW ) + 39];
BOOL null_driver = FALSE;
HMODULE module = 0; HMODULE module = 0;
HKEY hkey; HKEY hkey;
char error[80]; char error[80];
@ -790,6 +791,13 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
next = wcschr( name, ',' ); next = wcschr( name, ',' );
if (next) *next++ = 0; if (next) *next++ = 0;
if (!wcscmp( name, L"null" ))
{
TRACE( "display %s using null driver\n", debugstr_guid(guid) );
null_driver = TRUE;
break;
}
swprintf( libname, ARRAY_SIZE( libname ), drv_formatW, name ); swprintf( libname, ARRAY_SIZE( libname ), drv_formatW, name );
if ((module = LoadLibraryW( libname )) != 0) break; if ((module = LoadLibraryW( libname )) != 0) break;
switch (GetLastError()) switch (GetLastError())
@ -820,7 +828,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL, if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL )) REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL ))
{ {
if (module) if (module || null_driver)
RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ, RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ,
(BYTE *)buffer, (lstrlenW(buffer) + 1) * sizeof(WCHAR) ); (BYTE *)buffer, (lstrlenW(buffer) + 1) * sizeof(WCHAR) );
else else