mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
win32u: Move writing mode to registry out of graphics drivers.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
This commit is contained in:
parent
a7e135f4b3
commit
d83fcafcd3
5 changed files with 73 additions and 215 deletions
|
@ -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 );
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue