From 074abfe097e31d382772aaa5fc8fdee45bbc2656 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 25 Jun 2019 16:38:38 +0800 Subject: [PATCH] winex11.drv: Use generic EnumDisplayMonitors. Signed-off-by: Zhiyi Zhang Signed-off-by: Alexandre Julliard --- dlls/user32/driver.c | 10 ------ dlls/user32/sysparams.c | 58 +++++++++++++++++++++++++++++++ dlls/user32/user_private.h | 2 ++ dlls/winex11.drv/desktop.c | 1 + dlls/winex11.drv/display.c | 5 +++ dlls/winex11.drv/winex11.drv.spec | 1 - dlls/winex11.drv/x11drv.h | 2 ++ dlls/winex11.drv/xinerama.c | 15 +------- 8 files changed, 69 insertions(+), 25 deletions(-) diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index 5b2929245c9..bf600708edf 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -354,16 +354,6 @@ static LONG CDECL nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode return DISP_CHANGE_FAILED; } -static BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp ) -{ - RECT r = {0, 0, 640, 480}; - - TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp); - - proc(NULLDRV_DEFAULT_HMONITOR, hdc, &r, lp); - return TRUE; -} - static BOOL CDECL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags ) { return FALSE; diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 4d644b9edf0..17becff651a 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -251,6 +251,9 @@ static const WCHAR CSrgb[] = {'%','u',' ','%','u',' ','%','u',0}; /* Wine specific monitor properties */ DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2); +DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3); + +#define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1)) /* Strings for monitor functions */ static const WCHAR DEFAULT_ADAPTER_NAME[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0}; @@ -3815,6 +3818,61 @@ static BOOL CALLBACK enum_mon_callback( HMONITOR monitor, HDC hdc, LPRECT rect, #endif } +BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp ) +{ + SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + USEROBJECTFLAGS flags; + HWINSTA winstation; + BOOL success = FALSE; + HDEVINFO devinfo; + RECT monitor_rect; + DWORD state_flags; + HANDLE mutex; + DWORD type; + DWORD i = 0; + + TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp); + + /* Use SetupAPI to get monitors only if window station has visible display surfaces */ + winstation = GetProcessWindowStation(); + if (GetUserObjectInformationA( winstation, UOI_FLAGS, &flags, sizeof(flags), NULL ) && (flags.dwFlags & WSF_VISIBLE)) + { + mutex = get_display_device_init_mutex(); + devinfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_MONITOR, NULL, NULL, 0 ); + while (SetupDiEnumDeviceInfo( devinfo, i++, &device_data )) + { + /* Inactive monitors don't get enumerated */ + if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type, + (BYTE *)&state_flags, sizeof(state_flags), NULL, 0 ) + || !(state_flags & DISPLAY_DEVICE_ACTIVE)) + continue; + + if (SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, &type, + (BYTE *)&monitor_rect, sizeof(monitor_rect), NULL, 0 )) + { + if (!proc( (HMONITOR)(UINT_PTR)i, hdc, &monitor_rect, lp )) + { + SetupDiDestroyDeviceInfoList( devinfo ); + release_display_device_init_mutex( mutex ); + return FALSE; + } + success = TRUE; + } + } + SetupDiDestroyDeviceInfoList( devinfo ); + release_display_device_init_mutex( mutex ); + } + + /* Fallback to report one monitor if using SetupAPI failed */ + if (!success) + { + RECT default_rect = {0, 0, 640, 480}; + if (!proc( NULLDRV_DEFAULT_HMONITOR, hdc, &default_rect, lp )) + return FALSE; + } + return TRUE; +} + /*********************************************************************** * EnumDisplayMonitors (USER32.@) */ diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 514cf6753f4..a503ebe4db2 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -122,6 +122,8 @@ extern const USER_DRIVER *USER_Driver DECLSPEC_HIDDEN; extern void USER_unload_driver(void) DECLSPEC_HIDDEN; +extern BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp ) DECLSPEC_HIDDEN; + struct received_message_info; enum user_obj_type diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index a0495c44b16..ecbcd6b3813 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -304,6 +304,7 @@ void X11DRV_resize_desktop( unsigned int width, unsigned int height ) resize_data.old_virtual_rect = get_virtual_screen_rect(); xinerama_init( width, height ); + X11DRV_DisplayDevices_Init( TRUE ); resize_data.new_virtual_rect = get_virtual_screen_rect(); if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index ce2c568ad8e..d6969b0cfe8 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -41,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv); /* Wine specific monitor properties */ DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2); +DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3); static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0}; static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0}; @@ -276,6 +277,10 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32, (const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0)) goto done; + /* RcMonitor */ + if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY, + (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0)) + goto done; ret = TRUE; done: diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 614f0b90f43..5b00a5dc5d6 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -20,7 +20,6 @@ @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos @ cdecl ClipCursor(ptr) X11DRV_ClipCursor @ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) X11DRV_ChangeDisplaySettingsEx -@ cdecl EnumDisplayMonitors(long ptr ptr long) X11DRV_EnumDisplayMonitors @ cdecl EnumDisplaySettingsEx(ptr long ptr long) X11DRV_EnumDisplaySettingsEx @ cdecl GetMonitorInfo(long ptr) X11DRV_GetMonitorInfo @ cdecl CreateDesktopWindow(long) X11DRV_CreateDesktopWindow diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index ed5e2683919..a6b07699a7a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -695,6 +695,8 @@ struct x11drv_monitor { /* Name */ WCHAR name[128]; + /* RcMonitor in MONITORINFO struct */ + RECT rc_monitor; /* StateFlags in DISPLAY_DEVICE struct */ DWORD state_flags; }; diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index e4015314509..c8fa63f4594 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -321,6 +321,7 @@ static BOOL xinerama_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor * && !IsRectEmpty( &monitors[first].rcMonitor ))) { lstrcpyW( monitor[index].name, generic_nonpnp_monitorW ); + monitor[index].rc_monitor = monitors[i].rcMonitor; /* Xinerama only reports monitors already attached */ monitor[index].state_flags = DISPLAY_DEVICE_ATTACHED; if (!IsRectEmpty( &monitors[i].rcMonitor )) @@ -410,17 +411,3 @@ BOOL CDECL X11DRV_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info ) lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitors[i].szDevice ); return TRUE; } - - -/*********************************************************************** - * X11DRV_EnumDisplayMonitors (X11DRV.@) - */ -BOOL CDECL X11DRV_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp ) -{ - int i; - - for (i = 0; i < nb_monitors; i++) - if (!proc( index_to_monitor(i), 0, &monitors[i].rcMonitor, lp )) return FALSE; - - return TRUE; -}