This primary adapter key aims to replace the Atom mechanism currently used to store what registry key the primary adapter is using. This way we can let user drivers create the GUIDs for adapters if it's supported without treating primary adapter differently.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v2: Fix tests. Supersede 160033~160039.
dlls/user32/tests/monitor.c | 4 +-- programs/explorer/desktop.c | 64 ++++++++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 8bf284a5e1..4f7e4c2287 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -107,7 +107,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de { sprintf(video_name, "\Device\Video%d", index); ls = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\DEVICEMAP\VIDEO", 0, KEY_READ, &hkey); - todo_wine ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls); + ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls); if (!ls) { memset(video_value, 0, sizeof(video_value)); @@ -115,7 +115,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de ls = RegQueryValueExA(hkey, video_name, NULL, NULL, (unsigned char *)video_value, &size); ok(!ls, "#%d: failed to get registry value, error: %#x\n", index, ls); RegCloseKey(hkey); - ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey); + todo_wine ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey); } } else diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 27b9b24901..97fc7a219d 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -775,6 +775,13 @@ static BOOL get_default_enable_shell( const WCHAR *name )
static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) { + static const WCHAR video_keyW[] = {'H','A','R','D','W','A','R','E','\', + 'D','E','V','I','C','E','M','A','P','\', + 'V','I','D','E','O',0}; + static const WCHAR device_video0W[] = {'\','D','e','v','i','c','e','\', + 'V','i','d','e','o','0',0}; + static const WCHAR device_video_prefixW[] = {'\','R','e','g','i','s','t','r','y','\', + 'M','a','c','h','i','n','e','\',0}; static const WCHAR device_keyW[] = { 'S','y','s','t','e','m','\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\', @@ -793,6 +800,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) WCHAR key[ARRAY_SIZE( device_keyW ) + 39]; HMODULE module = 0; HKEY hkey; + DWORD disposition = 0; char error[80];
if (!driver) @@ -832,25 +840,51 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) name = next; }
- if (module) + /* Create HKLM\HARDWARE\DEVICEMAP\VIDEO key if user drivers didn't do it */ + if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, + &disposition )) { - GetModuleFileNameW( module, buffer, MAX_PATH ); - TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) ); - } + /* User driver did create it. Nothing to do */ + if (disposition != REG_CREATED_NEW_KEY) + { + RegCloseKey( hkey ); + return module; + }
- sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); + sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); + + strcpyW( buffer, device_video_prefixW ); + strcatW( buffer, key); + + TRACE( "primary adapter key %s\n", wine_dbgstr_w(buffer) ); + /* Set \Device\Video0 value data in HKLM\HARDWARE\DEVICEMAP\VIDEO key */ + if (RegSetValueExW( hkey, device_video0W, 0, REG_SZ, + (const BYTE *)(buffer), (strlenW( buffer ) + 1) * sizeof(WCHAR)) ) + { + ERR("Failed to set primary video value, display related functions may not function properly\n"); + RegCloseKey( hkey ); + return module; + }
- if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL, - REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL )) - { - if (module) - RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ, - (BYTE *)buffer, (strlenW(buffer) + 1) * sizeof(WCHAR) ); - else - RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 ); RegCloseKey( hkey ); + + /* Create primary adapter key SYSTEM\CurrentControlSet\Control\Video{Primary adapter GUID}\0000 */ + if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL, + REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL )) + { + if (module) + { + GetModuleFileNameW( module, buffer, MAX_PATH ); + TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) ); + RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ, + (BYTE *)buffer, (strlenW( buffer ) + 1) * sizeof(WCHAR) ); + } + else + RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen( error ) + 1 ); + RegCloseKey( hkey ); + } }
return module;
Zhiyi Zhang zzhang@codeweavers.com writes:
This primary adapter key aims to replace the Atom mechanism currently used to store what registry key the primary adapter is using. This way we can let user drivers create the GUIDs for adapters if it's supported without treating primary adapter differently.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
How is this going to handle multiple explorer processes, potentially using different drivers?
On 08/03/2019 02:11, Alexandre Julliard wrote:
Zhiyi Zhang zzhang@codeweavers.com writes:
This primary adapter key aims to replace the Atom mechanism currently used to store what registry key the primary adapter is using. This way we can let user drivers create the GUIDs for adapters if it's supported without treating primary adapter differently.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
How is this going to handle multiple explorer processes, potentially using different drivers?
I did assume explorer are all using the same driver when running on a platform.
Could you give some examples on why using different drivers with multiple explorer is necessary?
If we insist on running different user display drivers at the same time, there will be conflicts on the registry, making it difficult to get a coherent view of the registry, say when enumerating adapters via SetupAPI.
If it's for other reasons. I think we can still keep the current graphics driver in explorer hwnd. Most of the time other code query the explorer hwnd just for which graphics driver is used. They don't really need the adapter key.
On 08/03/2019 10:42, Zhiyi Zhang wrote:
On 08/03/2019 02:11, Alexandre Julliard wrote:
Zhiyi Zhang zzhang@codeweavers.com writes:
This primary adapter key aims to replace the Atom mechanism currently used to store what registry key the primary adapter is using. This way we can let user drivers create the GUIDs for adapters if it's supported without treating primary adapter differently.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
How is this going to handle multiple explorer processes, potentially using different drivers?
I did assume explorer are all using the same driver when running on a platform.
Could you give some examples on why using different drivers with multiple explorer is necessary?
If we insist on running different user display drivers at the same time, there will be conflicts on the registry, making it difficult to get a coherent view of the registry, say when enumerating adapters via SetupAPI.
If it's for other reasons. I think we can still keep the current graphics driver in explorer hwnd. Most of the time other code query the explorer hwnd just for which graphics driver is used. They don't really need the adapter key.
I should have mentioned this earlier. I put a repo at https://github.com/zzhiyi/wine/commits/user32/EnumDisplayDevices.
It should give some context regarding recent graphics driver changes. Comments are very appreciated.
Zhiyi Zhang zzhang@codeweavers.com writes:
On 08/03/2019 02:11, Alexandre Julliard wrote:
Zhiyi Zhang zzhang@codeweavers.com writes:
This primary adapter key aims to replace the Atom mechanism currently used to store what registry key the primary adapter is using. This way we can let user drivers create the GUIDs for adapters if it's supported without treating primary adapter differently.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
How is this going to handle multiple explorer processes, potentially using different drivers?
I did assume explorer are all using the same driver when running on a platform.
Could you give some examples on why using different drivers with multiple explorer is necessary?
If we insist on running different user display drivers at the same time, there will be conflicts on the registry, making it difficult to get a coherent view of the registry, say when enumerating adapters via SetupAPI.
You can use the Mac driver and the X11 driver at the same time for instance. This can be necessary if you want to run an app remotely.
Also desktop mode requires multiple explorer instances, and presumably multiple adapters, even with the same driver. Also you can run multiple X11 explorer sessions connected to different remote displays. You can't assume that the adapters are limited to the physical adapters of the local display.