Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57610
This attempt to fix a regression which is caused by XRandR enumerated output/crtc changing during the display device initial enumeration.
The user setup uses an external display and somehow XRandR enumerates the first (non-primary) monitor and its mode without being able to find a primary output/crtc (and uses that first monitor position as primary as fallback). Then, when the second (primary) monitor and its modes are enumerated it actually finds it and uses its as it should. This results in both monitor modes being positioned at 0x0, which breaks various things later on.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57610 --- dlls/win32u/sysparams.c | 54 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 15c85a44e13..cd8337877e4 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1855,6 +1855,45 @@ static void monitor_get_info( struct monitor *monitor, MONITORINFO *info, UINT d } }
+/* display_lock mutex must be held */ +static struct source *find_primary_source(void) +{ + struct source *source; + + LIST_FOR_EACH_ENTRY(source, &sources, struct source, entry) + if (source->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) + return source; + + WARN( "Failed to find primary source.\n" ); + return NULL; +} + +/* display_lock mutex must be held */ +static void update_primary_source_offset(void) +{ + struct source *primary = NULL, *source; + struct monitor *monitor; + + if (!(primary = find_primary_source())) + { + WARN( "Failed to find primary source\n" ); + return; + } + + LIST_FOR_EACH_ENTRY( source, &sources, struct source, entry ) + { + source->current.dmPosition.x -= primary->current.dmPosition.x; + source->current.dmPosition.y -= primary->current.dmPosition.y; + source->physical.dmPosition.x -= primary->physical.dmPosition.x; + source->physical.dmPosition.y -= primary->physical.dmPosition.y; + } + + LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + { + OffsetRect( &monitor->rc_work, -primary->current.dmPosition.x, -primary->current.dmPosition.y ); + } +} + /* display_lock must be held */ static void set_winstation_monitors( BOOL increment ) { @@ -2057,6 +2096,7 @@ static BOOL update_display_cache_from_registry( UINT64 serial ) if ((ret = !list_empty( &sources ) && !list_empty( &monitors ))) last_query_display_time = key.LastWriteTime.QuadPart;
+ update_primary_source_offset(); set_winstation_monitors( FALSE ); release_display_device_init_mutex( mutex ); return ret; @@ -2241,6 +2281,7 @@ static void commit_display_devices( struct device_manager_ctx *ctx ) add_gpu( gpu->name, &gpu->pci_id, &gpu->uuid, ctx ); }
+ update_primary_source_offset(); set_winstation_monitors( TRUE ); }
@@ -3238,19 +3279,6 @@ static struct source *find_source_by_index( UINT index ) return NULL; }
-/* display_lock mutex must be held */ -static struct source *find_primary_source(void) -{ - struct source *source; - - LIST_FOR_EACH_ENTRY(source, &sources, struct source, entry) - if (source->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) - return source; - - WARN( "Failed to find primary source.\n" ); - return NULL; -} - /* display_lock mutex must be held */ static struct source *find_source_by_name( UNICODE_STRING *name ) {
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57610 --- dlls/winex11.drv/xrandr.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 48b579e87e3..81473c2979b 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1164,13 +1164,6 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct gdi_monitor **ne monitors[0] = monitors[primary_index]; monitors[primary_index] = tmp; } - - /* Make sure the primary monitor origin is at (0, 0) */ - for (i = 0; i < monitor_count; i++) - { - OffsetRect( &monitors[i].rc_monitor, -primary_rect.left, -primary_rect.top ); - OffsetRect( &monitors[i].rc_work, -primary_rect.left, -primary_rect.top ); - } }
*new_monitors = monitors; @@ -1462,7 +1455,6 @@ static BOOL xrandr14_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) XRRModeInfo *mode_info = NULL; XRRCrtcInfo *crtc_info = NULL; BOOL ret = FALSE; - RECT primary; INT mode_idx;
pthread_mutex_lock( &xrandr_mutex ); @@ -1535,10 +1527,8 @@ static BOOL xrandr14_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) mode->dmPelsHeight = crtc_info->height; mode->dmDisplayFlags = 0; mode->dmDisplayFrequency = get_frequency( mode_info ); - /* Convert RandR coordinates to virtual screen coordinates */ - primary = get_primary_rect( screen_resources ); - mode->dmPosition.x = crtc_info->x - primary.left; - mode->dmPosition.y = crtc_info->y - primary.top; + mode->dmPosition.x = crtc_info->x; + mode->dmPosition.y = crtc_info->y; ret = TRUE;
done:
Superseded by MR 7136
This merge request was closed by Zhiyi Zhang.