mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-30 19:00:08 +01:00
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 simply fix the hdisplay/vdisplay to match the given size if that's the case. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1540 Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1549 Reviewed-by: Michel Dänzer <mdaenzer@redhat.com> (cherry picked from commitad2d461dec) (cherry picked from commit2713383548) (cherry picked from commit814a04927d)
This commit is contained in:
parent
7cfa26d0b2
commit
9d2cc63a9a
1 changed files with 34 additions and 16 deletions
|
|
@ -29,30 +29,48 @@
|
|||
|
||||
#include "xwayland-cvt.h"
|
||||
|
||||
RRModePtr
|
||||
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
|
||||
Bool interlaced)
|
||||
static void
|
||||
xwayland_modeinfo_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);
|
||||
}
|
||||
|
||||
RRModePtr
|
||||
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
|
||||
Bool interlaced)
|
||||
{
|
||||
char name[128];
|
||||
xRRModeInfo modeinfo = { 0, };
|
||||
|
||||
xwayland_modeinfo_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 up, and we will advertise a wrong
|
||||
* size to our XRandR clients.
|
||||
* Force the width/height (i.e. simply increase blanking which should not
|
||||
* hurt anything), keeping the rest of the CVT mode timings unchanged.
|
||||
*/
|
||||
modeinfo.width = hdisplay;
|
||||
modeinfo.height = vdisplay;
|
||||
|
||||
snprintf(name, sizeof name, "%dx%d",
|
||||
modeinfo.width, modeinfo.height);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue