From: "Rémi Bernon" Subject: [PATCH v2 5/5] win32u: Move writing mode to registry out of graphics drivers. Message-Id: Date: Fri, 01 Jul 2022 09:50:06 +0000 In-Reply-To: References: From: Rémi Bernon Signed-off-by: Rémi Bernon --- dlls/win32u/sysparams.c | 52 +++++++++++++++++++ dlls/winemac.drv/display.c | 102 +------------------------------------ dlls/winex11.drv/display.c | 92 +-------------------------------- 3 files changed, 54 insertions(+), 192 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ccc2351c310..ef71b9d0581 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -408,6 +408,35 @@ static void release_display_device_init_mutex( HANDLE mutex ) NtClose( mutex ); } +static BOOL write_adapter_mode( HKEY adapter_key, const DEVMODEW *mode ) +{ + static const WCHAR default_settingsW[] = {'D','e','f','a','u','l','t','S','e','t','t','i','n','g','s','.',0}; + WCHAR bufferW[MAX_PATH]; + +#define set_mode_field( name, field, flag ) \ + do \ + { \ + lstrcpyW( bufferW, default_settingsW ); \ + lstrcatW( bufferW, (name) ); \ + if (mode->dmFields & (flag)) \ + set_reg_value( adapter_key, (name), REG_DWORD, &mode->field, sizeof(mode->field) ); \ + } while (0) + + set_mode_field( bits_per_pelW, dmBitsPerPel, DM_BITSPERPEL ); + set_mode_field( x_resolutionW, dmPelsWidth, DM_PELSWIDTH ); + set_mode_field( y_resolutionW, dmPelsHeight, DM_PELSHEIGHT ); + set_mode_field( v_refreshW, dmDisplayFrequency, DM_DISPLAYFREQUENCY ); + set_mode_field( flagsW, dmDisplayFlags, DM_DISPLAYFLAGS ); + set_mode_field( orientationW, dmDisplayOrientation, DM_DISPLAYORIENTATION ); + set_mode_field( fixed_outputW, dmDisplayFixedOutput, DM_DISPLAYFIXEDOUTPUT ); + set_mode_field( x_panningW, dmPosition.x, DM_POSITION ); + set_mode_field( y_panningW, dmPosition.y, DM_POSITION ); + +#undef set_mode_field + + return TRUE; +} + static BOOL read_adapter_mode( HKEY adapter_key, DEVMODEW *mode ) { static const WCHAR default_settingsW[] = {'D','e','f','a','u','l','t','S','e','t','t','i','n','g','s','.',0}; @@ -463,6 +492,26 @@ static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode ) return ret; } +static BOOL write_registry_settings( const WCHAR *adapter_path, const DEVMODEW *mode ) +{ + HANDLE mutex; + HKEY hkey; + BOOL ret; + + mutex = get_display_device_init_mutex(); + + if (!config_key && !(config_key = reg_open_key( NULL, config_keyW, sizeof(config_keyW) ))) ret = FALSE; + if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) ))) ret = FALSE; + else + { + ret = write_adapter_mode( hkey, mode ); + NtClose( hkey ); + } + + release_display_device_init_mutex( mutex ); + return ret; +} + static BOOL read_display_adapter_settings( unsigned int index, struct adapter *info ) { char buffer[4096]; @@ -1944,6 +1993,9 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0; if (!(devmode = validate_display_settings( &default_mode, ¤t_mode, devmode ))) ret = DISP_CHANGE_BADMODE; + else if (user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags | CDS_TEST, lparam )) ret = DISP_CHANGE_BADMODE; + else if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings( adapter_path, devmode )) ret = DISP_CHANGE_NOTUPDATED; + else if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; else ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam ); if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret ); diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 6444f7bef30..55f95af4e39 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -79,100 +79,6 @@ static void release_display_device_init_mutex(HANDLE mutex) NtClose(mutex); } -static HKEY get_display_device_reg_key(const WCHAR *device_name) -{ - static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'}; - static const WCHAR video_key[] = { - '\\','R','e','g','i','s','t','r','y', - '\\','M','a','c','h','i','n','e', - '\\','H','A','R','D','W','A','R','E', - '\\','D','E','V','I','C','E','M','A','P', - '\\','V','I','D','E','O'}; - static const WCHAR current_config_key[] = { - '\\','R','e','g','i','s','t','r','y', - '\\','M','a','c','h','i','n','e', - '\\','S','y','s','t','e','m', - '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', - '\\','H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s', - '\\','C','u','r','r','e','n','t'}; - WCHAR value_name[MAX_PATH], buffer[4096], *end_ptr; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - DWORD adapter_index, size; - char adapter_name[100]; - HKEY hkey; - - /* Device name has to be \\.\DISPLAY%d */ - if (wcsnicmp(device_name, display, ARRAY_SIZE(display))) - return FALSE; - - /* Parse \\.\DISPLAY* */ - adapter_index = wcstol(device_name + ARRAY_SIZE(display), &end_ptr, 10) - 1; - if (*end_ptr) - return FALSE; - - /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */ - if (!(hkey = reg_open_key(NULL, video_key, sizeof(video_key)))) return FALSE; - sprintf(adapter_name, "\\Device\\Video%d", adapter_index); - asciiz_to_unicode(value_name, adapter_name); - size = query_reg_value(hkey, value_name, value, sizeof(buffer)); - NtClose(hkey); - if (!size || value->Type != REG_SZ) return FALSE; - - /* Replace \Registry\Machine\ prefix with HKEY_CURRENT_CONFIG */ - memmove(buffer + ARRAYSIZE(current_config_key), (const WCHAR *)value->Data + 17, - size - 17 * sizeof(WCHAR)); - memcpy(buffer, current_config_key, sizeof(current_config_key)); - TRACE("display device %s registry settings key %s.\n", wine_dbgstr_w(device_name), - wine_dbgstr_w(buffer)); - return reg_open_key(NULL, buffer, lstrlenW(buffer) * sizeof(WCHAR)); -} - - -static BOOL query_display_setting(HKEY hkey, const char *name, DWORD *ret) -{ - char buffer[1024]; - WCHAR nameW[128]; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - - asciiz_to_unicode(nameW, name); - if (query_reg_value(hkey, nameW, value, sizeof(buffer)) != sizeof(DWORD) || - value->Type != REG_DWORD) - return FALSE; - - *ret = *(DWORD *)value->Data; - return TRUE; -} - - -static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm) -{ - HANDLE mutex; - HKEY hkey; - BOOL ret = TRUE; - - mutex = get_display_device_init_mutex(); - if (!(hkey = get_display_device_reg_key(device_name))) - { - release_display_device_init_mutex(mutex); - return FALSE; - } - - ret &= set_setting_value(hkey, "DefaultSettings.BitsPerPel", dm->dmBitsPerPel); - ret &= set_setting_value(hkey, "DefaultSettings.XResolution", dm->dmPelsWidth); - ret &= set_setting_value(hkey, "DefaultSettings.YResolution", dm->dmPelsHeight); - ret &= set_setting_value(hkey, "DefaultSettings.VRefresh", dm->dmDisplayFrequency); - ret &= set_setting_value(hkey, "DefaultSettings.Flags", dm->dmDisplayFlags); - ret &= set_setting_value(hkey, "DefaultSettings.XPanning", dm->dmPosition.x); - ret &= set_setting_value(hkey, "DefaultSettings.YPanning", dm->dmPosition.y); - ret &= set_setting_value(hkey, "DefaultSettings.Orientation", dm->dmDisplayOrientation); - ret &= set_setting_value(hkey, "DefaultSettings.FixedOutput", dm->dmDisplayFixedOutput); - - NtClose(hkey); - release_display_device_init_mutex(mutex); - return ret; -} - - static BOOL write_display_settings(HKEY parent_hkey, CGDirectDisplayID displayID) { BOOL ret = FALSE; @@ -942,13 +848,7 @@ better: /* we have a valid mode */ TRACE("Requested display settings match mode %ld\n", best); - if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devname, devmode)) - { - WARN("Failed to update registry\n"); - ret = DISP_CHANGE_NOTUPDATED; - } - else if (flags & (CDS_TEST | CDS_NORESET)) - ret = DISP_CHANGE_SUCCESSFUL; + if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; else if (wcsicmp(primary_adapter, devname)) { FIXME("Changing non-primary adapter settings is currently unsupported.\n"); diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index b45a317603a..3a3c241ca70 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -209,89 +209,6 @@ void init_registry_display_settings(void) } } -static HKEY get_display_device_reg_key( const WCHAR *device_name ) -{ - static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'}; - static const WCHAR video_key[] = { - '\\','R','e','g','i','s','t','r','y', - '\\','M','a','c','h','i','n','e', - '\\','H','A','R','D','W','A','R','E', - '\\','D','E','V','I','C','E','M','A','P', - '\\','V','I','D','E','O'}; - static const WCHAR current_config_key[] = { - '\\','R','e','g','i','s','t','r','y', - '\\','M','a','c','h','i','n','e', - '\\','S','y','s','t','e','m', - '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', - '\\','H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s', - '\\','C','u','r','r','e','n','t'}; - WCHAR value_name[MAX_PATH], buffer[4096], *end_ptr; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - DWORD adapter_index, size; - char adapter_name[100]; - HKEY hkey; - - /* Device name has to be \\.\DISPLAY%d */ - if (wcsnicmp( device_name, display, ARRAY_SIZE(display) )) - return FALSE; - - /* Parse \\.\DISPLAY* */ - adapter_index = wcstol( device_name + ARRAY_SIZE(display), &end_ptr, 10 ) - 1; - if (*end_ptr) - return FALSE; - - /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */ - if (!(hkey = reg_open_key( NULL, video_key, sizeof(video_key) ))) return FALSE; - sprintf( adapter_name, "\\Device\\Video%d", adapter_index ); - asciiz_to_unicode( value_name, adapter_name ); - size = query_reg_value( hkey, value_name, value, sizeof(buffer) ); - NtClose( hkey ); - if (!size || value->Type != REG_SZ) return FALSE; - - /* Replace \Registry\Machine\ prefix with HKEY_CURRENT_CONFIG */ - memmove( buffer + ARRAYSIZE(current_config_key), (const WCHAR *)value->Data + 17, - size - 17 * sizeof(WCHAR) ); - memcpy( buffer, current_config_key, sizeof(current_config_key) ); - TRACE( "display device %s registry settings key %s.\n", wine_dbgstr_w(device_name), - wine_dbgstr_w(buffer) ); - return reg_open_key( NULL, buffer, lstrlenW(buffer) * sizeof(WCHAR) ); -} - -static BOOL set_setting_value( HKEY hkey, const char *name, DWORD val ) -{ - WCHAR nameW[128]; - UNICODE_STRING str = { asciiz_to_unicode( nameW, name ) - sizeof(WCHAR), sizeof(nameW), nameW }; - return !NtSetValueKey( hkey, &str, 0, REG_DWORD, &val, sizeof(val) ); -} - -static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm) -{ - HANDLE mutex; - HKEY hkey; - BOOL ret = TRUE; - - mutex = get_display_device_init_mutex(); - if (!(hkey = get_display_device_reg_key( device_name ))) - { - release_display_device_init_mutex(mutex); - return FALSE; - } - - ret &= set_setting_value( hkey, "DefaultSettings.BitsPerPel", dm->dmBitsPerPel ); - ret &= set_setting_value( hkey, "DefaultSettings.XResolution", dm->dmPelsWidth ); - ret &= set_setting_value( hkey, "DefaultSettings.YResolution", dm->dmPelsHeight ); - ret &= set_setting_value( hkey, "DefaultSettings.VRefresh", dm->dmDisplayFrequency ); - ret &= set_setting_value( hkey, "DefaultSettings.Flags", dm->dmDisplayFlags ); - ret &= set_setting_value( hkey, "DefaultSettings.XPanning", dm->dmPosition.x ); - ret &= set_setting_value( hkey, "DefaultSettings.YPanning", dm->dmPosition.y ); - ret &= set_setting_value( hkey, "DefaultSettings.Orientation", dm->dmDisplayOrientation ); - ret &= set_setting_value( hkey, "DefaultSettings.FixedOutput", dm->dmDisplayFixedOutput ); - - NtClose( hkey ); - release_display_device_init_mutex(mutex); - return ret; -} - BOOL get_primary_adapter(WCHAR *name) { DISPLAY_DEVICEW dd; @@ -883,14 +800,7 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, return DISP_CHANGE_BADMODE; } - if (!write_registry_settings(devname, full_mode)) - { - ERR("Failed to write %s display settings to registry.\n", wine_dbgstr_w(devname)); - free_full_mode(full_mode); - free(displays); - return DISP_CHANGE_NOTUPDATED; - } - + memcpy( &devmode->dmFields, &full_mode->dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); free_full_mode(full_mode); break; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/355