From aa849658c5643a1018b96316210574d9fc460c8b Mon Sep 17 00:00:00 2001 From: Ryan Gonzalez Date: Mon, 23 Aug 2021 12:53:19 -0500 Subject: [PATCH] xwayland: Allow controlling global output scale via properties This adds a new property, _XWAYLAND_GLOBAL_OUTPUT_SCALE, to control the global output scale from the compositor. --- hw/xwayland/xwayland-screen.c | 55 +++++++++++++++++++++++++++++++---- hw/xwayland/xwayland-screen.h | 1 + 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index c1fe34de0..aeb1c11f2 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -133,6 +133,37 @@ xwl_screen_get_first_output(struct xwl_screen *xwl_screen) return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link); } +static void +xwl_screen_set_global_scale_from_property(struct xwl_screen *screen, + PropertyPtr prop) +{ + CARD32 *propdata; + + if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) { + // TODO: handle warnings more cleanly. + LogMessageVerb(X_WARNING, 0, "Bad value for property %s.\n", + NameForAtom(prop->propertyName)); + return; + } + + propdata = prop->data; + xwl_screen_set_global_scale(screen, propdata[0]); +} + +static void +xwl_screen_update_property(struct xwl_screen *screen, + PropertyStateRec *propstate) +{ + switch (propstate->state) { + case PropertyNewValue: + xwl_screen_set_global_scale_from_property(screen, propstate->prop); + break; + case PropertyDelete: + xwl_screen_set_global_scale(screen, 1); + break; + } +} + static void xwl_property_callback(CallbackListPtr *pcbl, void *closure, void *calldata) @@ -140,19 +171,24 @@ xwl_property_callback(CallbackListPtr *pcbl, void *closure, ScreenPtr screen = closure; PropertyStateRec *rec = calldata; struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; if (rec->win->drawable.pScreen != screen) return; - xwl_window = xwl_window_get(rec->win); - if (!xwl_window) - return; - xwl_screen = xwl_screen_get(screen); - if (rec->prop->propertyName == xwl_screen->allow_commits_prop) + if (rec->prop->propertyName == xwl_screen->allow_commits_prop) { + struct xwl_window *xwl_window; + + xwl_window = xwl_window_get(rec->win); + if (!xwl_window) + return; + xwl_window_update_property(xwl_window, rec); + } + else if (rec->prop->propertyName == xwl_screen->global_output_scale_prop) { + xwl_screen_update_property(xwl_screen, rec); + } } Bool @@ -566,6 +602,7 @@ Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) { static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS"; + static const char global_output_scale[] = "_XWAYLAND_GLOBAL_OUTPUT_SCALE"; struct xwl_screen *xwl_screen; Pixel red_mask, blue_mask, green_mask; int ret, bpc, green_bpc, i; @@ -768,6 +805,12 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) if (xwl_screen->allow_commits_prop == BAD_RESOURCE) return FALSE; + xwl_screen->global_output_scale_prop = MakeAtom(global_output_scale, + strlen(global_output_scale), + TRUE); + if (xwl_screen->global_output_scale_prop == BAD_RESOURCE) + return FALSE; + AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); xwl_screen_roundtrip(xwl_screen); diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index 812387d99..7446829d0 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -109,6 +109,7 @@ struct xwl_screen { struct glamor_context *glamor_ctx; Atom allow_commits_prop; + Atom global_output_scale_prop; /* The preferred GLVND vendor. If NULL, "mesa" is assumed. */ const char *glvnd_vendor;