From 42e34498f87a8ff1afb0c5fa962432815190dad0 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 2 May 2020 03:52:55 +0200 Subject: [PATCH] xwayland: Add XWAYLAND protocol extension to configure a global hidpi scaling factor for all xwayland windows. This puts the extension scaffolding in place, in order to implement the actual scaling in a next commit. --- hw/xwayland/meson.build | 2 + hw/xwayland/xwayland-ext.c | 134 ++++++++++++++++++++++++++++++++++ hw/xwayland/xwayland-ext.h | 76 +++++++++++++++++++ hw/xwayland/xwayland-screen.c | 8 ++ hw/xwayland/xwayland-screen.h | 3 + hw/xwayland/xwayland.c | 4 + 6 files changed, 227 insertions(+) create mode 100644 hw/xwayland/xwayland-ext.c create mode 100644 hw/xwayland/xwayland-ext.h diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build index 37c39497c3..f0f9d748aa 100644 --- a/hw/xwayland/meson.build +++ b/hw/xwayland/meson.build @@ -6,6 +6,8 @@ srcs = [ 'xwayland-cursor.h', 'xwayland-drm-lease.h', 'xwayland-drm-lease.c', + 'xwayland-ext.c', + 'xwayland-ext.h', 'xwayland-glamor.h', 'xwayland-glx.h', 'xwayland-pixmap.c', diff --git a/hw/xwayland/xwayland-ext.c b/hw/xwayland/xwayland-ext.c new file mode 100644 index 0000000000..1668dda570 --- /dev/null +++ b/hw/xwayland/xwayland-ext.c @@ -0,0 +1,134 @@ +/* + * Copyright © 2020 Dario Nieuwenhuis + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "dixstruct.h" + +#include +#include "misc.h" +#include "os.h" +#include "extinit.h" + +#include "xwayland-ext.h" +#include "xwayland-screen.h" + +#ifdef DEBUG +#define DEBUG_P(x) DebugF(x"\n") +#else +#define DEBUG_P(x) /**/ +#endif + +static int XwaylandErrorBase; + +static int +ProcXwaylandQueryVersion(ClientPtr client) +{ + xXwaylandQueryVersionReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .majorVersion = XWAYLAND_MAJOR_VERSION, + .minorVersion = XWAYLAND_MINOR_VERSION + }; + + DEBUG_P("XwaylandQueryVersion"); + + REQUEST_SIZE_MATCH(xXwaylandQueryVersionReq); + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swaps(&rep.majorVersion); + swaps(&rep.minorVersion); + } + WriteToClient(client, sizeof(xXwaylandQueryVersionReply), &rep); + return Success; +} + +static int +ProcXwaylandSetScale(ClientPtr client) +{ + DEBUG_P("XwaylandSetScale"); + + REQUEST(xXwaylandSetScaleReq); + REQUEST_SIZE_MATCH(xXwaylandSetScaleReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + ScreenPtr pScreen = screenInfo.screens[stuff->screen]; + + struct xwl_screen* xwl_screen = xwl_screen_get(pScreen); + if (xwl_screen == NULL) + return BadImplementation; + + if(stuff->scale < 1) + return BadValue; + + xwl_screen_set_global_scale(xwl_screen, stuff->scale); + + return Success; +} + +static int +ProcXwaylandDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_XwaylandQueryVersion: + return ProcXwaylandQueryVersion(client); + case X_XwaylandSetScale: + return ProcXwaylandSetScale(client); + default: + return BadRequest; + } +} + +static int _X_COLD +SProcXwaylandDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + default: + return BadRequest; + } +} + +void +xwlExtensionInit(void) +{ + ExtensionEntry* extEntry; + if ((extEntry = AddExtension(XWAYLANDNAME, + XwaylandNumberEvents, + XwaylandNumberErrors, + ProcXwaylandDispatch, + SProcXwaylandDispatch, + NULL, StandardMinorOpcode))) { + XwaylandErrorBase = extEntry->errorBase; + } +} + diff --git a/hw/xwayland/xwayland-ext.h b/hw/xwayland/xwayland-ext.h new file mode 100644 index 0000000000..be8fb39d92 --- /dev/null +++ b/hw/xwayland/xwayland-ext.h @@ -0,0 +1,76 @@ +/* + * Copyright © 2020 Dario Nieuwenhuis + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef XWAYLAND_EXT_H +#define XWAYLAND_EXT_H + +#include + +#define XWAYLANDNAME "XWAYLAND" +#define XwaylandNumberEvents 0 +#define XwaylandNumberErrors 0 + +#define XWAYLAND_MAJOR_VERSION 1 /* current version numbers */ +#define XWAYLAND_MINOR_VERSION 0 + +#define X_XwaylandQueryVersion 0 +#define X_XwaylandSetScale 1 + + +typedef struct _XwaylandQueryVersion { + CARD8 reqType; /* always XwaylandReqCode */ + CARD8 xwaylandReqType; /* always X_XwaylandQueryVersion */ + CARD16 length; +} xXwaylandQueryVersionReq; +#define sz_xXwaylandQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD16 majorVersion; /* major version of Xwayland */ + CARD16 minorVersion; /* minor version of Xwayland */ + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xXwaylandQueryVersionReply; +#define sz_xXwaylandQueryVersionReply 32 + + +typedef struct { + CARD8 reqType; /* always XwaylandReqCode */ + CARD8 xwaylandReqType; /* always X_XwaylandSetScale */ + CARD16 length; + CARD16 screen; + CARD16 scale; +} xXwaylandSetScaleReq; +#define sz_xXwaylandSetScaleReq 8 + +void xwlExtensionInit(void); + +#endif /* XWAYLAND_EXT_H */ diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index b249dbb083..ddf6336565 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -580,6 +580,13 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen) xwl_give_up("could not connect to wayland server\n"); } +void +xwl_screen_set_global_scale( struct xwl_screen *xwl_screen, int32_t scale) +{ + struct xwl_output *it; + xwl_screen->global_output_scale = scale; +} + Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) { @@ -615,6 +622,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) #ifdef XWL_HAS_GLAMOR xwl_screen->glamor = 1; #endif + xwl_screen->global_output_scale = 1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-rootless") == 0) { diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index f04d431c74..e1e610f87d 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -73,6 +73,8 @@ struct xwl_screen { struct xorg_list damage_window_list; struct xorg_list window_list; + int32_t global_output_scale; + int wayland_fd; struct wl_display *display; struct wl_registry *registry; @@ -139,5 +141,6 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen); void xwl_surface_damage(struct xwl_screen *xwl_screen, struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height); +void xwl_screen_set_global_scale( struct xwl_screen *xwl_screen, int32_t scale); #endif /* XWAYLAND_SCREEN_H */ diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 21587dbb64..7a02515044 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -41,12 +41,15 @@ #include "xwayland-screen.h" #include "xwayland-vidmode.h" +#include "xwayland-ext.h" #ifdef XF86VIDMODE #include extern _X_EXPORT Bool noXFree86VidModeExtension; #endif +_X_EXPORT Bool noXwaylandExtension; + void ddxGiveUp(enum ExitCode error) { @@ -246,6 +249,7 @@ xwl_log_handler(const char *format, va_list args) static const ExtensionModule xwayland_extensions[] = { #ifdef XF86VIDMODE { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, + { xwlExtensionInit, XWAYLANDNAME, &noXwaylandExtension }, #endif };