From 98d13ef3af738ad9186b5c5a027e874d1bc1dfbc Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Thu, 22 Sep 2022 16:36:33 +0300 Subject: homescreen: Support for bound_ok and bound_fail events This adds support for version 2 of the protocol, but to also provide an example for other clients how to use it. Bug-AGL: SPEC-4502 Signed-off-by: Marius Vlad Change-Id: I710026bf293280d7aec2aa5d6e4528965840e23c --- homescreen/src/main.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp index 2c2f7c0..4a13607 100644 --- a/homescreen/src/main.cpp +++ b/homescreen/src/main.cpp @@ -32,9 +32,16 @@ #include "wayland-agl-shell-desktop-client-protocol.h" #include "shell.h" +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + struct shell_data { struct agl_shell *shell; struct agl_shell_desktop *shell_desktop; + bool wait_for_bound; + bool bound_ok; + int ver; }; static void @@ -62,6 +69,31 @@ agl_shell_desktop_state_app(void *data, homescreenHandler->deactivateApp(app_id); } +static void +agl_shell_bound_ok(void *data, struct agl_shell *agl_shell) +{ + struct shell_data *shell_data = static_cast(data); + shell_data->wait_for_bound = false; + + shell_data->bound_ok = true; +} + +static void +agl_shell_bound_fail(void *data, struct agl_shell *agl_shell) +{ + struct shell_data *shell_data = static_cast(data); + shell_data->wait_for_bound = false; + + shell_data->bound_ok = false; +} + +#ifdef AGL_SHELL_BOUND_OK_SINCE_VERSION +static const struct agl_shell_listener shell_listener = { + agl_shell_bound_ok, + agl_shell_bound_fail, +}; +#endif + static const struct agl_shell_desktop_listener shell_desktop_listener = { agl_shell_desktop_application, agl_shell_desktop_state_app @@ -69,7 +101,7 @@ static const struct agl_shell_desktop_listener shell_desktop_listener = { static void global_add(void *data, struct wl_registry *reg, uint32_t name, - const char *interface, uint32_t) + const char *interface, uint32_t ver) { struct shell_data *shell_data = static_cast(data); @@ -77,9 +109,20 @@ global_add(void *data, struct wl_registry *reg, uint32_t name, return; if (strcmp(interface, agl_shell_interface.name) == 0) { - shell_data->shell = static_cast( - wl_registry_bind(reg, name, &agl_shell_interface, 1) - ); + if (ver >= 2) { + shell_data->shell = + static_cast( + wl_registry_bind(reg, name, &agl_shell_interface, MIN(2, ver))); +#ifdef AGL_SHELL_BOUND_OK_SINCE_VERSION + agl_shell_add_listener(shell_data->shell, &shell_listener, data); +#endif + } else { + shell_data->shell = + static_cast( + wl_registry_bind(reg, name, &agl_shell_interface, 1)); + } + shell_data->ver = ver; + } if (strcmp(interface, agl_shell_desktop_interface.name) == 0) { @@ -117,6 +160,14 @@ getWlOutput(QPlatformNativeInterface *native, QScreen *screen) return static_cast(output); } +static struct wl_display * +getWlDisplay(QPlatformNativeInterface *native) +{ + return static_cast( + native->nativeResourceForIntegration("display") + ); +} + static void register_agl_shell(QPlatformNativeInterface *native, struct shell_data *shell_data) @@ -124,9 +175,7 @@ register_agl_shell(QPlatformNativeInterface *native, struct shell_data *shell_da struct wl_display *wl; struct wl_registry *registry; - wl = static_cast( - native->nativeResourceForIntegration("display") - ); + wl = getWlDisplay(native); registry = wl_display_get_registry(wl); wl_registry_add_listener(registry, ®istry_listener, shell_data); @@ -248,7 +297,8 @@ int main(int argc, char *argv[]) QGuiApplication app(argc, argv); const char *screen_name; bool is_demo_val = false; - struct shell_data shell_data = { nullptr, nullptr }; + int ret = 0; + struct shell_data shell_data = { nullptr, nullptr, true, false, 0 }; QPlatformNativeInterface *native = qApp->platformNativeInterface(); screen_name = getenv("HOMESCREEN_START_SCREEN"); @@ -277,6 +327,22 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + qDebug() << "agl-shell interface is at version " << shell_data.ver; + if (shell_data.ver >= 2) { + while (ret != -1 && shell_data.wait_for_bound) { + ret = wl_display_dispatch(getWlDisplay(native)); + + if (shell_data.wait_for_bound) + continue; + } + + if (!shell_data.bound_ok) { + qInfo() << "agl_shell extension already in use by other shell client."; + exit(EXIT_FAILURE); + } + } + + std::shared_ptr agl_shell{shell_data.shell, agl_shell_destroy}; Shell *aglShell = new Shell(agl_shell, &app); -- cgit 1.2.3-korg