Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- On my 2-monitor setup this results in:
for device 0, got name: \.\DISPLAY1, string: X11 Windowing System, flags: 0x15 for device 0 sub 0, got name: \.\DISPLAY1\Monitor0, string: Generic PnP Monitor, flags: 0x3
for device 1, got name: \.\DISPLAY1, string: X11 Windowing System, flags: 0x11 for device 1 sub 0, got name: \.\DISPLAY1\Monitor0, string: Generic PnP Monitor, flags: 0x3
Which nearly matches Windows 10 on the same hardware. The differences are the 2nd device should be DISPLAY2, not DISPLAY1; and the primary adapter comes 2nd on Windows.
However, DISPLAY1 is hard-coded at least in gdi32, winex11, and winemac, so I hard-coded it here as well. This results in both monitors and adapters having the same name, which is clumsy. But it is sufficient to fix Unity games displaying on the non-primary monitor by default.
dlls/user32/misc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++---------- include/wingdi.h | 6 +++- 2 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 895ccce312..96d5212725 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -243,11 +243,13 @@ DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd) return 1; }
-static const WCHAR primary_device_name[] = {'\','\','.','\','D','I','S','P','L','A','Y','1',0}; -static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ', +static const WCHAR device_name[] = {'\','\','.','\','D','I','S','P','L','A','Y','1',0}; +static const WCHAR device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ', 'S','y','s','t','e','m',0}; -static const WCHAR primary_device_deviceid[] = {'P','C','I','\','V','E','N','_','0','0','0','0','&', +static const WCHAR monitor_string[] = {'G','e','n','e','r','i','c',' ','P','n','P',' ','M','o','n','i','t','o','r',0}; +static const WCHAR device_deviceid[] = {'P','C','I','\','V','E','N','_','0','0','0','0','&', 'D','E','V','_','0','0','0','0',0}; +static const WCHAR monitor0W[] = {'\','M','o','n','i','t','o','r','0',0};
/*********************************************************************** * EnumDisplayDevicesA (USER32.@) @@ -282,29 +284,87 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpD return TRUE; }
+struct edd_enum_info +{ + UINT idx; + UINT desired; + HMONITOR hmon; +}; + +static BOOL CALLBACK edd_enum( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp ) +{ + struct edd_enum_info *info = (struct edd_enum_info *)lp; + if (info->idx == info->desired) + { + info->hmon = monitor; + return FALSE; + } + info->idx++; + return TRUE; +} + /*********************************************************************** * EnumDisplayDevicesW (USER32.@) */ BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags ) { - FIXME("(%s,%d,%p,0x%08x), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags); + TRACE("(%s, %d, %p, 0x%08x)\n", debugstr_w(lpDevice), i, lpDisplayDevice, dwFlags);
- if (i) + if (!lpDisplayDevice) return FALSE;
- memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name)); - memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string)); - - lpDisplayDevice->StateFlags = - DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | - DISPLAY_DEVICE_PRIMARY_DEVICE | - DISPLAY_DEVICE_VGA_COMPATIBLE; - - if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID)) - memcpy(lpDisplayDevice->DeviceID, primary_device_deviceid, sizeof(primary_device_deviceid)); - if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey)) - lpDisplayDevice->DeviceKey[0] = 0; + if (!lpDevice) + { + struct edd_enum_info info = {0}; + MONITORINFO monitor = {0}; + + /* one adapter per monitor */ + info.desired = i; + EnumDisplayMonitors(0, NULL, edd_enum, (LPARAM)&info); + + if (info.hmon == NULL) + return FALSE; + + monitor.cbSize = sizeof(monitor); + if (!GetMonitorInfoW(info.hmon, &monitor)) + return FALSE; + + memcpy(lpDisplayDevice->DeviceName, device_name, sizeof(device_name)); + memcpy(lpDisplayDevice->DeviceString, device_string, sizeof(device_string)); + + lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | + DISPLAY_DEVICE_VGA_COMPATIBLE; + + if (monitor.dwFlags & MONITORINFOF_PRIMARY) + lpDisplayDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE; + + if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID)) + memcpy(lpDisplayDevice->DeviceID, device_deviceid, sizeof(device_deviceid)); + if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey)) + lpDisplayDevice->DeviceKey[0] = 0; + } + else + { + if (i != 0) + /* one monitor per adapter */ + return FALSE; + + if (strcmpW(lpDevice, device_name) != 0) + return FALSE; + + strcpyW(lpDisplayDevice->DeviceName, lpDevice); + strcatW(lpDisplayDevice->DeviceName, monitor0W); + + memcpy(lpDisplayDevice->DeviceString, monitor_string, sizeof(monitor_string)); + + lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED; + + if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID)) + memcpy(lpDisplayDevice->DeviceID, device_deviceid, sizeof(device_deviceid)); + if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey)) + lpDisplayDevice->DeviceKey[0] = 0; + }
return TRUE; } diff --git a/include/wingdi.h b/include/wingdi.h index 1851654194..03b7ed2ce4 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -3318,13 +3318,17 @@ DECL_WINELIB_TYPE_AW(DISPLAY_DEVICE) DECL_WINELIB_TYPE_AW(PDISPLAY_DEVICE) DECL_WINELIB_TYPE_AW(LPDISPLAY_DEVICE)
-/* DISPLAY_DEVICE.StateFlags (?)*/ +/* DISPLAY_DEVICE.StateFlags, adapter flags */ #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
+/* DISPLAY_DEVICE.StateFlags, monitor flags */ +#define DISPLAY_DEVICE_ACTIVE 0x00000001 +#define DISPLAY_DEVICE_ATTACHED 0x00000002 + typedef struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO { POINTL PathSourceSize;
Turns out Ken already did this (better) almost 4 years ago, so nevermind:
https://www.winehq.org/pipermail/wine-devel/2014-March/103665.html
Andrew
On Wed, Feb 07, 2018 at 01:18:49PM -0600, Andrew Eikum wrote:
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On my 2-monitor setup this results in:
for device 0, got name: \\.\DISPLAY1, string: X11 Windowing System, flags: 0x15 for device 0 sub 0, got name: \\.\DISPLAY1\Monitor0, string: Generic PnP Monitor, flags: 0x3 for device 1, got name: \\.\DISPLAY1, string: X11 Windowing System, flags: 0x11 for device 1 sub 0, got name: \\.\DISPLAY1\Monitor0, string: Generic PnP Monitor, flags: 0x3
Which nearly matches Windows 10 on the same hardware. The differences are the 2nd device should be DISPLAY2, not DISPLAY1; and the primary adapter comes 2nd on Windows.
However, DISPLAY1 is hard-coded at least in gdi32, winex11, and winemac, so I hard-coded it here as well. This results in both monitors and adapters having the same name, which is clumsy. But it is sufficient to fix Unity games displaying on the non-primary monitor by default.
dlls/user32/misc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++---------- include/wingdi.h | 6 +++- 2 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 895ccce312..96d5212725 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -243,11 +243,13 @@ DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd) return 1; }
-static const WCHAR primary_device_name[] = {'\','\','.','\','D','I','S','P','L','A','Y','1',0}; -static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ', +static const WCHAR device_name[] = {'\','\','.','\','D','I','S','P','L','A','Y','1',0}; +static const WCHAR device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ', 'S','y','s','t','e','m',0}; -static const WCHAR primary_device_deviceid[] = {'P','C','I','\','V','E','N','_','0','0','0','0','&', +static const WCHAR monitor_string[] = {'G','e','n','e','r','i','c',' ','P','n','P',' ','M','o','n','i','t','o','r',0}; +static const WCHAR device_deviceid[] = {'P','C','I','\','V','E','N','_','0','0','0','0','&', 'D','E','V','_','0','0','0','0',0}; +static const WCHAR monitor0W[] = {'\','M','o','n','i','t','o','r','0',0};
/***********************************************************************
EnumDisplayDevicesA (USER32.@)
@@ -282,29 +284,87 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpD return TRUE; }
+struct edd_enum_info +{
- UINT idx;
- UINT desired;
- HMONITOR hmon;
+};
+static BOOL CALLBACK edd_enum( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp ) +{
- struct edd_enum_info *info = (struct edd_enum_info *)lp;
- if (info->idx == info->desired)
- {
info->hmon = monitor;
return FALSE;
- }
- info->idx++;
- return TRUE;
+}
/***********************************************************************
EnumDisplayDevicesW (USER32.@)
*/ BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags ) {
- FIXME("(%s,%d,%p,0x%08x), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
- TRACE("(%s, %d, %p, 0x%08x)\n", debugstr_w(lpDevice), i, lpDisplayDevice, dwFlags);
- if (i)
- if (!lpDisplayDevice) return FALSE;
- memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
- memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
- lpDisplayDevice->StateFlags =
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
DISPLAY_DEVICE_PRIMARY_DEVICE |
DISPLAY_DEVICE_VGA_COMPATIBLE;
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
memcpy(lpDisplayDevice->DeviceID, primary_device_deviceid, sizeof(primary_device_deviceid));
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
lpDisplayDevice->DeviceKey[0] = 0;
if (!lpDevice)
{
struct edd_enum_info info = {0};
MONITORINFO monitor = {0};
/* one adapter per monitor */
info.desired = i;
EnumDisplayMonitors(0, NULL, edd_enum, (LPARAM)&info);
if (info.hmon == NULL)
return FALSE;
monitor.cbSize = sizeof(monitor);
if (!GetMonitorInfoW(info.hmon, &monitor))
return FALSE;
memcpy(lpDisplayDevice->DeviceName, device_name, sizeof(device_name));
memcpy(lpDisplayDevice->DeviceString, device_string, sizeof(device_string));
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
DISPLAY_DEVICE_VGA_COMPATIBLE;
if (monitor.dwFlags & MONITORINFOF_PRIMARY)
lpDisplayDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
memcpy(lpDisplayDevice->DeviceID, device_deviceid, sizeof(device_deviceid));
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
lpDisplayDevice->DeviceKey[0] = 0;
}
else
{
if (i != 0)
/* one monitor per adapter */
return FALSE;
if (strcmpW(lpDevice, device_name) != 0)
return FALSE;
strcpyW(lpDisplayDevice->DeviceName, lpDevice);
strcatW(lpDisplayDevice->DeviceName, monitor0W);
memcpy(lpDisplayDevice->DeviceString, monitor_string, sizeof(monitor_string));
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED;
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
memcpy(lpDisplayDevice->DeviceID, device_deviceid, sizeof(device_deviceid));
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
lpDisplayDevice->DeviceKey[0] = 0;
}
return TRUE;
} diff --git a/include/wingdi.h b/include/wingdi.h index 1851654194..03b7ed2ce4 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -3318,13 +3318,17 @@ DECL_WINELIB_TYPE_AW(DISPLAY_DEVICE) DECL_WINELIB_TYPE_AW(PDISPLAY_DEVICE) DECL_WINELIB_TYPE_AW(LPDISPLAY_DEVICE)
-/* DISPLAY_DEVICE.StateFlags (?)*/ +/* DISPLAY_DEVICE.StateFlags, adapter flags */ #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
+/* DISPLAY_DEVICE.StateFlags, monitor flags */ +#define DISPLAY_DEVICE_ACTIVE 0x00000001 +#define DISPLAY_DEVICE_ATTACHED 0x00000002
typedef struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO { POINTL PathSourceSize; -- 2.16.1