/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwaylandscreen_p.h"

#include "qwaylanddisplay_p.h"
#include "qwaylandintegration_p.h"
#include "qwaylandcursor_p.h"
#include "qwaylandwindow_p.h"

#include <QtGui/QGuiApplication>

#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>

QT_BEGIN_NAMESPACE

namespace QtWaylandClient {

QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id)
    : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 2))
    , m_outputId(id)
    , mWaylandDisplay(waylandDisplay)
    , mOutputName(QStringLiteral("Screen%1").arg(id))
{
    if (auto *xdgOutputManager = waylandDisplay->xdgOutputManager())
        initXdgOutput(xdgOutputManager);

    if (version < WL_OUTPUT_DONE_SINCE_VERSION) {
        qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
                                << "QScreen may not work correctly";
        mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
        mOutputDone = true; // Fake the done event
        maybeInitialize();
    }
}

QWaylandScreen::~QWaylandScreen()
{
    if (zxdg_output_v1::isInitialized())
        zxdg_output_v1::destroy();
}

void QWaylandScreen::maybeInitialize()
{
    Q_ASSERT(!mInitialized);

    if (!mOutputDone)
        return;

    if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
        return;

    mInitialized = true;
    mWaylandDisplay->handleScreenInitialized(this);

    updateOutputProperties();
    if (zxdg_output_v1::isInitialized())
        updateXdgOutputProperties();
}

void QWaylandScreen::initXdgOutput(QtWayland::zxdg_output_manager_v1 *xdgOutputManager)
{
    Q_ASSERT(xdgOutputManager);
    if (zxdg_output_v1::isInitialized())
        return;

    zxdg_output_v1::init(xdgOutputManager->get_xdg_output(wl_output::object()));
}

QWaylandDisplay * QWaylandScreen::display() const
{
    return mWaylandDisplay;
}

QString QWaylandScreen::manufacturer() const
{
    return mManufacturer;
}

QString QWaylandScreen::model() const
{
    return mModel;
}

QRect QWaylandScreen::geometry() const
{
    if (zxdg_output_v1::isInitialized()) {
        return mXdgGeometry;
    } else {
        // Scale geometry for QScreen. This makes window and screen
        // geometry be in the same coordinate system.
        return QRect(mGeometry.topLeft(), mGeometry.size() / mScale);
    }
}

int QWaylandScreen::depth() const
{
    return mDepth;
}

QImage::Format QWaylandScreen::format() const
{
    return mFormat;
}

QSizeF QWaylandScreen::physicalSize() const
{
    if (mPhysicalSize.isEmpty())
        return QPlatformScreen::physicalSize();
    else
        return mPhysicalSize;
}

QDpi QWaylandScreen::logicalDpi() const
{
    static bool physicalDpi = qEnvironmentVariable("QT_WAYLAND_FORCE_DPI") == QStringLiteral("physical");
    if (physicalDpi)
        return QPlatformScreen::logicalDpi();

    static int forceDpi = qgetenv("QT_WAYLAND_FORCE_DPI").toInt();
    if (forceDpi)
        return QDpi(forceDpi, forceDpi);

    return QDpi(96, 96);
}

QList<QPlatformScreen *> QWaylandScreen::virtualSiblings() const
{
    QList<QPlatformScreen *> list;
    const QList<QWaylandScreen*> screens = mWaylandDisplay->screens();
    list.reserve(screens.count());
    for (QWaylandScreen *screen : qAsConst(screens)) {
        if (screen->screen())
            list << screen;
    }
    return list;
}

void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
{
    const auto allWindows = QGuiApplication::allWindows();
    for (QWindow *window : allWindows) {
        QWaylandWindow *w = static_cast<QWaylandWindow *>(window->handle());
        if (w && w->waylandScreen() == this)
            w->setOrientationMask(mask);
    }
}

Qt::ScreenOrientation QWaylandScreen::orientation() const
{
    return m_orientation;
}

int QWaylandScreen::scale() const
{
    return mScale;
}

qreal QWaylandScreen::devicePixelRatio() const
{
    return qreal(mScale);
}

qreal QWaylandScreen::refreshRate() const
{
    return mRefreshRate / 1000.f;
}

#if QT_CONFIG(cursor)
QPlatformCursor *QWaylandScreen::cursor() const
{
    return mWaylandDisplay->waylandCursor();
}
#endif // QT_CONFIG(cursor)

QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
{
    QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
    return static_cast<QWaylandScreen *>(platformScreen);
}

QWaylandScreen *QWaylandScreen::fromWlOutput(::wl_output *output)
{
    if (auto *o = QtWayland::wl_output::fromObject(output))
        return static_cast<QWaylandScreen *>(o);
    return nullptr;
}

void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)
{
    if (!(flags & WL_OUTPUT_MODE_CURRENT))
        return;

    QSize size(width, height);
    if (size != mGeometry.size())
        mGeometry.setSize(size);

    if (refresh != mRefreshRate)
        mRefreshRate = refresh;
}

void QWaylandScreen::output_geometry(int32_t x, int32_t y,
                                     int32_t width, int32_t height,
                                     int subpixel,
                                     const QString &make,
                                     const QString &model,
                                     int32_t transform)
{
    Q_UNUSED(subpixel);

    mManufacturer = make;
    mModel = model;

    mTransform = transform;

    mPhysicalSize = QSize(width, height);
    mGeometry.moveTopLeft(QPoint(x, y));
}

void QWaylandScreen::output_scale(int32_t factor)
{
    mScale = factor;
}

void QWaylandScreen::output_done()
{
    mOutputDone = true;
    if (mInitialized)
        updateOutputProperties();
    else
        maybeInitialize();
}

void QWaylandScreen::updateOutputProperties()
{
    if (mTransform >= 0) {
        bool isPortrait = mGeometry.height() > mGeometry.width();
        switch (mTransform) {
            case WL_OUTPUT_TRANSFORM_NORMAL:
                m_orientation = isPortrait ? Qt::PortraitOrientation : Qt::LandscapeOrientation;
                break;
            case WL_OUTPUT_TRANSFORM_90:
                m_orientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
                break;
            case WL_OUTPUT_TRANSFORM_180:
                m_orientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
                break;
            case WL_OUTPUT_TRANSFORM_270:
                m_orientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
                break;
            // Ignore these ones, at least for now
            case WL_OUTPUT_TRANSFORM_FLIPPED:
            case WL_OUTPUT_TRANSFORM_FLIPPED_90:
            case WL_OUTPUT_TRANSFORM_FLIPPED_180:
            case WL_OUTPUT_TRANSFORM_FLIPPED_270:
                break;
        }

        QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
        mTransform = -1;
    }

    QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());

    if (!zxdg_output_v1::isInitialized())
        QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry());
}


void QWaylandScreen::zxdg_output_v1_logical_position(int32_t x, int32_t y)
{
    mXdgGeometry.moveTopLeft(QPoint(x, y));
}

void QWaylandScreen::zxdg_output_v1_logical_size(int32_t width, int32_t height)
{
    mXdgGeometry.setSize(QSize(width, height));
}

void QWaylandScreen::zxdg_output_v1_done()
{
    mXdgOutputDone = true;
    if (mInitialized)
        updateXdgOutputProperties();
    else
        maybeInitialize();
}

void QWaylandScreen::zxdg_output_v1_name(const QString &name)
{
    mOutputName = name;
}

void QWaylandScreen::updateXdgOutputProperties()
{
    Q_ASSERT(zxdg_output_v1::isInitialized());
    QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry());
}

} // namespace QtWaylandClient

QT_END_NAMESPACE
