summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPier Luigi Fiorini <pierluigi.fiorini@gmail.com>2013-08-26 08:18:56 +0200
committerPier Luigi Fiorini <pierluigi.fiorini@gmail.com>2015-02-08 10:35:22 +0000
commitb09f2e8440b7a0c9532d730d52296cf05b944ee2 (patch)
treef70d559074195c454f31d0e48292e8b43bae0eb2
parent2322ef51948ef20afb3a93d1fea7830dfee4f7d6 (diff)
Add QWaylandOutput to support multiple outputs
Add a new QWaylandOutput class to support multiple outputs. Each QWaylandOutput need a window for rendering. Rename OutputGlobal to Output and Output to OutputResource. Add support for physical size, mode and available geometry. Use better defaults for geometry and refreshRate from the QWindow if available. A window is no longer passed to QWaylandCompositor constructor and all output related methods are removed, however one or more outputs are required for hardware integration. QWaylandCompositor returns a list of outputs and offers an API to add or remove outputs. Hardware integrations can run headless. Change-Id: I742996571ddb78328f7bfa4f79b25a81995279e1 Done-with: Jan Arne Petersen <jan.petersen@kdab.com> Done-with: Jørgen Lind <jorgen.lind@theqtcompany.com> Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
-rw-r--r--examples/wayland/qml-compositor/main.cpp5
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.cpp9
-rw-r--r--examples/wayland/server-buffer/compositor/main.cpp5
-rw-r--r--src/compositor/compositor_api/compositor_api.pri4
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp77
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h20
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.cpp246
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.h164
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.cpp32
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.h12
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.cpp78
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.h74
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.cpp7
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp8
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h3
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp106
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h20
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedoutput.cpp4
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedoutput_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp6
-rw-r--r--src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h3
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp239
-rw-r--r--src/compositor/wayland_wrapper/qwloutput_p.h98
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface.cpp57
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp7
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h4
-rw-r--r--src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp3
-rw-r--r--src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp3
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp2
-rw-r--r--src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp4
-rw-r--r--src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp2
-rw-r--r--src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp4
33 files changed, 1078 insertions, 236 deletions
diff --git a/examples/wayland/qml-compositor/main.cpp b/examples/wayland/qml-compositor/main.cpp
index 26e730d4..06961dfc 100644
--- a/examples/wayland/qml-compositor/main.cpp
+++ b/examples/wayland/qml-compositor/main.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
**
@@ -42,6 +43,7 @@
#include "qwaylandquicksurface.h"
#include <QtCompositor/qwaylandsurfaceitem.h>
+#include <QtCompositor/qwaylandoutput.h>
#include <QGuiApplication>
#include <QTimer>
@@ -60,7 +62,7 @@ class QmlCompositor : public QQuickView, public QWaylandQuickCompositor
public:
QmlCompositor()
- : QWaylandQuickCompositor(this, 0, DefaultExtensions | SubSurfaceExtension)
+ : QWaylandQuickCompositor(0, DefaultExtensions | SubSurfaceExtension)
, m_fullscreenSurface(0)
{
setSource(QUrl("main.qml"));
@@ -68,6 +70,7 @@ public:
setColor(Qt::black);
winId();
addDefaultShell();
+ createOutput(this, "", "");
connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks()));
}
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
index c933152d..8801ad14 100644
--- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
+++ b/examples/wayland/qwindow-compositor/qwindowcompositor.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
**
@@ -55,6 +56,7 @@
#include <QtCompositor/qwaylandinput.h>
#include <QtCompositor/qwaylandbufferref.h>
#include <QtCompositor/qwaylandsurfaceview.h>
+#include <QtCompositor/qwaylandoutput.h>
QT_BEGIN_NAMESPACE
@@ -108,7 +110,7 @@ public:
};
QWindowCompositor::QWindowCompositor(CompositorWindow *window)
- : QWaylandCompositor(window, 0, DefaultExtensions | SubSurfaceExtension)
+ : QWaylandCompositor(0, DefaultExtensions | SubSurfaceExtension)
, m_window(window)
, m_backgroundTexture(0)
, m_textureBlitter(0)
@@ -134,8 +136,7 @@ QWindowCompositor::QWindowCompositor(CompositorWindow *window)
setRetainedSelectionEnabled(true);
- setOutputGeometry(QRect(QPoint(0, 0), window->size()));
- setOutputRefreshRate(qRound(qGuiApp->primaryScreen()->refreshRate() * 1000.0));
+ createOutput(window, "", "");
addDefaultShell();
}
@@ -321,7 +322,7 @@ void QWindowCompositor::render()
// Draw the background image texture
m_textureBlitter->drawTexture(m_backgroundTexture->textureId(),
QRect(QPoint(0, 0), m_backgroundImage.size()),
- window()->size(),
+ m_window->size(),
0, false, true);
foreach (QWaylandSurface *surface, m_surfaces) {
diff --git a/examples/wayland/server-buffer/compositor/main.cpp b/examples/wayland/server-buffer/compositor/main.cpp
index 9f0108fa..0bf6408c 100644
--- a/examples/wayland/server-buffer/compositor/main.cpp
+++ b/examples/wayland/server-buffer/compositor/main.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -54,6 +55,7 @@
#include <QQuickView>
#include "qwayland-server-share-buffer.h"
+#include <QtCompositor/qwaylandoutput.h>
#include <QtCompositor/private/qwlcompositor_p.h>
#include <QtCompositor/private/qwlserverbufferintegration_p.h>
@@ -70,7 +72,7 @@ class QmlCompositor
public:
QmlCompositor()
- : QWaylandQuickCompositor(this, 0, DefaultExtensions | SubSurfaceExtension)
+ : QWaylandQuickCompositor(0, DefaultExtensions | SubSurfaceExtension)
, QtWaylandServer::qt_share_buffer(QWaylandCompositor::handle()->wl_display(), 1)
, m_server_buffer_32_bit(0)
, m_server_buffer_item_32_bit(0)
@@ -82,6 +84,7 @@ public:
setColor(Qt::black);
create();
grabWindow();
+ createOutput(this, "", "");
addDefaultShell();
connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks()));
diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri
index 931d6c8f..ac356b8f 100644
--- a/src/compositor/compositor_api/compositor_api.pri
+++ b/src/compositor/compositor_api/compositor_api.pri
@@ -7,6 +7,7 @@ HEADERS += \
compositor_api/qwaylandsurface_p.h \
compositor_api/qwaylandinput.h \
compositor_api/qwaylandinputpanel.h \
+ compositor_api/qwaylandoutput.h \
compositor_api/qwaylanddrag.h \
compositor_api/qwaylandbufferref.h \
compositor_api/qwaylandsurfaceview.h \
@@ -19,6 +20,7 @@ SOURCES += \
compositor_api/qwaylandsurface.cpp \
compositor_api/qwaylandinput.cpp \
compositor_api/qwaylandinputpanel.cpp \
+ compositor_api/qwaylandoutput.cpp \
compositor_api/qwaylanddrag.cpp \
compositor_api/qwaylandbufferref.cpp \
compositor_api/qwaylandsurfaceview.cpp \
@@ -31,11 +33,13 @@ qtHaveModule(quick) {
SOURCES += \
compositor_api/qwaylandquickcompositor.cpp \
compositor_api/qwaylandquicksurface.cpp \
+ compositor_api/qwaylandquickoutput.cpp \
compositor_api/qwaylandsurfaceitem.cpp
HEADERS += \
compositor_api/qwaylandquickcompositor.h \
compositor_api/qwaylandquicksurface.h \
+ compositor_api/qwaylandquickoutput.h \
compositor_api/qwaylandsurfaceitem.h
QT += qml quick
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 25ceb6e8..1839832e 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -41,6 +41,7 @@
#include "qwaylandcompositor.h"
#include "qwaylandinput.h"
+#include "qwaylandoutput.h"
#include "qwaylandglobalinterface.h"
#include "qwaylandsurfaceview.h"
@@ -55,22 +56,21 @@
#include <QtCore/QStringList>
#include <QtGui/QDesktopServices>
+#include <QtGui/QScreen>
#include <QDebug>
QT_BEGIN_NAMESPACE
-QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName, ExtensionFlags extensions)
+QWaylandCompositor::QWaylandCompositor(const char *socketName, ExtensionFlags extensions)
: m_compositor(new QtWayland::Compositor(this, extensions))
- , m_toplevel_window(window)
{
m_compositor->m_socket_name = socketName;
m_compositor->init();
}
-QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName, QtWayland::Compositor *dptr)
+QWaylandCompositor::QWaylandCompositor(const char *socketName, QtWayland::Compositor *dptr)
: m_compositor(dptr)
- , m_toplevel_window(window)
{
m_compositor->m_socket_name = socketName;
m_compositor->init();
@@ -143,9 +143,24 @@ QList<QWaylandSurface *> QWaylandCompositor::surfaces() const
return surfs;
}
-QWindow * QWaylandCompositor::window() const
+QList<QWaylandOutput *> QWaylandCompositor::outputs() const
{
- return m_toplevel_window;
+ return m_compositor->outputs();
+}
+
+QWaylandOutput *QWaylandCompositor::output(QWindow *window)
+{
+ return m_compositor->output(window);
+}
+
+QWaylandOutput *QWaylandCompositor::primaryOutput() const
+{
+ return m_compositor->primaryOutput();
+}
+
+void QWaylandCompositor::setPrimaryOutput(QWaylandOutput *output)
+{
+ m_compositor->setPrimaryOutput(output);
}
void QWaylandCompositor::cleanupGraphicsResources()
@@ -221,33 +236,66 @@ const char *QWaylandCompositor::socketName() const
return m_compositor->m_socket_name.constData();
}
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
Set the screen orientation based on accelerometer data or similar.
*/
void QWaylandCompositor::setScreenOrientation(Qt::ScreenOrientation orientation)
{
- m_compositor->setScreenOrientation(orientation);
+ QWaylandOutput *output = primaryOutput();
+ if (output) {
+ bool isPortrait = output->window()->screen()->primaryOrientation() == Qt::PortraitOrientation;
+
+ switch (orientation) {
+ case Qt::PrimaryOrientation:
+ output->setTransform(QWaylandOutput::TransformNormal);
+ break;
+ case Qt::LandscapeOrientation:
+ output->setTransform(isPortrait ? QWaylandOutput::Transform270 : QWaylandOutput::TransformNormal);
+ break;
+ case Qt::PortraitOrientation:
+ output->setTransform(isPortrait ? QWaylandOutput::TransformNormal : QWaylandOutput::Transform90);
+ break;
+ case Qt::InvertedLandscapeOrientation:
+ output->setTransform(isPortrait ? QWaylandOutput::Transform90 : QWaylandOutput::Transform180);
+ break;
+ case Qt::InvertedPortraitOrientation:
+ output->setTransform(isPortrait ? QWaylandOutput::Transform180 : QWaylandOutput::Transform270);
+ break;
+ }
+ }
}
void QWaylandCompositor::setOutputGeometry(const QRect &geometry)
{
- m_compositor->setOutputGeometry(geometry);
+ QWaylandOutput *output = primaryOutput();
+ if (output)
+ output->setGeometry(geometry);
}
QRect QWaylandCompositor::outputGeometry() const
{
- return m_compositor->outputGeometry();
+ QWaylandOutput *output = primaryOutput();
+ if (output)
+ return output->geometry();
+ return QRect();
}
void QWaylandCompositor::setOutputRefreshRate(int rate)
{
- m_compositor->setOutputRefreshRate(rate);
+ QWaylandOutput *output = primaryOutput();
+ if (output)
+ output->setMode({output->mode().size, rate});
}
int QWaylandCompositor::outputRefreshRate() const
{
- return m_compositor->outputRefreshRate();
+ QWaylandOutput *output = primaryOutput();
+ if (output)
+ return output->mode().refreshRate;
+ return 0;
}
+#endif
QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const
{
@@ -302,4 +350,11 @@ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent)
return m_compositor->inputDeviceFor(inputEvent);
}
+QWaylandOutput *QWaylandCompositor::createOutput(QWindow *window,
+ const QString &manufacturer,
+ const QString &model)
+{
+ return new QWaylandOutput(this, window, manufacturer, model);
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h
index 2c73a1d3..c1c78551 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.h
+++ b/src/compositor/compositor_api/qwaylandcompositor.h
@@ -63,6 +63,7 @@ class QWaylandInputPanel;
class QWaylandDrag;
class QWaylandGlobalInterface;
class QWaylandSurfaceView;
+class QWaylandOutput;
namespace QtWayland
{
@@ -86,7 +87,7 @@ public:
};
Q_DECLARE_FLAGS(ExtensionFlags, ExtensionFlag)
- QWaylandCompositor(QWindow *window = 0, const char *socketName = 0, ExtensionFlags extensions = DefaultExtensions);
+ QWaylandCompositor(const char *socketName = 0, ExtensionFlags extensions = DefaultExtensions);
virtual ~QWaylandCompositor();
void addGlobalInterface(QWaylandGlobalInterface *interface);
@@ -102,7 +103,11 @@ public:
QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const;
QList<QWaylandSurface *> surfaces() const;
- QWindow *window()const;
+ QList<QWaylandOutput *> outputs() const;
+ QWaylandOutput *output(QWindow *window);
+
+ QWaylandOutput *primaryOutput() const;
+ void setPrimaryOutput(QWaylandOutput *output);
virtual void surfaceCreated(QWaylandSurface *surface) = 0;
virtual void surfaceAboutToBeDestroyed(QWaylandSurface *surface);
@@ -122,6 +127,7 @@ public:
const char *socketName() const;
+#if QT_DEPRECATED_SINCE(5, 5)
void setScreenOrientation(Qt::ScreenOrientation orientation);
void setOutputGeometry(const QRect &outputGeometry);
@@ -129,6 +135,7 @@ public:
void setOutputRefreshRate(int refreshRate);
int outputRefreshRate() const;
+#endif
QWaylandInputDevice *defaultInputDevice() const;
@@ -154,14 +161,15 @@ public:
QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent);
protected:
- QWaylandCompositor(QWindow *window, const char *socketName, QtWayland::Compositor *dptr);
+ QWaylandCompositor(const char *socketName, QtWayland::Compositor *dptr);
virtual void retainedSelectionReceived(QMimeData *mimeData);
+ virtual QWaylandOutput *createOutput(QWindow *window,
+ const QString &manufacturer,
+ const QString &model);
+
friend class QtWayland::Compositor;
QtWayland::Compositor *m_compositor;
-
-private:
- QWindow *m_toplevel_window;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::ExtensionFlags)
diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp
new file mode 100644
index 00000000..ab2ee526
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutput.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QtMath>
+#include <QtGui/QWindow>
+#include <QtGui/QExposeEvent>
+#include <private/qobject_p.h>
+
+#include "wayland_wrapper/qwlcompositor_p.h"
+#include "wayland_wrapper/qwloutput_p.h"
+#include "qwaylandcompositor.h"
+#include "qwaylandoutput.h"
+
+QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window,
+ const QString &manufacturer, const QString &model)
+ : QObject()
+ , d_ptr(new QtWayland::Output(compositor->handle(), window))
+{
+ d_ptr->m_output = this;
+ d_ptr->setManufacturer(manufacturer);
+ d_ptr->setModel(model);
+ d_ptr->compositor()->addOutput(this);
+}
+
+QWaylandOutput::~QWaylandOutput()
+{
+ d_ptr->compositor()->removeOutput(this);
+ delete d_ptr;
+}
+
+QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource)
+{
+ QtWayland::OutputResource *outputResource = static_cast<QtWayland::OutputResource *>(
+ QtWayland::Output::Resource::fromResource(resource));
+ if (!outputResource)
+ return Q_NULLPTR;
+
+ QtWayland::Output *output = static_cast<QtWayland::Output *>(outputResource->output_object);
+ if (!output)
+ return Q_NULLPTR;
+
+ return output->output();
+}
+
+void QWaylandOutput::update()
+{
+ QRect rect(QPoint(0, 0), window()->size());
+ QRegion region(rect);
+ QExposeEvent *event = new QExposeEvent(region);
+ QCoreApplication::postEvent(window(), event);
+}
+
+QWaylandCompositor *QWaylandOutput::compositor() const
+{
+ return d_ptr->compositor()->waylandCompositor();
+}
+
+QString QWaylandOutput::manufacturer() const
+{
+ return d_ptr->manufacturer();
+}
+
+QString QWaylandOutput::model() const
+{
+ return d_ptr->model();
+}
+
+QPoint QWaylandOutput::position() const
+{
+ return d_ptr->position();
+}
+
+void QWaylandOutput::setPosition(const QPoint &pt)
+{
+ if (d_ptr->position() == pt)
+ return;
+
+ d_ptr->setPosition(pt);
+ Q_EMIT positionChanged();
+ Q_EMIT geometryChanged();
+}
+
+QWaylandOutput::Mode QWaylandOutput::mode() const
+{
+ return d_ptr->mode();
+}
+
+void QWaylandOutput::setMode(const Mode &mode)
+{
+ if (d_ptr->mode().size == mode.size && d_ptr->mode().refreshRate == mode.refreshRate)
+ return;
+
+ d_ptr->setMode(mode);
+ Q_EMIT modeChanged();
+ Q_EMIT geometryChanged();
+
+ if (window()) {
+ window()->resize(mode.size);
+ window()->setMinimumSize(mode.size);
+ window()->setMaximumSize(mode.size);
+ }
+}
+
+QRect QWaylandOutput::geometry() const
+{
+ return d_ptr->geometry();
+}
+
+void QWaylandOutput::setGeometry(const QRect &geometry)
+{
+ if (d_ptr->geometry() == geometry)
+ return;
+
+ d_ptr->setGeometry(geometry);
+ Q_EMIT positionChanged();
+ Q_EMIT modeChanged();
+
+ if (window()) {
+ window()->resize(geometry.size());
+ window()->setMinimumSize(geometry.size());
+ window()->setMaximumSize(geometry.size());
+ }
+}
+
+QRect QWaylandOutput::availableGeometry() const
+{
+ if (!d_ptr->availableGeometry().isValid())
+ return QRect(d_ptr->position(), d_ptr->mode().size);
+
+ return d_ptr->availableGeometry();
+}
+
+void QWaylandOutput::setAvailableGeometry(const QRect &availableGeometry)
+{
+ if (d_ptr->availableGeometry() == availableGeometry)
+ return;
+
+ d_ptr->setAvailableGeometry(availableGeometry);
+ Q_EMIT availableGeometryChanged();
+}
+
+QSize QWaylandOutput::physicalSize() const
+{
+ return d_ptr->physicalSize();
+}
+
+void QWaylandOutput::setPhysicalSize(const QSize &size)
+{
+ if (d_ptr->physicalSize() == size)
+ return;
+
+ d_ptr->setPhysicalSize(size);
+ Q_EMIT physicalSizeChanged();
+}
+
+QWaylandOutput::Subpixel QWaylandOutput::subpixel() const
+{
+ return d_ptr->subpixel();
+}
+
+void QWaylandOutput::setSubpixel(const Subpixel &subpixel)
+{
+ if (d_ptr->subpixel() == subpixel)
+ return;
+
+ d_ptr->setSubpixel(subpixel);
+ Q_EMIT subpixelChanged();
+}
+
+QWaylandOutput::Transform QWaylandOutput::transform() const
+{
+ return d_ptr->transform();
+}
+
+void QWaylandOutput::setTransform(const Transform &transform)
+{
+ if (d_ptr->transform() == transform)
+ return;
+
+ d_ptr->setTransform(transform);
+ Q_EMIT transformChanged();
+}
+
+int QWaylandOutput::scaleFactor() const
+{
+ return d_ptr->scaleFactor();
+}
+
+void QWaylandOutput::setScaleFactor(int scale)
+{
+ if (d_ptr->scaleFactor() == scale)
+ return;
+
+ d_ptr->setScaleFactor(scale);
+ Q_EMIT scaleFactorChanged();
+
+}
+
+QWindow *QWaylandOutput::window() const
+{
+ return d_ptr->window();
+}
+
+QtWayland::Output *QWaylandOutput::handle()
+{
+ return d_ptr;
+}
diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h
new file mode 100644
index 00000000..5c31be9d
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutput.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDOUTPUT_H
+#define QWAYLANDOUTPUT_H
+
+#include <QtCompositor/qwaylandexport.h>
+
+#include <QObject>
+#include <QRect>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+struct wl_resource;
+
+class QWaylandCompositor;
+class QWindow;
+
+namespace QtWayland {
+ class Output;
+}
+
+class Q_COMPOSITOR_EXPORT QWaylandOutput : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString manufacturer READ manufacturer CONSTANT)
+ Q_PROPERTY(QString model READ model CONSTANT)
+ Q_PROPERTY(QPoint position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(QWaylandOutput::Mode mode READ mode WRITE setMode NOTIFY modeChanged)
+ Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
+ Q_PROPERTY(QRect availableGeometry READ availableGeometry WRITE setAvailableGeometry NOTIFY availableGeometryChanged)
+ Q_PROPERTY(QSize physicalSize READ physicalSize WRITE setPhysicalSize NOTIFY physicalSizeChanged)
+ Q_PROPERTY(QWaylandOutput::Subpixel subpixel READ subpixel WRITE setSubpixel NOTIFY subpixelChanged)
+ Q_PROPERTY(QWaylandOutput::Transform transform READ transform WRITE setTransform NOTIFY transformChanged)
+ Q_PROPERTY(int scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
+ Q_PROPERTY(QWindow *window READ window CONSTANT)
+ Q_ENUMS(Subpixel Transform)
+public:
+ enum Subpixel {
+ SubpixelUnknown = 0,
+ SubpixelNone,
+ SubpixelHorizontalRgb,
+ SubpixelHorizontalBgr,
+ SubpixelVerticalRgb,
+ SubpixelVerticalBgr
+ };
+
+ enum Transform {
+ TransformNormal = 0,
+ Transform90,
+ Transform180,
+ Transform270,
+ TransformFlipped,
+ TransformFlipped90,
+ TransformFlipped180,
+ TransformFlipped270
+ };
+
+ struct Mode
+ {
+ QSize size;
+ int refreshRate;
+ };
+
+ QWaylandOutput(QWaylandCompositor *compositor, QWindow *window,
+ const QString &manufacturer, const QString &model);
+ ~QWaylandOutput();
+
+ static QWaylandOutput *fromResource(wl_resource *resource);
+
+ virtual void update();
+
+ QWaylandCompositor *compositor() const;
+
+ QString manufacturer() const;
+
+ QString model() const;
+
+ QPoint position() const;
+ void setPosition(const QPoint &pt);
+
+ Mode mode() const;
+ void setMode(const Mode &mode);
+
+ QRect geometry() const;
+ void setGeometry(const QRect &geometry);
+
+ QRect availableGeometry() const;
+ void setAvailableGeometry(const QRect &availableGeometry);
+
+ QSize physicalSize() const;
+ void setPhysicalSize(const QSize &size);
+
+ Subpixel subpixel() const;
+ void setSubpixel(const Subpixel &subpixel);
+
+ Transform transform() const;
+ void setTransform(const Transform &transform);
+
+ int scaleFactor() const;
+ void setScaleFactor(int scale);
+
+ QWindow *window() const;
+
+ QtWayland::Output *handle();
+
+Q_SIGNALS:
+ void positionChanged();
+ void geometryChanged();
+ void modeChanged();
+ void availableGeometryChanged();
+ void physicalSizeChanged();
+ void scaleFactorChanged();
+ void subpixelChanged();
+ void transformChanged();
+
+private:
+ QtWayland::Output *const d_ptr;
+};
+
+Q_DECLARE_METATYPE(QWaylandOutput::Mode)
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDOUTPUT_H
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
index 1333100c..bd053a93 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
@@ -39,14 +39,13 @@
**
****************************************************************************/
-#include <QQuickWindow>
-
#include <QtCompositor/private/qwlcompositor_p.h>
#include "qwaylandclient.h"
#include "qwaylandquickcompositor.h"
#include "qwaylandquicksurface.h"
#include "qwaylandsurfaceitem.h"
+#include "qwaylandquickoutput.h"
QT_BEGIN_NAMESPACE
@@ -78,32 +77,29 @@ public:
};
-QWaylandQuickCompositor::QWaylandQuickCompositor(QQuickWindow *window, const char *socketName, ExtensionFlags extensions)
- : QWaylandCompositor(window, socketName, new QWaylandQuickCompositorPrivate(this, extensions))
+QWaylandQuickCompositor::QWaylandQuickCompositor(const char *socketName, ExtensionFlags extensions)
+ : QWaylandCompositor(socketName, new QWaylandQuickCompositorPrivate(this, extensions))
{
- window->connect(window, &QQuickWindow::beforeSynchronizing, d_ptr(), &QWaylandQuickCompositorPrivate::updateStarted, Qt::DirectConnection);
-
qmlRegisterUncreatableType<QWaylandSurfaceItem>("QtCompositor", 1, 0, "WaylandSurfaceItem", QObject::tr("Cannot create instance of WaylandSurfaceItem"));
qmlRegisterUncreatableType<QWaylandQuickSurface>("QtCompositor", 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface"));
qmlRegisterUncreatableType<QWaylandClient>("QtCompositor", 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient"));
+ qmlRegisterUncreatableType<QWaylandOutput>("QtCompositor", 1, 0, "WaylandOutput", QObject::tr("Cannot create instance of WaylandOutput"));
}
-QWaylandQuickCompositorPrivate *QWaylandQuickCompositor::d_ptr()
-{
- return static_cast<QWaylandQuickCompositorPrivate *>(m_compositor);
-}
-
-void QWaylandQuickCompositor::update()
+QWaylandSurfaceView *QWaylandQuickCompositor::createView(QWaylandSurface *surf)
{
- if (!d_ptr()->updateScheduled) {
- static_cast<QQuickWindow *>(window())->update();
- d_ptr()->updateScheduled = true;
- }
+ return new QWaylandSurfaceItem(static_cast<QWaylandQuickSurface *>(surf));
}
-QWaylandSurfaceView *QWaylandQuickCompositor::createView(QWaylandSurface *surf)
+QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window,
+ const QString &manufacturer,
+ const QString &model)
{
- return new QWaylandSurfaceItem(static_cast<QWaylandQuickSurface *>(surf));
+ QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window);
+ if (!quickWindow)
+ qFatal("%s: couldn't cast QWindow to QQuickWindow. All output windows must "
+ "be QQuickWindow derivates when using QWaylandQuickCompositor", Q_FUNC_INFO);
+ return new QWaylandQuickOutput(this, quickWindow, manufacturer, model);
}
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h
index 0e252ba0..9d9a54e5 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.h
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.h
@@ -49,19 +49,17 @@ QT_BEGIN_NAMESPACE
class QQuickWindow;
class QWaylandQuickCompositorPrivate;
class QWaylandSurfaceView;
+class QWaylandOutput;
class Q_COMPOSITOR_EXPORT QWaylandQuickCompositor : public QWaylandCompositor
{
public:
- QWaylandQuickCompositor(QQuickWindow *window = 0, const char *socketName = 0, QWaylandCompositor::ExtensionFlags extensions = DefaultExtensions);
-
- void update();
+ QWaylandQuickCompositor(const char *socketName = 0, QWaylandCompositor::ExtensionFlags extensions = DefaultExtensions);
QWaylandSurfaceView *createView(QWaylandSurface *surf) Q_DECL_OVERRIDE;
-
-private:
- friend class QWaylandQuickCompositorPrivate;
- QWaylandQuickCompositorPrivate *d_ptr();
+ QWaylandOutput *createOutput(QWindow *window,
+ const QString &manufacturer,
+ const QString &model) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp
new file mode 100644
index 00000000..6dfe1e04
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandquickoutput.h"
+#include "qwaylandquickcompositor.h"
+
+QT_BEGIN_NAMESPACE
+
+QWaylandQuickOutput::QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window,
+ const QString &manufacturer, const QString &model)
+ : QWaylandOutput(compositor, window, manufacturer, model)
+ , m_updateScheduled(false)
+{
+ connect(window, &QQuickWindow::beforeSynchronizing,
+ this, &QWaylandQuickOutput::updateStarted,
+ Qt::DirectConnection);
+}
+
+QQuickWindow *QWaylandQuickOutput::quickWindow() const
+{
+ return static_cast<QQuickWindow *>(window());
+}
+
+void QWaylandQuickOutput::update()
+{
+ if (!m_updateScheduled) {
+ quickWindow()->update();
+ m_updateScheduled = true;
+ }
+}
+
+void QWaylandQuickOutput::updateStarted()
+{
+ m_updateScheduled = false;
+ frameStarted();
+ compositor()->cleanupGraphicsResources();
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h
new file mode 100644
index 00000000..141f6e13
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandquickoutput.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDQUICKOUTPUT_H
+#define QWAYLANDQUICKOUTPUT_H
+
+#include <QtQuick/QQuickWindow>
+#include <QtCompositor/qwaylandoutput.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandQuickCompositor;
+class QQuickWindow;
+
+class Q_COMPOSITOR_EXPORT QWaylandQuickOutput : public QWaylandOutput
+{
+ Q_OBJECT
+public:
+ QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window,
+ const QString &manufacturer, const QString &model);
+
+ QQuickWindow *quickWindow() const;
+
+ void update() Q_DECL_OVERRIDE;
+
+public Q_SLOTS:
+ void updateStarted();
+
+private:
+ bool m_updateScheduled;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp
index 40cd8b74..83b37da5 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.cpp
+++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp
@@ -48,6 +48,7 @@
#include "qwaylandquicksurface.h"
#include "qwaylandquickcompositor.h"
#include "qwaylandsurfaceitem.h"
+#include "qwaylandoutput.h"
#include <QtCompositor/qwaylandbufferref.h>
#include <QtCompositor/private/qwaylandsurface_p.h>
@@ -84,7 +85,7 @@ public:
bufferRef.destroyTexture();
bufferRef = nextBuffer;
- QQuickWindow *window = static_cast<QQuickWindow *>(surface->compositor()->window());
+ QQuickWindow *window = static_cast<QQuickWindow *>(surface->output()->window());
// If the next buffer is NULL do not delete the current texture. If the client called
// attach(0) the surface is going to be unmapped anyway, if instead the client attached
// a valid buffer but died before we got here we want to keep the old buffer around
@@ -149,7 +150,7 @@ public:
}
QWaylandSurfacePrivate::surface_commit(resource);
- compositor->update();
+ output()->waylandOutput()->update();
}
BufferAttacher *buffer;
@@ -166,7 +167,7 @@ QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, int ve
d->buffer->surface = this;
setBufferAttacher(d->buffer);
- QQuickWindow *window = static_cast<QQuickWindow *>(compositor->window());
+ QQuickWindow *window = static_cast<QQuickWindow *>(output()->window());
connect(window, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickSurface::updateTexture, Qt::DirectConnection);
connect(window, &QQuickWindow::sceneGraphInvalidated, this, &QWaylandQuickSurface::invalidateTexture, Qt::DirectConnection);
connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert);
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index 8dacc8ec..b504d2f4 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -239,6 +239,14 @@ QWaylandCompositor *QWaylandSurface::compositor() const
return d->compositor()->waylandCompositor();
}
+QWaylandOutput *QWaylandSurface::output() const
+{
+ Q_D(const QWaylandSurface);
+ if (!d->output())
+ return Q_NULLPTR;
+ return d->output()->waylandOutput();
+}
+
QWindow::Visibility QWaylandSurface::visibility() const
{
Q_D(const QWaylandSurface);
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 4b802d77..1294d4f9 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -62,6 +62,7 @@ class QWaylandBufferRef;
class QWaylandSurfaceView;
class QWaylandSurfaceInterface;
class QWaylandSurfaceOp;
+class QWaylandOutput;
namespace QtWayland {
class Surface;
@@ -162,6 +163,8 @@ public:
QWaylandCompositor *compositor() const;
+ QWaylandOutput *output() const;
+
QString className() const;
QString title() const;
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index 6eee0770..aa772d93 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -63,6 +63,7 @@
#include "qwaylandglobalinterface.h"
#include "qwaylandsurfaceview.h"
#include "qwaylandshmformathelper.h"
+#include "qwaylandoutput.h"
#include <QWindow>
#include <QSocketNotifier>
@@ -150,8 +151,6 @@ void Compositor::init()
foreach (wl_shm_format format, formats)
wl_display_add_shm_format(m_display->handle(), format);
- m_output_global = new OutputGlobal(m_display->handle());
-
if (wl_display_add_socket(m_display->handle(), m_qt_compositor->socketName())) {
fprintf(stderr, "Fatal: Failed to open server socket\n");
exit(EXIT_FAILURE);
@@ -184,6 +183,7 @@ Compositor::~Compositor()
qWarning("QWaylandCompositor::cleanupGraphicsResources() must be called manually");
qDeleteAll(m_clients);
+ qDeleteAll(m_outputs);
delete m_outputExtension;
delete m_surfaceExtension;
@@ -195,7 +195,6 @@ Compositor::~Compositor()
delete m_default_wayland_input_device;
delete m_data_device_manager;
- delete m_output_global;
delete m_display;
}
@@ -212,6 +211,57 @@ uint Compositor::currentTimeMsecs() const
return m_timer.elapsed();
}
+QList<QWaylandOutput *> Compositor::outputs() const
+{
+ return m_outputs;
+}
+
+QWaylandOutput *Compositor::output(QWindow *window) const
+{
+ Q_FOREACH (QWaylandOutput *output, m_outputs) {
+ if (output->window() == window)
+ return output;
+ }
+
+ return Q_NULLPTR;
+}
+
+void Compositor::addOutput(QWaylandOutput *output)
+{
+ Q_ASSERT(output->handle());
+
+ if (m_outputs.contains(output))
+ return;
+
+ m_outputs.append(output);
+}
+
+void Compositor::removeOutput(QWaylandOutput *output)
+{
+ Q_ASSERT(output->handle());
+
+ m_outputs.removeOne(output);
+}
+
+QWaylandOutput *Compositor::primaryOutput() const
+{
+ if (m_outputs.size() == 0)
+ return Q_NULLPTR;
+ return m_outputs.at(0);
+}
+
+void Compositor::setPrimaryOutput(QWaylandOutput *output)
+{
+ Q_ASSERT(output->handle());
+
+ int i = m_outputs.indexOf(output);
+ if (i <= 0)
+ return;
+
+ m_outputs.removeAt(i);
+ m_outputs.prepend(output);
+}
+
void Compositor::processWaylandEvents()
{
int ret = wl_event_loop_dispatch(m_loop, 0);
@@ -271,11 +321,6 @@ void Compositor::destroyClient(QWaylandClient *client)
wl_client_destroy(client->client());
}
-QWindow *Compositor::window() const
-{
- return m_qt_compositor->window();
-}
-
ClientBufferIntegration * Compositor::clientBufferIntegration() const
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
@@ -299,11 +344,9 @@ void Compositor::initializeHardwareIntegration()
#ifdef QT_COMPOSITOR_WAYLAND_GL
if (m_extensions & QWaylandCompositor::HardwareIntegrationExtension)
m_hw_integration.reset(new HardwareIntegration(this));
- QWindow *window = m_qt_compositor->window();
- if (window && window->surfaceType() != QWindow::RasterSurface) {
- loadClientBufferIntegration();
- loadServerBufferIntegration();
- }
+
+ loadClientBufferIntegration();
+ loadServerBufferIntegration();
if (m_client_buffer_integration)
m_client_buffer_integration->initializeHardware(m_display);
@@ -345,43 +388,6 @@ QList<QWaylandClient *> Compositor::clients() const
return m_clients;
}
-void Compositor::setScreenOrientation(Qt::ScreenOrientation orientation)
-{
- m_orientation = orientation;
- m_output_global->sendOutputOrientation(orientation);
-}
-
-Qt::ScreenOrientation Compositor::screenOrientation() const
-{
- return m_orientation;
-}
-
-void Compositor::setOutputGeometry(const QRect &geometry)
-{
- if (m_output_global)
- m_output_global->setGeometry(geometry);
-}
-
-QRect Compositor::outputGeometry() const
-{
- if (m_output_global)
- return m_output_global->geometry();
- return QRect();
-}
-
-void Compositor::setOutputRefreshRate(int rate)
-{
- if (m_output_global)
- m_output_global->setRefreshRate(rate);
-}
-
-int Compositor::outputRefreshRate() const
-{
- if (m_output_global)
- return m_output_global->refreshRate();
- return 0;
-}
-
void Compositor::setClientFullScreenHint(bool value)
{
if (m_windowManagerIntegration)
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index 9c3a0f9d..85f020d4 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -49,7 +49,6 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QSet>
-#include <QtGui/QWindow>
#include <private/qwldisplay_p.h>
@@ -111,7 +110,14 @@ public:
uint currentTimeMsecs() const;
- QWindow *window() const;
+ QList<QWaylandOutput *> outputs() const;
+ QWaylandOutput *output(QWindow *window) const;
+
+ void addOutput(QWaylandOutput *output);
+ void removeOutput(QWaylandOutput *output);
+
+ QWaylandOutput *primaryOutput() const;
+ void setPrimaryOutput(QWaylandOutput *output);
ClientBufferIntegration *clientBufferIntegration() const;
ServerBufferIntegration *serverBufferIntegration() const;
@@ -133,13 +139,6 @@ public:
WindowManagerServerIntegration *windowManagerIntegration() const { return m_windowManagerIntegration; }
- void setScreenOrientation(Qt::ScreenOrientation orientation);
- Qt::ScreenOrientation screenOrientation() const;
- void setOutputGeometry(const QRect &geometry);
- QRect outputGeometry() const;
- void setOutputRefreshRate(int rate);
- int outputRefreshRate() const;
-
void setClientFullScreenHint(bool value);
QWaylandCompositor::ExtensionFlags extensions() const;
@@ -189,8 +188,7 @@ protected:
QList<QWaylandInputDevice *> m_inputDevices;
/* Output */
- //make this a list of the available screens
- OutputGlobal *m_output_global;
+ QList<QWaylandOutput *> m_outputs;
DataDeviceManager *m_data_device_manager;
diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
index 8bf69ff4..edb4f553 100644
--- a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
+++ b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
@@ -56,10 +56,10 @@ OutputExtensionGlobal::OutputExtensionGlobal(Compositor *compositor)
void OutputExtensionGlobal::output_extension_get_extended_output(qt_output_extension::Resource *resource, uint32_t id, wl_resource *output_resource)
{
- Output *output = static_cast<Output *>(OutputGlobal::Resource::fromResource(output_resource));
+ OutputResource *output = static_cast<OutputResource *>(Output::Resource::fromResource(output_resource));
Q_ASSERT(output->extendedOutput == 0);
- ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id, resource->version()));
+ ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id));
Q_ASSERT(!output->extendedOutput);
output->extendedOutput = extendedOutput;
diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h
index 5f620cd8..f0772e11 100644
--- a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h
+++ b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h
@@ -54,14 +54,14 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
class Compositor;
-class Output;
+class OutputResource;
class ExtendedOutput : public QtWaylandServer::qt_extended_output::Resource
{
public:
ExtendedOutput() : output(0) {}
- Output *output;
+ OutputResource *output;
};
class OutputExtensionGlobal : public QtWaylandServer::qt_output_extension, public QtWaylandServer::qt_extended_output
diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
index 138e5703..f92d2bf3 100644
--- a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
@@ -77,10 +78,11 @@ void InputPanelSurface::input_panel_surface_set_overlay_panel(Resource *)
m_type = OverlayPanel;
}
-void InputPanelSurface::input_panel_surface_set_toplevel(Resource *, wl_resource *output, uint32_t position)
+void InputPanelSurface::input_panel_surface_set_toplevel(Resource *, wl_resource *output_resource, uint32_t position)
{
m_type = Toplevel;
- m_output = static_cast<Output *>(Output::Resource::fromResource(output));
+ OutputResource *output = static_cast<OutputResource *>(Output::Resource::fromResource(output_resource));
+ m_output = static_cast<Output *>(output->output_object);
m_position = static_cast<wl_input_panel_surface::position>(position);
}
diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h b/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h
index 89c85895..88bd5f63 100644
--- a/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
@@ -68,7 +69,7 @@ public:
protected:
void input_panel_surface_set_overlay_panel(Resource *resource) Q_DECL_OVERRIDE;
- void input_panel_surface_set_toplevel(Resource *resource, wl_resource *output, uint32_t position) Q_DECL_OVERRIDE;
+ void input_panel_surface_set_toplevel(Resource *resource, wl_resource *output_resource, uint32_t position) Q_DECL_OVERRIDE;
private:
Surface *m_surface;
diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp
index 7638370b..1659a63c 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
diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h
index 9d90550e..027cc55b 100644
--- a/src/compositor/wayland_wrapper/qwloutput_p.h
+++ b/src/compositor/wayland_wrapper/qwloutput_p.h
@@ -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
**
@@ -41,74 +42,95 @@
#ifndef WL_OUTPUT_H
#define WL_OUTPUT_H
+#include <QtCompositor/qwaylandexport.h>
+
#include <QtCore/QRect>
#include <QtCore/QList>
#include <QtCompositor/private/qwayland-server-wayland.h>
+#include <QtCompositor/qwaylandoutput.h>
QT_BEGIN_NAMESPACE
+class QWindow;
+
namespace QtWayland {
+class Compositor;
class ExtendedOutput;
-struct Output : public QtWaylandServer::wl_output::Resource
+struct OutputResource : public QtWaylandServer::wl_output::Resource
{
- Output() : extendedOutput(0) {}
+ OutputResource() : extendedOutput(0) {}
ExtendedOutput *extendedOutput;
};
-class OutputGlobal : public QtWaylandServer::wl_output
+class Output : public QtWaylandServer::wl_output
{
public:
- OutputGlobal(struct ::wl_display *display);
- ~OutputGlobal();
+ explicit Output(Compositor *compositor, QWindow *window = 0);
+
+ Compositor *compositor() const { return m_compositor; }
+
+ QWaylandOutput *output() const { return m_output; }
+
+ QString manufacturer() const { return m_manufacturer; }
+ void setManufacturer(const QString &manufacturer);
+ QString model() const { return m_model; }
+ void setModel(const QString &model);
+
+ QPoint position() const { return m_position; }
+ void setPosition(const QPoint &position);
+
+ QRect geometry() const;
void setGeometry(const QRect &geometry);
- QRect geometry() const { return m_geometry; }
- int x() const { return m_geometry.x(); }
- int y() const { return m_geometry.y(); }
- QSize size() const { return m_geometry.size(); }
+ QWaylandOutput::Mode mode() const { return m_mode; }
+ void setMode(const QWaylandOutput::Mode &mode);
- void setPhysicalSize(const QSize &size);
- void setRefreshRate(int rate);
- int refreshRate() const { return m_refreshRate; }
- void sendOutputOrientation(Qt::ScreenOrientation orientation);
+ QRect availableGeometry() const { return m_availableGeometry; }
+ void setAvailableGeometry(const QRect &availableGeometry);
- Output *outputForClient(struct wl_client *client) const;
+ QSize physicalSize() const { return m_physicalSize; }
+ void setPhysicalSize(const QSize &physicalSize);
- void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
- Resource *output_allocate() Q_DECL_OVERRIDE { return new Output; }
+ QWaylandOutput::Subpixel subpixel() const { return m_subpixel; }
+ void setSubpixel(const QWaylandOutput::Subpixel &subpixel);
-private:
- QRect m_geometry;
- QSize m_physicalSize;
- int m_refreshRate;
- int m_displayId;
- int m_numQueued;
- wl_output_transform m_transform;
-};
+ QWaylandOutput::Transform transform() const { return m_transform; }
+ void setTransform(const QWaylandOutput::Transform &transform);
-#if 0
-class Output
-{
-public:
- Output(OutputGlobal *outputGlobal, struct ::wl_resource *resource);
- ~Output();
+ int scaleFactor() const { return m_scaleFactor; }
+ void setScaleFactor(int scale);
+
+ QWindow *window() const { return m_window; }
- OutputGlobal *outputGlobal() const;
+ OutputResource *outputForClient(struct wl_client *client) const;
- ExtendedOutput *extendedOutput() const;
- void setExtendedOutput(ExtendedOutput *extendedOutput);
+ QWaylandOutput *waylandOutput() const { return m_output; }
+
+ void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
+ Resource *output_allocate() Q_DECL_OVERRIDE { return new OutputResource; }
- struct wl_resource *handle() const;
private:
- struct wl_resource *m_output_resource;
- OutputGlobal *m_output_global;
- ExtendedOutput *m_extended_output;
+ friend class QT_PREPEND_NAMESPACE(QWaylandOutput);
+
+ Compositor *m_compositor;
+ QWindow *m_window;
+ QWaylandOutput *m_output;
+ QString m_manufacturer;
+ QString m_model;
+ QPoint m_position;
+ QWaylandOutput::Mode m_mode;
+ QRect m_availableGeometry;
+ QSize m_physicalSize;
+ QWaylandOutput::Subpixel m_subpixel;
+ QWaylandOutput::Transform m_transform;
+ int m_scaleFactor;
+
+ void sendGeometryInfo();
};
-#endif
}
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
index 80304f3c..ed8e148c 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlshellsurface.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
**
@@ -42,11 +43,13 @@
#include "qwlcompositor_p.h"
#include "qwlsurface_p.h"
+#include "qwloutput_p.h"
#include "qwlinputdevice_p.h"
#include "qwlsubsurface_p.h"
#include "qwlpointer_p.h"
#include "qwlextendedsurface_p.h"
+#include "qwaylandoutput.h"
#include "qwaylandsurfaceview.h"
#include <QtCore/qglobal.h>
@@ -278,14 +281,33 @@ void ShellSurface::shell_surface_set_transient(Resource *resource,
void ShellSurface::shell_surface_set_fullscreen(Resource *resource,
uint32_t method,
uint32_t framerate,
- struct wl_resource *output)
+ struct wl_resource *output_resource)
{
Q_UNUSED(resource);
Q_UNUSED(method);
Q_UNUSED(framerate);
- Q_UNUSED(output);
- QSize defaultScreenSize = m_surface->compositor()->outputGeometry().size();
- send_configure(resize_bottom_right, defaultScreenSize.width(), defaultScreenSize.height());
+
+ QWaylandOutput *output = output_resource
+ ? QWaylandOutput::fromResource(output_resource)
+ : Q_NULLPTR;
+ if (!output) {
+ // Look for an output that can contain this surface
+ Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) {
+ if (curOutput->geometry().size().width() >= m_surface->size().width() &&
+ curOutput->geometry().size().height() >= m_surface->size().height()) {
+ output = curOutput;
+ break;
+ }
+ }
+ }
+ if (!output) {
+ qWarning() << "Unable to resize surface full screen, cannot determine output";
+ return;
+ }
+ QSize outputSize = output->geometry().size();
+
+ m_view->setPos(output->geometry().topLeft());
+ send_configure(resize_bottom_right, outputSize.width(), outputSize.height());
if (m_surface->extendedSurface())
m_surface->extendedSurface()->setVisibility(QWindow::FullScreen, false);
@@ -311,12 +333,31 @@ void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *inpu
}
void ShellSurface::shell_surface_set_maximized(Resource *resource,
- struct wl_resource *output)
+ struct wl_resource *output_resource)
{
Q_UNUSED(resource);
- Q_UNUSED(output);
- QSize defaultScreenSize = m_surface->compositor()->outputGeometry().size();
- send_configure(resize_bottom_right, defaultScreenSize.width(), defaultScreenSize.height());
+
+ QWaylandOutput *output = output_resource
+ ? QWaylandOutput::fromResource(output_resource)
+ : Q_NULLPTR;
+ if (!output) {
+ // Look for an output that can contain this surface
+ Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) {
+ if (curOutput->geometry().size().width() >= m_surface->size().width() &&
+ curOutput->geometry().size().height() >= m_surface->size().height()) {
+ output = curOutput;
+ break;
+ }
+ }
+ }
+ if (!output) {
+ qWarning() << "Unable to maximize surface, cannot determine output";
+ return;
+ }
+ QSize outputSize = output->availableGeometry().size();
+
+ m_view->setPos(output->availableGeometry().topLeft());
+ send_configure(resize_bottom_right, outputSize.width(), outputSize.height());
if (m_surface->extendedSurface())
m_surface->extendedSurface()->setVisibility(QWindow::Maximized, false);
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h
index 92405bbc..5d0b29db 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlshellsurface_p.h
@@ -139,7 +139,7 @@ private:
void shell_surface_set_fullscreen(Resource *resource,
uint32_t method,
uint32_t framerate,
- struct wl_resource *output) Q_DECL_OVERRIDE;
+ struct wl_resource *output_resource) Q_DECL_OVERRIDE;
void shell_surface_set_popup(Resource *resource,
struct wl_resource *input_device,
uint32_t time,
@@ -148,7 +148,7 @@ private:
int32_t y,
uint32_t flags) Q_DECL_OVERRIDE;
void shell_surface_set_maximized(Resource *resource,
- struct wl_resource *output) Q_DECL_OVERRIDE;
+ struct wl_resource *output_resource) Q_DECL_OVERRIDE;
void shell_surface_pong(Resource *resource,
uint32_t serial) Q_DECL_OVERRIDE;
void shell_surface_set_title(Resource *resource,
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index ee819701..a24aa7e3 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -48,6 +48,7 @@
#include "qwlsubsurface_p.h"
#include "qwlsurfacebuffer_p.h"
#include "qwaylandsurfaceview.h"
+#include "qwaylandoutput.h"
#include <QtCore/QDebug>
#include <QTouchEvent>
@@ -113,6 +114,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCom
: QtWaylandServer::wl_surface(client, id, version)
, m_compositor(compositor->handle())
, m_waylandSurface(surface)
+ , m_output(m_compositor->primaryOutput()->handle())
, m_buffer(0)
, m_surfaceMapped(false)
, m_attacher(0)
@@ -276,6 +278,11 @@ Compositor *Surface::compositor() const
return m_compositor;
}
+Output *Surface::output() const
+{
+ return m_output;
+}
+
/*!
* Sets the backbuffer for this surface. The back buffer is not yet on
* screen and will become live during the next swapBuffers().
diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h
index bbab57a4..07eb358f 100644
--- a/src/compositor/wayland_wrapper/qwlsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurface_p.h
@@ -44,6 +44,7 @@
#include <QtCompositor/qwaylandexport.h>
#include <private/qwlsurfacebuffer_p.h>
+#include <private/qwloutput_p.h>
#include <QtCompositor/qwaylandsurface.h>
#include <QtCompositor/qwaylandbufferref.h>
@@ -112,6 +113,8 @@ public:
Compositor *compositor() const;
+ Output *output() const;
+
QString className() const { return m_className; }
void setClassName(const QString &className);
@@ -159,6 +162,7 @@ protected:
Compositor *m_compositor;
QWaylandSurface *m_waylandSurface;
+ Output *m_output;
QRegion m_damage;
SurfaceBuffer *m_buffer;
diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
index 4e9a0449..e4f0a3b8 100644
--- a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
@@ -127,10 +127,9 @@ DrmEglServerBufferIntegration::~DrmEglServerBufferIntegration()
void DrmEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor)
{
- QWindow *window = compositor->window();
Q_ASSERT(QGuiApplication::platformNativeInterface());
- m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("egldisplay", window));
+ m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
if (!m_egl_display) {
qWarning("Cant initialize drm egl server buffer integration. Missing egl display from platformplugin");
return;
diff --git a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
index 7e7a14ab..9882083c 100644
--- a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
@@ -131,10 +131,9 @@ LibHybrisEglServerBufferIntegration::~LibHybrisEglServerBufferIntegration()
void LibHybrisEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor)
{
- QWindow *window = compositor->window();
Q_ASSERT(QGuiApplication::platformNativeInterface());
- m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("egldisplay", window));
+ m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
if (!m_egl_display) {
qWarning("Cant initialize libhybris egl server buffer integration. Missing egl display from platformplugin");
return;
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
index 3f7487c4..c1634a23 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
@@ -119,7 +119,7 @@ void WaylandEglClientBufferIntegration::initializeHardware(QtWayland::Display *w
return;
}
- d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window());
+ d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay");
if (!d->egl_display) {
qWarning("QtCompositor: Failed to initialize EGL display. Could not get EglDisplay for window.");
return;
diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
index 2401d671..60b17283 100644
--- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
+++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
@@ -78,10 +78,10 @@ void XCompositeEglClientBufferIntegration::initializeHardware(QtWayland::Display
{
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
if (nativeInterface) {
- mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window()));
+ mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForIntegration("Display"));
if (!mDisplay)
qFatal("could not retireve Display from platform integration");
- mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWindow("EGLDisplay",m_compositor->window()));
+ mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForIntegration("EGLDisplay"));
if (!mEglDisplay)
qFatal("could not retrieve EGLDisplay from platform integration");
} else {
diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
index bd5ddef9..d02840e2 100644
--- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
+++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
@@ -89,7 +89,7 @@ void XCompositeGLXClientBufferIntegration::initializeHardware(QtWayland::Display
qDebug() << "Initializing GLX integration";
QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface();
if (nativeInterface) {
- mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window()));
+ mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForIntegration("Display"));
if (!mDisplay)
qFatal("could not retireve Display from platform integration");
} else {
diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
index 5e002377..13f2e65c 100644
--- a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
+++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
@@ -50,9 +50,7 @@ QT_BEGIN_NAMESPACE
XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display)
: QtWaylandServer::qt_xcomposite(compositor->wl_display(), 1)
{
- compositor->window()->create();
-
- mFakeRootWindow = new QWindow(compositor->window());
+ mFakeRootWindow = new QWindow();
mFakeRootWindow->setGeometry(QRect(-1,-1,1,1));
mFakeRootWindow->create();
mFakeRootWindow->show();