winex11.drv: Support multiple adapter display settings in registry.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b5d58ff69c
commit
3db619d46e
|
@ -124,7 +124,7 @@ static CRITICAL_SECTION_DEBUG screen_critsect_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION screen_section = {&screen_critsect_debug, -1, 0, 0, 0, 0};
|
static CRITICAL_SECTION screen_section = {&screen_critsect_debug, -1, 0, 0, 0, 0};
|
||||||
|
|
||||||
static HANDLE get_display_device_init_mutex(void)
|
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',0};
|
static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t',0};
|
||||||
HANDLE mutex = CreateMutexW(NULL, FALSE, init_mutexW);
|
HANDLE mutex = CreateMutexW(NULL, FALSE, init_mutexW);
|
||||||
|
@ -133,7 +133,7 @@ static HANDLE get_display_device_init_mutex(void)
|
||||||
return mutex;
|
return mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_display_device_init_mutex(HANDLE mutex)
|
void release_display_device_init_mutex(HANDLE mutex)
|
||||||
{
|
{
|
||||||
ReleaseMutex(mutex);
|
ReleaseMutex(mutex);
|
||||||
CloseHandle(mutex);
|
CloseHandle(mutex);
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#define NONAMELESSUNION
|
#define NONAMELESSUNION
|
||||||
#define NONAMELESSSTRUCT
|
#define NONAMELESSSTRUCT
|
||||||
|
@ -32,6 +29,7 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(x11settings);
|
WINE_DEFAULT_DEBUG_CHANNEL(x11settings);
|
||||||
|
|
||||||
|
@ -154,43 +152,63 @@ void X11DRV_Settings_Init(void)
|
||||||
X11DRV_Settings_AddOneMode( primary.right - primary.left, primary.bottom - primary.top, 0, 60);
|
X11DRV_Settings_AddOneMode( primary.right - primary.left, primary.bottom - primary.top, 0, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL get_display_device_reg_key(char *key, unsigned len)
|
static BOOL get_display_device_reg_key(const WCHAR *device_name, WCHAR *key, unsigned len)
|
||||||
{
|
{
|
||||||
static const char display_device_guid_prop[] = "__wine_display_device_guid";
|
static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
|
||||||
static const char video_path[] = "System\\CurrentControlSet\\Control\\Video\\{";
|
static const WCHAR video_value_fmt[] = {'\\','D','e','v','i','c','e','\\',
|
||||||
static const char display0[] = "}\\0000";
|
'V','i','d','e','o','%','d',0};
|
||||||
ATOM guid_atom;
|
static const WCHAR video_key[] = {'H','A','R','D','W','A','R','E','\\',
|
||||||
|
'D','E','V','I','C','E','M','A','P','\\',
|
||||||
|
'V','I','D','E','O','\\',0};
|
||||||
|
WCHAR value_name[MAX_PATH], buffer[MAX_PATH], *end_ptr;
|
||||||
|
DWORD adapter_index, size;
|
||||||
|
|
||||||
assert(len >= sizeof(video_path) + sizeof(display0) + 40);
|
/* Device name has to be \\.\DISPLAY%d */
|
||||||
|
if (strncmpiW(device_name, display, ARRAY_SIZE(display)))
|
||||||
guid_atom = HandleToULong(GetPropA(GetDesktopWindow(), display_device_guid_prop));
|
|
||||||
if (!guid_atom) return FALSE;
|
|
||||||
|
|
||||||
memcpy(key, video_path, sizeof(video_path));
|
|
||||||
|
|
||||||
if (!GlobalGetAtomNameA(guid_atom, key + strlen(key), 40))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
strcat(key, display0);
|
/* Parse \\.\DISPLAY* */
|
||||||
|
adapter_index = strtolW(device_name + ARRAY_SIZE(display), &end_ptr, 10) - 1;
|
||||||
|
if (*end_ptr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
TRACE("display device key %s\n", wine_dbgstr_a(key));
|
/* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
|
||||||
|
sprintfW(value_name, video_value_fmt, adapter_index);
|
||||||
|
size = sizeof(buffer);
|
||||||
|
if (RegGetValueW(HKEY_LOCAL_MACHINE, video_key, value_name, RRF_RT_REG_SZ, NULL, buffer, &size))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (len < lstrlenW(buffer + 18) + 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Skip \Registry\Machine\ prefix */
|
||||||
|
lstrcpyW(key, buffer + 18);
|
||||||
|
TRACE("display device %s registry settings key %s.\n", wine_dbgstr_w(device_name), wine_dbgstr_w(key));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL read_registry_settings(DEVMODEW *dm)
|
static BOOL read_registry_settings(const WCHAR *device_name, DEVMODEW *dm)
|
||||||
{
|
{
|
||||||
char wine_x11_reg_key[128];
|
WCHAR wine_x11_reg_key[MAX_PATH];
|
||||||
|
HANDLE mutex;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
DWORD type, size;
|
DWORD type, size;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
dm->dmFields = 0;
|
dm->dmFields = 0;
|
||||||
|
|
||||||
if (!get_display_device_reg_key(wine_x11_reg_key, sizeof(wine_x11_reg_key)))
|
mutex = get_display_device_init_mutex();
|
||||||
|
if (!get_display_device_reg_key(device_name, wine_x11_reg_key, ARRAY_SIZE(wine_x11_reg_key)))
|
||||||
|
{
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (RegOpenKeyExA(HKEY_CURRENT_CONFIG, wine_x11_reg_key, 0, KEY_READ, &hkey))
|
if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, wine_x11_reg_key, 0, KEY_READ, &hkey))
|
||||||
|
{
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#define query_value(name, data) \
|
#define query_value(name, data) \
|
||||||
size = sizeof(DWORD); \
|
size = sizeof(DWORD); \
|
||||||
|
@ -218,21 +236,30 @@ static BOOL read_registry_settings(DEVMODEW *dm)
|
||||||
#undef query_value
|
#undef query_value
|
||||||
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL write_registry_settings(const DEVMODEW *dm)
|
static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm)
|
||||||
{
|
{
|
||||||
char wine_x11_reg_key[128];
|
WCHAR wine_x11_reg_key[MAX_PATH];
|
||||||
|
HANDLE mutex;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
if (!get_display_device_reg_key(wine_x11_reg_key, sizeof(wine_x11_reg_key)))
|
mutex = get_display_device_init_mutex();
|
||||||
|
if (!get_display_device_reg_key(device_name, wine_x11_reg_key, ARRAY_SIZE(wine_x11_reg_key)))
|
||||||
|
{
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (RegCreateKeyExA(HKEY_CURRENT_CONFIG, wine_x11_reg_key, 0, NULL,
|
if (RegCreateKeyExW(HKEY_CURRENT_CONFIG, wine_x11_reg_key, 0, NULL,
|
||||||
REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL))
|
REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL))
|
||||||
|
{
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#define set_value(name, data) \
|
#define set_value(name, data) \
|
||||||
if (RegSetValueExA(hkey, name, 0, REG_DWORD, (const BYTE*)(data), sizeof(DWORD))) \
|
if (RegSetValueExA(hkey, name, 0, REG_DWORD, (const BYTE*)(data), sizeof(DWORD))) \
|
||||||
|
@ -251,6 +278,7 @@ static BOOL write_registry_settings(const DEVMODEW *dm)
|
||||||
#undef set_value
|
#undef set_value
|
||||||
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
|
release_display_device_init_mutex(mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +329,7 @@ BOOL CDECL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmo
|
||||||
if (n == ENUM_REGISTRY_SETTINGS)
|
if (n == ENUM_REGISTRY_SETTINGS)
|
||||||
{
|
{
|
||||||
TRACE("mode %d (registry) -- getting default mode (%s)\n", n, handler_name);
|
TRACE("mode %d (registry) -- getting default mode (%s)\n", n, handler_name);
|
||||||
return read_registry_settings(devmode);
|
return read_registry_settings(name, devmode);
|
||||||
}
|
}
|
||||||
if (n < dd_mode_count)
|
if (n < dd_mode_count)
|
||||||
{
|
{
|
||||||
|
@ -368,13 +396,6 @@ LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
|
||||||
devmode = &default_mode;
|
devmode = &default_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lstrcmpiW(primary_adapter, devname))
|
|
||||||
{
|
|
||||||
FIXME("Changing non-primary adapter %s settings is currently unsupported.\n",
|
|
||||||
wine_dbgstr_w(devname));
|
|
||||||
return DISP_CHANGE_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_detached_mode(devmode))
|
if (is_detached_mode(devmode))
|
||||||
{
|
{
|
||||||
FIXME("Detaching adapters is currently unsupported.\n");
|
FIXME("Detaching adapters is currently unsupported.\n");
|
||||||
|
@ -407,8 +428,18 @@ LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
|
||||||
/* we have a valid mode */
|
/* we have a valid mode */
|
||||||
TRACE("Requested display settings match mode %d (%s)\n", i, handler_name);
|
TRACE("Requested display settings match mode %d (%s)\n", i, handler_name);
|
||||||
|
|
||||||
if (flags & CDS_UPDATEREGISTRY)
|
if (flags & CDS_UPDATEREGISTRY && !write_registry_settings(devname, devmode))
|
||||||
write_registry_settings(devmode);
|
{
|
||||||
|
ERR("Failed to write %s display settings to registry.\n", wine_dbgstr_w(devname));
|
||||||
|
return DISP_CHANGE_NOTUPDATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lstrcmpiW(primary_adapter, devname))
|
||||||
|
{
|
||||||
|
FIXME("Changing non-primary adapter %s settings is currently unsupported.\n",
|
||||||
|
wine_dbgstr_w(devname));
|
||||||
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(flags & (CDS_TEST | CDS_NORESET)))
|
if (!(flags & (CDS_TEST | CDS_NORESET)))
|
||||||
return pSetCurrentMode(i);
|
return pSetCurrentMode(i);
|
||||||
|
|
|
@ -754,6 +754,8 @@ struct x11drv_display_device_handler
|
||||||
void (*register_event_handlers)(void);
|
void (*register_event_handlers)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern HANDLE get_display_device_init_mutex(void) 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_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN;
|
||||||
extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN;
|
extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN;
|
||||||
extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN;
|
extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue