[PATCH 0/3] MR395: win32u: Move reading and writing mode from registry out of graphics drivers.
What was initially in https://gitlab.winehq.org/wine/wine/-/merge_requests/355, with the test failures hopefully fixed. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/395
From: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 83 ++++++++++++++++++++++++++++++++++--- dlls/wineandroid.drv/init.c | 2 +- dlls/winemac.drv/display.c | 60 --------------------------- dlls/winex11.drv/display.c | 62 --------------------------- 4 files changed, 78 insertions(+), 129 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index fa82566e24c..0ff9a4aaeab 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -169,6 +169,15 @@ static const WCHAR displayW[] = {'D','i','s','p','l','a','y',0}; static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0}; static const WCHAR yesW[] = {'Y','e','s',0}; static const WCHAR noW[] = {'N','o',0}; +static const WCHAR bits_per_pelW[] = {'B','i','t','s','P','e','r','P','e','l',0}; +static const WCHAR x_resolutionW[] = {'X','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR y_resolutionW[] = {'Y','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR v_refreshW[] = {'V','R','e','f','r','e','s','h',0}; +static const WCHAR flagsW[] = {'F','l','a','g','s',0}; +static const WCHAR x_panningW[] = {'X','P','a','n','n','i','n','g',0}; +static const WCHAR y_panningW[] = {'Y','P','a','n','n','i','n','g',0}; +static const WCHAR orientationW[] = {'O','r','i','e','n','t','a','t','i','o','n',0}; +static const WCHAR fixed_outputW[] = {'F','i','x','e','d','O','u','t','p','u','t',0}; static const char guid_devclass_displayA[] = "{4D36E968-E325-11CE-BFC1-08002BE10318}"; static const WCHAR guid_devclass_displayW[] = @@ -411,6 +420,59 @@ static void release_display_device_init_mutex( HANDLE mutex ) NtClose( mutex ); } +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}; + char value_buf[offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[sizeof(DWORD)])]; + KEY_VALUE_PARTIAL_INFORMATION *value = (void *)value_buf; + WCHAR bufferW[MAX_PATH]; + +#define query_mode_field( name, field, flag ) \ + do \ + { \ + lstrcpyW( bufferW, default_settingsW ); \ + lstrcatW( bufferW, (name) ); \ + if (!query_reg_value( adapter_key, bufferW, value, sizeof(value_buf) ) || \ + value->Type != REG_DWORD) return FALSE; \ + mode->field = *(const DWORD *)value->Data; \ + mode->dmFields |= (flag); \ + } while (0) + + query_mode_field( bits_per_pelW, dmBitsPerPel, DM_BITSPERPEL ); + query_mode_field( x_resolutionW, dmPelsWidth, DM_PELSWIDTH ); + query_mode_field( y_resolutionW, dmPelsHeight, DM_PELSHEIGHT ); + query_mode_field( v_refreshW, dmDisplayFrequency, DM_DISPLAYFREQUENCY ); + query_mode_field( flagsW, dmDisplayFlags, DM_DISPLAYFLAGS ); + query_mode_field( x_panningW, dmPosition.x, DM_POSITION ); + query_mode_field( y_panningW, dmPosition.y, DM_POSITION ); + query_mode_field( orientationW, dmDisplayOrientation, DM_DISPLAYORIENTATION ); + query_mode_field( fixed_outputW, dmDisplayFixedOutput, 0 ); + +#undef query_mode_field + + return TRUE; +} + +static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode ) +{ + BOOL ret = FALSE; + HANDLE mutex; + HKEY hkey; + + mutex = get_display_device_init_mutex(); + + if (!config_key && !(config_key = reg_open_key( NULL, config_keyW, sizeof(config_keyW) ))) ret = FALSE; + else if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) ))) ret = FALSE; + else + { + ret = read_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]; @@ -1840,7 +1902,7 @@ static BOOL is_detached_mode( const DEVMODEW *mode ) LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { - WCHAR device_name[CCHDEVICENAME]; + WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; struct adapter *adapter; BOOL def_mode = TRUE; DEVMODEW dm; @@ -1858,7 +1920,11 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm } if (!lock_display_devices()) return DISP_CHANGE_FAILED; - if ((adapter = find_adapter( devname ))) lstrcpyW( device_name, adapter->dev.device_name ); + if ((adapter = find_adapter( devname ))) + { + lstrcpyW( device_name, adapter->dev.device_name ); + lstrcpyW( adapter_path, adapter->config_key ); + } unlock_display_devices(); if (!adapter) { @@ -1885,7 +1951,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm { memset( &dm, 0, sizeof(dm) ); dm.dmSize = sizeof(dm); - if (!NtUserEnumDisplaySettings( devname, ENUM_REGISTRY_SETTINGS, &dm, 0 )) + if (!read_registry_settings( adapter_path, &dm )) { ERR( "Default mode not found!\n" ); return DISP_CHANGE_BADMODE; @@ -1929,14 +1995,18 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVMODEW *devmode, DWORD flags ) { static const WCHAR wine_display_driverW[] = {'W','i','n','e',' ','D','i','s','p','l','a','y',' ','D','r','i','v','e','r',0}; - WCHAR device_name[CCHDEVICENAME]; + WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; struct adapter *adapter; BOOL ret; TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), index, devmode, flags ); if (!lock_display_devices()) return FALSE; - if ((adapter = find_adapter( device ))) lstrcpyW( device_name, adapter->dev.device_name ); + if ((adapter = find_adapter( device ))) + { + lstrcpyW( device_name, adapter->dev.device_name ); + lstrcpyW( adapter_path, adapter->config_key ); + } unlock_display_devices(); if (!adapter) { @@ -1950,7 +2020,8 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM devmode->dmSize = offsetof(DEVMODEW, dmICMMethod); memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) ); - ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags ); + if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode ); + else ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags ); if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_w(device_name) ); else TRACE( "position %dx%d, resolution %ux%u, frequency %u, depth %u, orientation %#x.\n", diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index e2cebb974c3..a82932bf65f 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -310,7 +310,7 @@ BOOL ANDROID_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, D devmode->u1.s2.dmDisplayOrientation = 0; devmode->u1.s2.dmDisplayFixedOutput = 0; - if (n == ENUM_CURRENT_SETTINGS || n == ENUM_REGISTRY_SETTINGS) n = 0; + if (n == ENUM_CURRENT_SETTINGS) n = 0; if (n == 0) { devmode->dmPelsWidth = screen_width; diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 191dc1f789b..a558216b7ea 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -128,60 +128,6 @@ static HKEY get_display_device_reg_key(const WCHAR *device_name) } -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 read_registry_settings(const WCHAR *device_name, DEVMODEW *dm) -{ - HANDLE mutex; - HKEY hkey; - BOOL ret = TRUE; - - dm->dmFields = 0; - - mutex = get_display_device_init_mutex(); - if (!(hkey = get_display_device_reg_key(device_name))) - { - release_display_device_init_mutex(mutex); - return FALSE; - } - - ret &= query_display_setting(hkey, "DefaultSettings.BitsPerPel", &dm->dmBitsPerPel); - dm->dmFields |= DM_BITSPERPEL; - ret &= query_display_setting(hkey, "DefaultSettings.XResolution", &dm->dmPelsWidth); - dm->dmFields |= DM_PELSWIDTH; - ret &= query_display_setting(hkey, "DefaultSettings.YResolution", &dm->dmPelsHeight); - dm->dmFields |= DM_PELSHEIGHT; - ret &= query_display_setting(hkey, "DefaultSettings.VRefresh", &dm->dmDisplayFrequency); - dm->dmFields |= DM_DISPLAYFREQUENCY; - ret &= query_display_setting(hkey, "DefaultSettings.Flags", &dm->dmDisplayFlags); - dm->dmFields |= DM_DISPLAYFLAGS; - ret &= query_display_setting(hkey, "DefaultSettings.XPanning", (DWORD *)&dm->dmPosition.x); - ret &= query_display_setting(hkey, "DefaultSettings.YPanning", (DWORD *)&dm->dmPosition.y); - dm->dmFields |= DM_POSITION; - ret &= query_display_setting(hkey, "DefaultSettings.Orientation", &dm->dmDisplayOrientation); - dm->dmFields |= DM_DISPLAYORIENTATION; - ret &= query_display_setting(hkey, "DefaultSettings.FixedOutput", &dm->dmDisplayFixedOutput); - - NtClose(hkey); - release_display_device_init_mutex(mutex); - return ret; -} - - static BOOL set_setting_value(HKEY hkey, const char *name, DWORD val) { WCHAR nameW[128]; @@ -1056,12 +1002,6 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, DEVMODEW *devmode init_original_display_mode(); - if (mode == ENUM_REGISTRY_SETTINGS) - { - TRACE("mode %d (registry) -- getting default mode\n", mode); - return read_registry_settings(devname, devmode); - } - if (macdrv_get_displays(&displays, &num_displays)) goto failed; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 740e018247b..b45a317603a 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -257,58 +257,6 @@ static HKEY get_display_device_reg_key( const WCHAR *device_name ) 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 read_registry_settings(const WCHAR *device_name, DEVMODEW *dm) -{ - HANDLE mutex; - HKEY hkey; - BOOL ret = TRUE; - - dm->dmFields = 0; - - mutex = get_display_device_init_mutex(); - if (!(hkey = get_display_device_reg_key( device_name ))) - { - release_display_device_init_mutex(mutex); - return FALSE; - } - - ret &= query_display_setting( hkey, "DefaultSettings.BitsPerPel", &dm->dmBitsPerPel ); - dm->dmFields |= DM_BITSPERPEL; - ret &= query_display_setting( hkey, "DefaultSettings.XResolution", &dm->dmPelsWidth ); - dm->dmFields |= DM_PELSWIDTH; - ret &= query_display_setting( hkey, "DefaultSettings.YResolution", &dm->dmPelsHeight ); - dm->dmFields |= DM_PELSHEIGHT; - ret &= query_display_setting( hkey, "DefaultSettings.VRefresh", &dm->dmDisplayFrequency ); - dm->dmFields |= DM_DISPLAYFREQUENCY; - ret &= query_display_setting( hkey, "DefaultSettings.Flags", &dm->dmDisplayFlags ); - dm->dmFields |= DM_DISPLAYFLAGS; - ret &= query_display_setting( hkey, "DefaultSettings.XPanning", (DWORD *)&dm->dmPosition.x ); - ret &= query_display_setting( hkey, "DefaultSettings.YPanning", (DWORD *)&dm->dmPosition.y ); - dm->dmFields |= DM_POSITION; - ret &= query_display_setting( hkey, "DefaultSettings.Orientation", &dm->dmDisplayOrientation ); - dm->dmFields |= DM_DISPLAYORIENTATION; - ret &= query_display_setting( hkey, "DefaultSettings.FixedOutput", &dm->dmDisplayFixedOutput ); - - NtClose( hkey ); - release_display_device_init_mutex(mutex); - return ret; -} - static BOOL set_setting_value( HKEY hkey, const char *name, DWORD val ) { WCHAR nameW[128]; @@ -468,16 +416,6 @@ BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DW UINT mode_count; ULONG_PTR id; - if (n == ENUM_REGISTRY_SETTINGS) - { - if (!read_registry_settings(name, devmode)) - { - ERR("Failed to get %s registry display settings.\n", wine_dbgstr_w(name)); - return FALSE; - } - return TRUE; - } - if (n == ENUM_CURRENT_SETTINGS) { if (!settings_handler.get_id( name, &id ) || !settings_handler.get_current_mode( id, &mode )) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/395
From: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 100 ++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 0ff9a4aaeab..656534349a8 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1896,17 +1896,54 @@ static BOOL is_detached_mode( const DEVMODEW *mode ) mode->dmPelsHeight == 0; } +static DEVMODEW *validate_display_settings( DEVMODEW *default_mode, DEVMODEW *current_mode, DEVMODEW *devmode ) +{ + if (devmode) + { + trace_devmode( devmode ); + + if (devmode->dmSize < offsetof(DEVMODEW, dmICMMethod)) return NULL; + if (!is_detached_mode( devmode ) && + (!(devmode->dmFields & DM_BITSPERPEL) || !devmode->dmBitsPerPel) && + (!(devmode->dmFields & DM_PELSWIDTH) || !devmode->dmPelsWidth) && + (!(devmode->dmFields & DM_PELSHEIGHT) || !devmode->dmPelsHeight) && + (!(devmode->dmFields & DM_DISPLAYFREQUENCY) || !devmode->dmDisplayFrequency)) + devmode = NULL; + } + + if (!devmode) + { + if (!default_mode->dmSize) return NULL; + TRACE( "Return to original display mode\n" ); + devmode = default_mode; + } + + if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT)) + { + WARN( "devmode doesn't specify the resolution: %#x\n", devmode->dmFields ); + return NULL; + } + + if (!is_detached_mode( devmode ) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight)) + { + if (!current_mode->dmSize) return NULL; + if (!devmode->dmPelsWidth) devmode->dmPelsWidth = current_mode->dmPelsWidth; + if (!devmode->dmPelsHeight) devmode->dmPelsHeight = current_mode->dmPelsHeight; + } + + return devmode; +} + /*********************************************************************** * NtUserChangeDisplaySettingsExW (win32u.@) */ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { + DEVMODEW default_mode = {.dmSize = sizeof(DEVMODEW)}, current_mode = {.dmSize = sizeof(DEVMODEW)}; WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; + LONG ret = DISP_CHANGE_SUCCESSFUL; struct adapter *adapter; - BOOL def_mode = TRUE; - DEVMODEW dm; - LONG ret; TRACE( "%s %p %p %#x %p\n", debugstr_us(devname), devmode, hwnd, flags, lparam ); TRACE( "flags=%s\n", _CDS_flags(flags) ); @@ -1932,60 +1969,13 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm return DISP_CHANGE_BADPARAM; } - if (devmode) - { - trace_devmode( devmode ); - - if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmICMMethod)) - return DISP_CHANGE_BADMODE; - - if (is_detached_mode(devmode) || - ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel) || - ((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth) || - ((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight) || - ((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency)) - def_mode = FALSE; - } - - if (def_mode) - { - memset( &dm, 0, sizeof(dm) ); - dm.dmSize = sizeof(dm); - if (!read_registry_settings( adapter_path, &dm )) - { - ERR( "Default mode not found!\n" ); - return DISP_CHANGE_BADMODE; - } - - TRACE( "Return to original display mode\n" ); - devmode = &dm; - } - - if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT)) - { - WARN( "devmode doesn't specify the resolution: %#x\n", devmode->dmFields ); - return DISP_CHANGE_BADMODE; - } + if (!read_registry_settings( adapter_path, &default_mode )) default_mode.dmSize = 0; + if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0; - if (!is_detached_mode(devmode) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight)) - { - memset(&dm, 0, sizeof(dm)); - dm.dmSize = sizeof(dm); - if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, &dm, 0 )) - { - ERR( "Current mode not found!\n" ); - return DISP_CHANGE_BADMODE; - } - - if (!devmode->dmPelsWidth) - devmode->dmPelsWidth = dm.dmPelsWidth; - if (!devmode->dmPelsHeight) - devmode->dmPelsHeight = dm.dmPelsHeight; - } + if (!(devmode = validate_display_settings( &default_mode, ¤t_mode, devmode ))) ret = DISP_CHANGE_BADMODE; + else ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam ); - ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam ); - if (ret != DISP_CHANGE_SUCCESSFUL) - ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret ); + if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret ); return ret; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/395
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118460 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:1896 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:1896 Task: Patch failed to apply
From: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 52 +++++++++++++++ dlls/winemac.drv/display.c | 104 +----------------------------- dlls/winex11.drv/display.c | 111 +-------------------------------- dlls/winex11.drv/x11drv.h | 2 - dlls/winex11.drv/x11drv_main.c | 19 ++++++ 5 files changed, 73 insertions(+), 215 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 656534349a8..09f1aa354b1 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -420,6 +420,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 (!set_reg_value( adapter_key, bufferW, REG_DWORD, &mode->field, sizeof(mode->field) )) \ + return FALSE; \ + } 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}; @@ -473,6 +502,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]; @@ -1973,6 +2022,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 a558216b7ea..a217a3fc422 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -60,73 +60,6 @@ static pthread_mutex_t modes_mutex = PTHREAD_MUTEX_INITIALIZER; static BOOL inited_original_display_mode; -static HANDLE get_display_device_init_mutex(void) -{ - static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t'}; - UNICODE_STRING name = { sizeof(init_mutexW), sizeof(init_mutexW), (WCHAR *)init_mutexW }; - OBJECT_ATTRIBUTES attr; - HANDLE mutex = 0; - - InitializeObjectAttributes(&attr, &name, OBJ_OPENIF, NULL, NULL); - NtCreateMutant(&mutex, MUTEX_ALL_ACCESS, &attr, FALSE); - if (mutex) NtWaitForSingleObject(mutex, FALSE, NULL); - return mutex; -} - -static void release_display_device_init_mutex(HANDLE mutex) -{ - NtReleaseMutant(mutex, NULL); - 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 set_setting_value(HKEY hkey, const char *name, DWORD val) { @@ -136,35 +69,6 @@ static BOOL set_setting_value(HKEY hkey, const char *name, DWORD 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; -} - - static BOOL write_display_settings(HKEY parent_hkey, CGDirectDisplayID displayID) { BOOL ret = FALSE; @@ -934,13 +838,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..cbf1e7f70cd 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; } @@ -922,25 +832,6 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, return ret; } -HANDLE get_display_device_init_mutex(void) -{ - static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t'}; - UNICODE_STRING name = { sizeof(init_mutexW), sizeof(init_mutexW), (WCHAR *)init_mutexW }; - OBJECT_ATTRIBUTES attr; - HANDLE mutex = 0; - - InitializeObjectAttributes( &attr, &name, OBJ_OPENIF, NULL, NULL ); - NtCreateMutant( &mutex, MUTEX_ALL_ACCESS, &attr, FALSE ); - if (mutex) NtWaitForSingleObject( mutex, FALSE, NULL ); - return mutex; -} - -void release_display_device_init_mutex(HANDLE mutex) -{ - NtReleaseMutant( mutex, NULL ); - NtClose( mutex ); -} - POINT virtual_screen_to_root(INT x, INT y) { RECT virtual = NtUserGetVirtualScreenRect(); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index cd0d33f59bf..f44b3006345 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -805,9 +805,7 @@ struct x11drv_display_device_handler void (*register_event_handlers)(void); }; -extern HANDLE get_display_device_init_mutex(void) DECLSPEC_HIDDEN; extern BOOL get_host_primary_gpu(struct gdi_gpu *gpu) DECLSPEC_HIDDEN; -extern void release_display_device_init_mutex(HANDLE) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 4e908f2918b..cd2ea87190a 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -1017,6 +1017,25 @@ NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDP return STATUS_SUCCESS; } +static HANDLE get_display_device_init_mutex(void) +{ + static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t'}; + UNICODE_STRING name = { sizeof(init_mutexW), sizeof(init_mutexW), (WCHAR *)init_mutexW }; + OBJECT_ATTRIBUTES attr; + HANDLE mutex = 0; + + InitializeObjectAttributes( &attr, &name, OBJ_OPENIF, NULL, NULL ); + NtCreateMutant( &mutex, MUTEX_ALL_ACCESS, &attr, FALSE ); + if (mutex) NtWaitForSingleObject( mutex, FALSE, NULL ); + return mutex; +} + +static void release_display_device_init_mutex(HANDLE mutex) +{ + NtReleaseMutant( mutex, NULL ); + NtClose( mutex ); +} + /* Find the Vulkan device UUID corresponding to a LUID */ static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/395
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118550 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:420 error: patch failed: dlls/winemac.drv/display.c:60 error: patch failed: dlls/winex11.drv/display.c:209 error: patch failed: dlls/winex11.drv/x11drv.h:805 error: patch failed: dlls/winex11.drv/x11drv_main.c:1017 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:420 error: patch failed: dlls/winemac.drv/display.c:60 error: patch failed: dlls/winex11.drv/display.c:209 error: patch failed: dlls/winex11.drv/x11drv.h:805 error: patch failed: dlls/winex11.drv/x11drv_main.c:1017 Task: Patch failed to apply
On Thu Jul 7 06:40:32 2022 +0000, **** wrote:
Marvin replied on the mailing list: ``` Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118460 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:1896 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/win32u/sysparams.c:1896 Task: Patch failed to apply ``` Not sure what happened here - it looks like testbot just tried to use the second commit.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/395#note_3517
On Thu Jul 7 07:26:05 2022 +0000, Huw Davies wrote:
Not sure what happened here - it looks like testbot just tried to use the second commit. Yeah, it mixed things up with <https://gitlab.winehq.org/wine/wine/-/merge_requests/393>. Maybe it got confused by the matching number of patches.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/395#note_3518
Huw Davies (@huw) commented about dlls/win32u/sysparams.c:
+ if (!is_detached_mode( devmode ) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight)) + { + if (!current_mode->dmSize) return NULL; + if (!devmode->dmPelsWidth) devmode->dmPelsWidth = current_mode->dmPelsWidth; + if (!devmode->dmPelsHeight) devmode->dmPelsHeight = current_mode->dmPelsHeight; + } + + return devmode; +} + /*********************************************************************** * NtUserChangeDisplaySettingsExW (win32u.@) */ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { How about fixing the comment (i.e. remove the tailing "ExW") while we're making changes here? I wouldn't have bothered pointing this out, but it'll give testbot another chance.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/395#note_3520
participants (3)
-
Huw Davies (@huw) -
Marvin -
Rémi Bernon