From 2700bc60451642176eccd16c7383bf144861f5c2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 28 Jul 2022 12:22:14 +1000 Subject: [PATCH] xwayland: add support for the XWAYLAND extension This extension exists to serve one purpose: reliably identifying Xwayland. Previous attempts at doing so included querying root window properties, output names or input device names. All these attempts are somewhat unreliable. Instead, let's use an extension - where that extension is present we have an Xwayland server. Clients should never need to do anything but check whether the extension exists through XQueryExtension or search through XListExtensions. This extension provides a single QueryVersion request only, and that is only to provide future compatibility if we ever need anything other than "this extension exists" functionality. https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/54 Signed-off-by: Peter Hutterer --- .gitlab-ci.yml | 2 +- .gitlab-ci/debian-install.sh | 4 +- hw/xwayland/xwayland.c | 94 ++++++++++++++++++++++++++++++ include/meson.build | 1 + include/xwayland-config.h.meson.in | 3 + meson.build | 1 + 6 files changed, 102 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd2effcb2..92b023913 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,7 @@ variables: FDO_UPSTREAM_REPO: xorg/xserver FDO_DISTRIBUTION_VERSION: bullseye-slim FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh' - FDO_DISTRIBUTION_TAG: "2022-07-01" + FDO_DISTRIBUTION_TAG: "2022-08-11" include: - project: 'freedesktop/ci-templates' diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh index f8f83b701..8913e17ea 100644 --- a/.gitlab-ci/debian-install.sh +++ b/.gitlab-ci/debian-install.sh @@ -120,8 +120,8 @@ ninja -C _build -j${FDO_CI_CONCURRENT:-4} install cd .. rm -rf libxcvt -# xserver requires xorgproto >= 2021.4.99.2 for XI 2.3.99.1 -git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2021.4.99.2 +# xserver requires xorgproto >= 2022.2 for XWAYLAND +git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2022.2 pushd xorgproto ./autogen.sh make -j${FDO_CI_CONCURRENT:-4} install diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index a15b1f3ee..9a1f4a6da 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -299,10 +299,104 @@ xwl_log_handler(const char *format, va_list args) FatalError("%s", msg); } +#ifdef XWL_HAS_XWAYLAND_EXTENSION +#include + +Bool noXWaylandExtension = FALSE; + +static int +ProcXwlQueryVersion(ClientPtr client) +{ + xXwlQueryVersionReply reply; + int major, minor; + + REQUEST(xXwlQueryVersionReq); + REQUEST_SIZE_MATCH(xXwlQueryVersionReq); + + if (version_compare(stuff->majorVersion, stuff->minorVersion, + XWAYLAND_EXTENSION_MAJOR, + XWAYLAND_EXTENSION_MINOR) < 0) { + major = stuff->majorVersion; + minor = stuff->minorVersion; + } else { + major = XWAYLAND_EXTENSION_MAJOR; + minor = XWAYLAND_EXTENSION_MINOR; + } + + reply = (xXwlQueryVersionReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .majorVersion = major, + .minorVersion = minor, + }; + + if (client->swapped) { + swaps(&reply.sequenceNumber); + swapl(&reply.length); + swaps(&reply.majorVersion); + swaps(&reply.minorVersion); + } + + WriteReplyToClient(client, sizeof(reply), &reply); + return Success; +} + +static int _X_COLD +SProcXwlQueryVersion(ClientPtr client) +{ + REQUEST(xXwlQueryVersionReq); + + swaps(&stuff->length); + REQUEST_AT_LEAST_SIZE(xXwlQueryVersionReq); + swaps(&stuff->majorVersion); + swaps(&stuff->minorVersion); + + return ProcXwlQueryVersion(client); +} + +static int +ProcXWaylandDispatch(ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_XwlQueryVersion: + return ProcXwlQueryVersion(client); + } + return BadRequest; +} + +static int +SProcXWaylandDispatch(ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_XwlQueryVersion: + return SProcXwlQueryVersion(client); + } + return BadRequest; +} + +static void +xwlExtensionInit(void) +{ + AddExtension(XWAYLAND_EXTENSION_NAME, + XwlNumberEvents, XwlNumberErrors, + ProcXWaylandDispatch, SProcXWaylandDispatch, + NULL, StandardMinorOpcode); +} + +#endif + static const ExtensionModule xwayland_extensions[] = { #ifdef XF86VIDMODE { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, #endif +#ifdef XWL_HAS_XWAYLAND_EXTENSION + { xwlExtensionInit, XWAYLAND_EXTENSION_NAME, &noXWaylandExtension }, +#endif }; void diff --git a/include/meson.build b/include/meson.build index 57466dc79..5e50e1fad 100644 --- a/include/meson.build +++ b/include/meson.build @@ -416,6 +416,7 @@ xwayland_data = configuration_data() xwayland_data.set('XWL_HAS_GLAMOR', build_glamor and (gbm_dep.found() or build_eglstream) ? '1' : false) xwayland_data.set('XWL_HAS_EGLSTREAM', build_eglstream ? '1' : false) xwayland_data.set('XWL_HAS_LIBDECOR', have_libdecor ? '1' : false) +xwayland_data.set('XWL_HAS_XWAYLAND_EXTENSION', xwaylandproto_dep.found() ? '1' : false) configure_file(output : 'xwayland-config.h', input : 'xwayland-config.h.meson.in', diff --git a/include/xwayland-config.h.meson.in b/include/xwayland-config.h.meson.in index bb121e355..c254c1fd3 100644 --- a/include/xwayland-config.h.meson.in +++ b/include/xwayland-config.h.meson.in @@ -12,3 +12,6 @@ /* Build Xwayland with libdecor support*/ #mesondefine XWL_HAS_LIBDECOR + +/* Build Xwayland with XWAYLAND extension */ +#mesondefine XWL_HAS_XWAYLAND_EXTENSION diff --git a/meson.build b/meson.build index 0b129cc80..2498025a2 100644 --- a/meson.build +++ b/meson.build @@ -94,6 +94,7 @@ xf86bigfontproto_dep = dependency('xf86bigfontproto', version: '>= 1.2.0', fallb xf86vidmodeproto_dep = dependency('xf86vidmodeproto', version: '>= 2.2.99.1', fallback: ['xorgproto', 'ext_xorgproto']) applewmproto_dep = dependency('applewmproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'], required: false) xshmfence_dep = dependency('xshmfence', version: '>= 1.1', required: false) +xwaylandproto_dep = dependency('xwaylandproto', version: '>= 1.0', fallback: ['xorgproto', 'ext_xorgproto'], required: false) pixman_dep = dependency('pixman-1') libbsd_dep = dependency('libbsd', required: false)