From 25167fb286822c93582457815bcf069fef040976 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Wed, 14 Aug 2019 16:23:55 +0800 Subject: [PATCH] winex11.drv: Make screen helpers independent of Xinerama. So that other display device handlers such as XRandR can be introduced because they might report a virtual screen size with different top-left corner and the primary screen may be different as well. Signed-off-by: Zhiyi Zhang Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/winex11.drv/display.c | 70 +++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/xinerama.c | 33 ----------------- 2 files changed, 70 insertions(+), 33 deletions(-) diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index a0f84892453..f96fd93a547 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -104,6 +104,34 @@ static const WCHAR monitor_hardware_idW[] = { 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r',0,0}; static struct x11drv_display_device_handler handler; +static RECT virtual_screen_rect; +static RECT primary_monitor_rect; + +POINT virtual_screen_to_root(INT x, INT y) +{ + POINT pt; + pt.x = x - virtual_screen_rect.left; + pt.y = y - virtual_screen_rect.top; + return pt; +} + +POINT root_to_virtual_screen(INT x, INT y) +{ + POINT pt; + pt.x = x + virtual_screen_rect.left; + pt.y = y + virtual_screen_rect.top; + return pt; +} + +RECT get_virtual_screen_rect(void) +{ + return virtual_screen_rect; +} + +RECT get_primary_monitor_rect(void) +{ + return primary_monitor_rect; +} void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *new_handler) { @@ -293,6 +321,9 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY, (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0)) goto done; + UnionRect(&virtual_screen_rect, &virtual_screen_rect, &monitor->rc_monitor); + if (video_index == 0) + primary_monitor_rect = monitor->rc_monitor; /* RcWork */ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY, (const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0)) @@ -317,6 +348,9 @@ static void prepare_devices(HKEY video_hkey) HDEVINFO devinfo; DWORD i = 0; + SetRectEmpty(&virtual_screen_rect); + SetRectEmpty(&primary_monitor_rect); + /* Remove all monitors */ devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, displayW, NULL, 0); while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data)) @@ -365,6 +399,36 @@ static void cleanup_devices(void) SetupDiDestroyDeviceInfoList(devinfo); } +/* Initialize virtual screen rect and primary monitor rect for current process */ +static void init_screen_rects(void) +{ + SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + HDEVINFO devinfo; + DWORD type; + DWORD i = 0; + RECT rect; + + /* Already initialized */ + if (!IsRectEmpty(&virtual_screen_rect)) + return; + + devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, displayW, NULL, 0); + while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data)) + { + if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, &type, (BYTE *)&rect, + sizeof(rect), NULL, 0)) + ERR("Failed to get monitor size property\n"); + + UnionRect(&virtual_screen_rect, &virtual_screen_rect, &rect); + if (i == 1) + primary_monitor_rect = rect; + } + SetupDiDestroyDeviceInfoList(devinfo); + + TRACE("virtual screen rect:%s primary monitor rect:%s\n", wine_dbgstr_rect(&virtual_screen_rect), + wine_dbgstr_rect(&primary_monitor_rect)); +} + void X11DRV_DisplayDevices_Init(BOOL force) { static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t',0}; @@ -393,7 +457,10 @@ void X11DRV_DisplayDevices_Init(BOOL force) /* Avoid unnecessary reinit */ if (!force && disposition != REG_CREATED_NEW_KEY) + { + init_screen_rects(); goto done; + } TRACE("via %s\n", wine_dbgstr_a(handler.name)); @@ -440,6 +507,9 @@ void X11DRV_DisplayDevices_Init(BOOL force) adapters = NULL; } + TRACE("virtual screen rect:%s primary monitor rect:%s\n", wine_dbgstr_rect(&virtual_screen_rect), + wine_dbgstr_rect(&primary_monitor_rect)); + done: cleanup_devices(); SetupDiDestroyDeviceInfoList(monitor_devinfo); diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 75ef3a2a999..370d34e9cde 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -35,8 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv); -static RECT virtual_screen_rect; - static MONITORINFOEXW default_monitor = { sizeof(default_monitor), /* cbSize */ @@ -161,32 +159,6 @@ static inline int query_screens(void) #endif /* SONAME_LIBXINERAMA */ -POINT virtual_screen_to_root( INT x, INT y ) -{ - POINT pt; - pt.x = x - virtual_screen_rect.left; - pt.y = y - virtual_screen_rect.top; - return pt; -} - -POINT root_to_virtual_screen( INT x, INT y ) -{ - POINT pt; - pt.x = x + virtual_screen_rect.left; - pt.y = y + virtual_screen_rect.top; - return pt; -} - -RECT get_virtual_screen_rect(void) -{ - return virtual_screen_rect; -} - -RECT get_primary_monitor_rect(void) -{ - return get_primary()->rcMonitor; -} - static BOOL xinerama_get_gpus( struct x11drv_gpu **new_gpus, int *count ) { static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0}; @@ -349,7 +321,6 @@ void xinerama_init( unsigned int width, unsigned int height ) } primary = get_primary(); - SetRectEmpty( &virtual_screen_rect ); /* coordinates (0,0) have to point to the primary monitor origin */ OffsetRect( &rect, -primary->rcMonitor.left, -primary->rcMonitor.top ); @@ -357,7 +328,6 @@ void xinerama_init( unsigned int width, unsigned int height ) { OffsetRect( &monitors[i].rcMonitor, rect.left, rect.top ); OffsetRect( &monitors[i].rcWork, rect.left, rect.top ); - UnionRect( &virtual_screen_rect, &virtual_screen_rect, &monitors[i].rcMonitor ); TRACE( "monitor 0x%x: %s work %s%s\n", i, wine_dbgstr_rect(&monitors[i].rcMonitor), wine_dbgstr_rect(&monitors[i].rcWork), @@ -373,7 +343,4 @@ void xinerama_init( unsigned int width, unsigned int height ) handler.pFreeAdapters = xinerama_free_adapters; handler.pFreeMonitors = xinerama_free_monitors; X11DRV_DisplayDevices_SetHandler( &handler ); - - TRACE( "virtual size: %s primary: %s\n", - wine_dbgstr_rect(&virtual_screen_rect), wine_dbgstr_rect(&primary->rcMonitor) ); }