summaryrefslogtreecommitdiffstats
path: root/app/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/main.cpp')
-rw-r--r--app/main.cpp171
1 files changed, 117 insertions, 54 deletions
diff --git a/app/main.cpp b/app/main.cpp
index 669341e..035f2d9 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include <QGuiApplication>
#include <QtCore/QDebug>
#include <QtCore/QCommandLineParser>
#include <QtCore/QUrlQuery>
@@ -24,17 +25,93 @@
#include <QtQml/qqml.h>
#include <QQuickWindow>
#include <QtQuickControls2/QQuickStyle>
+#include <qpa/qplatformnativeinterface.h>
#include <json-c/json.h>
-#include <qlibwindowmanager.h>
#include <qlibhomescreen.h>
#include <guimetadata.h>
#include "afbclient.h"
+#include "shell-desktop.h"
#include <iostream>
-// Disable window activation at launch by default, but keep option
-// for potential debug use.
-#define HIDE_AT_LAUNCH
+QString my_app_id = QString("alexa-viewer");
+
+// this and the agl-shell extension should be added in some kind of a wrapper
+// for easy usage
+static void
+global_add(void *data, struct wl_registry *reg, uint32_t name,
+ const char *interface, uint32_t version)
+{
+ struct agl_shell_desktop **shell =
+ static_cast<struct agl_shell_desktop **>(data);
+
+ if (strcmp(interface, agl_shell_desktop_interface.name) == 0) {
+ *shell = static_cast<struct agl_shell_desktop *>(
+ wl_registry_bind(reg, name, &agl_shell_desktop_interface, version)
+ );
+ }
+}
+
+static void
+global_remove(void *data, struct wl_registry *reg, uint32_t id)
+{
+ (void) data;
+ (void) reg;
+ (void) id;
+}
+
+static const struct wl_registry_listener registry_listener = {
+ global_add,
+ global_remove,
+};
+
+static void
+application_id_event(void *data, struct agl_shell_desktop *agl_shell_desktop,
+ const char *app_id)
+{
+ (void) data;
+ (void) agl_shell_desktop;
+ // un-used
+ qInfo() << "app_id: " << app_id;
+}
+
+static void
+application_id_state(void *data, struct agl_shell_desktop *agl_shell_desktop,
+ const char *app_id, const char *app_data, uint32_t app_state, uint32_t app_role)
+{
+ (void) data;
+ (void) app_data;
+ (void) app_role;
+ (void) app_state;
+ (void) app_id;
+ (void) agl_shell_desktop;
+
+ // un-used
+}
+
+static const struct agl_shell_desktop_listener agl_shell_desk_listener = {
+ application_id_event,
+ application_id_state,
+};
+
+static struct agl_shell_desktop *
+register_agl_shell_desktop(void)
+{
+ struct wl_display *wl;
+ struct wl_registry *registry;
+ struct agl_shell_desktop *shell = nullptr;
+
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display"));
+ registry = wl_display_get_registry(wl);
+
+ wl_registry_add_listener(registry, &registry_listener, &shell);
+ // Roundtrip to get all globals advertised by the compositor
+ wl_display_roundtrip(wl);
+ wl_registry_destroy(registry);
+
+ return shell;
+}
bool check_template_supported(json_object *data)
{
@@ -61,30 +138,32 @@ bool check_template_supported(json_object *data)
void async_event_cb(const char *event, json_object *data, void *closure)
{
+ Shell *aglShell;
if(!data)
return;
+ if (!closure)
+ return;
+
+ aglShell = static_cast<Shell *>(closure);
+
+ qDebug() << "got async_event_cb()";
if(!strcmp(event, "vshl-capabilities/setDestination")) {
// Slight hack here, there's currently no convenient place to hook up raising
// the navigation app when a route is set by Alexa, so do so here for now.
- if(closure != nullptr) {
- static_cast<QLibHomeScreen*>(closure)->showWindow("navigation", "normal");
- }
+ aglShell->activate_app(nullptr, "navigation", nullptr);
} else if(!strcmp(event, "vshl-capabilities/render_template")) {
// Raise ourselves, the UI code will receive the event as well and render it
- if(closure != nullptr) {
- if(!check_template_supported(data)) {
- qDebug() << "Unsupported template type, ignoring!";
- return;
- }
- static_cast<QLibHomeScreen*>(closure)->showWindow("alexa-viewer", "on_screen");
+ if(!check_template_supported(data)) {
+ qDebug() << "Unsupported template type, ignoring!";
+ return;
}
+ aglShell->activate_app(nullptr, my_app_id, nullptr);
} else if(!strcmp(event, "vshl-capabilities/clear_template")) {
// Hide ourselves
- if(closure != nullptr) {
- static_cast<QLibHomeScreen*>(closure)->hideWindow("alexa-viewer");
- }
+ aglShell->deactivate_app(my_app_id);
}
+
}
void subscribe_async_events(AfbClient &client)
@@ -128,9 +207,8 @@ void subscribe_async_events(AfbClient &client)
int main(int argc, char *argv[])
{
- QString graphic_role = QString("on_screen");
-
QGuiApplication app(argc, argv);
+ app.setDesktopFileName(my_app_id);
QCommandLineParser parser;
parser.addPositionalArgument("port", app.translate("main", "port for binding"));
@@ -155,52 +233,37 @@ int main(int argc, char *argv[])
bindingAddress.setQuery(query);
}
- // QLibWM
- QLibWindowmanager* qwmHandler = new QLibWindowmanager();
- int res;
- if((res = qwmHandler->init(port, token)) != 0){
- qCritical("init qlibwm err(%d)", res);
- return -1;
- }
- if((res = qwmHandler->requestSurface(graphic_role)) != 0) {
- qCritical("requestSurface error(%d)", res);
- return -1;
+ struct agl_shell_desktop *shell = register_agl_shell_desktop();
+ if (!shell) {
+ qDebug() << "agl_shell_desktop extension missing";
+ exit(EXIT_FAILURE);
}
- qwmHandler->set_event_handler(QLibWindowmanager::Event_SyncDraw,
- [qwmHandler, &graphic_role](json_object *object) {
- qwmHandler->endDraw(graphic_role);
- });
-
- // QLibHS
- QLibHomeScreen* qhsHandler = new QLibHomeScreen();
- qhsHandler->init(port, token.toStdString().c_str());
- qhsHandler->set_event_handler(QLibHomeScreen::Event_ShowWindow,
- [qwmHandler, &graphic_role](json_object *object){
- qDebug("Surface %s got showWindow\n", graphic_role.toStdString().c_str());
- qwmHandler->activateWindow(graphic_role, "on_screen");
- });
- qhsHandler->set_event_handler(QLibHomeScreen::Event_HideWindow,
- [qwmHandler, &graphic_role](json_object *object){
- qDebug("Surface %s got hideWindow\n", graphic_role.toStdString().c_str());
- qwmHandler->deactivateWindow(graphic_role);
- });
+
+ agl_shell_desktop_add_listener(shell, &agl_shell_desk_listener, NULL);
+
+ std::shared_ptr<struct agl_shell_desktop> agl_shell{shell, agl_shell_desktop_destroy};
+ Shell *aglShell = new Shell(agl_shell, &app);
+
+ // before loading the QML we can tell the compositor that we'd like to
+ // be a pop-up kind of window: we need to do this before creating the
+ // window itself (either engine load or any of the comp.create()), or
+ // we can use/designate another application to behave like that
+ //
+ // note that x and y initial positioning values have to be specified
+ // here (the last two args)
+ aglShell->set_window_props(nullptr, my_app_id,
+ AGL_SHELL_DESKTOP_APP_ROLE_POPUP, 0, 0);
// Load qml
QQmlApplicationEngine engine;
QQmlContext *context = engine.rootContext();
-
- context->setContextProperty("homescreen", qhsHandler);
+ context->setContextProperty("homescreen", aglShell);
context->setContextProperty("GuiMetadata", new GuiMetadata(bindingAddress, context));
engine.load(QUrl(QStringLiteral("qrc:/Main.qml")));
-#ifndef HIDE_AT_LAUNCH
- QObject *root = engine.rootObjects().first();
- QQuickWindow *window = qobject_cast<QQuickWindow *>(root);
- QObject::connect(window, SIGNAL(frameSwapped()), qwmHandler, SLOT(slotActivateWindow()));
-#endif
// Create app framework client to handle events when window is not visible
AfbClient client(port, token.toStdString());
- client.set_event_callback(async_event_cb, (void*) qhsHandler);
+ client.set_event_callback(async_event_cb, static_cast<void *>(aglShell));
subscribe_async_events(client);
return app.exec();