C

Qt Cluster: Rendering and Recovery from Main UI Failure

// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

// This file is part of the Qt Safe Renderer module

#include "gauge.h"
#include "qtiviclusterdata.h"
#include "circularindicator.h"

#include <QtQml/QQmlApplicationEngine>
#include <QtGui/QFont>
#include <QtGui/QFontDatabase>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QNetworkInterface>
#include <QHostAddress>

#include "etcprovider.h"
#include "crasher.h"

QT_USE_NAMESPACE

int main(int argc, char **argv)
{
    qputenv("QT_QPA_EGLFS_HIDECURSOR", "1");
    qputenv("QT_QPA_EGLFS_DISABLE_INPUT", "1");
    qputenv("QT_QPA_EGLFS_FORCE888", "1");
    qputenv("QT_QPA_EGLFS_WIDTH","1920");
    qputenv("QT_QPA_EGLFS_HEIGHT","1080");
    qputenv("QT_QPA_EGLFS_PHYSICAL_WIDTH","292");
    qputenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT","99");
    qputenv("QT_QPA_WM_DISP_ID", "0");
    qputenv("QT_QPA_WM_LAYER", "3");

    QGuiApplication app(argc, argv);

    QFontDatabase::addApplicationFont(":/fonts/Lato-Bold.ttf");
    QFontDatabase::addApplicationFont(":/fonts/Lato-Semibold.ttf");
    int latoID = QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf");
    QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(latoID);
    if (!loadedFontFamilies.empty()) {
        QString fontName = loadedFontFamilies.at(0);
        QGuiApplication::setFont(QFont(fontName));
    } else {
        qWarning("Error: fail to load Open Sans font");
    }

    // Check if the environment variable for IP is already set
    QByteArray envIp = qgetenv("QT_SAFERENDER_HOST");
    if (envIp.isEmpty()) {
        // Find the IP address to set as environment variable
        QString ipAddress;
        const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();

        // Use the first non-localhost IPv4 address
        for (const QHostAddress &address : std::as_const(ipAddressesList)) {
            if (address != QHostAddress::LocalHost && address.toIPv4Address()) {
                ipAddress = address.toString();
                break;
            }
        }

        // If none found, then use localhost
        if (ipAddress.isEmpty()) {
            ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
        }
        qputenv("QT_SAFERENDER_HOST", ipAddress.toLocal8Bit());
    }

    // Check if the environment variable for PORT is already set
    QByteArray envPort = qgetenv("QT_SAFERENDER_PORT");
    if (envPort.isEmpty()) {
        qputenv("QT_SAFERENDER_PORT", "32112");
    }

    qmlRegisterType<QtIVIClusterData>("ClusterDemoData", 1, 0, "ClusterData");
    qmlRegisterType<Gauge>("ClusterDemo", 1, 0, "GaugeFiller");
    qmlRegisterType<CircularIndicator>("ClusterDemo", 1, 0, "CircularIndicator");
    qmlRegisterType<Crasher>("ClusterDemo", 1, 0, "Crasher");
    qmlRegisterSingletonType(QUrl("qrc:/qml/ValueSource.qml"), "ClusterDemo", 1, 0, "ValueSource");

    QQuickView view;
    view.setFlags(Qt::Window | Qt::FramelessWindowHint);
    view.setX(0);
    view.setY(0);

//Pipeline setting in QNX
//Pipeline 1 is the background layer.
//See graphics.conf in your build configuration.
//This value has been added to qtbase in
//https://codereview.qt-project.org/c/tqtc-boot2qt/qtsaferenderer/+/304161
#if defined(Q_OS_QNX)
    view.setProperty("_q_platform_qnxPipeline", 1);
#endif
    EtcProvider *etcProvider = new EtcProvider();
    etcProvider->setBaseUrl(QUrl("qrc:///images/"));
    view.engine()->addImageProvider("etc", etcProvider);

    view.setColor(QColor(Qt::black));
    view.setWidth(1920);
    view.setHeight(1080);
    view.engine()->addImportPath("qrc:/imports/");
    view.setSource(QUrl("qrc:/qml/DashboardLoader.qml"));
    view.show();
    return app.exec();
}