/****************************************************************************
**
** Copyright (C) 2017-2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2017 Klarälvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwaylandoutput.h"
#include "qwaylandoutput_p.h"

#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandView>

#include <QtWaylandCompositor/private/qwaylandsurface_p.h>
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
#include <QtWaylandCompositor/private/qwaylandview_p.h>
#include <QtWaylandCompositor/private/qwaylandutils_p.h>
#include <QtWaylandCompositor/private/qwaylandxdgoutputv1_p.h>

#include <QtCore/QCoreApplication>
#include <QtCore/QtMath>
#include <QtGui/QWindow>
#include <QtGui/QExposeEvent>
#include <QtGui/QScreen>
#include <private/qobject_p.h>

QT_BEGIN_NAMESPACE

static QtWaylandServer::wl_output::subpixel toWlSubpixel(const QWaylandOutput::Subpixel &value)
{
    switch (value) {
    case QWaylandOutput::SubpixelUnknown:
        return QtWaylandServer::wl_output::subpixel_unknown;
    case QWaylandOutput::SubpixelNone:
        return QtWaylandServer::wl_output::subpixel_none;
    case QWaylandOutput::SubpixelHorizontalRgb:
        return QtWaylandServer::wl_output::subpixel_horizontal_rgb;
    case QWaylandOutput::SubpixelHorizontalBgr:
        return QtWaylandServer::wl_output::subpixel_horizontal_bgr;
    case QWaylandOutput::SubpixelVerticalRgb:
        return QtWaylandServer::wl_output::subpixel_vertical_rgb;
    case QWaylandOutput::SubpixelVerticalBgr:
        return QtWaylandServer::wl_output::subpixel_vertical_bgr;
    default:
        break;
    }

    return QtWaylandServer::wl_output::subpixel_unknown;
}

static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput::Transform &value)
{
    switch (value) {
    case QWaylandOutput::Transform90:
        return QtWaylandServer::wl_output::transform_90;
    case QWaylandOutput::Transform180:
        return QtWaylandServer::wl_output::transform_180;
    case QWaylandOutput::Transform270:
        return QtWaylandServer::wl_output::transform_270;
    case QWaylandOutput::TransformFlipped:
        return QtWaylandServer::wl_output::transform_flipped;
    case QWaylandOutput::TransformFlipped90:
        return QtWaylandServer::wl_output::transform_flipped_90;
    case QWaylandOutput::TransformFlipped180:
        return QtWaylandServer::wl_output::transform_flipped_180;
    case QWaylandOutput::TransformFlipped270:
        return QtWaylandServer::wl_output::transform_flipped_270;
    default:
        break;
    }

    return QtWaylandServer::wl_output::transform_normal;
}

QWaylandOutputPrivate::QWaylandOutputPrivate()
{
}

QWaylandOutputPrivate::~QWaylandOutputPrivate()
{
}

void QWaylandOutputPrivate::output_bind_resource(Resource *resource)
{
    sendGeometry(resource);

    for (const QWaylandOutputMode &mode : modes)
        sendMode(resource, mode);

    if (resource->version() >= 2) {
        send_scale(resource->handle, scaleFactor);
        send_done(resource->handle);
    }
}

void QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged()
{
    if (!window)
        return;

    const QSize pixelSize = window->size() * window->devicePixelRatio();

    if (pixelSize != windowPixelSize) {
        windowPixelSize = pixelSize;
        handleWindowPixelSizeChanged();
    }
}

void QWaylandOutputPrivate::_q_handleWindowDestroyed()
{
    Q_Q(QWaylandOutput);
    window = nullptr;
    emit q->windowChanged();
    emit q->windowDestroyed();
}

void QWaylandOutputPrivate::sendGeometry(const Resource *resource)
{
    send_geometry(resource->handle,
                  position.x(), position.y(),
                  physicalSize.width(), physicalSize.height(),
                  toWlSubpixel(subpixel), manufacturer, model,
                  toWlTransform(transform));
}

void QWaylandOutputPrivate::sendGeometryInfo()
{
    for (const Resource *resource : resourceMap().values()) {
        sendGeometry(resource);
        if (resource->version() >= 2)
            send_done(resource->handle);
    }

    if (xdgOutput)
        QWaylandXdgOutputV1Private::get(xdgOutput)->sendDone();
}

void QWaylandOutputPrivate::sendMode(const Resource *resource, const QWaylandOutputMode &mode)
{
    quint32 flags = 0;
    if (currentMode == modes.indexOf(mode))
        flags |= QtWaylandServer::wl_output::mode_current;
    if (preferredMode == modes.indexOf(mode))
        flags |= QtWaylandServer::wl_output::mode_preferred;

    send_mode(resource->handle, flags,
              mode.size().width(), mode.size().height(),
              mode.refreshRate());
}

void QWaylandOutputPrivate::sendModesInfo()
{
    for (const Resource *resource : resourceMap().values()) {
        for (const QWaylandOutputMode &mode : modes)
            sendMode(resource, mode);
        if (resource->version() >= 2)
            send_done(resource->handle);
    }

    if (xdgOutput)
        QWaylandXdgOutputV1Private::get(xdgOutput)->sendDone();
}

void QWaylandOutputPrivate::handleWindowPixelSizeChanged()
{
    Q_Q(QWaylandOutput);
    Q_ASSERT(window);
    if (sizeFollowsWindow && currentMode <= modes.size() - 1) {
        if (currentMode >= 0) {
            QWaylandOutputMode mode = modes.at(currentMode);
            mode.setSize(windowPixelSize);
            modes.replace(currentMode, mode);
            emit q->geometryChanged();
            if (!availableGeometry.isValid())
                emit q->availableGeometryChanged();
            sendModesInfo();
        } else {
            // We didn't add a mode during the initialization because the window
            // size was invalid, let's add it now
            int mHzRefreshRate = qFloor(window->screen()->refreshRate() * 1000);
            QWaylandOutputMode mode(windowPixelSize, mHzRefreshRate);
            if (mode.isValid()) {
                modes.clear();
                q->addMode(mode, true);
                q->setCurrentMode(mode);
            }
        }
    }
}

void QWaylandOutputPrivate::addView(QWaylandView *view, QWaylandSurface *surface)
{
    for (int i = 0; i < surfaceViews.size(); i++) {
        if (surface == surfaceViews.at(i).surface) {
            if (!surfaceViews.at(i).views.contains(view)) {
                surfaceViews[i].views.append(view);
            }
            return;
        }
    }

    surfaceViews.append(QWaylandSurfaceViewMapper(surface,view));
}

void QWaylandOutputPrivate::removeView(QWaylandView *view, QWaylandSurface *surface)
{
    Q_Q(QWaylandOutput);
    for (int i = 0; i < surfaceViews.size(); i++) {
        if (surface == surfaceViews.at(i).surface) {
            bool removed = surfaceViews[i].views.removeOne(view);
            if (surfaceViews.at(i).views.isEmpty() && removed) {
                if (surfaceViews.at(i).has_entered)
                    q->surfaceLeave(surface);
                surfaceViews.remove(i);
            }
            return;
        }
    }
    qWarning("%s Could not find view %p for surface %p to remove. Possible invalid state", Q_FUNC_INFO, view, surface);
}

QWaylandOutput::QWaylandOutput()
    : QWaylandObject(*new QWaylandOutputPrivate())
{
}

/*!
   \qmltype WaylandOutput
   \inqmlmodule QtWayland.Compositor
   \since 5.8
   \brief Provides access to a displayable area managed by the compositor.

   The WaylandOutput manages a rectangular area within bounds of the compositor's
   geometry, to use it for displaying client content. This could, for instance, be
   a screen managed by the WaylandCompositor.

   The type corresponds to the \c wl_output interface in the Wayland protocol.
*/

/*!
   \class QWaylandOutput
   \inmodule QtWaylandCompositor
   \since 5.8
   \brief The QWaylandOutput class represents a displayable area managed by the compositor.

   The QWaylandOutput manages a rectangular area within bounds of the compositor's
   geometry, to use it for displaying client content. This could, for instance, be
   a screen managed by the WaylandCompositor.

   The class corresponds to the \c wl_output interface in the Wayland protocol.
*/

/*!
 * Constructs a QWaylandOutput in \a compositor and with the specified \a window. The
 * \l{QWaylandCompositor::create()}{create()} function must be called on the
 * \a compositor before constructing a QWaylandOutput for it.
 *
 * The QWaylandOutput object is initialized later, in reaction to an event.
 * At this point it is added as an output for the \a compositor. If it is the
 * first QWaylandOutput object created for this \a compositor, it becomes the
 * \l{QWaylandCompositor::defaultOutput()}{default output}.
 */
QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window)
    : QWaylandObject(*new QWaylandOutputPrivate())
{
    Q_D(QWaylandOutput);
    d->compositor = compositor;
    d->window = window;
    QWaylandCompositorPrivate::get(compositor)->addPolishObject(this);
}

/*!
 * Destroys the QWaylandOutput.
 */
QWaylandOutput::~QWaylandOutput()
{
    Q_D(QWaylandOutput);
    if (d->compositor)
        QWaylandCompositorPrivate::get(d->compositor)->removeOutput(this);
}

/*!
 * \internal
 */
void QWaylandOutput::initialize()
{
    Q_D(QWaylandOutput);

    Q_ASSERT(!d->initialized);
    Q_ASSERT(d->compositor);
    Q_ASSERT(d->compositor->isCreated());

    if (!d->window && d->sizeFollowsWindow) {
        qWarning("Setting QWaylandOutput::sizeFollowsWindow without a window has no effect");
    }

    // Replace modes with one that follows the window size and refresh rate,
    // but only if window size is valid
    if (d->window && d->sizeFollowsWindow) {
        QWaylandOutputMode mode(d->window->size() * d->window->devicePixelRatio(),
                                qFloor(d->window->screen()->refreshRate() * 1000));
        if (mode.isValid()) {
            d->modes.clear();
            addMode(mode, true);
            setCurrentMode(mode);
        }
    }

    QWaylandCompositorPrivate::get(d->compositor)->addOutput(this);

    if (d->window) {
        QObjectPrivate::connect(d->window, &QWindow::widthChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
        QObjectPrivate::connect(d->window, &QWindow::heightChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
        QObjectPrivate::connect(d->window, &QWindow::screenChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
        QObjectPrivate::connect(d->window, &QObject::destroyed, d, &QWaylandOutputPrivate::_q_handleWindowDestroyed);
    }

    d->init(d->compositor->display(), 2);

    d->initialized = true;
}

/*!
 * Returns the QWaylandOutput corresponding to \a resource.
 */
QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource)
{
    if (auto p = QtWayland::fromResource<QWaylandOutputPrivate *>(resource))
        return p->q_func();
    return nullptr;
}

/*!
 * \internal
 */
struct ::wl_resource *QWaylandOutput::resourceForClient(QWaylandClient *client) const
{
    Q_D(const QWaylandOutput);
    QWaylandOutputPrivate::Resource *r = d->resourceMap().value(client->client());
    if (r)
        return r->handle;

    return nullptr;
}

/*!
 * Schedules a QEvent::UpdateRequest to be delivered to the QWaylandOutput's \l{window()}{window}.
 *
 * \sa QWindow::requestUpdate()
 */
void QWaylandOutput::update()
{
    Q_D(QWaylandOutput);
    if (!d->window)
        return;
    d->window->requestUpdate();
}

/*!
 * \qmlproperty WaylandCompositor QtWaylandCompositor::WaylandOutput::compositor
 *
 * This property holds the compositor displaying content on this WaylandOutput.
 *
 * \note This property can be set only once, before the WaylandOutput component
 * is completed.
 */

/*!
 * Returns the compositor for this QWaylandOutput.
 */
QWaylandCompositor *QWaylandOutput::compositor() const
{
    return d_func()->compositor;
}

/*!
 * \internal
 */
void QWaylandOutput::setCompositor(QWaylandCompositor *compositor)
{
    Q_D(QWaylandOutput);

    if (d->compositor == compositor)
        return;

    if (d->initialized) {
        qWarning("Setting QWaylandCompositor %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n", compositor, this);
        return;
    }
    if (d->compositor && d->compositor != compositor) {
        qWarning("Possible initialization error. Moving QWaylandOutput %p between compositor instances.\n", this);
    }

    d->compositor = compositor;

    QWaylandCompositorPrivate::get(compositor)->addPolishObject(this);
}

/*!
 * \qmlproperty string QtWaylandCompositor::WaylandOutput::manufacturer
 *
 * This property holds a textual description of the manufacturer of this WaylandOutput.
 */

/*!
 * \property QWaylandOutput::manufacturer
 *
 * This property holds a textual description of the manufacturer of this QWaylandOutput.
 */
QString QWaylandOutput::manufacturer() const
{
    return d_func()->manufacturer;
}

void QWaylandOutput::setManufacturer(const QString &manufacturer)
{
    Q_D(QWaylandOutput);

    if (d->manufacturer == manufacturer)
        return;

    d->manufacturer = manufacturer;
    d->sendGeometryInfo();
    Q_EMIT manufacturerChanged();
}

/*!
 * \qmlproperty string QtWaylandCompositor::WaylandOutput::model
 *
 * This property holds a textual description of the model of this WaylandOutput.
 */

/*!
 * \property QWaylandOutput::model
 *
 * This property holds a textual description of the model of this QWaylandOutput.
 */
QString QWaylandOutput::model() const
{
    return d_func()->model;
}

void QWaylandOutput::setModel(const QString &model)
{
    Q_D(QWaylandOutput);

    if (d->model == model)
        return;

    d->model = model;
    d->sendGeometryInfo();
    Q_EMIT modelChanged();
}

/*!
 * \qmlproperty point QtWaylandCompositor::WaylandOutput::position
 *
 * This property holds the position of this WaylandOutput in the compositor's coordinate system.
 */

/*!
 * \property QWaylandOutput::position
 *
 * This property holds the position of this QWaylandOutput in the compositor's coordinate system.
 */
QPoint QWaylandOutput::position() const
{
    return d_func()->position;
}

void QWaylandOutput::setPosition(const QPoint &pt)
{
    Q_D(QWaylandOutput);
    if (d->position == pt)
        return;

    d->position = pt;

    d->sendGeometryInfo();

    Q_EMIT positionChanged();
    Q_EMIT geometryChanged();
}

/*!
 * Returns the list of modes.
 */
QList<QWaylandOutputMode> QWaylandOutput::modes() const
{
    Q_D(const QWaylandOutput);
    return d->modes.toList();
}

/*!
 * Adds the mode \a mode to the output and mark it as preferred
 * if \a preferred is \c true.
 * Please note there can only be one preferred mode.
 */
void QWaylandOutput::addMode(const QWaylandOutputMode &mode, bool preferred)
{
    Q_D(QWaylandOutput);

    if (!mode.isValid()) {
        qWarning("Cannot add an invalid mode");
        return;
    }

    d->modes.append(mode);

    if (preferred)
        d->preferredMode = d->modes.indexOf(mode);

    emit modeAdded();
}

/*!
 * Returns the output's size in pixels and refresh rate in mHz.
 * If the current mode is not set it will return an invalid mode.
 *
 * \sa QWaylandOutput::modes
 * \sa QWaylandOutputMode
 */
QWaylandOutputMode QWaylandOutput::currentMode() const
{
    Q_D(const QWaylandOutput);

    if (d->currentMode >= 0 && d->currentMode <= d->modes.size() - 1)
        return d->modes.at(d->currentMode);
    return QWaylandOutputMode();
}

/*!
 * Sets the current mode.
 * The mode \a mode must have been previously added.
 *
 * \sa QWaylandOutput::modes
 * \sa QWaylandOutputMode
 */
void QWaylandOutput::setCurrentMode(const QWaylandOutputMode &mode)
{
    Q_D(QWaylandOutput);

    int index = d->modes.indexOf(mode);
    if (index < 0) {
        qWarning("Cannot set an unknown QWaylandOutput mode as current");
        return;
    }

    d->currentMode = index;

    Q_EMIT currentModeChanged();
    Q_EMIT geometryChanged();
    if (!d->availableGeometry.isValid())
        emit availableGeometryChanged();

    d->sendModesInfo();
}

/*!
 * \qmlproperty rect QtWaylandCompositor::WaylandOutput::geometry
 *
 * This property holds the geometry of the WaylandOutput.
 */

/*!
 * \property QWaylandOutput::geometry
 *
 * This property holds the geometry of the QWaylandOutput.
 *
 * \sa QWaylandOutput::currentMode
 */
QRect QWaylandOutput::geometry() const
{
    Q_D(const QWaylandOutput);
    return QRect(d->position, currentMode().size());
}

/*!
 * \qmlproperty rect QtWaylandCompositor::WaylandOutput::availableGeometry
 *
 * This property holds the geometry of the WaylandOutput available for displaying content.
 * The available geometry is in output coordinates space, starts from 0,0 and it's as big
 * as the output by default.
 *
 * \sa QWaylandOutput::geometry
 */

/*!
 * \property QWaylandOutput::availableGeometry
 *
 * This property holds the geometry of the QWaylandOutput available for displaying content.
 * The available geometry is in output coordinates space, starts from 0,0 and it's as big
 * as the output by default.
 *
 * \sa QWaylandOutput::currentMode, QWaylandOutput::geometry
 */
QRect QWaylandOutput::availableGeometry() const
{
    Q_D(const QWaylandOutput);

    if (!d->availableGeometry.isValid())
        return QRect(QPoint(0, 0), currentMode().size());

    return d->availableGeometry;
}

void QWaylandOutput::setAvailableGeometry(const QRect &availableGeometry)
{
    Q_D(QWaylandOutput);
    if (d->availableGeometry == availableGeometry)
        return;

    if (availableGeometry.topLeft().x() < 0 || availableGeometry.topLeft().y() < 0)
        qWarning("Available geometry should be a portion of the output");

    d->availableGeometry = availableGeometry;

    Q_EMIT availableGeometryChanged();
}

/*!
 * \qmlproperty size QtWaylandCompositor::WaylandOutput::physicalSize
 *
 * This property holds the physical size of the WaylandOutput in millimeters.
 *
 * \sa QWaylandOutput::geometry
 */

/*!
 * \property QWaylandOutput::physicalSize
 *
 * This property holds the physical size of the QWaylandOutput in millimeters.
 *
 * \sa QWaylandOutput::geometry, QWaylandOutput::currentMode
 */
QSize QWaylandOutput::physicalSize() const
{
    return d_func()->physicalSize;
}

void QWaylandOutput::setPhysicalSize(const QSize &size)
{
    Q_D(QWaylandOutput);
    if (d->physicalSize == size)
        return;

    d->physicalSize = size;

    d->sendGeometryInfo();

    Q_EMIT physicalSizeChanged();
}

/*!
 * \enum QWaylandOutput::Subpixel
 *
 * This enum type is used to specify the subpixel arrangement of a QWaylandOutput.
 *
 * \value SubpixelUnknown The subpixel arrangement is not set.
 * \value SubpixelNone There are no subpixels.
 * \value SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order.
 * \value SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order.
 * \value SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order.
 * \value SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order.
 *
 * \sa QWaylandOutput::subpixel
 */

/*!
 * \qmlproperty enum QtWaylandCompositor::WaylandOutput::subpixel
 *
 * This property holds the subpixel arrangement of this WaylandOutput.
 *
 * \list
 * \li WaylandOutput.SubpixelUnknown The subpixel arrangement is not set.
 * \li WaylandOutput.SubpixelNone There are no subpixels.
 * \li WaylandOutput.SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order.
 * \li WaylandOutput.SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order.
 * \li WaylandOutput.SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order.
 * \li WaylandOutput.SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order.
 * \endlist
 *
 * The default is WaylandOutput.SubpixelUnknown.
 */

/*!
 * \property QWaylandOutput::subpixel
 *
 * This property holds the subpixel arrangement of this QWaylandOutput. The default is
 * QWaylandOutput::SubpixelUnknown.
 */
QWaylandOutput::Subpixel QWaylandOutput::subpixel() const
{
    return d_func()->subpixel;
}

void QWaylandOutput::setSubpixel(const Subpixel &subpixel)
{
    Q_D(QWaylandOutput);
    if (d->subpixel == subpixel)
        return;

    d->subpixel = subpixel;

    d->sendGeometryInfo();

    Q_EMIT subpixelChanged();
}

/*! \enum QWaylandOutput::Transform
 *
 * This enum type is used to specify the orientation of a QWaylandOutput.
 *
 * \value TransformNormal The orientation is normal.
 * \value Transform90 The orientation is rotated 90 degrees.
 * \value Transform180 The orientation is rotated 180 degrees.
 * \value Transform270 The orientation is rotated 270 degrees.
 * \value TransformFlipped The orientation is mirrored.
 * \value TransformFlipped90 The orientation is mirrored, and rotated 90 degrees.
 * \value TransformFlipped180 The orientation is mirrored, and rotated 180 degrees.
 * \value TransformFlipped270 The orientation is mirrored, and rotated 270 degrees.
 *
 * \sa QWaylandOutput::transform
*/

/*!
 * \qmlproperty enum QtWaylandCompositor::WaylandOutput::transform
 *
 * This property holds the transformation that the QWaylandCompositor applies to a surface
 * to compensate for the orientation of the QWaylandOutput.
 *
 * \list
 * \li WaylandOutput.TransformNormal The orientation is normal.
 * \li WaylandOutput.Transform90 The orientation is rotated 90 degrees.
 * \li WaylandOutput.Transform180 The orientation is rotated 180 degrees.
 * \li WaylandOutput.Transform270 The orientation is rotated 270 degrees.
 * \li WaylandOutput.TransformFlipped The orientation is mirrored.
 * \li WaylandOutput.TransformFlipped90 The orientation is mirrored, then rotated 90 degrees.
 * \li WaylandOutput.TransformFlipped180 The orientation is mirrored, then rotated 180 degrees.
 * \li WaylandOutput.TransformFlipped270 The orientation is mirrored, then rotated 270 degrees.
 * \endlist
 *
 * The default is WaylandOutput.TransformNormal.
 */

/*!
 * \property QWaylandOutput::transform
 *
 * This property holds the transformation that the QWaylandCompositor applies to a surface
 * to compensate for the orientation of the QWaylandOutput.
 *
 * The default is QWaylandOutput::TransformNormal.
 */
QWaylandOutput::Transform QWaylandOutput::transform() const
{
    return d_func()->transform;
}

void QWaylandOutput::setTransform(const Transform &transform)
{
    Q_D(QWaylandOutput);
    if (d->transform == transform)
        return;

    d->transform = transform;

    d->sendGeometryInfo();

    Q_EMIT transformChanged();
}

/*!
 * \qmlproperty int QtWaylandCompositor::WaylandOutput::scaleFactor
 *
 * This property holds the factor by which the WaylandCompositor scales surface buffers
 * before they are displayed. It is used on high density output devices where unscaled content
 * would be too small to be practical. The client can in turn set the scale factor of its
 * buffer to match the output if it prefers to provide high resolution content that is
 * suitable for the output device.
 *
 * The default is 1 (no scaling).
 */

/*!
 * \property QWaylandOutput::scaleFactor
 *
 * This property holds the factor by which the QWaylandCompositor scales surface buffers
 * before they are displayed. This is used on high density output devices where unscaled content
 * would be too small to be practical. The client can in turn set the scale factor of its
 * buffer to match the output if it prefers to provide high resolution content that is
 * suitable for the output device.
 *
 * The default is 1 (no scaling).
 */
int QWaylandOutput::scaleFactor() const
{
    return d_func()->scaleFactor;
}

void QWaylandOutput::setScaleFactor(int scale)
{
    Q_D(QWaylandOutput);
    if (d->scaleFactor == scale)
        return;

    d->scaleFactor = scale;

    const auto resMap = d->resourceMap();
    for (QWaylandOutputPrivate::Resource *resource : resMap) {
        if (resource->version() >= 2) {
            d->send_scale(resource->handle, scale);
            d->send_done(resource->handle);
        }
    }

    Q_EMIT scaleFactorChanged();

    if (d->xdgOutput)
        QWaylandXdgOutputV1Private::get(d->xdgOutput)->sendDone();
}

/*!
 * \qmlproperty bool QtWaylandCompositor::WaylandOutput::sizeFollowsWindow
 *
 * This property controls whether the size of the WaylandOutput matches the
 * size of its window.
 *
 * If this property is true, all modes previously added are replaced by a
 * mode that matches window size and screen refresh rate.
 *
 * The default is false.
 */

/*!
 * \property QWaylandOutput::sizeFollowsWindow
 *
 * This property controls whether the size of the QWaylandOutput matches the
 * size of its window.
 *
 * If this property is true, all modes previously added are replaced by a
 * mode that matches window size and screen refresh rate.
 *
 * The default is false.
 */
bool QWaylandOutput::sizeFollowsWindow() const
{
    return d_func()->sizeFollowsWindow;
}

void QWaylandOutput::setSizeFollowsWindow(bool follow)
{
    Q_D(QWaylandOutput);

    if (follow != d->sizeFollowsWindow) {
        d->sizeFollowsWindow = follow;
        Q_EMIT sizeFollowsWindowChanged();
    }
}

/*!
 * \qmlproperty Window QtWaylandCompositor::WaylandOutput::window
 *
 * This property holds the Window for this WaylandOutput.
 *
 * \note This property can be set only once, before the WaylandOutput
 * component is completed.
 */

/*!
 * \property QWaylandOutput::window
 *
 * This property holds the QWindow for this QWaylandOutput.
 */
QWindow *QWaylandOutput::window() const
{
    return d_func()->window;
}

void QWaylandOutput::setWindow(QWindow *window)
{
    Q_D(QWaylandOutput);
    if (d->window == window)
        return;
    if (d->initialized) {
        qWarning("Setting QWindow %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n", window, this);
        return;
    }
    d->window = window;
    emit windowChanged();
}

/*!
 * Informs QWaylandOutput that a frame has started.
 */
void QWaylandOutput::frameStarted()
{
    Q_D(QWaylandOutput);
    for (int i = 0; i < d->surfaceViews.size(); i++) {
        QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews[i];
        if (surfacemapper.maybePrimaryView())
            surfacemapper.surface->frameStarted();
    }
}

/*!
 * Sends pending frame callbacks.
 */
void QWaylandOutput::sendFrameCallbacks()
{
    Q_D(QWaylandOutput);
    for (int i = 0; i < d->surfaceViews.size(); i++) {
        const QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews.at(i);
        if (surfacemapper.surface && surfacemapper.surface->hasContent()) {
            if (!surfacemapper.has_entered) {
                surfaceEnter(surfacemapper.surface);
                d->surfaceViews[i].has_entered = true;
            }
            if (auto primaryView = surfacemapper.maybePrimaryView()) {
                if (!QWaylandViewPrivate::get(primaryView)->independentFrameCallback)
                    surfacemapper.surface->sendFrameCallbacks();
            }
        }
    }
    wl_display_flush_clients(d->compositor->display());
}

/*!
 * \internal
 */
void QWaylandOutput::surfaceEnter(QWaylandSurface *surface)
{
    if (!surface)
        return;

    auto clientResource = resourceForClient(surface->client());
    if (clientResource)
        QWaylandSurfacePrivate::get(surface)->send_enter(clientResource);
}

/*!
 * \internal
 */
void QWaylandOutput::surfaceLeave(QWaylandSurface *surface)
{
    if (!surface || !surface->client())
        return;

    auto *clientResource = resourceForClient(surface->client());
    if (clientResource)
        QWaylandSurfacePrivate::get(surface)->send_leave(clientResource);
}

/*!
 * \internal
 */
bool QWaylandOutput::event(QEvent *event)
{
    if (event->type() == QEvent::Polish)
        initialize();
    return QObject::event(event);
}

QT_END_NAMESPACE

#include "moc_qwaylandoutput.cpp"
