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 <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2022-07-28 12:22:14 +10:00
parent 190320795f
commit 2700bc6045
6 changed files with 102 additions and 3 deletions

View File

@ -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'

View File

@ -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

View File

@ -299,10 +299,104 @@ xwl_log_handler(const char *format, va_list args)
FatalError("%s", msg);
}
#ifdef XWL_HAS_XWAYLAND_EXTENSION
#include <X11/extensions/xwaylandproto.h>
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

View File

@ -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',

View File

@ -12,3 +12,6 @@
/* Build Xwayland with libdecor support*/
#mesondefine XWL_HAS_LIBDECOR
/* Build Xwayland with XWAYLAND extension */
#mesondefine XWL_HAS_XWAYLAND_EXTENSION

View File

@ -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)