[PATCH 0/2] MR7110: Draft: win32u: Update current modes relative to the primary source.
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. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7110
From: Rémi Bernon <rbernon(a)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 ) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7110
From: Rémi Bernon <rbernon(a)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: -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7110
Superseded by MR 7136 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7110#note_91804
This merge request was closed by Zhiyi Zhang. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7110
participants (2)
-
Rémi Bernon -
Zhiyi Zhang (@zhiyi)