summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper/qwloutput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/wayland_wrapper/qwloutput.cpp')
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp239
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