xserver: Branch 'master' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 11 15:48:11 UTC 2023


 hw/xwayland/xwayland-cvt.c    |   62 +++++++++++++++++++++++++++++++-----------
 hw/xwayland/xwayland-output.c |   21 ++------------
 2 files changed, 50 insertions(+), 33 deletions(-)

New commits:
commit eb20ba039a1acca8a291eef095388893e327adc0
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Apr 25 11:33:12 2023 +0200

    xwayland: Use our CVT function for fixed mode as well
    
    Now that our CVT function is able to deal with non-standard modes, we
    can safely use it for the fixed mode as well.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 661e1828d..738c3320f 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -1086,11 +1086,8 @@ xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
 {
     RRModePtr *modes = NULL;
     RRModePtr mode;
-    xRRModeInfo mode_info = { 0, };
-    char mode_name[128];
     int i, nmodes, current;
 
-
     modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
     if (!modes) {
         ErrorF("Failed to allocated RandR modes\n");
@@ -1115,21 +1112,11 @@ xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
     }
 
     if (!current) {
-        /* Add the current mode as it's not part of the fake modes.
-         * Not using libcvt as the size is set from the command line and
-         * may not be a valid CVT mode.
-         */
-        mode_info.width = current_width;
-        mode_info.height = current_height;
-        mode_info.hTotal = current_width;
-        mode_info.vTotal = current_height;
-        mode_info.dotClock = 60 * 1000 * 1000;
-
-        snprintf(mode_name, sizeof(mode_name), "%dx%d",
-                 current_width, current_height);
-        mode_info.nameLength = strlen(mode_name);
+        /* Add the current mode as it's not part of the fake modes. */
+        mode = xwayland_cvt(current_width, current_height, 60, 0, 0);
 
-        modes[nmodes++] = RRModeGet(&mode_info, mode_name);
+        if (mode)
+            modes[nmodes++] = mode;
     }
 
     qsort(modes, nmodes, sizeof(RRModePtr), mode_sort);
commit ad2d461dec84b33a7fa0784776f3eee7bd6c55f4
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Apr 24 16:26:19 2023 +0200

    xwayland: Do not round non-standard modes
    
    Currently, Xwayland uses libxcvt to generate the mode info and then
    passes that to RRModeGet() to generate a RRMode.
    
    However, libxcvt may round down the width to match the horizontal
    granularity (8), and that's a problem when the Wayland compositor is
    running a non-standard size (like, e.g. running nested with a custom
    size) because XRandR would report a width smaller than the actual size.
    
    To avoid that, check whether the CVT computed size differs from the
    expected size, and fallback to a simpler computation not doing any
    rounding if that's the case.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1540
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>

diff --git a/hw/xwayland/xwayland-cvt.c b/hw/xwayland/xwayland-cvt.c
index ba8cbc9d1..0fc4ae82a 100644
--- a/hw/xwayland/xwayland-cvt.c
+++ b/hw/xwayland/xwayland-cvt.c
@@ -29,30 +29,60 @@
 
 #include "xwayland-cvt.h"
 
-RRModePtr
-xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
-             Bool interlaced)
+static void
+xwayland_modinfo_from_cvt(xRRModeInfo *modeinfo,
+                          int hdisplay, int vdisplay, float vrefresh,
+                          Bool reduced, Bool interlaced)
 {
     struct libxcvt_mode_info *libxcvt_mode_info;
-    char name[128];
-    xRRModeInfo modeinfo;
 
     libxcvt_mode_info =
         libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
 
-    memset(&modeinfo, 0, sizeof modeinfo);
-    modeinfo.width      = libxcvt_mode_info->hdisplay;
-    modeinfo.height     = libxcvt_mode_info->vdisplay;
-    modeinfo.dotClock   = libxcvt_mode_info->dot_clock * 1000.0;
-    modeinfo.hSyncStart = libxcvt_mode_info->hsync_start;
-    modeinfo.hSyncEnd   = libxcvt_mode_info->hsync_end;
-    modeinfo.hTotal     = libxcvt_mode_info->htotal;
-    modeinfo.vSyncStart = libxcvt_mode_info->vsync_start;
-    modeinfo.vSyncEnd   = libxcvt_mode_info->vsync_end;
-    modeinfo.vTotal     = libxcvt_mode_info->vtotal;
-    modeinfo.modeFlags  = libxcvt_mode_info->mode_flags;
+    modeinfo->width      = libxcvt_mode_info->hdisplay;
+    modeinfo->height     = libxcvt_mode_info->vdisplay;
+    modeinfo->dotClock   = libxcvt_mode_info->dot_clock * 1000.0;
+    modeinfo->hSyncStart = libxcvt_mode_info->hsync_start;
+    modeinfo->hSyncEnd   = libxcvt_mode_info->hsync_end;
+    modeinfo->hTotal     = libxcvt_mode_info->htotal;
+    modeinfo->vSyncStart = libxcvt_mode_info->vsync_start;
+    modeinfo->vSyncEnd   = libxcvt_mode_info->vsync_end;
+    modeinfo->vTotal     = libxcvt_mode_info->vtotal;
+    modeinfo->modeFlags  = libxcvt_mode_info->mode_flags;
 
     free(libxcvt_mode_info);
+}
+
+static void
+xwayland_modinfo_from_values(xRRModeInfo *modeinfo,
+                             int hdisplay, int vdisplay, float vrefresh)
+{
+    modeinfo->width  = hdisplay;
+    modeinfo->height = vdisplay;
+    modeinfo->hTotal = hdisplay;
+    modeinfo->vTotal = vdisplay;
+    modeinfo->dotClock = hdisplay * vdisplay * vrefresh;
+}
+
+RRModePtr
+xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
+             Bool interlaced)
+{
+    char name[128];
+    xRRModeInfo modeinfo = { 0, };
+
+    xwayland_modinfo_from_cvt(&modeinfo,
+                              hdisplay, vdisplay, vrefresh, reduced, interlaced);
+
+    /* Horizontal granularity in libxcvt is 8, so if our horizontal size is not
+     * divisible by 8, libxcvt will round it down, and we will advertise a wrong
+     * size to our XRandR clients. Fallback to a simpler method in that case.
+     */
+    if (modeinfo.width != hdisplay || modeinfo.height != vdisplay) {
+        memset(&modeinfo, 0, sizeof(xRRModeInfo));
+        xwayland_modinfo_from_values(&modeinfo,
+                                     hdisplay, vdisplay, vrefresh);
+    }
 
     snprintf(name, sizeof name, "%dx%d",
              modeinfo.width, modeinfo.height);


More information about the xorg-commit mailing list