summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2023-11-27 13:42:13 +0100
committerOlivier Fourdan <ofourdan@redhat.com>2024-03-20 09:05:36 +0100
commit5b05a299126e621f11977c75318975c850b98c93 (patch)
tree6a214ed62edb16608cde16124a3aeb56621f0e0b
parent6a09cd2d20a6e6dfdb1efdbcbeb823ad99930a4d (diff)
xwayland: Use CRTC transforms
Advertise the scaling factor applied to the Xwayland output using the mechanism of CRTC transforms. That allows for X11 clients to query the scale factor using XRandR. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-By: Kenny Levinsen <kl@kl.wtf> Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1197>
-rw-r--r--hw/xwayland/xwayland-output.c37
-rw-r--r--hw/xwayland/xwayland-output.h1
2 files changed, 36 insertions, 2 deletions
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 23c9733d2..8a4a55312 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -945,6 +945,8 @@ xwl_output_destroy(struct xwl_output *xwl_output)
{
if (xwl_output->lease_connector)
wp_drm_lease_connector_v1_destroy(xwl_output->lease_connector);
+ if (xwl_output->transform)
+ free(xwl_output->transform);
if (xwl_output->xdg_output)
zxdg_output_v1_destroy(xwl_output->xdg_output);
if (xwl_output->output)
@@ -1142,10 +1144,41 @@ mode_sort(const void *left, const void *right)
return (*mode_b)->mode.width - (*mode_a)->mode.width;
}
+static void
+xwl_output_set_transform(struct xwl_output *xwl_output)
+{
+ pixman_fixed_t transform_xscale;
+ RRModePtr mode;
+
+ mode = xwl_output_find_mode(xwl_output, xwl_output->mode_width, xwl_output->mode_height);
+ if (!mode) {
+ ErrorF("XWAYLAND: Failed to find mode for %ix%i\n",
+ xwl_output->mode_width, xwl_output->mode_height);
+ return;
+ }
+
+ if (xwl_output->transform == NULL) {
+ xwl_output->transform = xnfalloc(sizeof(RRTransformRec));
+ RRTransformInit(xwl_output->transform);
+ }
+
+ transform_xscale = pixman_double_to_fixed(xwl_output->xscale);
+ pixman_transform_init_scale(&xwl_output->transform->transform,
+ transform_xscale, transform_xscale);
+ pixman_f_transform_init_scale(&xwl_output->transform->f_transform,
+ xwl_output->xscale, xwl_output->xscale);
+ pixman_f_transform_invert(&xwl_output->transform->f_inverse,
+ &xwl_output->transform->f_transform);
+
+ RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0,
+ xwl_output->transform, 1, &xwl_output->randr_output);
+}
+
void
xwl_output_set_xscale(struct xwl_output *xwl_output, double xscale)
{
xwl_output->xscale = xscale;
+ xwl_output_set_transform(xwl_output);
}
Bool
@@ -1209,8 +1242,7 @@ xwl_output_set_mode_fixed(struct xwl_output *xwl_output, RRModePtr mode)
round((double) mode->mode.width * xwl_output->xscale),
round((double) mode->mode.height * xwl_output->xscale));
- RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0,
- NULL, 1, &xwl_output->randr_output);
+ xwl_output_set_transform(xwl_output);
}
static Bool
@@ -1264,6 +1296,7 @@ xwl_screen_init_randr_fixed(struct xwl_screen *xwl_screen)
}
RRCrtcSetRotations (xwl_output->randr_crtc, RR_Rotate_0);
RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
+ RRCrtcSetTransformSupport(xwl_output->randr_crtc, TRUE);
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
xwl_randr_add_modes_fixed(xwl_output,
diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h
index 7923a7e1a..5138d5e88 100644
--- a/hw/xwayland/xwayland-output.h
+++ b/hw/xwayland/xwayland-output.h
@@ -48,6 +48,7 @@ struct xwl_output {
struct xwl_screen *xwl_screen;
RROutputPtr randr_output;
RRCrtcPtr randr_crtc;
+ RRTransformPtr transform;
/* only for regular outputs */
struct wl_output *output;