diff options
Diffstat (limited to 'src/compositor/wayland_wrapper/qwloutput.cpp')
-rw-r--r-- | src/compositor/wayland_wrapper/qwloutput.cpp | 239 |
1 files changed, 181 insertions, 58 deletions
diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp index 7638370bc..1659a63cc 100644 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ b/src/compositor/wayland_wrapper/qwloutput.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** @@ -39,100 +40,222 @@ ****************************************************************************/ #include "qwloutput_p.h" + +#include "qwlcompositor_p.h" #include "qwlextendedoutput_p.h" -#include <QGuiApplication> -#include <QtGui/QScreen> + +#include <QtGui/QWindow> #include <QRect> QT_BEGIN_NAMESPACE namespace QtWayland { -OutputGlobal::OutputGlobal(struct ::wl_display *display) - : QtWaylandServer::wl_output(display, 2) - , m_displayId(-1) - , m_numQueued(0) - , m_transform(WL_OUTPUT_TRANSFORM_NORMAL) +static QtWaylandServer::wl_output::subpixel toWlSubpixel(const QWaylandOutput::Subpixel &value) { - QScreen *screen = QGuiApplication::primaryScreen(); - m_geometry = QRect(QPoint(0, 0), screen->availableGeometry().size()); - m_refreshRate = qRound(screen->refreshRate() * 1000.0); + 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; } -OutputGlobal::~OutputGlobal() +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; } -void OutputGlobal::output_bind_resource(Resource *resource) +Output::Output(Compositor *compositor, QWindow *window) + : QtWaylandServer::wl_output(compositor->wl_display(), 2) + , m_compositor(compositor) + , m_window(window) + , m_output(Q_NULLPTR) + , m_position(QPoint()) + , m_availableGeometry(QRect()) + , m_physicalSize(QSize()) + , m_subpixel(QWaylandOutput::SubpixelUnknown) + , m_transform(QWaylandOutput::TransformNormal) + , m_scaleFactor(1) { - wl_output_send_geometry(resource->handle, 0, 0, - m_physicalSize.width(), m_physicalSize.height(), 0, "", "", m_transform); + m_mode.size = window ? window->size() : QSize(); + m_mode.refreshRate = 60; - wl_output_send_mode(resource->handle, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED, - size().width(), size().height(), refreshRate()); + qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode"); +} - if (resource->version() >= 2) - wl_output_send_done(resource->handle); +void Output::output_bind_resource(Resource *resource) +{ + send_geometry(resource->handle, + m_position.x(), m_position.y(), + m_physicalSize.width(), m_physicalSize.height(), + toWlSubpixel(m_subpixel), m_manufacturer, m_model, + toWlTransform(m_transform)); + + send_mode(resource->handle, mode_current | mode_preferred, + m_mode.size.width(), m_mode.size.height(), + m_mode.refreshRate); + + send_scale(resource->handle, m_scaleFactor); + + send_done(resource->handle); } -void OutputGlobal::setPhysicalSize(const QSize &size) +void Output::setManufacturer(const QString &manufacturer) { - if (m_physicalSize != size) { - m_physicalSize = size; + m_manufacturer = manufacturer; +} - foreach (Resource *res, resourceMap()) { - wl_output_send_geometry(res->handle, 0, 0, - m_physicalSize.width(), m_physicalSize.height(), 0, "", "", m_transform); +void Output::setModel(const QString &model) +{ + m_model = model; +} - if (res->version() >= 2) - wl_output_send_done(res->handle); - } - } +void Output::setPosition(const QPoint &position) +{ + if (m_position == position) + return; + + m_position = position; + + sendGeometryInfo(); } -void OutputGlobal::setGeometry(const QRect &geometry) +void Output::setMode(const QWaylandOutput::Mode &mode) { - m_geometry = geometry; + if (m_mode.size == mode.size && m_mode.refreshRate == mode.refreshRate) + return; + + m_mode = mode; + + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_mode(resource->handle, mode_current, + m_mode.size.width(), m_mode.size.height(), + m_mode.refreshRate * 1000); + send_done(resource->handle); + } } -void OutputGlobal::setRefreshRate(int rate) +QRect Output::geometry() const { - m_refreshRate = rate; + return QRect(m_position, m_mode.size); } -void OutputGlobal::sendOutputOrientation(Qt::ScreenOrientation orientation) +void Output::setGeometry(const QRect &geometry) { - QScreen *screen = QGuiApplication::primaryScreen(); - bool isPortrait = screen->primaryOrientation() == Qt::PortraitOrientation; - switch (orientation) { - case Qt::PrimaryOrientation: - m_transform = WL_OUTPUT_TRANSFORM_NORMAL; - break; - case Qt::PortraitOrientation: - m_transform = isPortrait ? WL_OUTPUT_TRANSFORM_NORMAL : WL_OUTPUT_TRANSFORM_90; - break; - case Qt::LandscapeOrientation: - m_transform = isPortrait ? WL_OUTPUT_TRANSFORM_270 : WL_OUTPUT_TRANSFORM_NORMAL; - break; - case Qt::InvertedPortraitOrientation: - m_transform = isPortrait ? WL_OUTPUT_TRANSFORM_180 : WL_OUTPUT_TRANSFORM_270; - break; - case Qt::InvertedLandscapeOrientation: - m_transform = isPortrait ? WL_OUTPUT_TRANSFORM_90 : WL_OUTPUT_TRANSFORM_180; - break; + if (m_position == geometry.topLeft() && m_mode.size == geometry.size()) + return; + + m_position = geometry.topLeft(); + m_mode.size = geometry.size(); + + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_geometry(resource->handle, + m_position.x(), m_position.y(), + m_physicalSize.width(), m_physicalSize.height(), + toWlSubpixel(m_subpixel), m_manufacturer, m_model, + toWlTransform(m_transform)); + send_mode(resource->handle, mode_current, + m_mode.size.width(), m_mode.size.height(), + m_mode.refreshRate * 1000); + send_done(resource->handle); } +} - foreach (Resource *res, resourceMap()) { - wl_output_send_geometry(res->handle, 0, 0, - m_physicalSize.width(), m_physicalSize.height(), 0, "", "", m_transform); - if (res->version() >= 2) - wl_output_send_done(res->handle); +void Output::setAvailableGeometry(const QRect &availableGeometry) +{ + m_availableGeometry = availableGeometry; +} + +void Output::setPhysicalSize(const QSize &physicalSize) +{ + if (m_physicalSize == physicalSize) + return; + + m_physicalSize = physicalSize; + + sendGeometryInfo(); +} + +void Output::setSubpixel(const QWaylandOutput::Subpixel &subpixel) +{ + if (m_subpixel == subpixel) + return; + + m_subpixel = subpixel; + + sendGeometryInfo(); +} + +void Output::setTransform(const QWaylandOutput::Transform &transform) +{ + if (m_transform == transform) + return; + + m_transform = transform; + + sendGeometryInfo(); +} + +void Output::setScaleFactor(int scale) +{ + if (m_scaleFactor == scale) + return; + + m_scaleFactor = scale; + + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_scale(resource->handle, m_scaleFactor); + send_done(resource->handle); } } -Output *OutputGlobal::outputForClient(wl_client *client) const +OutputResource *Output::outputForClient(wl_client *client) const +{ + return static_cast<OutputResource *>(resourceMap().value(client)); +} + +void Output::sendGeometryInfo() { - return static_cast<Output *>(resourceMap().value(client)); + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_geometry(resource->handle, + m_position.x(), m_position.x(), + m_physicalSize.width(), m_physicalSize.height(), + toWlSubpixel(m_subpixel), m_manufacturer, m_model, + toWlTransform(m_transform)); + send_done(resource->handle); + } } } // namespace Wayland |