From a3433100dccaca03c95bc03fd66939fb4eca6670 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 28 Sep 2019 15:23:11 +1200 Subject: Update to new weston design This split the panels into their own separate windows which can be managed by the compositor. It also makes use of the custom agl-shell wayland protocol for this. Signed-off-by: Scott Anderson --- homescreen.pro | 4 +- homescreen/homescreen.pro | 17 +++-- homescreen/protocol/agl-shell.xml | 100 +++++++++++++++++++++++++++ homescreen/qml/MediaArea.qml | 3 +- homescreen/qml/MediaAreaBlank.qml | 5 +- homescreen/qml/ShortcutArea.qml | 5 +- homescreen/qml/ShortcutIcon.qml | 11 +-- homescreen/qml/StatusArea.qml | 95 +++++++++++++++---------- homescreen/qml/TopArea.qml | 10 +-- homescreen/qml/background.qml | 15 ++++ homescreen/qml/bottompanel.qml | 14 ++++ homescreen/qml/main.qml | 32 ++------- homescreen/qml/qml.qrc | 3 + homescreen/qml/toppanel.qml | 15 ++++ homescreen/src/homescreenhandler.cpp | 121 -------------------------------- homescreen/src/homescreenhandler.h | 51 -------------- homescreen/src/main.cpp | 130 +++++++++++++++++++++++++---------- 17 files changed, 331 insertions(+), 300 deletions(-) create mode 100644 homescreen/protocol/agl-shell.xml create mode 100644 homescreen/qml/background.qml create mode 100644 homescreen/qml/bottompanel.qml create mode 100644 homescreen/qml/toppanel.qml delete mode 100644 homescreen/src/homescreenhandler.cpp delete mode 100644 homescreen/src/homescreenhandler.h diff --git a/homescreen.pro b/homescreen.pro index 7c49383..8f61890 100644 --- a/homescreen.pro +++ b/homescreen.pro @@ -17,8 +17,6 @@ TEMPLATE = subdirs load(configure) SUBDIRS = interfaces \ - homescreen \ - package + homescreen homescreen.depends = interfaces -package.depends += homescreen diff --git a/homescreen/homescreen.pro b/homescreen/homescreen.pro index 8baa90d..0ec86d4 100644 --- a/homescreen/homescreen.pro +++ b/homescreen/homescreen.pro @@ -15,12 +15,10 @@ TEMPLATE = app TARGET = HomeScreen -QT = qml quick dbus websockets -CONFIG += c++11 link_pkgconfig +QT = qml quick dbus websockets gui-private +CONFIG += c++11 link_pkgconfig wayland-scanner DESTDIR = $${OUT_PWD}/../package/root/bin -PKGCONFIG += qlibwindowmanager qtappfw afb-helpers-qt - -LIBS += -lhomescreen +PKGCONFIG += qtappfw afb-helpers-qt wayland-client include(../interfaces/interfaces.pri) @@ -29,15 +27,16 @@ SOURCES += \ src/statusbarmodel.cpp \ src/statusbarserver.cpp \ src/applicationlauncher.cpp \ - src/mastervolume.cpp \ - src/homescreenhandler.cpp + src/mastervolume.cpp + +WAYLANDCLIENTSOURCES += \ + protocol/agl-shell.xml HEADERS += \ src/statusbarmodel.h \ src/statusbarserver.h \ src/applicationlauncher.h \ - src/mastervolume.h \ - src/homescreenhandler.h + src/mastervolume.h OTHER_FILES += \ README.md diff --git a/homescreen/protocol/agl-shell.xml b/homescreen/protocol/agl-shell.xml new file mode 100644 index 0000000..59548e7 --- /dev/null +++ b/homescreen/protocol/agl-shell.xml @@ -0,0 +1,100 @@ + + + + Copyright © 2019 Collabora, Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + + + + + + + + + + + + + + + + + Tell the server that this client is ready to be shown. The server + will delay presentation during start-up until all shell clients are + ready to be shown, and will display a black screen instead. + This gives the client an oppurtunity to set up and configure several + surfaces into a coherent interface. + + The client that binds to this interface must send this request, otherwise + they may stall the compositor unnecessarily. + + If this request is called after the compositor has already finished + start-up, no operation is performed. + + + + + + Set the surface to act as the background of an output. After this + request, the server will immediately send a configure event with + the dimensions the client should use to cover the entire output. + + The surface must have a "desktop" surface role, as supported by + libweston-desktop. + + Only a single surface may be the background for any output. If a + background surface already exists, a protocol error is raised. + + + + + + + + Set the surface to act as a panel of an output. The 'edge' argument + says what edge of the output the surface will be anchored to. + After this request, the server will send a configure event with the + correponding width/height that the client should use, and 0 for the + other dimension. E.g. if the edge is 'top', the width will be the + output's width, and the height will be 0. + + The surface must have a "desktop" surface role, as supported by + libweston-desktop. + + The compositor will take the panel's window geometry into account when + positioning other windows, so the panels are not covered. + + XXX: What happens if e.g. both top and left are used at the same time? + Who gets to have the corner? + + Only a single surface may be the panel for an output's edge. If a + surface already exists on an edge, a protocol error is raised. + + + + + + + diff --git a/homescreen/qml/MediaArea.qml b/homescreen/qml/MediaArea.qml index 0447589..88eaf1e 100644 --- a/homescreen/qml/MediaArea.qml +++ b/homescreen/qml/MediaArea.qml @@ -20,8 +20,7 @@ import QtQuick.Controls 2.0 StackView { id: root - width: 1080 - height: 215 + anchors.fill: parent initialItem: blank diff --git a/homescreen/qml/MediaAreaBlank.qml b/homescreen/qml/MediaAreaBlank.qml index 347c26a..44baaa0 100644 --- a/homescreen/qml/MediaAreaBlank.qml +++ b/homescreen/qml/MediaAreaBlank.qml @@ -22,8 +22,7 @@ import AGL.Demo.Controls 1.0 import MasterVolume 1.0 Image { - width: 1080 - height: 215 + anchors.fill: parent source: './images/Utility_Logo_Background-01.svg' property bool displayVolume: false; @@ -40,7 +39,7 @@ Image { } Image { - id: logo_image + id: logo_image anchors.centerIn: parent source: './images/Utility_Logo_Grey-01.svg' } diff --git a/homescreen/qml/ShortcutArea.qml b/homescreen/qml/ShortcutArea.qml index a8ce127..9e404dc 100644 --- a/homescreen/qml/ShortcutArea.qml +++ b/homescreen/qml/ShortcutArea.qml @@ -21,9 +21,6 @@ import QtQuick.Layouts 1.1 Item { id: root - width: 785 - height: 218 - ListModel { id: applicationModel @@ -53,7 +50,7 @@ Item { RowLayout { anchors.fill: parent - spacing: 2 + spacing: 0 Repeater { model: applicationModel delegate: ShortcutIcon { diff --git a/homescreen/qml/ShortcutIcon.qml b/homescreen/qml/ShortcutIcon.qml index 1100a7c..d039d36 100644 --- a/homescreen/qml/ShortcutIcon.qml +++ b/homescreen/qml/ShortcutIcon.qml @@ -21,8 +21,6 @@ import QtGraphicalEffects 1.0 MouseArea { id: root - width: 195 - height: 216.8 property string name: 'Home' property bool active: false Item { @@ -32,12 +30,14 @@ MouseArea { Image { id: inactiveIcon anchors.fill: parent - source: './images/Shortcut/%1.svg'.arg(root.name.toLowerCase()) + source: './images/Shortcut/%1.svg'.arg(root.name.toLowerCase()) + fillMode: Image.PreserveAspectFit } Image { id: activeIcon anchors.fill: parent source: './images/Shortcut/%1_active.svg'.arg(root.name.toLowerCase()) + fillMode: Image.PreserveAspectFit opacity: 0.0 } layer.enabled: true @@ -49,12 +49,13 @@ MouseArea { } Label { id: name - y: 160 width: root.width - 10 font.pixelSize: 15 font.letterSpacing: 5 // wrapMode: Text.WordWrap - anchors.horizontalCenter: parent.horizontalCenter + anchors.centerIn: icon + anchors.verticalCenterOffset: icon.height * 0.2 + //anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter color: "white" text: qsTr(model.name.toUpperCase()) diff --git a/homescreen/qml/StatusArea.qml b/homescreen/qml/StatusArea.qml index d2e0930..c74672c 100644 --- a/homescreen/qml/StatusArea.qml +++ b/homescreen/qml/StatusArea.qml @@ -22,8 +22,6 @@ import HomeScreen 1.0 Item { id: root - width: 295 - height: 218 property date now: new Date Timer { @@ -58,48 +56,71 @@ Item { RowLayout { anchors.fill: parent spacing: 0 - Item { + + ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true - Layout.preferredWidth: 295 - 76 + Layout.preferredWidth: 217 + spacing: 0 + ColumnLayout { - anchors.fill: parent - anchors.margins: 40 + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 130 spacing: 0 - Text { + + Item { Layout.fillWidth: true Layout.fillHeight: true - text: Qt.formatDate(now, 'dddd').toUpperCase() - font.family: 'Roboto' - font.pixelSize: 13 - color: 'white' - verticalAlignment: Text.AlignVCenter -// Rectangle { -// anchors.fill: parent -// anchors.margins: 5 -// color: 'red' -// border.color: 'blue' -// border.width: 1 -// z: -1 -// } + Layout.preferredHeight: 70 + + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: parent.width * 0.2 + + text: Qt.formatDate(now, 'dddd').toUpperCase() + font.family: 'Roboto' + font.pixelSize: 13 + color: 'white' + verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.Fit + } } - Text { + Item { Layout.fillWidth: true Layout.fillHeight: true - text: Qt.formatTime(now, 'h:mm ap').toUpperCase() - font.family: 'Roboto' - font.pixelSize: 40 - color: 'white' - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + Layout.preferredHeight: 60 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: parent.height * 0.05 + + text: Qt.formatTime(now, 'h:mm ap').toUpperCase() + font.family: 'Roboto' + font.pixelSize: 40 + color: 'white' + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.Fit + } } + } + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 82 + RowLayout { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: 20 + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: parent.height * 0.1 + Image { id: condition_item source: './images/Weather/WeatherIcons_Rain-01.png' + fillMode: Image.PreserveAspectFit } Text { id: temperature_item @@ -107,6 +128,8 @@ Item { color: 'white' font.family: 'Helvetica' font.pixelSize: 32 + fontSizeMode: Text.Fit + verticalAlignment: Text.AlignVCenter } } } @@ -115,13 +138,14 @@ Item { id: icons Layout.fillWidth: true Layout.fillHeight: true - Layout.preferredWidth: 76 + Layout.preferredWidth: 74 spacing: -10 Image { id: bt_icon - Layout.preferredWidth: 77 - Layout.preferredHeight: 73 + Layout.preferredHeight: 70 + Layout.fillWidth: true + Layout.fillHeight: true source: connStatus ? './images/Status/HMI_Status_Bluetooth_On-01.png' : './images/Status/HMI_Status_Bluetooth_Inactive-01.png' fillMode: Image.PreserveAspectFit property string deviceName: "none" @@ -137,8 +161,9 @@ Item { Repeater { model: StatusBarModel { objectName: "statusBar" } delegate: Image { - Layout.preferredWidth: 77 - Layout.preferredHeight: 73 + Layout.preferredHeight: 70 + Layout.fillWidth: true + Layout.fillHeight: true source: model.modelData fillMode: Image.PreserveAspectFit } diff --git a/homescreen/qml/TopArea.qml b/homescreen/qml/TopArea.qml index 2a75cf8..19bed91 100644 --- a/homescreen/qml/TopArea.qml +++ b/homescreen/qml/TopArea.qml @@ -20,10 +20,10 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 2.0 Image { - width: 1920 - height: 218 + anchors.fill: parent source: './images/TopSection_NoText_NoIcons-01.svg' - fillMode: Image.PreserveAspectCrop + //fillMode: Image.PreserveAspectCrop + fillMode: Image.Stretch RowLayout { anchors.fill: parent @@ -32,13 +32,13 @@ Image { id: shortcutArea Layout.fillWidth: true Layout.fillHeight: true - Layout.preferredWidth: 785 + Layout.preferredWidth: 775 } StatusArea { id: statusArea Layout.fillWidth: true Layout.fillHeight: true - Layout.preferredWidth: 295 + Layout.preferredWidth: 291 } } diff --git a/homescreen/qml/background.qml b/homescreen/qml/background.qml new file mode 100644 index 0000000..c2bb309 --- /dev/null +++ b/homescreen/qml/background.qml @@ -0,0 +1,15 @@ +import QtQuick 2.13 +import QtQuick.Window 2.13 + +Window { + id: background + width: Screen.width + height: Screen.height + flags: Qt.FramelessWindowHint + visible: true + + Image { + anchors.fill: parent + source: './images/AGL_HMI_Blue_Background_NoCar-01.png' + } +} diff --git a/homescreen/qml/bottompanel.qml b/homescreen/qml/bottompanel.qml new file mode 100644 index 0000000..a859418 --- /dev/null +++ b/homescreen/qml/bottompanel.qml @@ -0,0 +1,14 @@ +import QtQuick 2.13 +import QtQuick.Window 2.13 +import QtQuick.Controls 2.13 + +Window { + id: bottompanel + width: Screen.width + height: Screen.height * (215.0 / 1920.0) + flags: Qt.FramelessWindowHint + visible: true + //color: "#aaaa0000" + MediaArea { + } +} diff --git a/homescreen/qml/main.qml b/homescreen/qml/main.qml index 7d40276..0526526 100644 --- a/homescreen/qml/main.qml +++ b/homescreen/qml/main.qml @@ -16,23 +16,20 @@ */ import QtQuick 2.2 -import QtQuick.Window 2.1 +import QtQuick.Window 2.13 import QtQuick.Layouts 1.1 import HomeScreen 1.0 Window { visible: true flags: Qt.FramelessWindowHint - width: container.width * container.scale - height: container.height * container.scale + width: Screen.width + height: Screen.height title: 'HomeScreen' Image { id: container - anchors.centerIn: parent - width: 1080 - height: 1920 - scale: screenInfo.scale_factor() + anchors.fill: parent source: './images/AGL_HMI_Blue_Background_NoCar-01.png' ColumnLayout { @@ -90,16 +87,7 @@ Window { } } - Connections { - target: homescreenHandler - onShowInformation: { - bottomText.text = info - bottomInformation.visible = true - informationTimer.restart() - } - } - - Timer { + Timer { id:notificationTimer interval: 3000 running: false @@ -143,14 +131,4 @@ Window { } } } - - Connections { - target: homescreenHandler - onShowNotification: { - notificationIcon.source = icon_path - notificationtext.text = text - notificationItem.visible = true - notificationTimer.restart() - } - } } diff --git a/homescreen/qml/qml.qrc b/homescreen/qml/qml.qrc index e60ea63..9639467 100644 --- a/homescreen/qml/qml.qrc +++ b/homescreen/qml/qml.qrc @@ -1,6 +1,9 @@ main.qml + background.qml + toppanel.qml + bottompanel.qml MediaArea.qml MediaAreaBlank.qml MediaAreaMusic.qml diff --git a/homescreen/qml/toppanel.qml b/homescreen/qml/toppanel.qml new file mode 100644 index 0000000..957b957 --- /dev/null +++ b/homescreen/qml/toppanel.qml @@ -0,0 +1,15 @@ +import QtQuick 2.13 +import QtQuick.Window 2.13 +import QtQuick.Controls 2.13 + +Window { + id: toppanel + width: Screen.width + height: Screen.height * (240.0 / 1920.0) + flags: Qt.FramelessWindowHint + visible: true + //color: "#aaaa0000" + + TopArea { + } +} diff --git a/homescreen/src/homescreenhandler.cpp b/homescreen/src/homescreenhandler.cpp deleted file mode 100644 index 4db60fb..0000000 --- a/homescreen/src/homescreenhandler.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2017, 2018, 2019 TOYOTA MOTOR CORPORATION - * - * 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 -#include "homescreenhandler.h" -#include -#include "hmi-debug.h" - -void* HomescreenHandler::myThis = 0; - -HomescreenHandler::HomescreenHandler(QObject *parent) : - QObject(parent), - mp_hs(NULL) -{ - -} - -HomescreenHandler::~HomescreenHandler() -{ - if (mp_hs != NULL) { - delete mp_hs; - } -} - -void HomescreenHandler::init(int port, const char *token) -{ - mp_hs = new LibHomeScreen(); - mp_hs->init(port, token); - - myThis = this; - - mp_hs->registerCallback(nullptr, HomescreenHandler::onRep_static); - - mp_hs->set_event_handler(LibHomeScreen::Event_OnScreenMessage, [this](json_object *object){ - const char *display_message = json_object_get_string( - json_object_object_get(object, "display_message")); - HMI_DEBUG("HomeScreen","set_event_handler Event_OnScreenMessage display_message = %s", display_message); - }); - - mp_hs->set_event_handler(LibHomeScreen::Event_ShowNotification,[this](json_object *object){ - json_object *p_obj = json_object_object_get(object, "parameter"); - const char *icon = json_object_get_string( - json_object_object_get(p_obj, "icon")); - const char *text = json_object_get_string( - json_object_object_get(p_obj, "text")); - const char *app_id = json_object_get_string( - json_object_object_get(p_obj, "caller")); - HMI_DEBUG("HomeScreen","Event_ShowNotification icon=%s, text=%s, caller=%s", icon, text, app_id); - QFileInfo icon_file(icon); - QString icon_path; - if (icon_file.isFile() && icon_file.exists()) { - icon_path = QString(QLatin1String(icon)); - } else { - icon_path = "./images/Utility_Logo_Grey-01.svg"; - } - - emit showNotification(QString(QLatin1String(app_id)), icon_path, QString(QLatin1String(text))); - }); - - mp_hs->set_event_handler(LibHomeScreen::Event_ShowInformation,[this](json_object *object){ - json_object *p_obj = json_object_object_get(object, "parameter"); - const char *info = json_object_get_string( - json_object_object_get(p_obj, "info")); - - emit showInformation(QString(QLatin1String(info))); - }); -} - -void HomescreenHandler::tapShortcut(QString application_id) -{ - HMI_DEBUG("HomeScreen","tapShortcut %s", application_id.toStdString().c_str()); - struct json_object* j_json = json_object_new_object(); - struct json_object* value; - value = json_object_new_string("normal.full"); - json_object_object_add(j_json, "area", value); - - mp_hs->showWindow(application_id.toStdString().c_str(), j_json); -} - -void HomescreenHandler::onRep_static(struct json_object* reply_contents) -{ - static_cast(HomescreenHandler::myThis)->onRep(reply_contents); -} - -void HomescreenHandler::onEv_static(const string& event, struct json_object* event_contents) -{ - static_cast(HomescreenHandler::myThis)->onEv(event, event_contents); -} - -void HomescreenHandler::onRep(struct json_object* reply_contents) -{ - const char* str = json_object_to_json_string(reply_contents); - HMI_DEBUG("HomeScreen","HomeScreen onReply %s", str); -} - -void HomescreenHandler::onEv(const string& event, struct json_object* event_contents) -{ - const char* str = json_object_to_json_string(event_contents); - HMI_DEBUG("HomeScreen","HomeScreen onEv %s, contents: %s", event.c_str(), str); - - if (event.compare("homescreen/on_screen_message") == 0) { - struct json_object *json_data = json_object_object_get(event_contents, "data"); - struct json_object *json_display_message = json_object_object_get(json_data, "display_message"); - const char* display_message = json_object_get_string(json_display_message); - - HMI_DEBUG("HomeScreen","display_message = %s", display_message); - } -} diff --git a/homescreen/src/homescreenhandler.h b/homescreen/src/homescreenhandler.h deleted file mode 100644 index 5dfe041..0000000 --- a/homescreen/src/homescreenhandler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 TOYOTA MOTOR CORPORATION - * - * 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 HOMESCREENHANDLER_H -#define HOMESCREENHANDLER_H - -#include -#include -#include - -using namespace std; - -class HomescreenHandler : public QObject -{ - Q_OBJECT -public: - explicit HomescreenHandler(QObject *parent = 0); - ~HomescreenHandler(); - - void init(int port, const char* token); - - Q_INVOKABLE void tapShortcut(QString application_id); - - void onRep(struct json_object* reply_contents); - void onEv(const string& event, struct json_object* event_contents); - - static void* myThis; - static void onRep_static(struct json_object* reply_contents); - static void onEv_static(const string& event, struct json_object* event_contents); - -signals: - void showNotification(QString application_id, QString icon_path, QString text); - void showInformation(QString info); -private: - LibHomeScreen *mp_hs; -}; - -#endif // HOMESCREENHANDLER_H diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp index 5f283fb..ae1fff8 100644 --- a/homescreen/src/main.cpp +++ b/homescreen/src/main.cpp @@ -20,19 +20,26 @@ #include #include #include +#include #include #include +#include +#include + +#include +#include +#include -#include #include #include #include "applicationlauncher.h" #include "statusbarmodel.h" #include "afm_user_daemon_proxy.h" #include "mastervolume.h" -#include "homescreenhandler.h" #include "hmi-debug.h" +#include "wayland-agl-shell-client-protocol.h" + // XXX: We want this DBus connection to be shared across the different // QML objects, is there another way to do this, a nice way, perhaps? org::AGL::afm::user *afm_user_daemon_proxy; @@ -46,15 +53,58 @@ struct Cleanup { } }; -void noOutput(QtMsgType, const QMessageLogContext &, const QString &) +} + +static void global_add(void *data, struct wl_registry *reg, uint32_t name, + const char *interface, uint32_t) { + struct agl_shell **shell = static_cast(data); + if (strcmp(interface, agl_shell_interface.name) == 0) { + *shell = static_cast(wl_registry_bind(reg, name, &agl_shell_interface, 1)); + } } +static void global_remove(void *, struct wl_registry *, uint32_t) +{ + // Don't care +} + +static const struct wl_registry_listener registry_listener = { + global_add, + global_remove, +}; + +static struct wl_surface *create_component(QPlatformNativeInterface *native, + QQmlComponent *comp, QScreen *screen) +{ + QObject *obj = comp->create(); + obj->setParent(screen); + + QWindow *win = qobject_cast(obj); + return static_cast(native->nativeResourceForWindow("surface", win)); } int main(int argc, char *argv[]) { + setenv("QT_QPA_PLATFORM", "wayland", 1); QGuiApplication a(argc, argv); + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + struct wl_display *wl; + struct wl_registry *registry; + struct agl_shell *agl_shell = nullptr; + + wl = static_cast(native->nativeResourceForIntegration("display")); + registry = wl_display_get_registry(wl); + + wl_registry_add_listener(registry, ®istry_listener, &agl_shell); + // Roundtrip to get all globals advertised by the compositor + wl_display_roundtrip(wl); + wl_registry_destroy(registry); + + if (!agl_shell) { + qFatal("Compositor does not support AGL shell protocol"); + return 1; + } // use launch process QScopedPointer afm_user_daemon_proxy(new org::AGL::afm::user("org.AGL.afm.user", @@ -93,34 +143,6 @@ int main(int argc, char *argv[]) qmlRegisterType("MasterVolume", 1, 0, "MasterVolume"); ApplicationLauncher *launcher = new ApplicationLauncher(); - QLibWindowmanager* layoutHandler = new QLibWindowmanager(); - if(layoutHandler->init(port,token) != 0){ - exit(EXIT_FAILURE); - } - - AGLScreenInfo screenInfo(layoutHandler->get_scale_factor()); - - if (layoutHandler->requestSurface(graphic_role) != 0) { - exit(EXIT_FAILURE); - } - - layoutHandler->set_event_handler(QLibWindowmanager::Event_SyncDraw, [layoutHandler, &graphic_role](json_object *object) { - layoutHandler->endDraw(graphic_role); - }); - - layoutHandler->set_event_handler(QLibWindowmanager::Event_ScreenUpdated, [layoutHandler, launcher](json_object *object) { - json_object *jarray = json_object_object_get(object, "ids"); - int arrLen = json_object_array_length(jarray); - for( int idx = 0; idx < arrLen; idx++) - { - QString label = QString(json_object_get_string( json_object_array_get_idx(jarray, idx) )); - HMI_DEBUG("HomeScreen","Event_ScreenUpdated application: %s.", label.toStdString().c_str()); - QMetaObject::invokeMethod(launcher, "setCurrent", Qt::QueuedConnection, Q_ARG(QString, label)); - } - }); - - HomescreenHandler* homescreenHandler = new HomescreenHandler(); - homescreenHandler->init(port, token.toStdString().c_str()); QUrl bindingAddress; bindingAddress.setScheme(QStringLiteral("ws")); @@ -132,24 +154,62 @@ int main(int argc, char *argv[]) query.addQueryItem(QStringLiteral("token"), token); bindingAddress.setQuery(query); +#if 0 // mail.qml loading QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("bindingAddress", bindingAddress); - engine.rootContext()->setContextProperty("layoutHandler", layoutHandler); - engine.rootContext()->setContextProperty("homescreenHandler", homescreenHandler); engine.rootContext()->setContextProperty("launcher", launcher); engine.rootContext()->setContextProperty("weather", new Weather(bindingAddress)); engine.rootContext()->setContextProperty("bluetooth", new Bluetooth(bindingAddress, engine.rootContext())); - engine.rootContext()->setContextProperty("screenInfo", &screenInfo); + //engine.rootContext()->setContextProperty("screenInfo", &screenInfo); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + engine.load(QUrl(QStringLiteral("qrc:/background.qml"))); + auto root_objects = engine.rootObjects(); + printf("num root objects: %d\n", root_objects.length()); QObject *root = engine.rootObjects().first(); QQuickWindow *window = qobject_cast(root); - QObject::connect(window, SIGNAL(frameSwapped()), layoutHandler, SLOT(slotActivateSurface())); + + for (auto o : root_objects) { + qDebug() << o->dynamicPropertyNames(); + } QList sobjs = engine.rootObjects(); StatusBarModel *statusBar = sobjs.first()->findChild("statusBar"); statusBar->init(bindingAddress, engine.rootContext()); +#endif + + QQmlEngine engine; + QQmlContext *context = engine.rootContext(); + context->setContextProperty("bindingAddress", bindingAddress); + context->setContextProperty("launcher", launcher); + context->setContextProperty("weather", new Weather(bindingAddress)); + context->setContextProperty("bluetooth", new Bluetooth(bindingAddress, engine.rootContext())); + + QQmlComponent bg_comp(&engine, QUrl("qrc:/background.qml")); + QQmlComponent top_comp(&engine, QUrl("qrc:/toppanel.qml")); + QQmlComponent bot_comp(&engine, QUrl("qrc:/bottompanel.qml")); + + for (QScreen *screen : qApp->screens()) { + struct wl_output *output; + + output = static_cast(native->nativeResourceForScreen("output", screen)); + + struct wl_surface *bg = create_component(native, &bg_comp, screen); + agl_shell_set_background(agl_shell, bg, output); + + struct wl_surface *top = create_component(native, &top_comp, screen); + agl_shell_set_panel(agl_shell, top, output, AGL_SHELL_EDGE_TOP); + + struct wl_surface *bot = create_component(native, &bot_comp, screen); + agl_shell_set_panel(agl_shell, bot, output, AGL_SHELL_EDGE_BOTTOM); + } + + // Delay the ready signal until after Qt has done all of its own setup in a.exec() + QTimer::singleShot(0, [agl_shell](){ + agl_shell_ready(agl_shell); + agl_shell_destroy(agl_shell); + }); return a.exec(); } -- cgit 1.2.3-korg