[PATCH 1/2] winex11.drv: Ignore disconnected outputs when finding mirroring slaves.

Zhiyi Zhang zzhang at codeweavers.com
Mon Apr 20 03:37:17 CDT 2020


Some graphics drivers keep CRTCs attached to disconnected outputs.
This could cause the XRandR 1.4 display device handler to incorrectly
mark outputs as mirrored. So enumerate outputs instead of CRTCs when
finding mirroring slaves.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48932
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/winex11.drv/xrandr.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index 578b68269e4..bef52128f21 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -769,7 +769,7 @@ static BOOL xrandr14_get_adapters( ULONG_PTR gpu_id, struct x11drv_adapter **new
     XRRScreenResources *screen_resources = NULL;
     XRRProviderInfo *provider_info = NULL;
     XRRCrtcInfo *enum_crtc_info, *crtc_info = NULL;
-    XRROutputInfo *output_info = NULL;
+    XRROutputInfo *enum_output_info, *output_info = NULL;
     RROutput *outputs;
     INT crtc_count, output_count;
     INT primary_adapter = 0;
@@ -833,24 +833,34 @@ static BOOL xrandr14_get_adapters( ULONG_PTR gpu_id, struct x11drv_adapter **new
         if (!output_info->crtc || !crtc_info->mode)
             detached = TRUE;
 
-        /* Ignore crtc mirroring slaves because mirrored monitors are under the same adapter */
+        /* Ignore mirroring output slaves because mirrored monitors are under the same adapter */
         mirrored = FALSE;
         if (!detached)
         {
-            for (j = 0; j < screen_resources->ncrtc; ++j)
+            for (j = 0; j < screen_resources->noutput; ++j)
             {
-                enum_crtc_info = pXRRGetCrtcInfo( gdi_display, screen_resources, screen_resources->crtcs[j] );
-                if (!enum_crtc_info)
-                    goto done;
+                enum_output_info = pXRRGetOutputInfo( gdi_display, screen_resources, screen_resources->outputs[j] );
+                if (!enum_output_info)
+                    continue;
 
-                /* Some crtcs on different providers may have the same coordinates, aka mirrored.
-                 * Choose the crtc with the lowest value as primary and the rest will then be slaves
-                 * in a mirroring set */
+                if (enum_output_info->connection != RR_Connected || !enum_output_info->crtc)
+                {
+                    pXRRFreeOutputInfo( enum_output_info );
+                    continue;
+                }
+
+                enum_crtc_info = pXRRGetCrtcInfo( gdi_display, screen_resources, enum_output_info->crtc );
+                pXRRFreeOutputInfo( enum_output_info );
+                if (!enum_crtc_info)
+                    continue;
+
+                /* Some outputs may have the same coordinates, aka mirrored. Choose the output with
+                 * the lowest value as primary and the rest will then be slaves in a mirroring set */
                 if (crtc_info->x == enum_crtc_info->x &&
                     crtc_info->y == enum_crtc_info->y &&
                     crtc_info->width == enum_crtc_info->width &&
                     crtc_info->height == enum_crtc_info->height &&
-                    output_info->crtc > screen_resources->crtcs[j])
+                    outputs[i] > screen_resources->outputs[j])
                 {
                     mirrored = TRUE;
                     pXRRFreeCrtcInfo( enum_crtc_info );
-- 
2.20.1




More information about the wine-devel mailing list