Commit 6b6a7124 authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

winemac.drv: Support multiple adapter display settings in registry.

parent 13e3d8f6
...@@ -71,6 +71,7 @@ static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0}; ...@@ -71,6 +71,7 @@ static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0};
static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0}; static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
static const WCHAR gpu_idW[] = {'G','P','U','I','D',0}; static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
static const WCHAR mointor_id_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0}; static const WCHAR mointor_id_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
static const WCHAR adapter_prefixW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
static const WCHAR adapter_name_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0}; static const WCHAR adapter_name_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0}; static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
static const WCHAR guid_fmtW[] = { static const WCHAR guid_fmtW[] = {
...@@ -151,44 +152,58 @@ static void release_display_device_init_mutex(HANDLE mutex) ...@@ -151,44 +152,58 @@ static void release_display_device_init_mutex(HANDLE mutex)
CloseHandle(mutex); CloseHandle(mutex);
} }
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"; WCHAR value_name[MAX_PATH], buffer[MAX_PATH], *end_ptr;
static const char video_path[] = "System\\CurrentControlSet\\Control\\Video\\{"; DWORD adapter_index, size;
static const char display0[] = "}\\0000";
ATOM guid_atom;
assert(len >= sizeof(video_path) + sizeof(display0) + 40); /* Device name has to be \\.\DISPLAY%d */
if (strncmpiW(device_name, adapter_prefixW, ARRAY_SIZE(adapter_prefixW)))
guid_atom = HandleToULong(GetPropA(GetDesktopWindow(), display_device_guid_prop)); return FALSE;
if (!guid_atom) return FALSE;
memcpy(key, video_path, sizeof(video_path)); /* Parse \\.\DISPLAY* */
adapter_index = strtolW(device_name + ARRAY_SIZE(adapter_prefixW), &end_ptr, 10) - 1;
if (*end_ptr)
return FALSE;
if (!GlobalGetAtomNameA(guid_atom, key + strlen(key), 40)) /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
sprintfW(value_name, device_video_fmtW, adapter_index);
size = sizeof(buffer);
if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, value_name, RRF_RT_REG_SZ, NULL, buffer, &size))
return FALSE; return FALSE;
strcat(key, display0); if (len < lstrlenW(buffer + 18) + 1)
return FALSE;
TRACE("display device key %s\n", wine_dbgstr_a(key)); /* 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_mac_reg_key[128]; WCHAR wine_mac_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_mac_reg_key, sizeof(wine_mac_reg_key))) mutex = get_display_device_init_mutex();
if (!get_display_device_reg_key(device_name, wine_mac_reg_key, ARRAY_SIZE(wine_mac_reg_key)))
{
release_display_device_init_mutex(mutex);
return FALSE; return FALSE;
}
if (RegOpenKeyExA(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, KEY_READ, &hkey)) if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, wine_mac_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); \
...@@ -216,22 +231,31 @@ static BOOL read_registry_settings(DEVMODEW *dm) ...@@ -216,22 +231,31 @@ 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_mac_reg_key[128]; WCHAR wine_mac_reg_key[MAX_PATH];
HANDLE mutex;
HKEY hkey; HKEY hkey;
BOOL ret = TRUE; BOOL ret = TRUE;
if (!get_display_device_reg_key(wine_mac_reg_key, sizeof(wine_mac_reg_key))) mutex = get_display_device_init_mutex();
if (!get_display_device_reg_key(device_name, wine_mac_reg_key, ARRAY_SIZE(wine_mac_reg_key)))
{
release_display_device_init_mutex(mutex);
return FALSE; return FALSE;
}
if (RegCreateKeyExA(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, NULL, if (RegCreateKeyExW(HKEY_CURRENT_CONFIG, wine_mac_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))) \
...@@ -250,6 +274,7 @@ static BOOL write_registry_settings(const DEVMODEW *dm) ...@@ -250,6 +274,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;
} }
...@@ -833,12 +858,6 @@ LONG CDECL macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, ...@@ -833,12 +858,6 @@ LONG CDECL macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode,
devmode = &default_mode; devmode = &default_mode;
} }
if (lstrcmpiW(primary_adapter, devname))
{
FIXME("Changing non-primary adapter settings is currently unsupported.\n");
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");
...@@ -958,13 +977,18 @@ better: ...@@ -958,13 +977,18 @@ better:
/* we have a valid mode */ /* we have a valid mode */
TRACE("Requested display settings match mode %ld\n", best); TRACE("Requested display settings match mode %ld\n", best);
if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devmode)) if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devname, devmode))
{ {
WARN("Failed to update registry\n"); WARN("Failed to update registry\n");
ret = DISP_CHANGE_NOTUPDATED; ret = DISP_CHANGE_NOTUPDATED;
} }
else if (flags & (CDS_TEST | CDS_NORESET)) else if (flags & (CDS_TEST | CDS_NORESET))
ret = DISP_CHANGE_SUCCESSFUL; ret = DISP_CHANGE_SUCCESSFUL;
else if (lstrcmpiW(primary_adapter, devname))
{
FIXME("Changing non-primary adapter settings is currently unsupported.\n");
ret = DISP_CHANGE_SUCCESSFUL;
}
else if (macdrv_set_display_mode(&displays[0], best_display_mode)) else if (macdrv_set_display_mode(&displays[0], best_display_mode))
{ {
int mode_bpp = display_mode_bits_per_pixel(best_display_mode); int mode_bpp = display_mode_bits_per_pixel(best_display_mode);
...@@ -1034,7 +1058,7 @@ BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, ...@@ -1034,7 +1058,7 @@ BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode,
if (mode == ENUM_REGISTRY_SETTINGS) if (mode == ENUM_REGISTRY_SETTINGS)
{ {
TRACE("mode %d (registry) -- getting default mode\n", mode); TRACE("mode %d (registry) -- getting default mode\n", mode);
return read_registry_settings(devmode); return read_registry_settings(devname, devmode);
} }
if (macdrv_get_displays(&displays, &num_displays)) if (macdrv_get_displays(&displays, &num_displays))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment