summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/client.pro2
-rw-r--r--src/client/qwaylandcursor.cpp2
-rw-r--r--src/client/qwaylanddisplay.cpp2
-rw-r--r--src/client/qwaylanddisplay_p.h5
-rw-r--r--src/client/qwaylandintegration.cpp15
-rw-r--r--src/client/qwaylandnativeinterface.cpp41
-rw-r--r--src/client/qwaylandnativeinterface_p.h6
-rw-r--r--src/client/qwaylandshm.cpp80
-rw-r--r--src/client/qwaylandshm_p.h76
-rw-r--r--src/client/qwaylandshmbackingstore.cpp49
-rw-r--r--src/client/qwaylandsubsurface.cpp27
-rw-r--r--src/client/qwaylandsubsurface_p.h14
12 files changed, 297 insertions, 22 deletions
diff --git a/src/client/client.pro b/src/client/client.pro
index 182a5d551..6802cd47b 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -80,6 +80,7 @@ SOURCES += qwaylandintegration.cpp \
qwaylandwindowmanagerintegration.cpp \
qwaylandinputcontext.cpp \
qwaylanddatadevice.cpp \
+ qwaylandshm.cpp \
HEADERS += qwaylandintegration_p.h \
qwaylandnativeinterface_p.h \
@@ -112,6 +113,7 @@ HEADERS += qwaylandintegration_p.h \
qwaylandwindowmanagerintegration_p.h \
qwaylandinputcontext_p.h \
qwaylanddatadevice_p.h \
+ qwaylandshm_p.h \
include(hardwareintegration/hardwareintegration.pri)
include(shellintegration/shellintegration.pri)
diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp
index 8dfc95c36..a76e05a9a 100644
--- a/src/client/qwaylandcursor.cpp
+++ b/src/client/qwaylandcursor.cpp
@@ -59,7 +59,7 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
int cursorSize = cursorSizeFromEnv.toInt(&hasCursorSize);
if (!hasCursorSize || cursorSize <= 0)
cursorSize = 32;
- mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm());
+ mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm()->object());
if (!mCursorTheme)
qDebug() << "Could not load theme" << cursorTheme;
initCursorMap();
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index a6f52bc24..82c1f201e 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -256,7 +256,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mCompositorVersion = qMin((int)version, 3);
mCompositor.init(registry, id, mCompositorVersion);
} else if (interface == QStringLiteral("wl_shm")) {
- mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1));
+ mShm.reset(new QWaylandShm(this, version, id));
} else if (interface == QStringLiteral("xdg_shell")
&& qEnvironmentVariableIsSet("QT_WAYLAND_USE_XDG_SHELL")) {
mShellXdg.reset(new QWaylandXdgShell(registry,id));
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index d5ee16fc9..65e914395 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -56,6 +56,7 @@
#include <QtWaylandClient/private/qwayland-wayland.h>
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
#include <QtWaylandClient/private/qwayland-xdg-shell.h>
+#include <QtWaylandClient/private/qwaylandshm_p.h>
struct wl_cursor_image;
@@ -156,7 +157,7 @@ public:
* to enable many listeners at once. */
void addRegistryListener(RegistryListener listener, void *data);
- struct wl_shm *shm() const { return mShm; }
+ QWaylandShm *shm() const { return mShm.data(); }
static uint32_t currentTimeMillisec();
@@ -185,7 +186,7 @@ private:
struct wl_display *mDisplay;
QtWayland::wl_compositor mCompositor;
- struct wl_shm *mShm;
+ QScopedPointer<QWaylandShm> mShm;
QScopedPointer<QtWayland::wl_shell> mShell;
QScopedPointer<QWaylandXdgShell> mShellXdg;
QList<QWaylandScreen *> mScreens;
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index 39fff533d..c04ddb610 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -130,8 +130,19 @@ QWaylandIntegration::QWaylandIntegration()
mDrag = new QWaylandDrag(mDisplay);
QString icStr = QPlatformInputContextFactory::requested();
- icStr.isNull() ? mInputContext.reset(new QWaylandInputContext(mDisplay))
- : mInputContext.reset(QPlatformInputContextFactory::create(icStr));
+ if (!icStr.isNull()) {
+ mInputContext.reset(QPlatformInputContextFactory::create(icStr));
+ } else {
+ //try to use the input context using the wl_text_input interface
+ QPlatformInputContext *ctx = new QWaylandInputContext(mDisplay);
+ mInputContext.reset(ctx);
+
+ //use the traditional way for on screen keyboards for now
+ if (!mInputContext.data()->isValid()) {
+ ctx = QPlatformInputContextFactory::create();
+ mInputContext.reset(ctx);
+ }
+ }
}
QWaylandIntegration::~QWaylandIntegration()
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
index 98e1a7366..7df31bbc5 100644
--- a/src/client/qwaylandnativeinterface.cpp
+++ b/src/client/qwaylandnativeinterface.cpp
@@ -34,6 +34,7 @@
#include "qwaylandnativeinterface_p.h"
#include "qwaylanddisplay_p.h"
#include "qwaylandwindow_p.h"
+#include "qwaylandsubsurface_p.h"
#include "qwaylandextendedsurface_p.h"
#include "qwaylandintegration_p.h"
#include "qwaylanddisplay_p.h"
@@ -44,6 +45,8 @@
#include <QtGui/QScreen>
#include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h>
+#include <QtPlatformHeaders/qwaylandwindowfunctions.h>
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
@@ -151,6 +154,44 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window,
emit windowPropertyChanged(window,name);
}
+QFunctionPointer QWaylandNativeInterface::platformFunction(const QByteArray &resource) const
+{
+ if (resource == QWaylandWindowFunctions::setSyncIdentifier()) {
+ return QFunctionPointer(setSync);
+ } else if (resource == QWaylandWindowFunctions::setDeSyncIdentifier()) {
+ return QFunctionPointer(setDeSync);
+ } else if (resource == QWaylandWindowFunctions::isSyncIdentifier()) {
+ return QFunctionPointer(isSync);
+ }
+ return 0;
+}
+
+
+void QWaylandNativeInterface::setSync(QWindow *window)
+{
+ QWaylandWindow *ww = static_cast<QWaylandWindow*>(window->handle());
+ if (ww->subSurfaceWindow()) {
+ ww->subSurfaceWindow()->setSync();
+ }
+}
+
+void QWaylandNativeInterface::setDeSync(QWindow *window)
+{
+ QWaylandWindow *ww = static_cast<QWaylandWindow*>(window->handle());
+ if (ww->subSurfaceWindow()) {
+ ww->subSurfaceWindow()->setDeSync();
+ }
+}
+
+bool QWaylandNativeInterface::isSync(QWindow *window)
+{
+ QWaylandWindow *ww = static_cast<QWaylandWindow*>(window->handle());
+ if (ww->subSurfaceWindow()) {
+ return ww->subSurfaceWindow()->isSync();
+ }
+ return false;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/client/qwaylandnativeinterface_p.h b/src/client/qwaylandnativeinterface_p.h
index 7050f9758..9ea62a90c 100644
--- a/src/client/qwaylandnativeinterface_p.h
+++ b/src/client/qwaylandnativeinterface_p.h
@@ -75,9 +75,15 @@ public:
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name);
+ QFunctionPointer platformFunction(const QByteArray &resource) const Q_DECL_OVERRIDE;
+
private:
QWaylandIntegration *m_integration;
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
+
+ static void setSync(QWindow *window);
+ static void setDeSync(QWindow *window);
+ static bool isSync(QWindow *window);
};
}
diff --git a/src/client/qwaylandshm.cpp b/src/client/qwaylandshm.cpp
new file mode 100644
index 000000000..1d7981477
--- /dev/null
+++ b/src/client/qwaylandshm.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 LG Electronics Inc, author: <mikko.levonmaa@lge.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtWaylandClient/private/qwaylandshm_p.h>
+#include <QtWaylandClient/private/qwaylanddisplay_p.h>
+
+#include "qwaylandshmformathelper.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+QWaylandShm::QWaylandShm(QWaylandDisplay *display, int version, uint32_t id)
+ : QtWayland::wl_shm(display->wl_registry(), id, qMin(version, 1))
+{
+}
+
+QWaylandShm::~QWaylandShm()
+{
+
+}
+
+void QWaylandShm::shm_format(uint32_t format)
+{
+ m_formats << format;
+}
+
+bool QWaylandShm::formatSupported(wl_shm_format format) const
+{
+ return m_formats.contains(format);
+}
+
+bool QWaylandShm::formatSupported(QImage::Format format) const
+{
+ wl_shm_format fmt = formatFrom(format);
+ return formatSupported(fmt);
+}
+
+wl_shm_format QWaylandShm::formatFrom(QImage::Format format)
+{
+ return QWaylandShmFormatHelper::fromQImageFormat(format);
+}
+
+QImage::Format QWaylandShm::formatFrom(wl_shm_format format)
+{
+ return QWaylandShmFormatHelper::fromWaylandShmFormat(format);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/qwaylandshm_p.h b/src/client/qwaylandshm_p.h
new file mode 100644
index 000000000..10feae6a7
--- /dev/null
+++ b/src/client/qwaylandshm_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 LG Electronics Inc, author: <mikko.levonmaa@lge.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDSHM_H
+#define QWAYLANDSHM_H
+
+#include <QVector>
+#include <QImage>
+
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+#include <QtWaylandClient/private/qwayland-wayland.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+class QWaylandDisplay;
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandShm : public QtWayland::wl_shm
+{
+
+public:
+
+ QWaylandShm(QWaylandDisplay *display, int version, uint32_t id);
+ ~QWaylandShm();
+
+ bool formatSupported(wl_shm_format format) const;
+ bool formatSupported(QImage::Format format) const;
+
+ static wl_shm_format formatFrom(QImage::Format format);
+ static QImage::Format formatFrom(wl_shm_format format);
+
+protected:
+ virtual void shm_format(uint32_t format);
+
+private:
+ QVector<uint32_t> m_formats;
+
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
index f009e0811..87205d4cd 100644
--- a/src/client/qwaylandshmbackingstore.cpp
+++ b/src/client/qwaylandshmbackingstore.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include "qwaylandshmbackingstore_p.h"
#include "qwaylandwindow_p.h"
+#include "qwaylandsubsurface_p.h"
#include "qwaylanddisplay_p.h"
#include "qwaylandscreen_p.h"
#include "qwaylandabstractdecoration_p.h"
@@ -42,7 +43,6 @@
#include <wayland-client.h>
#include <wayland-client-protocol.h>
-#include "qwaylandshmformathelper.h"
#include <unistd.h>
#include <fcntl.h>
@@ -85,11 +85,12 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
return;
}
- wl_shm_format wl_format = QWaylandShmFormatHelper::fromQImageFormat(format);
+ QWaylandShm* shm = display->shm();
+ wl_shm_format wl_format = shm->formatFrom(format);
mImage = QImage(data, size.width(), size.height(), stride, format);
mImage.setDevicePixelRatio(qreal(scale));
- mShmPool = wl_shm_create_pool(display->shm(), fd, alloc);
+ mShmPool = wl_shm_create_pool(shm->object(), fd, alloc);
mBuffer = wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(),
stride, wl_format);
close(fd);
@@ -174,8 +175,13 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &)
ensureSize();
QWaylandWindow *window = waylandWindow();
- if (window->attached() && mBackBuffer == window->attached() && mFrameCallback)
+ QWaylandSubSurface *sub = window->subSurfaceWindow();
+
+ bool waiting = window->attached() && mBackBuffer == window->attached() && mFrameCallback;
+ bool syncSubSurface = sub && sub->isSync();
+ if (waiting && !syncSubSurface) {
window->waitForFrameSync();
+ }
window->setCanResize(false);
}
@@ -219,34 +225,47 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, cons
mFrontBuffer = mBackBuffer;
+ QWaylandWindow *w = waylandWindow();
+ bool synchModeSubSurface = w->subSurfaceWindow() && w->subSurfaceWindow()->isSync();
+
if (mFrameCallback) {
- mFrontBufferIsDirty = true;
- return;
+ if (synchModeSubSurface) {
+ wl_callback_destroy(mFrameCallback);
+ mFrameCallback = Q_NULLPTR;
+ } else {
+ mFrontBufferIsDirty = true;
+ return;
+ }
}
- mFrameCallback = waylandWindow()->frame();
- wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this);
- QMargins margins = windowDecorationMargins();
+ // Dont acquire the frame callback as that will cause beginPaint
+ // to block in waiting for frame sync since the damage will trigger
+ // its own sync request
+ if (!synchModeSubSurface) {
+ mFrameCallback = w->frame();
+ wl_callback_add_listener(mFrameCallback, &frameCallbackListener, this);
+ }
+ QMargins margins = windowDecorationMargins();
bool damageAll = false;
- if (waylandWindow()->attached() != mFrontBuffer) {
- delete waylandWindow()->attached();
+ if (w->attached() != mFrontBuffer) {
+ delete w->attached();
damageAll = true;
}
- waylandWindow()->attachOffset(mFrontBuffer);
+ w->attachOffset(mFrontBuffer);
if (damageAll) {
//need to damage it all, otherwise the attach offset may screw up
- waylandWindow()->damage(QRect(QPoint(0,0), window->size()));
+ w->damage(QRect(QPoint(0,0), window->size()));
} else {
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); i++) {
QRect rect = rects.at(i);
rect.translate(margins.left(),margins.top());
- waylandWindow()->damage(rect);
+ w->damage(rect);
}
}
- waylandWindow()->commit();
+ w->commit();
mFrontBufferIsDirty = false;
}
diff --git a/src/client/qwaylandsubsurface.cpp b/src/client/qwaylandsubsurface.cpp
index ec813609f..eac847c75 100644
--- a/src/client/qwaylandsubsurface.cpp
+++ b/src/client/qwaylandsubsurface.cpp
@@ -45,9 +45,10 @@ QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, QWaylandWindow *p
: QtWayland::wl_subsurface(sub_surface)
, m_window(window)
, m_parent(parent)
+ , m_synchronized(false)
{
m_parent->mChildren << this;
- set_desync();
+ setDeSync();
}
QWaylandSubSurface::~QWaylandSubSurface()
@@ -55,6 +56,30 @@ QWaylandSubSurface::~QWaylandSubSurface()
m_parent->mChildren.removeOne(this);
}
+void QWaylandSubSurface::setSync()
+{
+ QMutexLocker l(&m_syncLock);
+ QWaylandSubSurface::set_sync();
+}
+
+void QWaylandSubSurface::setDeSync()
+{
+ QMutexLocker l(&m_syncLock);
+ QWaylandSubSurface::set_desync();
+}
+
+void QWaylandSubSurface::set_sync()
+{
+ m_synchronized = true;
+ QtWayland::wl_subsurface::set_sync();
+}
+
+void QWaylandSubSurface::set_desync()
+{
+ m_synchronized = false;
+ QtWayland::wl_subsurface::set_desync();
+}
+
}
QT_END_NAMESPACE
diff --git a/src/client/qwaylandsubsurface_p.h b/src/client/qwaylandsubsurface_p.h
index 4cbb99251..b8ea6aaf3 100644
--- a/src/client/qwaylandsubsurface_p.h
+++ b/src/client/qwaylandsubsurface_p.h
@@ -48,6 +48,7 @@
#include <wayland-client.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmutex.h>
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
@@ -68,9 +69,22 @@ public:
QWaylandWindow *window() const { return m_window; }
QWaylandWindow *parent() const { return m_parent; }
+ void setSync();
+ void setDeSync();
+ bool isSync() const { return m_synchronized; }
+ QMutex *syncMutex() { return &m_syncLock; }
+
private:
+
+ // Intentionally hide public methods from ::wl_subsurface
+ // to keep track of the sync state
+ void set_sync();
+ void set_desync();
QWaylandWindow *m_window;
QWaylandWindow *m_parent;
+ bool m_synchronized;
+ QMutex m_syncLock;
+
};
QT_END_NAMESPACE