+#include "mastervolume.h"
+#include "homescreenhandler.h"
+#include "hmi-debug.h"
+
+// meson will define these
+#include QT_QPA_HEADER
+#include <wayland-client.h>
+
+#include "agl-shell-client-protocol.h"
+#include "shell.h"
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+struct shell_data {
+ struct agl_shell *shell;
+ HomescreenHandler *homescreenHandler;
+ bool wait_for_bound;
+ bool bound_ok;
+ int ver;
+};
+
+static void
+agl_shell_bound_ok(void *data, struct agl_shell *agl_shell)
+{
+ struct shell_data *shell_data = static_cast<struct shell_data *>(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<struct shell_data *>(data);
+ shell_data->wait_for_bound = false;
+
+ shell_data->bound_ok = false;
+}
+
+static void
+agl_shell_app_state(void *data, struct agl_shell *agl_shell,
+ const char *app_id, uint32_t state)
+{
+ struct shell_data *shell_data = static_cast<struct shell_data *>(data);
+ HomescreenHandler *homescreenHandler = shell_data->homescreenHandler;
+
+ if (!homescreenHandler)
+ return;
+
+ switch (state) {
+ case AGL_SHELL_APP_STATE_STARTED:
+ qDebug() << "Got AGL_SHELL_APP_STATE_STARTED for app_id " << app_id;
+ homescreenHandler->processAppStatusEvent(app_id, "started");
+ break;
+ case AGL_SHELL_APP_STATE_TERMINATED:
+ qDebug() << "Got AGL_SHELL_APP_STATE_TERMINATED for app_id " << app_id;
+ // handled by HomescreenHandler::processAppStatusEvent
+ break;
+ case AGL_SHELL_APP_STATE_ACTIVATED:
+ qDebug() << "Got AGL_SHELL_APP_STATE_ACTIVATED for app_id " << app_id;
+ homescreenHandler->addAppToStack(app_id);
+ break;
+ default:
+ break;
+ }
+}
+
+
+#ifdef AGL_SHELL_BOUND_OK_SINCE_VERSION
+static const struct agl_shell_listener shell_listener = {
+ agl_shell_bound_ok,
+ agl_shell_bound_fail,
+ agl_shell_app_state,
+};
+#endif
+
+static void
+global_add(void *data, struct wl_registry *reg, uint32_t name,
+ const char *interface, uint32_t ver)
+{
+ struct shell_data *shell_data = static_cast<struct shell_data *>(data);
+
+ if (!shell_data)
+ return;
+
+ if (strcmp(interface, agl_shell_interface.name) == 0) {
+ if (ver >= 2) {
+ shell_data->shell =
+ static_cast<struct agl_shell *>(
+ wl_registry_bind(reg, name, &agl_shell_interface, MIN(3, 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<struct agl_shell *>(
+ wl_registry_bind(reg, name, &agl_shell_interface, 1));
+ }
+ shell_data->ver = ver;
+
+ }
+}
+
+static void
+global_remove(void *data, struct wl_registry *reg, uint32_t id)
+{
+ /* Don't care */
+ (void) data;
+ (void) reg;
+ (void) id;
+}
+
+static const struct wl_registry_listener registry_listener = {
+ global_add,
+ global_remove,
+};
+
+static struct wl_surface *
+getWlSurface(QPlatformNativeInterface *native, QWindow *window)
+{
+ void *surf = native->nativeResourceForWindow("surface", window);
+ return static_cast<struct ::wl_surface *>(surf);
+}
+
+static struct wl_output *
+getWlOutput(QPlatformNativeInterface *native, QScreen *screen)
+{
+ void *output = native->nativeResourceForScreen("output", screen);
+ return static_cast<struct ::wl_output*>(output);
+}
+
+static struct wl_display *
+getWlDisplay(QPlatformNativeInterface *native)
+{
+ return static_cast<struct wl_display *>(
+ native->nativeResourceForIntegration("display")
+ );
+}