diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2023-11-27 13:42:13 +0100 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2024-03-20 09:05:36 +0100 |
commit | 5b05a299126e621f11977c75318975c850b98c93 (patch) | |
tree | 6a214ed62edb16608cde16124a3aeb56621f0e0b | |
parent | 6a09cd2d20a6e6dfdb1efdbcbeb823ad99930a4d (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.c | 37 | ||||
-rw-r--r-- | hw/xwayland/xwayland-output.h | 1 |
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; |