summaryrefslogtreecommitdiffstats
path: root/shell/src
diff options
context:
space:
mode:
Diffstat (limited to 'shell/src')
-rw-r--r--shell/src/main.cpp191
-rw-r--r--shell/src/shell.cpp35
-rw-r--r--shell/src/shell.h45
3 files changed, 271 insertions, 0 deletions
diff --git a/shell/src/main.cpp b/shell/src/main.cpp
new file mode 100644
index 0000000..75cb6ec
--- /dev/null
+++ b/shell/src/main.cpp
@@ -0,0 +1,191 @@
+#include <QGuiApplication>
+#include <QCommandLineParser>
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlComponent>
+#include <QtQml/qqml.h>
+#include <QWindow>
+#include <QQuickWindow>
+#include <QScreen>
+#include <QTimer>
+#include <qpa/qplatformnativeinterface.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <wayland-client.h>
+#include <time.h>
+
+#include "wayland-agl-shell-client-protocol.h"
+#include "shell.h"
+
+// QGuiApplication::platformNativeInterface
+
+static void global_add(void *data, struct wl_registry *reg, uint32_t name,
+ const char *interface, uint32_t)
+{
+ 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, 1)
+ );
+ }
+}
+
+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,
+};
+
+wl_surface *
+getWlSurface(QWindow *window)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+
+ //void *surf = QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window);
+ void *surf = native->nativeResourceForWindow("surface", window);
+ return static_cast<struct ::wl_surface *>(surf);
+}
+
+struct wl_display *
+getWlDisplay(void)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+
+ //void *display = QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("display");
+ void *display = native->nativeResourceForIntegration("display");
+ return static_cast<struct ::wl_display *>(display);
+}
+
+struct wl_compositor *
+getWlCompositor(QWindow *window)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+
+ //void *compositor = QGuiApplication::platformNativeInterface()->nativeResourceForWindow("compositor", window);
+ void *compositor = native->nativeResourceForWindow("compositor", window);
+ return static_cast<struct ::wl_compositor*>(compositor);
+}
+
+struct wl_output *
+getWlOutput(QWindow *window)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+
+ //void *output = QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", window->screen());
+ void *output = native->nativeResourceForScreen("output", window->screen());
+ return static_cast<struct ::wl_output*>(output);
+}
+
+struct wl_output *
+getWlOutput(QScreen *screen)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+
+ //void *output = QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", window->screen());
+ void *output = native->nativeResourceForScreen("output", screen);
+ return static_cast<struct ::wl_output*>(output);
+}
+
+static struct wl_surface *
+create_component(QQmlComponent *comp, QScreen *screen)
+{
+ QObject *obj = comp->create();
+ obj->setParent(screen);
+
+ QWindow *win = qobject_cast<QWindow *>(obj);
+ return getWlSurface(win);
+}
+
+
+int main(int argc, char *argv[])
+{
+ setenv("QT_QPA_PLATFORM", "wayland", 1);
+ QGuiApplication app(argc, argv);
+ app.setDesktopFileName("homescreen-demo-ci");
+
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ struct agl_shell *agl_shell = nullptr;
+
+ struct wl_display *wl;
+ struct wl_registry *registry;
+
+ char *xdgdir = getenv("XDG_RUNTIME_DIR");
+ if (xdgdir) {
+ qInfo() << "xdg runtime dir " << xdgdir;
+ }
+
+ wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display"));
+ registry = wl_display_get_registry(wl);
+
+ wl_registry_add_listener(registry, &registry_listener, &agl_shell);
+ // Roundtrip to get all globals advertised by the compositor
+ wl_display_roundtrip(wl);
+ wl_registry_destroy(registry);
+
+ // check if binding to agl shell worked
+ std::shared_ptr<struct agl_shell> shell{agl_shell, agl_shell_destroy};
+
+ QQmlApplicationEngine engine;
+ QQmlContext *context = engine.rootContext();
+
+ context->setContextProperty("shell", new Shell(shell, &app));
+
+ QQmlComponent bg_comp(&engine, QUrl("qrc:/bg.qml"));
+ qInfo() << bg_comp.errors();
+
+ QQmlComponent top_comp(&engine, QUrl("qrc:/top.qml"));
+ qInfo() << top_comp.errors();
+
+ QQmlComponent bot_comp(&engine, QUrl("qrc:/bottom.qml"));
+ qInfo() << bot_comp.errors();
+
+ QQmlComponent left_comp(&engine, QUrl("qrc:/left.qml"));
+ qInfo() << left_comp.errors();
+
+ QQmlComponent right_comp(&engine, QUrl("qrc:/right.qml"));
+ qInfo() << right_comp.errors();
+
+ struct wl_surface *bg, *top, *bot;
+ struct wl_output *output;
+
+ QScreen *screen = app.primaryScreen();
+ qDebug() << "primary screen is " << screen->name();
+
+ if (qApp->screens().length() > 1) {
+ for (auto &ss: qApp->screens()) {
+ bg = create_component(&bg_comp, ss);
+ output = getWlOutput(ss);
+ qDebug() << "Seting background to screen " << ss->name();
+ agl_shell_set_background(agl_shell, bg, output);
+ }
+ } else {
+ bg = create_component(&bg_comp, screen);
+ output = getWlOutput(screen);
+ qDebug() << "Seting background to screen " << screen->name();
+ agl_shell_set_background(agl_shell, bg, output);
+ }
+
+ top = create_component(&top_comp, screen);
+ bot = create_component(&bot_comp, screen);
+
+ agl_shell_set_panel(agl_shell, bot, output, AGL_SHELL_EDGE_BOTTOM);
+ agl_shell_set_panel(agl_shell, top, output, AGL_SHELL_EDGE_TOP);
+
+ /* need to wait a bit in order for qtwayland to start dispatching */
+ QTimer::singleShot(500, [agl_shell](){
+ agl_shell_ready(agl_shell);
+ });
+
+ return app.exec();
+}
diff --git a/shell/src/shell.cpp b/shell/src/shell.cpp
new file mode 100644
index 0000000..15e16c4
--- /dev/null
+++ b/shell/src/shell.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 Collabora Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QGuiApplication>
+#include <QDebug>
+#include "shell.h"
+#include <qpa/qplatformnativeinterface.h>
+#include <stdio.h>
+
+void Shell::activate_app(QWindow *win, const QString &app_id)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ QScreen *screen = win->screen();
+ struct wl_output *output;
+
+ output = static_cast<struct wl_output *>(native->nativeResourceForScreen(
+ "output", const_cast<QScreen *>(screen)
+ ));
+
+ agl_shell_activate_app(this->shell.get(),
+ app_id.toStdString().c_str(), output);
+}
diff --git a/shell/src/shell.h b/shell/src/shell.h
new file mode 100644
index 0000000..34dc539
--- /dev/null
+++ b/shell/src/shell.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 Collabora Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SHELLHANDLER_H
+#define SHELLHANDLER_H
+
+#include <QObject>
+#include <QString>
+#include <QScreen>
+#include <QWindow>
+#include <memory>
+#include "wayland-agl-shell-client-protocol.h"
+
+/*
+ * Basic type to wrap the agl_shell wayland object into a QObject, so that it
+ * can be used in callbacks from QML.
+ */
+
+class Shell : public QObject
+{
+Q_OBJECT
+ std::shared_ptr<struct agl_shell> shell;
+
+public:
+ Shell(std::shared_ptr<struct agl_shell> shell, QObject *parent = nullptr) :
+ QObject(parent), shell(shell)
+ {}
+public slots:
+ void activate_app(QWindow *win, const QString &app_id);
+};
+
+#endif // SHELLHANDLER_H