diff options
Diffstat (limited to 'app/main.cpp')
-rw-r--r-- | app/main.cpp | 220 |
1 files changed, 156 insertions, 64 deletions
diff --git a/app/main.cpp b/app/main.cpp index a5b9ece..3c460d5 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -16,22 +16,85 @@ */ #include <QtCore/QDebug> +#include <QGuiApplication> #include <QtCore/QCommandLineParser> #include <QtCore/QUrlQuery> #include <QtGui/QGuiApplication> #include <QtQml/QQmlApplicationEngine> #include <QtQml/QQmlContext> +#include <QtQml/QQmlComponent> #include <QtQml/qqml.h> #include <QQuickWindow> #include <QtQuickControls2/QQuickStyle> +#include <qpa/qplatformnativeinterface.h> +#include <QTimer> #include <glib.h> +#include <QDebug> +#include <QScreen> -#include <qlibwindowmanager.h> #include <signalcomposer.h> +#include <wayland-client.h> +#include "agl-shell-client-protocol.h" // Global indicating whether canned animation should run bool runAnimation = true; +static void +global_add(void *data, struct wl_registry *reg, uint32_t name, + const char *interface, uint32_t version) +{ + struct agl_shell **shell = static_cast<struct agl_shell **>(data); + if (strcmp(interface, agl_shell_interface.name) == 0) { + *shell = static_cast<struct agl_shell *>(wl_registry_bind(reg, + name, &agl_shell_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 struct agl_shell * +register_agl_shell(QPlatformNativeInterface *native) +{ + struct wl_display *wl; + struct wl_registry *registry; + struct agl_shell *shell = nullptr; + + wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display")); + registry = wl_display_get_registry(wl); + + wl_registry_add_listener(registry, ®istry_listener, &shell); + wl_display_roundtrip(wl); + wl_registry_destroy(registry); + + return shell; +} + +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); +} + void read_config(void) { GKeyFile* conf_file; @@ -64,69 +127,98 @@ void read_config(void) } +static struct wl_surface * +create_component(QPlatformNativeInterface *native, QQmlComponent *comp, + QScreen *screen, QObject **qobj) +{ + QObject *obj = comp->create(); + //QObject *screen_obj = new QScreen(screen); + obj->setParent(screen); + + QWindow *win = qobject_cast<QWindow *>(obj); + *qobj = obj; + + return getWlSurface(native, win); +} + + int main(int argc, char *argv[]) { - // Slight hack, using the homescreen role greatly simplifies things wrt - // the windowmanager - QString myname = QString("homescreen"); - - QGuiApplication app(argc, argv); - - QCommandLineParser parser; - parser.addPositionalArgument("port", app.translate("main", "port for binding")); - parser.addPositionalArgument("secret", app.translate("main", "secret for binding")); - parser.addHelpOption(); - parser.addVersionOption(); - parser.process(app); - QStringList positionalArguments = parser.positionalArguments(); - - QQmlApplicationEngine engine; - - if (positionalArguments.length() == 2) { - int port = positionalArguments.takeFirst().toInt(); - QString secret = positionalArguments.takeFirst(); - QUrl bindingAddress; - bindingAddress.setScheme(QStringLiteral("ws")); - bindingAddress.setHost(QStringLiteral("localhost")); - bindingAddress.setPort(port); - bindingAddress.setPath(QStringLiteral("/api")); - QUrlQuery query; - query.addQueryItem(QStringLiteral("token"), secret); - bindingAddress.setQuery(query); - QQmlContext *context = engine.rootContext(); - context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress); - - std::string token = secret.toStdString(); - QLibWindowmanager* qwm = new QLibWindowmanager(); - - // WindowManager - if(qwm->init(port, secret) != 0){ - exit(EXIT_FAILURE); - } - - // Request a surface as described in layers.json windowmanager’s file - if (qwm->requestSurface(myname) != 0) { - exit(EXIT_FAILURE); - } - - // Create an event callback against an event type. Here a lambda is called when SyncDraw event occurs - qwm->set_event_handler(QLibWindowmanager::Event_SyncDraw, [qwm, myname](json_object*) { - fprintf(stderr, "Surface got syncDraw!\n"); - qwm->endDraw(myname); - }); - - context->setContextProperty("SignalComposer", new SignalComposer(bindingAddress, context)); - read_config(); - context->setContextProperty("runAnimation", runAnimation); - - engine.load(QUrl(QStringLiteral("qrc:/cluster-gauges.qml"))); - - // Find the instantiated model QObject and connect the signals/slots - QList<QObject *> mobjs = engine.rootObjects(); - - QQuickWindow *window = qobject_cast<QQuickWindow *>(mobjs.first()); - QObject::connect(window, SIGNAL(frameSwapped()), qwm, SLOT(slotActivateSurface())); - } - - return app.exec(); + QString myname = QString("cluster-gauges"); + struct agl_shell *agl_shell; + struct wl_output *output; + + QObject *qobj_bg; + QScreen *screen; + + QGuiApplication app(argc, argv); + app.setDesktopFileName(myname); + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + + agl_shell = register_agl_shell(native); + if (!agl_shell) { + exit(EXIT_FAILURE); + } + + std::shared_ptr<struct agl_shell> shell{agl_shell, agl_shell_destroy}; + + screen = qApp->primaryScreen(); + output = getWlOutput(native, screen); + + QCommandLineParser parser; + parser.addPositionalArgument("port", app.translate("main", "port for binding")); + parser.addPositionalArgument("secret", app.translate("main", "secret for binding")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.process(app); + + QStringList positionalArguments = parser.positionalArguments(); + + QQmlApplicationEngine engine; + QQmlContext *context = engine.rootContext(); + + if (positionalArguments.length() == 2) { + int port = positionalArguments.takeFirst().toInt(); + QString secret = positionalArguments.takeFirst(); + + QUrl bindingAddress; + QUrlQuery query; + + struct wl_surface *bg; + + bindingAddress.setScheme(QStringLiteral("ws")); + bindingAddress.setHost(QStringLiteral("localhost")); + bindingAddress.setPort(port); + bindingAddress.setPath(QStringLiteral("/api")); + + query.addQueryItem(QStringLiteral("token"), secret); + bindingAddress.setQuery(query); + + read_config(); + + context->setContextProperty(QStringLiteral("bindingAddress"), + bindingAddress); + + context->setContextProperty("SignalComposer", + new SignalComposer(bindingAddress, + context)); + context->setContextProperty("runAnimation", runAnimation); + + QQmlComponent bg_comp(&engine, QUrl("qrc:/cluster-gauges.qml")); + qDebug() << bg_comp.errors(); + + bg = create_component(native, &bg_comp, screen, &qobj_bg); + + // set the surface as the background + agl_shell_set_background(agl_shell, bg, output); + + // instruct the compositor it can display after Qt has a chance + // to load everything + QTimer::singleShot(500, [agl_shell](){ + qDebug() << "agl_shell ready!"; + agl_shell_ready(agl_shell); + }); + } + + return app.exec(); } |