diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/client.pro | 2 | ||||
-rw-r--r-- | src/client/qwaylandcursor.cpp | 2 | ||||
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 2 | ||||
-rw-r--r-- | src/client/qwaylanddisplay_p.h | 5 | ||||
-rw-r--r-- | src/client/qwaylandintegration.cpp | 15 | ||||
-rw-r--r-- | src/client/qwaylandnativeinterface.cpp | 41 | ||||
-rw-r--r-- | src/client/qwaylandnativeinterface_p.h | 6 | ||||
-rw-r--r-- | src/client/qwaylandshm.cpp | 80 | ||||
-rw-r--r-- | src/client/qwaylandshm_p.h | 76 | ||||
-rw-r--r-- | src/client/qwaylandshmbackingstore.cpp | 49 | ||||
-rw-r--r-- | src/client/qwaylandsubsurface.cpp | 27 | ||||
-rw-r--r-- | src/client/qwaylandsubsurface_p.h | 14 |
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 ®ion, 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 |