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