Update to new weston design
authorScott Anderson <scott.anderson@collabora.com>
Sat, 28 Sep 2019 03:23:11 +0000 (15:23 +1200)
committerScott Anderson <scott.anderson@collabora.com>
Sat, 28 Sep 2019 03:23:11 +0000 (15:23 +1200)
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 <scott.anderson@collabora.com>
17 files changed:
homescreen.pro
homescreen/homescreen.pro
homescreen/protocol/agl-shell.xml [new file with mode: 0644]
homescreen/qml/MediaArea.qml
homescreen/qml/MediaAreaBlank.qml
homescreen/qml/ShortcutArea.qml
homescreen/qml/ShortcutIcon.qml
homescreen/qml/StatusArea.qml
homescreen/qml/TopArea.qml
homescreen/qml/background.qml [new file with mode: 0644]
homescreen/qml/bottompanel.qml [new file with mode: 0644]
homescreen/qml/main.qml
homescreen/qml/qml.qrc
homescreen/qml/toppanel.qml [new file with mode: 0644]
homescreen/src/homescreenhandler.cpp [deleted file]
homescreen/src/homescreenhandler.h [deleted file]
homescreen/src/main.cpp

index 7c49383..8f61890 100644 (file)
@@ -17,8 +17,6 @@ TEMPLATE = subdirs
 load(configure)
 
 SUBDIRS = interfaces \
-    homescreen \
-    package
+    homescreen
 
 homescreen.depends = interfaces
-package.depends += homescreen
index 8baa90d..0ec86d4 100644 (file)
 
 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 (file)
index 0000000..59548e7
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="agl_shell">
+  <copyright>
+    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.
+  </copyright>
+  <interface name="agl_shell" version="1">
+    <description summary="user interface for weston-ivi">
+    </description>
+
+    <enum name="error">
+      <entry name="invalid_argument" value="0"/>
+      <entry name="background_exists" value="1"/>
+      <entry name="panel_exists" value="2"/>
+    </enum>
+
+    <enum name="edge">
+      <entry name="top" value="0"/>
+      <entry name="bottom" value="1"/>
+      <entry name="left" value="2"/>
+      <entry name="right" value="3"/>
+    </enum>
+
+    <request name="ready">
+      <description summary="client is ready to be shown">
+        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.
+      </description>
+    </request>
+
+    <request name="set_background">
+      <description summary="set surface as output's background">
+        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.
+      </description>
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="output" type="object" interface="wl_output"/>
+    </request>
+
+    <request name="set_panel">
+      <description summary="set surface as panel">
+        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.
+      </description>
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="output" type="object" interface="wl_output"/>
+      <arg name="edge" type="uint" enum="edge"/>
+    </request>
+  </interface>
+</protocol>
index 0447589..88eaf1e 100644 (file)
@@ -20,8 +20,7 @@ import QtQuick.Controls 2.0
 
 StackView {
     id: root
-    width: 1080
-    height: 215
+    anchors.fill: parent
 
     initialItem: blank
 
index 347c26a..44baaa0 100644 (file)
@@ -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'
     }
index a8ce127..9e404dc 100644 (file)
@@ -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 {
index 1100a7c..d039d36 100644 (file)
@@ -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())
index d2e0930..c74672c 100644 (file)
@@ -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
                 }
index 2a75cf8..19bed91 100644 (file)
@@ -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 (file)
index 0000000..c2bb309
--- /dev/null
@@ -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 (file)
index 0000000..a859418
--- /dev/null
@@ -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 {
+    }
+}
index 7d40276..0526526 100644 (file)
  */
 
 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()
-        }
-    }
 }
index e60ea63..9639467 100644 (file)
@@ -1,6 +1,9 @@
 <RCC>
     <qresource prefix="/">
         <file>main.qml</file>
+        <file>background.qml</file>
+        <file>toppanel.qml</file>
+        <file>bottompanel.qml</file>
         <file>MediaArea.qml</file>
         <file>MediaAreaBlank.qml</file>
         <file>MediaAreaMusic.qml</file>
diff --git a/homescreen/qml/toppanel.qml b/homescreen/qml/toppanel.qml
new file mode 100644 (file)
index 0000000..957b957
--- /dev/null
@@ -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 (file)
index 4db60fb..0000000
+++ /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 <QFileInfo>
-#include "homescreenhandler.h"
-#include <functional>
-#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*>(HomescreenHandler::myThis)->onRep(reply_contents);
-}
-
-void HomescreenHandler::onEv_static(const string& event, struct json_object* event_contents)
-{
-    static_cast<HomescreenHandler*>(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 (file)
index 5dfe041..0000000
+++ /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 <QObject>
-#include <libhomescreen.hpp>
-#include <string>
-
-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
index 5f283fb..ae1fff8 100644 (file)
 #include <QtGui/QGuiApplication>
 #include <QtQml/QQmlApplicationEngine>
 #include <QtQml/QQmlContext>
+#include <QtQml/QQmlComponent>
 #include <QtQml/qqml.h>
 #include <QQuickWindow>
+#include <QScreen>
+#include <qpa/qplatformnativeinterface.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <wayland-client.h>
 
-#include <qlibwindowmanager.h>
 #include <weather.h>
 #include <bluetooth.h>
 #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<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 *, 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<QWindow *>(obj);
+        return static_cast<struct wl_surface *>(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<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);
+    
+    if (!agl_shell) {
+        qFatal("Compositor does not support AGL shell protocol");
+        return 1;
+    }
 
     // use launch process
     QScopedPointer<org::AGL::afm::user, Cleanup> 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>("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<QQuickWindow *>(root);
-    QObject::connect(window, SIGNAL(frameSwapped()), layoutHandler, SLOT(slotActivateSurface()));
+
+    for (auto o : root_objects) {
+           qDebug() << o->dynamicPropertyNames();
+    }
 
     QList<QObject *> sobjs = engine.rootObjects();
     StatusBarModel *statusBar = sobjs.first()->findChild<StatusBarModel *>("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<struct wl_output *>(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();
 }