diff options
Diffstat (limited to 'src')
109 files changed, 2212 insertions, 1587 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 8c0d4d0b..c1300994 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -116,7 +116,7 @@ QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(WaylandClient* c) QList<QWaylandSurface *> result; for (int i = 0; i < surfaces.count(); ++i) { - if (surfaces.at(i)->base()->resource.client == client) { + if (surfaces.at(i)->resource()->client() == client) { result.append(surfaces.at(i)->waylandSurface()); } } @@ -124,9 +124,9 @@ QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(WaylandClient* c) return result; } -void QWaylandCompositor::setDirectRenderSurface(QWaylandSurface *surface, QOpenGLContext *context) +bool QWaylandCompositor::setDirectRenderSurface(QWaylandSurface *surface, QOpenGLContext *context) { - m_compositor->setDirectRenderSurface(surface ? surface->handle() : 0, context); + return m_compositor->setDirectRenderSurface(surface ? surface->handle() : 0, context); } QWaylandSurface *QWaylandCompositor::directRenderSurface() const diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index 0f258617..cd1f9bd3 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -75,7 +75,7 @@ public: QList<QWaylandSurface *> surfacesForClient(WaylandClient* client) const; - void setDirectRenderSurface(QWaylandSurface *surface, QOpenGLContext *context); + bool setDirectRenderSurface(QWaylandSurface *surface, QOpenGLContext *context); QWaylandSurface *directRenderSurface() const; QWindow *window()const; diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp index c73784eb..76e83030 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandinput.cpp @@ -41,6 +41,7 @@ #include "qwaylandinput.h" #include "qwlinputdevice_p.h" +#include "qwlkeyboard_p.h" #include "qwaylandcompositor.h" #include "qwlsurface_p.h" #include "qwlcompositor_p.h" @@ -88,12 +89,12 @@ void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int d void QWaylandInputDevice::sendKeyPressEvent(uint code) { - d->sendKeyPressEvent(code); + d->keyboardDevice()->sendKeyPressEvent(code); } void QWaylandInputDevice::sendKeyReleaseEvent(uint code) { - d->sendKeyReleaseEvent(code); + d->keyboardDevice()->sendKeyReleaseEvent(code); } void QWaylandInputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state) diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 7f0813a4..88b68ebd 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -92,7 +92,7 @@ QWaylandSurface::QWaylandSurface(QtWayland::Surface *surface) WaylandClient *QWaylandSurface::client() const { Q_D(const QWaylandSurface); - return d->surface->base()->resource.client; + return d->surface->resource()->client(); } QWaylandSurface *QWaylandSurface::parentSurface() const @@ -149,13 +149,7 @@ QSize QWaylandSurface::size() const return d->surface->size(); } -void QWaylandSurface::setSize(const QSize &size) -{ - Q_D(QWaylandSurface); - d->surface->setSize(size); -} - -void QWaylandSurface::sendConfigure(const QSize &size) +void QWaylandSurface::requestSize(const QSize &size) { Q_D(QWaylandSurface); if (d->surface->shellSurface()) @@ -226,7 +220,6 @@ void QWaylandSurface::setSurfaceItem(QWaylandSurfaceItem *surfaceItem) qint64 QWaylandSurface::processId() const { - Q_D(const QWaylandSurface); struct wl_client *client = static_cast<struct wl_client *>(this->client()); pid_t pid; wl_client_get_credentials(client,&pid, 0,0); @@ -291,11 +284,25 @@ QWaylandSurface *QWaylandSurface::transientParent() const return 0; } -void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) +QWindow::Visibility QWaylandSurface::visibility() const +{ + Q_D(const QWaylandSurface); + if (d->surface->extendedSurface()) + return d->surface->extendedSurface()->visibility(); + + return QWindow::AutomaticVisibility; +} + +void QWaylandSurface::setVisibility(QWindow::Visibility visibility) { Q_D(QWaylandSurface); if (d->surface->extendedSurface()) - d->surface->extendedSurface()->sendOnScreenVisibility(visible); + d->surface->extendedSurface()->setVisibility(visibility); +} + +void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) +{ + setVisibility(visible ? QWindow::AutomaticVisibility : QWindow::Hidden); } QString QWaylandSurface::className() const @@ -328,4 +335,21 @@ bool QWaylandSurface::transientInactive() const return d->surface->transientInactive(); } +void QWaylandSurface::destroySurface() +{ + Q_D(QWaylandSurface); + if (d->surface->extendedSurface()) { + d->surface->extendedSurface()->send_close(); + } else { + destroySurfaceByForce(); + } +} + +void QWaylandSurface::destroySurfaceByForce() +{ + Q_D(QWaylandSurface); + wl_resource *surface_resource = d->surface->resource()->handle; + wl_resource_destroy(surface_resource); +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 544fbc04..308e8d54 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -45,6 +45,7 @@ #include <QtCore/QScopedPointer> #include <QtGui/QImage> +#include <QtGui/QWindow> #include <QtCore/QVariantMap> #include <QtGui/QOpenGLContext> @@ -72,13 +73,14 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandSurface) - Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged) + Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) Q_PROPERTY(QPointF pos READ pos WRITE setPos NOTIFY posChanged) Q_PROPERTY(QWaylandSurface::WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged) Q_PROPERTY(QString className READ className NOTIFY classNameChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask NOTIFY orientationUpdateMaskChanged) + Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) Q_ENUMS(WindowFlag) Q_FLAGS(WindowFlag WindowFlags) @@ -111,8 +113,7 @@ public: QPointF pos() const; void setPos(const QPointF &pos); QSize size() const; - void setSize(const QSize &size); - void sendConfigure(const QSize &size); + Q_INVOKABLE void requestSize(const QSize &size); Qt::ScreenOrientations orientationUpdateMask() const; Qt::ScreenOrientation contentOrientation() const; @@ -126,7 +127,9 @@ public: uint texture(QOpenGLContext *context) const; #endif - Q_INVOKABLE void sendOnScreenVisibilityChange(bool visible); + QWindow::Visibility visibility() const; + void setVisibility(QWindow::Visibility visibility); + Q_INVOKABLE void sendOnScreenVisibilityChange(bool visible); // Compat void frameFinished(); @@ -157,6 +160,8 @@ public: bool transientInactive() const; + Q_INVOKABLE void destroySurface(); + Q_INVOKABLE void destroySurfaceByForce(); signals: void mapped(); void unmapped(); @@ -171,7 +176,9 @@ signals: void extendedSurfaceReady(); void classNameChanged(); void titleChanged(); - + void raiseRequested(); + void lowerRequested(); + void visibilityChanged(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index a6f425a8..dde6848b 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -93,7 +93,7 @@ QWaylandSurfaceItem::QWaylandSurfaceItem(QQuickItem *parent) , m_node(0) , m_paintEnabled(true) , m_useTextureAlpha(false) - , m_clientRenderingEnabled(false) + , m_clientRenderingEnabled(true) , m_touchEventsEnabled(false) , m_resizeSurfaceToItem(false) { @@ -108,8 +108,9 @@ QWaylandSurfaceItem::QWaylandSurfaceItem(QWaylandSurface *surface, QQuickItem *p , m_node(0) , m_paintEnabled(true) , m_useTextureAlpha(false) - , m_clientRenderingEnabled(false) + , m_clientRenderingEnabled(true) , m_touchEventsEnabled(false) + , m_resizeSurfaceToItem(false) { init(surface); } @@ -125,9 +126,7 @@ void QWaylandSurfaceItem::init(QWaylandSurface *surface) m_surface = surface; m_surface->setSurfaceItem(this); - if (m_clientRenderingEnabled) { - m_surface->sendOnScreenVisibilityChange(m_clientRenderingEnabled); - } + m_surface->sendOnScreenVisibilityChange(m_clientRenderingEnabled); if (m_resizeSurfaceToItem) { updateSurfaceSize(); @@ -203,8 +202,8 @@ void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event) if (m_surface) { QWaylandInputDevice *inputDevice = m_surface->compositor()->defaultInputDevice(); if (inputDevice->mouseFocus() != m_surface) - inputDevice->setMouseFocus(m_surface, event->pos(), event->globalPos()); - inputDevice->sendMousePressEvent(event->button(), toSurface(event->pos()), event->globalPos()); + inputDevice->setMouseFocus(m_surface, event->localPos(), event->windowPos()); + inputDevice->sendMousePressEvent(event->button(), event->localPos(), event->windowPos()); } } @@ -212,7 +211,7 @@ void QWaylandSurfaceItem::mouseMoveEvent(QMouseEvent *event) { if (m_surface){ QWaylandInputDevice *inputDevice = m_surface->compositor()->defaultInputDevice(); - inputDevice->sendMouseMoveEvent(m_surface, toSurface(event->pos()), event->globalPos()); + inputDevice->sendMouseMoveEvent(m_surface, event->localPos(), event->windowPos()); } } @@ -220,7 +219,7 @@ void QWaylandSurfaceItem::mouseReleaseEvent(QMouseEvent *event) { if (m_surface){ QWaylandInputDevice *inputDevice = m_surface->compositor()->defaultInputDevice(); - inputDevice->sendMouseReleaseEvent(event->button(), toSurface(event->pos()), event->globalPos()); + inputDevice->sendMouseReleaseEvent(event->button(), event->localPos(), event->windowPos()); } } @@ -276,11 +275,6 @@ void QWaylandSurfaceItem::takeFocus() } } -QPoint QWaylandSurfaceItem::toSurface(const QPointF &pos) const -{ - return pos.toPoint(); -} - void QWaylandSurfaceItem::surfaceMapped() { setPaintEnabled(true); @@ -339,7 +333,7 @@ void QWaylandSurfaceItem::updateSize() void QWaylandSurfaceItem::updateSurfaceSize() { if (m_resizeSurfaceToItem) { - m_surface->sendConfigure(QSize(width(), height())); + m_surface->requestSize(QSize(width(), height())); } } @@ -455,6 +449,6 @@ void QWaylandSurfaceItem::setResizeSurfaceToItem(bool enabled) } } -#include "qwaylandsurfaceitem.moc" - QT_END_NAMESPACE + +#include "qwaylandsurfaceitem.moc" diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h index c6a5cff8..93a0c62c 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.h +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h @@ -134,7 +134,6 @@ protected: private: friend class QWaylandSurfaceNode; void updateTexture(); - QPoint toSurface(const QPointF &pos) const; void init(QWaylandSurface *); void ensureProvider(); diff --git a/src/compositor/global/global.pri b/src/compositor/global/global.pri index f187619e..9cbd62d8 100644 --- a/src/compositor/global/global.pri +++ b/src/compositor/global/global.pri @@ -2,7 +2,6 @@ INCLUDEPATH += global/ HEADERS += \ global/qwaylandexport.h \ - global/qwaylandobject.h \ global/qwaylandresourcecollection.h SOURCES += \ diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h b/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h index 37388044..b8cc90fb 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h +++ b/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h @@ -66,14 +66,16 @@ public: /** Bind the Wayland buffer to the textureId. The correct context is the current context, so there is no need to do makeCurrent in this function. **/ - virtual GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context) = 0; - virtual bool isYInverted(struct wl_buffer *) const { return true; } + virtual GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) = 0; + virtual bool isYInverted(struct ::wl_resource *) const { return true; } virtual bool setDirectRenderSurface(QWaylandSurface *) {return false;} - virtual void *lockNativeBuffer(struct wl_buffer *, QOpenGLContext *) const { return 0; } + virtual void *lockNativeBuffer(struct ::wl_resource *, QOpenGLContext *) const { return 0; } virtual void unlockNativeBuffer(void *, QOpenGLContext *) const { return; } + virtual QSize bufferSize(struct ::wl_resource *) const { return QSize(); } + protected: QWaylandCompositor *m_compositor; }; diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp index 0f2fedc4..4f0e6ced 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp @@ -51,10 +51,11 @@ #include "qwlextendedsurface_p.h" #include "qwlsubsurface_p.h" #include "qwlshellsurface_p.h" -#include "qwltouch_p.h" +#include "qwlqttouch_p.h" #include "qwlqtkey_p.h" #include "qwlinputdevice_p.h" #include "qwlregion_p.h" +#include "qwlpointer_p.h" #include <QWindow> #include <QSocketNotifier> @@ -246,36 +247,6 @@ void Compositor::createSurface(struct wl_client *client, uint32_t id) m_qt_compositor->surfaceCreated(surface->waylandSurface()); } -struct wl_client *Compositor::getClientFromWinId(uint winId) const -{ - Surface *surface = getSurfaceFromWinId(winId); - if (surface) - return surface->resource()->client(); - - return 0; -} - -Surface *Compositor::getSurfaceFromWinId(uint winId) const -{ - foreach (Surface *surface, m_surfaces) { - if (surface->id() == winId) - return surface; - } - - return 0; -} - -QImage Compositor::image(uint winId) const -{ - foreach (Surface *surface, m_surfaces) { - if (surface->id() == winId) { - return surface->image(); - } - } - - return QImage(); -} - uint Compositor::currentTimeMsecs() { //### we throw away the time information @@ -286,9 +257,9 @@ uint Compositor::currentTimeMsecs() return 0; } -void Compositor::releaseBuffer(SurfaceBuffer *screenBuffer) +void Compositor::releaseBuffer(QPlatformScreenBuffer *screenBuffer) { - screenBuffer->scheduledRelease(); + static_cast<SurfaceBuffer *>(screenBuffer)->scheduledRelease(); } void Compositor::processWaylandEvents() @@ -307,7 +278,10 @@ void Compositor::surfaceDestroyed(Surface *surface) // Make sure the surface is reset regardless of what the grabber // interface's focus() does. (e.g. the default implementation does // nothing when a button is down which would be disastrous here) - wl_pointer_set_focus(dev->pointerDevice(), 0, 0, 0); + dev->pointerDevice()->setFocus(0, QPointF()); + } + if (dev->pointerDevice()->current() == surface) { + dev->pointerDevice()->setCurrent(0, QPointF()); } if (dev->keyboardFocus() == surface) dev->setKeyboardFocus(0); @@ -494,22 +468,6 @@ QList<QtWayland::Surface *> Compositor::surfacesForClient(wl_client *client) return ret; } -wl_resource *Compositor::resourceForSurface(wl_list *resourceList, Surface *surface) -{ - if (!surface) - return 0; - - wl_resource *r; - wl_client *surfaceClient = surface->resource()->client(); - - wl_list_for_each(r, resourceList, link) { - if (r->client == surfaceClient) - return r; - } - - return 0; -} - void Compositor::configureTouchExtension(int flags) { if (m_touchExtension) @@ -536,7 +494,7 @@ void Compositor::feedRetainedSelectionData(QMimeData *data) void Compositor::scheduleReleaseBuffer(SurfaceBuffer *screenBuffer) { - QMetaObject::invokeMethod(this,"releaseBuffer",Q_ARG(SurfaceBuffer*,screenBuffer)); + QMetaObject::invokeMethod(this,"releaseBuffer",Q_ARG(QPlatformScreenBuffer*,screenBuffer)); } void Compositor::overrideSelection(QMimeData *data) diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h index 62847068..5e3c7be4 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor_p.h +++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h @@ -84,11 +84,6 @@ public: void frameFinished(Surface *surface = 0); - //these 3 functions will be removed if noone steps up soon. - Surface *getSurfaceFromWinId(uint winId) const; - struct wl_client *getClientFromWinId(uint winId) const; - QImage image(uint winId) const; - InputDevice *defaultInputDevice(); //we just have 1 default device for now (since QPA doesn't give us anything else) void createSurface(struct wl_client *client, uint32_t id); @@ -153,11 +148,9 @@ public: void scheduleReleaseBuffer(SurfaceBuffer *screenBuffer); - static wl_resource *resourceForSurface(wl_list *resourceList, Surface *surface); - private slots: - void releaseBuffer(SurfaceBuffer *screenBuffer); + void releaseBuffer(QPlatformScreenBuffer *screenBuffer); void processWaylandEvents(); private: diff --git a/src/compositor/wayland_wrapper/qwldatasource.cpp b/src/compositor/wayland_wrapper/qwldatasource.cpp index 271467f2..d60ec510 100644 --- a/src/compositor/wayland_wrapper/qwldatasource.cpp +++ b/src/compositor/wayland_wrapper/qwldatasource.cpp @@ -43,7 +43,7 @@ #include "qwldatadevicemanager_p.h" #include "qwlcompositor_p.h" -#include <wayland-server-protocol.h> +#include <wayland-wayland-server-protocol.h> #include <QtCore/QDebug> diff --git a/src/compositor/wayland_wrapper/qwldisplay.cpp b/src/compositor/wayland_wrapper/qwldisplay.cpp index be5b5418..5dd6e382 100644 --- a/src/compositor/wayland_wrapper/qwldisplay.cpp +++ b/src/compositor/wayland_wrapper/qwldisplay.cpp @@ -42,7 +42,7 @@ #include <QtCore/QDebug> -#include <wayland-server-protocol.h> +#include <wayland-wayland-server-protocol.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp index 19df7eb2..4f1791da 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp @@ -48,52 +48,30 @@ QT_BEGIN_NAMESPACE namespace QtWayland { SurfaceExtensionGlobal::SurfaceExtensionGlobal(Compositor *compositor) - : m_compositor(compositor) + : QtWaylandServer::qt_surface_extension(compositor->wl_display()) { - wl_display_add_global(m_compositor->wl_display(), - &qt_surface_extension_interface, - this, - SurfaceExtensionGlobal::bind_func); } -void SurfaceExtensionGlobal::bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id) +void SurfaceExtensionGlobal::surface_extension_get_extended_surface(Resource *resource, + uint32_t id, + struct wl_resource *surface_resource) { - Q_UNUSED(version); - wl_client_add_object(client, &qt_surface_extension_interface,&surface_extension_interface,id,data); -} - -const struct qt_surface_extension_interface SurfaceExtensionGlobal::surface_extension_interface = { - SurfaceExtensionGlobal::get_extended_surface -}; - -void SurfaceExtensionGlobal::get_extended_surface(struct wl_client *client, - struct wl_resource *surface_extension_resource, - uint32_t id, - struct wl_resource *surface_resource) -{ - Q_UNUSED(surface_extension_resource); Surface *surface = Surface::fromResource(surface_resource); - new ExtendedSurface(client,id,surface); + new ExtendedSurface(resource->client(),id,surface); } ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, Surface *surface) - : m_surface(surface) + : QtWaylandServer::qt_extended_surface(client,id) + , m_surface(surface) , m_contentOrientation(Qt::PrimaryOrientation) , m_windowFlags(0) { Q_ASSERT(surface->extendedSurface() == 0); - m_extended_surface_resource = wl_client_add_object(client, - &qt_extended_surface_interface, - &extended_surface_interface, - id, - this); surface->setExtendedSurface(this); } ExtendedSurface::~ExtendedSurface() { - } void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant) @@ -101,31 +79,33 @@ void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &v QByteArray byteValue; QDataStream ds(&byteValue, QIODevice::WriteOnly); ds << variant; - wl_array data; - data.size = byteValue.size(); - data.data = (void*) byteValue.constData(); - data.alloc = 0; - qt_extended_surface_send_set_generic_property(m_extended_surface_resource, qPrintable(name), &data); + send_set_generic_property(name, byteValue); } -void ExtendedSurface::sendOnScreenVisibility(bool visible) +void ExtendedSurface::setVisibility(QWindow::Visibility visibility, bool updateClient) { - int32_t visibleInt = visible; - qt_extended_surface_send_onscreen_visibility(m_extended_surface_resource, visibleInt); -} + if (visibility == m_visibility) + return; + + m_visibility = visibility; + emit m_surface->waylandSurface()->visibilityChanged(); + // If this change came from the client, we shouldn't update it + if (updateClient) + send_onscreen_visibility(m_visibility); +} -void ExtendedSurface::update_generic_property(wl_client *client, wl_resource *extended_surface_resource, const char *name, wl_array *value) +void ExtendedSurface::extended_surface_update_generic_property(Resource *resource, + const QString &name, + struct wl_array *value) { - Q_UNUSED(client); - ExtendedSurface *extended_surface = static_cast<ExtendedSurface *>(extended_surface_resource->data); + Q_UNUSED(resource); QVariant variantValue; QByteArray byteValue((const char*)value->data, value->size); QDataStream ds(&byteValue, QIODevice::ReadOnly); ds >> variantValue; - extended_surface->setWindowProperty(QString::fromLatin1(name),variantValue,false); - + setWindowProperty(name,variantValue,false); } static Qt::ScreenOrientation screenOrientationFromWaylandOrientation(int32_t orientation) @@ -144,25 +124,13 @@ Qt::ScreenOrientation ExtendedSurface::contentOrientation() const return m_contentOrientation; } -void ExtendedSurface::set_content_orientation(struct wl_client *client, - struct wl_resource *extended_surface_resource, - int32_t orientation) -{ - Q_UNUSED(client); - ExtendedSurface *extended_surface = static_cast<ExtendedSurface *>(extended_surface_resource->data); - - Qt::ScreenOrientation oldOrientation = extended_surface->m_contentOrientation; - extended_surface->m_contentOrientation = screenOrientationFromWaylandOrientation(orientation); - if (extended_surface->m_contentOrientation != oldOrientation) - emit extended_surface->m_surface->waylandSurface()->contentOrientationChanged(); -} - -void ExtendedSurface::setWindowFlags(QWaylandSurface::WindowFlags flags) +void ExtendedSurface::extended_surface_set_content_orientation(Resource *resource, int32_t orientation) { - if (flags == m_windowFlags) - return; - m_windowFlags = flags; - emit m_surface->waylandSurface()->windowFlagsChanged(flags); + Q_UNUSED(resource); + Qt::ScreenOrientation oldOrientation = m_contentOrientation; + m_contentOrientation = screenOrientationFromWaylandOrientation(orientation); + if (m_contentOrientation != oldOrientation) + emit m_surface->waylandSurface()->contentOrientationChanged(); } QVariantMap ExtendedSurface::windowProperties() const @@ -184,18 +152,30 @@ void ExtendedSurface::setWindowProperty(const QString &name, const QVariant &val sendGenericProperty(name, value); } -void ExtendedSurface::set_window_flags(wl_client *client, wl_resource *resource, int32_t flags) +void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int32_t flags) +{ + Q_UNUSED(resource); + QWaylandSurface::WindowFlags windowFlags(flags); + if (windowFlags== m_windowFlags) + return; + m_windowFlags = windowFlags; + emit m_surface->waylandSurface()->windowFlagsChanged(windowFlags); +} + +void ExtendedSurface::extended_surface_destroy_resource(Resource *) +{ + delete this; +} + +void ExtendedSurface::extended_surface_raise(Resource *) { - Q_UNUSED(client); - ExtendedSurface *extended_surface = static_cast<ExtendedSurface *>(resource->data); - extended_surface->setWindowFlags(QWaylandSurface::WindowFlags(flags)); + emit m_surface->waylandSurface()->raiseRequested(); } -const struct qt_extended_surface_interface ExtendedSurface::extended_surface_interface = { - ExtendedSurface::update_generic_property, - ExtendedSurface::set_content_orientation, - ExtendedSurface::set_window_flags -}; +void ExtendedSurface::extended_surface_lower(Resource *) +{ + emit m_surface->waylandSurface()->lowerRequested(); +} } diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h index db9a2e8a..ecf2f49d 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h @@ -42,13 +42,14 @@ #define WLEXTENDEDSURFACE_H #include <wayland-server.h> -#include "wayland-surface-extension-server-protocol.h" +#include "qwayland-server-surface-extension.h" #include <private/qwlsurface_p.h> #include <QtCompositor/qwaylandsurface.h> #include <QtCore/QVariant> #include <QtCore/QLinkedList> +#include <QtGui/QWindow> QT_BEGIN_NAMESPACE @@ -58,32 +59,28 @@ namespace QtWayland { class Compositor; -class SurfaceExtensionGlobal +class SurfaceExtensionGlobal : public QtWaylandServer::qt_surface_extension { public: SurfaceExtensionGlobal(Compositor *compositor); private: - Compositor *m_compositor; - - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - static void get_extended_surface(struct wl_client *client, - struct wl_resource *resource, - uint32_t id, - struct wl_resource *surface); - static const struct qt_surface_extension_interface surface_extension_interface; + void surface_extension_get_extended_surface(Resource *resource, + uint32_t id, + struct wl_resource *surface); }; -class ExtendedSurface +class ExtendedSurface : public QtWaylandServer::qt_extended_surface { public: ExtendedSurface(struct wl_client *client, uint32_t id, Surface *surface); ~ExtendedSurface(); void sendGenericProperty(const QString &name, const QVariant &variant); - void sendOnScreenVisibility(bool visible); + + QWindow::Visibility visibility() const { return m_visibility; } + void setVisibility(QWindow::Visibility visibility, bool updateClient = true); void setSubSurface(ExtendedSurface *subSurface,int x, int y); void removeSubSurface(ExtendedSurface *subSurfaces); @@ -95,40 +92,34 @@ public: QWaylandSurface::WindowFlags windowFlags() const { return m_windowFlags; } - qint64 processId() const; - void setProcessId(qint64 processId); - QVariantMap windowProperties() const; QVariant windowProperty(const QString &propertyName) const; void setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient = true); private: - struct wl_resource *m_extended_surface_resource; Surface *m_surface; Qt::ScreenOrientation m_contentOrientation; QWaylandSurface::WindowFlags m_windowFlags; + QWindow::Visibility m_visibility; QByteArray m_authenticationToken; QVariantMap m_windowProperties; + void extended_surface_update_generic_property(Resource *resource, + const QString &name, + struct wl_array *value) Q_DECL_OVERRIDE; - static void update_generic_property(struct wl_client *client, - struct wl_resource *resource, - const char *name, - struct wl_array *value); - - static void set_content_orientation(struct wl_client *client, - struct wl_resource *resource, - int32_t orientation); + void extended_surface_set_content_orientation(Resource *resource, + int32_t orientation) Q_DECL_OVERRIDE; - static void set_window_flags(struct wl_client *client, - struct wl_resource *resource, - int32_t flags); - void setWindowFlags(QWaylandSurface::WindowFlags flags); + void extended_surface_set_window_flags(Resource *resource, + int32_t flags) Q_DECL_OVERRIDE; - static const struct qt_extended_surface_interface extended_surface_interface; + void extended_surface_destroy_resource(Resource *) Q_DECL_OVERRIDE; + void extended_surface_raise(Resource *) Q_DECL_OVERRIDE; + void extended_surface_lower(Resource *) Q_DECL_OVERRIDE; }; } diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp index e75d9833..d9a91bfa 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp @@ -43,23 +43,15 @@ #include "qwlcompositor_p.h" #include "qwldatadevice_p.h" #include "qwlsurface_p.h" -#include "qwltouch_p.h" +#include "qwlqttouch_p.h" #include "qwlqtkey_p.h" #include "qwaylandcompositor.h" +#include "qwlpointer_p.h" +#include "qwlkeyboard_p.h" +#include "qwltouch_p.h" #include <QtGui/QTouchEvent> -#ifndef QT_NO_WAYLAND_XKB -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/epoll.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#endif - QT_BEGIN_NAMESPACE namespace QtWayland { @@ -68,146 +60,54 @@ InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor) : QtWaylandServer::wl_seat(compositor->wl_display()) , m_handle(handle) , m_compositor(compositor) + , m_pointer(new Pointer(m_compositor, this)) + , m_keyboard(new Keyboard(m_compositor, this)) + , m_touch(new Touch(m_compositor)) { - wl_seat_init(&m_seat); - initDevices(); - -#ifndef QT_NO_WAYLAND_XKB - xkb_rule_names xkb_names; - xkb_context *context = xkb_context_new(xkb_context_flags(0)); - - memset(&xkb_names, 0, sizeof(xkb_names)); - xkb_names.rules = strdup("evdev"); - xkb_names.model = strdup("pc105"); - xkb_names.layout = strdup("us"); - - xkb_keymap *keymap = xkb_map_new_from_names(context, &xkb_names, xkb_map_compile_flags(0)); - if (!keymap) - qFatal("Failed to compile global XKB keymap"); - - char *keymap_str_data = xkb_map_get_as_string(keymap); - QByteArray keymap_str = keymap_str_data; - m_keymap_size = keymap_str.size() + 1; - free(keymap_str_data); - - const char *path = getenv("XDG_RUNTIME_DIR"); - if (!path) - qFatal("XDG_RUNTIME_DIR not set"); - - QByteArray name = QByteArray(path) + "/qtwayland-xkb-map-XXXXXX"; - - int fd = mkstemp(name.data()); - if (fd >= 0) { - long flags = fcntl(fd, F_GETFD); - if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { - close(fd); - qFatal("Failed to set FD_CLOEXEC on anonymous file"); - } - unlink(name.data()); - } else { - qFatal("Failed to create anonymous file with name %s", name.constData()); - } - - if (ftruncate(fd, m_keymap_size) < 0) - qFatal("Failed to create anonymous file of size %lu", (unsigned long)m_keymap_size); - - m_keymap_fd = fd; - - m_keymap_area = (char *)mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0); - if (m_keymap_area == MAP_FAILED) { - close(m_keymap_fd); - qFatal("Failed to map shared memory segment"); - } - - strcpy(m_keymap_area, keymap_str.constData()); - - m_state = xkb_state_new(keymap); - - free((char *)xkb_names.rules); - free((char *)xkb_names.model); - free((char *)xkb_names.layout); - xkb_map_unref(keymap); - xkb_context_unref(context); -#endif } InputDevice::~InputDevice() { qDeleteAll(m_data_devices); - releaseDevices(); - -#ifndef QT_NO_WAYLAND_XKB - if (m_keymap_area) - munmap(m_keymap_area, m_keymap_size); - close(m_keymap_fd); - xkb_state_unref(m_state); -#endif -} - -void InputDevice::initDevices() -{ - wl_pointer_init(&m_device_interfaces.pointer); - wl_seat_set_pointer(&m_seat, &m_device_interfaces.pointer); - - wl_keyboard_init(&m_device_interfaces.keyboard); - wl_seat_set_keyboard(&m_seat, &m_device_interfaces.keyboard); - - wl_touch_init(&m_device_interfaces.touch); - wl_seat_set_touch(&m_seat, &m_device_interfaces.touch); } -void InputDevice::releaseDevices() +Pointer *InputDevice::pointerDevice() { - wl_pointer_release(&m_device_interfaces.pointer); - wl_keyboard_release(&m_device_interfaces.keyboard); - wl_touch_release(&m_device_interfaces.touch); + return m_pointer.data(); } -wl_pointer *InputDevice::pointerDevice() +Keyboard *InputDevice::keyboardDevice() { - return &m_device_interfaces.pointer; + return m_keyboard.data(); } -wl_keyboard *InputDevice::keyboardDevice() +Touch *InputDevice::touchDevice() { - return &m_device_interfaces.keyboard; + return m_touch.data(); } -wl_touch *InputDevice::touchDevice() +const Pointer *InputDevice::pointerDevice() const { - return &m_device_interfaces.touch; + return m_pointer.data(); } -const wl_pointer *InputDevice::pointerDevice() const +const Keyboard *InputDevice::keyboardDevice() const { - return &m_device_interfaces.pointer; + return m_keyboard.data(); } -const wl_keyboard *InputDevice::keyboardDevice() const +const Touch *InputDevice::touchDevice() const { - return &m_device_interfaces.keyboard; -} - -const wl_touch *InputDevice::touchDevice() const -{ - return &m_device_interfaces.touch; + return m_touch.data(); } void InputDevice::seat_destroy_resource(wl_seat::Resource *resource) { - if (keyboardDevice()->focus_resource == resource->handle) - keyboardDevice()->focus_resource = 0; - - if (pointerDevice()->focus_resource == resource->handle) - pointerDevice()->focus_resource = 0; - cleanupDataDeviceForClient(resource->client(), true); } void InputDevice::seat_bind_resource(wl_seat::Resource *resource) { - wl_list_insert(&m_seat.base_resource_list, &resource->handle->link); - uint32_t caps = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD; if (!QTouchDevice::devices().isEmpty()) caps |= WL_SEAT_CAPABILITY_TOUCH; @@ -215,76 +115,34 @@ void InputDevice::seat_bind_resource(wl_seat::Resource *resource) wl_seat::send_capabilities(resource->handle, caps); } -void InputDevice::pointer_set_cursor(wl_pointer::Resource *resource, - uint32_t serial, wl_resource *surface_resource, - int32_t hotspot_x, int32_t hotspot_y) -{ - Q_UNUSED(resource); - Q_UNUSED(serial); - - QtWayland::Surface *surface = QtWayland::Surface::fromResource(surface_resource); - - surface->setCursorSurface(true); - m_compositor->waylandCompositor()->setCursorSurface(surface->waylandSurface(), hotspot_x, hotspot_y); -} - void InputDevice::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) { - ::wl_pointer *pointer = pointerDevice(); - wl_pointer::add(&pointer->resource_list, resource->client(), id); + m_pointer->add(resource->client(), id); } void InputDevice::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) { - ::wl_keyboard *keyboard = keyboardDevice(); - wl_keyboard::add(&keyboard->resource_list, resource->client(), id); -} - -void InputDevice::keyboard_bind_resource(wl_keyboard::Resource *resource) -{ -#ifndef QT_NO_WAYLAND_XKB - wl_keyboard::send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - m_keymap_fd, m_keymap_size); -#endif + m_keyboard->add(resource->client(), id); } void InputDevice::seat_get_touch(wl_seat::Resource *resource, uint32_t id) { - ::wl_touch *touch = touchDevice(); - wl_touch::add(&touch->resource_list, resource->client(), id); + m_touch->add(resource->client(), id); } void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { - sendMouseMoveEvent(localPos,globalPos); - ::wl_pointer *pointer = pointerDevice(); - pointer->button_count++; - uint32_t time = m_compositor->currentTimeMsecs(); - const struct wl_pointer_grab_interface *interface = pointer->grab->interface; - interface->button(pointer->grab, time, toWaylandButton(button), 1); + pointerDevice()->sendMousePressEvent(button, localPos, globalPos); } void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { - sendMouseMoveEvent(localPos,globalPos); - ::wl_pointer *pointer = pointerDevice(); - pointer->button_count--; - uint32_t time = m_compositor->currentTimeMsecs(); - const struct wl_pointer_grab_interface *interface = pointer->grab->interface; - interface->button(pointer->grab, time, toWaylandButton(button), 0); + pointerDevice()->sendMouseReleaseEvent(button, localPos, globalPos); } void InputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) { - Q_UNUSED(globalPos); - uint32_t time = m_compositor->currentTimeMsecs(); - ::wl_pointer *pointer = pointerDevice(); - const struct wl_pointer_grab_interface *interface = pointer->grab->interface; - pointer->x = wl_fixed_from_double(globalPos.x()); - pointer->y = wl_fixed_from_double(globalPos.y()); - interface->motion(pointer->grab, - time, - wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); + pointerDevice()->sendMouseMoveEvent(localPos, globalPos); } void InputDevice::sendMouseMoveEvent(Surface *surface, const QPointF &localPos, const QPointF &globalPos) @@ -295,100 +153,20 @@ void InputDevice::sendMouseMoveEvent(Surface *surface, const QPointF &localPos, void InputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { - ::wl_pointer *pointer = pointerDevice(); - struct wl_resource *resource = pointer->focus_resource; - if (!resource) - return; - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL - : WL_POINTER_AXIS_VERTICAL_SCROLL; - wl_pointer_send_axis(resource, time, axis, wl_fixed_from_int(-delta / 12)); -} - -void InputDevice::updateModifierState(uint code, int state) -{ -#ifndef QT_NO_WAYLAND_XKB - xkb_state_update_key(m_state, code, state ? XKB_KEY_DOWN : XKB_KEY_UP); - - uint32_t mods_depressed = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_DEPRESSED); - uint32_t mods_latched = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); - uint32_t mods_locked = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); - uint32_t group = xkb_state_serialize_group(m_state, (xkb_state_component)XKB_STATE_EFFECTIVE); - - ::wl_keyboard *keyboard = keyboardDevice(); - - if (mods_depressed == keyboard->modifiers.mods_depressed - && mods_latched == keyboard->modifiers.mods_latched - && mods_locked == keyboard->modifiers.mods_locked - && group == keyboard->modifiers.group) - { - return; // no change - } - - keyboard->modifiers.mods_depressed = mods_depressed; - keyboard->modifiers.mods_latched = mods_latched; - keyboard->modifiers.mods_locked = mods_locked; - keyboard->modifiers.group = group; - - if (keyboard->focus_resource) - sendKeyModifiers(keyboard->focus_resource); -#else - Q_UNUSED(code); - Q_UNUSED(state); -#endif -} - -void InputDevice::sendKeyModifiers(wl_resource *resource) -{ - ::wl_keyboard *keyboard = keyboardDevice(); - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - wl_keyboard_send_modifiers(resource, serial, keyboard->modifiers.mods_depressed, - keyboard->modifiers.mods_latched, keyboard->modifiers.mods_locked, keyboard->modifiers.group); -} - -void InputDevice::sendKeyPressEvent(uint code) -{ - ::wl_keyboard *keyboard = keyboardDevice(); - if (keyboard->focus_resource) { - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - wl_keyboard_send_key(keyboard->focus_resource, - serial, time, code - 8, 1); - } - updateModifierState(code, 1); -} - -void InputDevice::sendKeyReleaseEvent(uint code) -{ - ::wl_keyboard *keyboard = keyboardDevice(); - if (keyboard->focus_resource) { - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - wl_keyboard_send_key(keyboard->focus_resource, - serial, time, code - 8, 0); - } - updateModifierState(code, 0); + pointerDevice()->sendMouseWheelEvent(orientation, delta); } void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state) { - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t serial = 0; - ::wl_touch *touch = touchDevice(); - wl_resource *resource = touch->focus_resource; - if (!resource) - return; switch (state) { case Qt::TouchPointPressed: - wl_touch_send_down(resource, serial, time, &touch->focus->resource, id, - wl_fixed_from_double(x), wl_fixed_from_double(y)); + m_touch->sendDown(id, QPointF(x, y)); break; case Qt::TouchPointMoved: - wl_touch_send_motion(resource, time, id, - wl_fixed_from_double(x), wl_fixed_from_double(y)); + m_touch->sendMotion(id, QPointF(x, y)); break; case Qt::TouchPointReleased: - wl_touch_send_up(resource, serial, time, id); + m_touch->sendUp(id); break; case Qt::TouchPointStationary: // stationary points are not sent through wayland, the client must cache them @@ -400,18 +178,12 @@ void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPoint void InputDevice::sendTouchFrameEvent() { - ::wl_touch *touch = touchDevice(); - wl_resource *resource = touch->focus_resource; - if (resource) - wl_touch_send_frame(resource); + m_touch->sendFrame(); } void InputDevice::sendTouchCancelEvent() { - ::wl_touch *touch = touchDevice(); - wl_resource *resource = touch->focus_resource; - if (resource) - wl_touch_send_cancel(resource); + m_touch->sendCancel(); } void InputDevice::sendFullKeyEvent(QKeyEvent *event) @@ -426,9 +198,9 @@ void InputDevice::sendFullKeyEvent(QKeyEvent *event) return; if (event->type() == QEvent::KeyPress) - sendKeyPressEvent(event->nativeScanCode()); + m_keyboard->sendKeyPressEvent(event->nativeScanCode()); else if (event->type() == QEvent::KeyRelease) - sendKeyReleaseEvent(event->nativeScanCode()); + m_keyboard->sendKeyReleaseEvent(event->nativeScanCode()); } void InputDevice::sendFullTouchEvent(QTouchEvent *event) @@ -464,7 +236,7 @@ void InputDevice::sendFullTouchEvent(QTouchEvent *event) Surface *InputDevice::keyboardFocus() const { - return static_cast<Surface *>(keyboardDevice()->focus); + return m_keyboard->focus(); } /*! @@ -476,31 +248,22 @@ bool InputDevice::setKeyboardFocus(Surface *surface) return false; sendSelectionFocus(surface); - wl_keyboard_set_focus(keyboardDevice(), surface); + m_keyboard->setFocus(surface); return true; } Surface *InputDevice::mouseFocus() const { - return static_cast<Surface *>(pointerDevice()->focus); + return m_pointer->focusSurface(); } void InputDevice::setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos) { - ::wl_pointer *pointer = pointerDevice(); - pointer->x = wl_fixed_from_double(globalPos.x()); - pointer->y = wl_fixed_from_double(globalPos.y()); - pointer->current = surface; - pointer->current_x = wl_fixed_from_double(localPos.x()); - pointer->current_y = wl_fixed_from_double(localPos.y()); - pointer->grab->interface->focus(pointer->grab, surface, - wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); + m_pointer->setMouseFocus(surface, localPos, globalPos); // We have no separate touch focus management so make it match the pointer focus always. // No wl_touch_set_focus() is available so set it manually. - ::wl_touch *touch = touchDevice(); - touch->focus = surface; - touch->focus_resource = Compositor::resourceForSurface(&touch->resource_list, surface); + m_touch->setFocus(surface); } void InputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev) @@ -544,35 +307,6 @@ QWaylandInputDevice *InputDevice::handle() const return m_handle; } -uint32_t InputDevice::toWaylandButton(Qt::MouseButton button) -{ -#ifndef BTN_LEFT - uint32_t BTN_LEFT = 0x110; -#endif - // the range of valid buttons (evdev module) is from 0x110 - // through 0x11f. 0x120 is the first 'Joystick' button. - switch (button) { - case Qt::LeftButton: return BTN_LEFT; - case Qt::RightButton: return uint32_t(0x111); - case Qt::MiddleButton: return uint32_t(0x112); - case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 - case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 - case Qt::ExtraButton3: return uint32_t(0x115); - case Qt::ExtraButton4: return uint32_t(0x116); - case Qt::ExtraButton5: return uint32_t(0x117); - case Qt::ExtraButton6: return uint32_t(0x118); - case Qt::ExtraButton7: return uint32_t(0x119); - case Qt::ExtraButton8: return uint32_t(0x11a); - case Qt::ExtraButton9: return uint32_t(0x11b); - case Qt::ExtraButton10: return uint32_t(0x11c); - case Qt::ExtraButton11: return uint32_t(0x11d); - case Qt::ExtraButton12: return uint32_t(0x11e); - case Qt::ExtraButton13: return uint32_t(0x11f); - // default should not occur; but if it does, then return Wayland's highest possible button number. - default: return uint32_t(0x11f); - } -} - DataDevice *InputDevice::dataDevice(struct wl_client *client) const { for (int i = 0; i < m_data_devices.size();i++) { diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h index fd1b0fb4..8ad8a0a7 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h @@ -45,6 +45,7 @@ #include <QtCore/QList> #include <QtCore/QPoint> +#include <QtCore/QScopedPointer> #ifndef QT_NO_WAYLAND_XKB #include <xkbcommon/xkbcommon.h> @@ -64,8 +65,11 @@ class Compositor; class DataDevice; class Surface; class DataDeviceManager; +class Pointer; +class Keyboard; +class Touch; -class InputDevice : public QtWaylandServer::wl_seat, public QtWaylandServer::wl_pointer, public QtWaylandServer::wl_keyboard, public QtWaylandServer::wl_touch +class InputDevice : public QtWaylandServer::wl_seat, public QtWaylandServer::wl_touch { public: InputDevice(QWaylandInputDevice *handle, Compositor *compositor); @@ -77,9 +81,6 @@ public: void sendMouseMoveEvent(Surface *surface, const QPointF &localPos, const QPointF &globalPos = QPointF()); void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - void sendKeyPressEvent(uint code); - void sendKeyReleaseEvent(uint code); - void sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state); void sendTouchFrameEvent(); void sendTouchCancelEvent(); @@ -100,13 +101,13 @@ public: Compositor *compositor() const; QWaylandInputDevice *handle() const; - ::wl_pointer *pointerDevice(); - ::wl_keyboard *keyboardDevice(); - ::wl_touch *touchDevice(); + Pointer *pointerDevice(); + Keyboard *keyboardDevice(); + Touch *touchDevice(); - const ::wl_pointer *pointerDevice() const; - const ::wl_keyboard *keyboardDevice() const; - const ::wl_touch *touchDevice() const; + const Pointer *pointerDevice() const; + const Keyboard *keyboardDevice() const; + const Touch *touchDevice() const; static InputDevice *fromSeatResource(struct ::wl_resource *resource) { @@ -114,44 +115,18 @@ public: } private: - void initDevices(); - void releaseDevices(); void cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev); - void updateModifierState(uint key, int state); - void sendKeyModifiers(wl_resource *resource); QWaylandInputDevice *m_handle; Compositor *m_compositor; QList<DataDevice *> m_data_devices; - struct { - ::wl_pointer pointer; - ::wl_keyboard keyboard; - ::wl_touch touch; - } m_device_interfaces; - - ::wl_seat m_seat; - -#ifndef QT_NO_WAYLAND_XKB - struct xkb_keymap *m_keymap; - struct xkb_state *m_state; - int m_keymap_fd; - size_t m_keymap_size; - char *m_keymap_area; -#endif - - uint32_t toWaylandButton(Qt::MouseButton button); + QScopedPointer<Pointer> m_pointer; + QScopedPointer<Keyboard> m_keyboard; + QScopedPointer<Touch> m_touch; void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; - void pointer_set_cursor(wl_pointer::Resource *resource, - uint32_t serial, - struct wl_resource *surface, - int32_t hotspot_x, - int32_t hotspot_y) Q_DECL_OVERRIDE; - - void keyboard_bind_resource(wl_keyboard::Resource *resource) Q_DECL_OVERRIDE; - void seat_get_pointer(wl_seat::Resource *resource, uint32_t id) Q_DECL_OVERRIDE; void seat_get_keyboard(wl_seat::Resource *resource, diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp new file mode 100644 index 00000000..54349e30 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** 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 "qwlkeyboard_p.h" + +#include <QFile> +#include <QStandardPaths> + +#include "qwlcompositor_p.h" +#include "qwlsurface_p.h" + +#include <fcntl.h> +#include <unistd.h> +#ifndef QT_NO_WAYLAND_XKB +#include <sys/mman.h> +#include <sys/types.h> +#endif + +namespace QtWayland { + +Keyboard::Keyboard(Compositor *compositor, InputDevice *seat) + : QtWaylandServer::wl_keyboard() + , m_compositor(compositor) + , m_seat(seat) + , m_focus() + , m_focusResource() + , m_keys() + , m_modsDepressed() + , m_modsLatched() + , m_modsLocked() + , m_group() +{ +#ifndef QT_NO_WAYLAND_XKB + initXKB(); +#endif +} + +Keyboard::~Keyboard() +{ +#ifndef QT_NO_WAYLAND_XKB + if (m_keymap_area) + munmap(m_keymap_area, m_keymap_size); + close(m_keymap_fd); + xkb_state_unref(m_state); +#endif +} + +void Keyboard::setFocus(Surface *surface) +{ + if (m_focusResource && m_focus != surface) { + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); + } + + Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; + + if (resource && (m_focus != surface || m_focusResource != resource)) { + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_modifiers(resource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); + send_enter(resource->handle, serial, surface->resource()->handle, m_keys); + } + + m_focusResource = resource; + m_focus = surface; +} + +void Keyboard::sendKeyModifiers(wl_keyboard::Resource *resource, uint32_t serial) +{ + send_modifiers(resource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); +} + +void Keyboard::sendKeyPressEvent(uint code) +{ + sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_PRESSED); +} + +void Keyboard::sendKeyReleaseEvent(uint code) +{ + sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_RELEASED); +} + +Surface *Keyboard::focus() const +{ + return m_focus; +} + +void Keyboard::keyboard_bind_resource(wl_keyboard::Resource *resource) +{ +#ifndef QT_NO_WAYLAND_XKB + send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + m_keymap_fd, m_keymap_size); +#else + int null_fd = open("/dev/null", O_RDONLY); + send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, + null_fd, 0); + close(null_fd); +#endif +} + +void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource) +{ + if (m_focusResource == resource) + m_focusResource = 0; +} + +void Keyboard::sendKeyEvent(uint code, uint32_t state) +{ + if (m_focusResource) { + uint32_t time = m_compositor->currentTimeMsecs(); + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_key(m_focusResource->handle, serial, time, code - 8, state); + } + updateModifierState(code, state); +} + +void Keyboard::updateModifierState(uint code, uint32_t state) +{ +#ifndef QT_NO_WAYLAND_XKB + xkb_state_update_key(m_state, code, state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); + + uint32_t modsDepressed = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_DEPRESSED); + uint32_t modsLatched = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); + uint32_t modsLocked = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); + uint32_t group = xkb_state_serialize_group(m_state, (xkb_state_component)XKB_STATE_EFFECTIVE); + + if (modsDepressed == m_modsDepressed + && modsLatched == m_modsLatched + && modsLocked == m_modsLocked + && group == m_group) + return; + + m_modsDepressed = modsDepressed; + m_modsLatched = modsLatched; + m_modsLocked = modsLocked; + m_group = group; + + if (m_focusResource) + sendKeyModifiers(m_focusResource, wl_display_next_serial(m_compositor->wl_display())); +#else + Q_UNUSED(code); + Q_UNUSED(state); +#endif +} + +#ifndef QT_NO_WAYLAND_XKB +static int createAnonymousFile(size_t size) +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); + if (path.isEmpty()) + return -1; + + QByteArray name = QFile::encodeName(path + QStringLiteral("/qtwayland-XXXXXX")); + + int fd = mkstemp(name.data()); + if (fd < 0) + return -1; + + long flags = fcntl(fd, F_GETFD); + if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + close(fd); + fd = -1; + } + unlink(name.constData()); + + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) + return -1; + + return fd; +} + +void Keyboard::initXKB() +{ + struct xkb_context *context = xkb_context_new(static_cast<xkb_context_flags>(0)); + + struct xkb_rule_names rule_names = {0, 0, 0, 0, 0}; + struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rule_names, static_cast<xkb_keymap_compile_flags>(0)); + + char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (!keymap_str) + qFatal("Failed to compile global XKB keymap"); + + m_keymap_size = strlen(keymap_str) + 1; + m_keymap_fd = createAnonymousFile(m_keymap_size); + if (m_keymap_fd < 0) + qFatal("Failed to create anonymous file of size %lu", static_cast<unsigned long>(m_keymap_size)); + + m_keymap_area = static_cast<char *>(mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0)); + if (m_keymap_area == MAP_FAILED) { + close(m_keymap_fd); + qFatal("Failed to map shared memory segment"); + } + + strcpy(m_keymap_area, keymap_str); + + m_state = xkb_state_new(keymap); + + xkb_keymap_unref(keymap); + xkb_context_unref(context); +} +#endif + +} // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h new file mode 100644 index 00000000..80b21106 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidi ary(-ies). +** 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 QTWAYLAND_QWLKEYBOARD_P_H +#define QTWAYLAND_QWLKEYBOARD_P_H + +#include <qwayland-server-wayland.h> + +#include <QtCore/QByteArray> + +#ifndef QT_NO_WAYLAND_XKB +#include <xkbcommon/xkbcommon.h> +#endif + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; +class InputDevice; +class Surface; + +class Keyboard : public QtWaylandServer::wl_keyboard +{ +public: + Keyboard(Compositor *compositor, InputDevice *seat); + ~Keyboard(); + + void setFocus(Surface *surface); + + void sendKeyModifiers(Resource *resource, uint32_t serial); + void sendKeyPressEvent(uint code); + void sendKeyReleaseEvent(uint code); + + Surface *focus() const; + +protected: + void keyboard_bind_resource(Resource *resource); + void keyboard_destroy_resource(Resource *resource); + +private: + void sendKeyEvent(uint code, uint32_t state); + void updateModifierState(uint code, uint32_t state); + +#ifndef QT_NO_WAYLAND_XKB + void initXKB(); +#endif + + Compositor *m_compositor; + InputDevice *m_seat; + + Surface *m_focus; + Resource *m_focusResource; + + QByteArray m_keys; + uint32_t m_modsDepressed; + uint32_t m_modsLatched; + uint32_t m_modsLocked; + uint32_t m_group; + +#ifndef QT_NO_WAYLAND_XKB + size_t m_keymap_size; + int m_keymap_fd; + char *m_keymap_area; + struct xkb_state *m_state; +#endif +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLKEYBOARD_P_H diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp index bb516f8c..e5123e03 100644 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ b/src/compositor/wayland_wrapper/qwloutput.cpp @@ -44,8 +44,6 @@ #include <QtGui/QScreen> #include <QRect> -#include "qwaylandresourcecollection.h" - QT_BEGIN_NAMESPACE namespace QtWayland { @@ -57,7 +55,7 @@ OutputGlobal::OutputGlobal(struct ::wl_display *display) { QScreen *screen = QGuiApplication::primaryScreen(); m_geometry = QRect(QPoint(0, 0), screen->availableGeometry().size()); - m_refreshRate = qRound(screen->refreshRate()); + m_refreshRate = qRound(screen->refreshRate() * 1000.0); } OutputGlobal::~OutputGlobal() @@ -85,7 +83,7 @@ void OutputGlobal::setRefreshRate(int rate) Output *OutputGlobal::outputForClient(wl_client *client) const { - return static_cast<Output *>(resourceForClient(resourceList(), client)->data); + return static_cast<Output *>(resourceMap().value(client)); } } // namespace Wayland diff --git a/src/compositor/wayland_wrapper/qwlpointer.cpp b/src/compositor/wayland_wrapper/qwlpointer.cpp new file mode 100644 index 00000000..e1e1305e --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlpointer.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** 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 "qwlpointer_p.h" + +#include "qwlcompositor_p.h" +#include "qwlinputdevice_p.h" +#include "qwlkeyboard_p.h" +#include "qwlsurface_p.h" +#include "qwaylandcompositor.h" + +namespace QtWayland { + +using QtWaylandServer::wl_keyboard; + +static uint32_t toWaylandButton(Qt::MouseButton button) +{ +#ifndef BTN_LEFT + uint32_t BTN_LEFT = 0x110; +#endif + // the range of valid buttons (evdev module) is from 0x110 + // through 0x11f. 0x120 is the first 'Joystick' button. + switch (button) { + case Qt::LeftButton: return BTN_LEFT; + case Qt::RightButton: return uint32_t(0x111); + case Qt::MiddleButton: return uint32_t(0x112); + case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 + case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 + case Qt::ExtraButton3: return uint32_t(0x115); + case Qt::ExtraButton4: return uint32_t(0x116); + case Qt::ExtraButton5: return uint32_t(0x117); + case Qt::ExtraButton6: return uint32_t(0x118); + case Qt::ExtraButton7: return uint32_t(0x119); + case Qt::ExtraButton8: return uint32_t(0x11a); + case Qt::ExtraButton9: return uint32_t(0x11b); + case Qt::ExtraButton10: return uint32_t(0x11c); + case Qt::ExtraButton11: return uint32_t(0x11d); + case Qt::ExtraButton12: return uint32_t(0x11e); + case Qt::ExtraButton13: return uint32_t(0x11f); + // default should not occur; but if it does, then return Wayland's highest possible button number. + default: return uint32_t(0x11f); + } +} + +Pointer::Pointer(Compositor *compositor, InputDevice *seat) + : wl_pointer() + , PointerGrabber() + , m_compositor(compositor) + , m_seat(seat) + , m_grab(this) + , m_position(100, 100) + , m_focus() + , m_focusResource() + , m_current() + , m_currentPoint() + , m_buttonCount() +{ +} + +void Pointer::setFocus(Surface *surface, const QPointF &position) +{ + if (m_focusResource && m_focus != surface) { + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); + } + + Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; + + if (resource && (m_focus != surface || resource != m_focusResource)) { + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + Keyboard *keyboard = m_seat->keyboardDevice(); + if (keyboard) { + wl_keyboard::Resource *kr = keyboard->resourceMap().value(surface->resource()->client()); + if (kr) + keyboard->sendKeyModifiers(kr, serial); + } + send_enter(resource->handle, serial, surface->resource()->handle, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); + } + + m_focusResource = resource; + m_focus = surface; +} + +void Pointer::startGrab(PointerGrabber *grab) +{ + m_grab = grab; + grab->m_pointer = this; + + if (m_current) + grab->focus(); +} + +void Pointer::endGrab() +{ + m_grab = this; + m_grab->focus(); +} + +void Pointer::setCurrent(Surface *surface, const QPointF &point) +{ + m_current = surface; + m_currentPoint = point; +} + +bool Pointer::buttonPressed() const +{ + return m_buttonCount > 0; +} + +Surface *Pointer::focusSurface() const +{ + return m_focus; +} + +Surface *Pointer::current() const +{ + return m_current; +} + +QPointF Pointer::position() const +{ + return m_position; +} + +void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource) +{ + if (m_focusResource == resource) + m_focusResource = 0; +} + +void Pointer::setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos) +{ + m_position = globalPos; + + m_current = surface; + m_currentPoint = localPos; + + m_grab->focus(); +} + +void Pointer::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) +{ + sendMouseMoveEvent(localPos, globalPos); + m_buttonCount++; + uint32_t time = m_compositor->currentTimeMsecs(); + m_grab->button(time, button, WL_POINTER_BUTTON_STATE_PRESSED); +} + +void Pointer::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) +{ + sendMouseMoveEvent(localPos, globalPos); + m_buttonCount--; + uint32_t time = m_compositor->currentTimeMsecs(); + m_grab->button(time, button, WL_POINTER_BUTTON_STATE_RELEASED); +} + +void Pointer::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) +{ + uint32_t time = m_compositor->currentTimeMsecs(); + + m_position = globalPos; + m_currentPoint = localPos; + + m_grab->motion(time); +} + +void Pointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta) +{ + if (!m_focusResource) + return; + + uint32_t time = m_compositor->currentTimeMsecs(); + uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL + : WL_POINTER_AXIS_VERTICAL_SCROLL; + send_axis(m_focusResource->handle, time, axis, wl_fixed_from_int(-delta / 12)); +} + +void Pointer::focus() +{ + if (buttonPressed()) + return; + + setFocus(m_current, m_currentPoint); +} + +void Pointer::motion(uint32_t time) +{ + if (m_focusResource) + send_motion(m_focusResource->handle, time, + wl_fixed_from_double(m_currentPoint.x()), + wl_fixed_from_double(m_currentPoint.y())); + +} + +void Pointer::button(uint32_t time, Qt::MouseButton button, uint32_t state) +{ + if (m_focusResource) { + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_button(m_focusResource->handle, serial, time, toWaylandButton(button), state); + } + + if (!buttonPressed() && state == WL_POINTER_BUTTON_STATE_RELEASED) + setFocus(m_current, m_currentPoint); +} + +void Pointer::pointer_set_cursor(wl_pointer::Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + if (!surface) { + m_compositor->waylandCompositor()->setCursorSurface(NULL, 0, 0); + return; + } + + Surface *s = Surface::fromResource(surface); + s->setCursorSurface(true); + m_compositor->waylandCompositor()->setCursorSurface(s->waylandSurface(), hotspot_x, hotspot_y); +} + +PointerGrabber::~PointerGrabber() +{ +} + +} // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwlpointer_p.h b/src/compositor/wayland_wrapper/qwlpointer_p.h new file mode 100644 index 00000000..f6db2dcb --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlpointer_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** 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 QTWAYLAND_QWLPOINTER_P_H +#define QTWAYLAND_QWLPOINTER_P_H + +#include <QtCore/QList> +#include <QtCore/QPoint> + +#include <qwayland-server-wayland.h> + +#include <stdint.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; +class InputDevice; +class Pointer; +class Surface; + +class PointerGrabber { +public: + virtual ~PointerGrabber(); + + virtual void focus() = 0; + virtual void motion(uint32_t time) = 0; + virtual void button(uint32_t time, Qt::MouseButton button, uint32_t state) = 0; + + Pointer *m_pointer; +}; + +class Pointer : public QtWaylandServer::wl_pointer, public PointerGrabber +{ +public: + Pointer(Compositor *compositor, InputDevice *seat); + + void setFocus(Surface *surface, const QPointF &position); + + void startGrab(PointerGrabber *grab); + void endGrab(); + + void setCurrent(Surface *surface, const QPointF &point); + void setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos); + + void sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); + void sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); + void sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos); + void sendMouseWheelEvent(Qt::Orientation orientation, int delta); + + Surface *focusSurface() const; + Surface *current() const; + QPointF position() const; + + void focus() Q_DECL_OVERRIDE; + void motion(uint32_t time) Q_DECL_OVERRIDE; + void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; + +protected: + void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) Q_DECL_OVERRIDE; + void pointer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + +private: + bool buttonPressed() const; + + Compositor *m_compositor; + InputDevice *m_seat; + + PointerGrabber *m_grab; + + QPointF m_position; + + Surface *m_focus; + Resource *m_focusResource; + + Surface *m_current; + QPointF m_currentPoint; + + int m_buttonCount; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLPOINTER_P_H diff --git a/src/compositor/wayland_wrapper/qwlqtkey.cpp b/src/compositor/wayland_wrapper/qwlqtkey.cpp index 6ced2788..a2b99ebc 100644 --- a/src/compositor/wayland_wrapper/qwlqtkey.cpp +++ b/src/compositor/wayland_wrapper/qwlqtkey.cpp @@ -57,14 +57,12 @@ QtKeyExtensionGlobal::QtKeyExtensionGlobal(Compositor *compositor) bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, Surface *surface) { - wl_client *surfaceClient = surface->resource()->client(); - uint32_t time = m_compositor->currentTimeMsecs(); - struct wl_resource *target = resourceForClient(resourceList(), surfaceClient); + Resource *target = surface ? resourceMap().value(surface->resource()->client()) : 0; if (target) { - send_qtkey(target, + send_qtkey(target->handle, time, event->type(), event->key(), event->modifiers(), event->nativeScanCode(), event->nativeVirtualKey(), diff --git a/src/compositor/wayland_wrapper/qwlqttouch.cpp b/src/compositor/wayland_wrapper/qwlqttouch.cpp new file mode 100644 index 00000000..2b97bef7 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlqttouch.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** 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 "qwlqttouch_p.h" +#include "qwlsurface_p.h" +#include <QTouchEvent> +#include <QWindow> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +static const int maxRawPos = 24; + +TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor) + : QtWaylandServer::qt_touch_extension(compositor->wl_display()) + , m_compositor(compositor) + , m_flags(0) + , m_resources() + , m_posData(maxRawPos * 2) +{ +} + +TouchExtensionGlobal::~TouchExtensionGlobal() +{ +} + +static inline int toFixed(qreal f) +{ + return int(f * 10000); +} + +bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, Surface *surface) +{ + const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); + const int pointCount = points.count(); + if (!pointCount) + return false; + + QPointF surfacePos = surface->pos(); + wl_client *surfaceClient = surface->resource()->client(); + uint32_t time = m_compositor->currentTimeMsecs(); + const int rescount = m_resources.count(); + + for (int res = 0; res < rescount; ++res) { + Resource *target = m_resources.at(res); + if (target->client() != surfaceClient) + continue; + + // We will use no touch_frame type of event, to reduce the number of + // events flowing through the wire. Instead, the number of points sent is + // included in the touch point events. + int sentPointCount = 0; + for (int i = 0; i < pointCount; ++i) { + if (points.at(i).state() != Qt::TouchPointStationary) + ++sentPointCount; + } + + for (int i = 0; i < pointCount; ++i) { + const QTouchEvent::TouchPoint &tp(points.at(i)); + // Stationary points are never sent. They are cached on client side. + if (tp.state() == Qt::TouchPointStationary) + continue; + + uint32_t id = tp.id(); + uint32_t state = (tp.state() & 0xFFFF) | (sentPointCount << 16); + uint32_t flags = (tp.flags() & 0xFFFF) | (int(event->device()->capabilities()) << 16); + + QPointF p = tp.pos() - surfacePos; // surface-relative + int x = toFixed(p.x()); + int y = toFixed(p.y()); + int nx = toFixed(tp.normalizedPos().x()); + int ny = toFixed(tp.normalizedPos().y()); + int w = toFixed(tp.rect().width()); + int h = toFixed(tp.rect().height()); + int vx = toFixed(tp.velocity().x()); + int vy = toFixed(tp.velocity().y()); + uint32_t pressure = uint32_t(tp.pressure() * 255); + + QByteArray rawData; + QVector<QPointF> rawPosList = tp.rawScreenPositions(); + int rawPosCount = rawPosList.count(); + if (rawPosCount) { + rawPosCount = qMin(maxRawPos, rawPosCount); + QVector<float>::iterator iter = m_posData.begin(); + for (int rpi = 0; rpi < rawPosCount; ++rpi) { + const QPointF &rawPos(rawPosList.at(rpi)); + // This will stay in screen coordinates for performance + // reasons, clients using this data will presumably know + // what they are doing. + *iter++ = static_cast<float>(rawPos.x()); + *iter++ = static_cast<float>(rawPos.y()); + } + rawData = QByteArray::fromRawData(reinterpret_cast<const char*>(m_posData.constData()), sizeof(float) * rawPosCount * 2); + } + + send_touch(target->handle, + time, id, state, + x, y, nx, ny, w, h, + pressure, vx, vy, + flags, rawData); + } + + return true; + } + + return false; +} + +void TouchExtensionGlobal::touch_extension_bind_resource(Resource *resource) +{ + m_resources.append(resource); + send_configure(resource->handle, m_flags); +} + +void TouchExtensionGlobal::touch_extension_destroy_resource(Resource *resource) +{ + m_resources.removeOne(resource); +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/global/qwaylandobject.h b/src/compositor/wayland_wrapper/qwlqttouch_p.h index 9b345039..2610936a 100644 --- a/src/compositor/global/qwaylandobject.h +++ b/src/compositor/wayland_wrapper/qwlqttouch_p.h @@ -38,32 +38,44 @@ ** ****************************************************************************/ -#ifndef WAYLAND_OBJECT_H -#define WAYLAND_OBJECT_H +#ifndef WLTOUCH_H +#define WLTOUCH_H -#include <wayland-server.h> -#include <string.h> - -#include <QtCompositor/qwaylandexport.h> +#include <private/qwlcompositor_p.h> +#include "qwayland-server-touch-extension.h" +#include "wayland-util.h" QT_BEGIN_NAMESPACE +class Compositor; +class Surface; +class QTouchEvent; + namespace QtWayland { -template <typename T> -class Object : public T +class TouchExtensionGlobal : public QtWaylandServer::qt_touch_extension { public: - typedef T Base; + TouchExtensionGlobal(Compositor *compositor); + ~TouchExtensionGlobal(); + + bool postTouchEvent(QTouchEvent *event, Surface *surface); + + void setFlags(int flags) { m_flags = flags; } - Object() { memset(this, 0, sizeof(T)); } +protected: + void touch_extension_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void touch_extension_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - const T *base() const { return this; } - T *base() { return this; } +private: + Compositor *m_compositor; + int m_flags; + QList<Resource *> m_resources; + QVector<float> m_posData; }; } QT_END_NAMESPACE -#endif //WAYLAND_OBJECT_H +#endif // WLTOUCH_H diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp index 903b4259..a1e6bb37 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp @@ -44,6 +44,8 @@ #include "qwlsurface_p.h" #include "qwlinputdevice_p.h" #include "qwlsubsurface_p.h" +#include "qwlpointer_p.h" +#include "qwlextendedsurface_p.h" #include <QtCore/qglobal.h> #include <QtCore/QDebug> @@ -106,8 +108,8 @@ void ShellSurface::adjustPosInResize() if (!m_resizeGrabber || !(m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT)) return; - int bottomLeftX = wl_fixed_to_int(m_resizeGrabber->base()->x) + m_resizeGrabber->width; - int bottomLeftY = wl_fixed_to_int(m_resizeGrabber->base()->y) + m_resizeGrabber->height; + int bottomLeftX = m_resizeGrabber->point.x() + m_resizeGrabber->width; + int bottomLeftY = m_resizeGrabber->point.y() + m_resizeGrabber->height; qreal x = surface()->pos().x(); qreal y = surface()->pos().y(); if (m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) @@ -166,15 +168,11 @@ void ShellSurface::shell_surface_move(Resource *resource, } InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); - ::wl_pointer *pointer = input_device->pointerDevice(); + Pointer *pointer = input_device->pointerDevice(); - m_moveGrabber = new ShellSurfaceMoveGrabber(this); - m_moveGrabber->base()->x = pointer->x; - m_moveGrabber->base()->y = pointer->y; - m_moveGrabber->offset_x = wl_fixed_to_int(pointer->x) - surface()->pos().x(); - m_moveGrabber->offset_y = wl_fixed_to_int(pointer->y) - surface()->pos().y(); + m_moveGrabber = new ShellSurfaceMoveGrabber(this, pointer->position() - surface()->pos()); - wl_pointer_start_grab(pointer, m_moveGrabber->base()); + pointer->startGrab(m_moveGrabber); } void ShellSurface::shell_surface_resize(Resource *resource, @@ -194,15 +192,14 @@ void ShellSurface::shell_surface_resize(Resource *resource, m_resizeGrabber = new ShellSurfaceResizeGrabber(this); InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); - ::wl_pointer *pointer = input_device->pointerDevice(); + Pointer *pointer = input_device->pointerDevice(); - m_resizeGrabber->base()->x = pointer->x; - m_resizeGrabber->base()->y = pointer->y; - m_resizeGrabber->resize_edges = wl_shell_surface_resize(edges); + m_resizeGrabber->point = pointer->position(); + m_resizeGrabber->resize_edges = static_cast<wl_shell_surface_resize>(edges); m_resizeGrabber->width = surface()->size().width(); m_resizeGrabber->height = surface()->size().height(); - wl_pointer_start_grab(pointer, m_resizeGrabber->base()); + pointer->startGrab(m_resizeGrabber); } void ShellSurface::shell_surface_set_toplevel(Resource *resource) @@ -212,6 +209,8 @@ void ShellSurface::shell_surface_set_toplevel(Resource *resource) m_xOffset = 0; m_yOffset = 0; + if (m_surface->extendedSurface()) + m_surface->extendedSurface()->setVisibility(QWindow::Windowed, false); } void ShellSurface::shell_surface_set_transient(Resource *resource, @@ -229,6 +228,9 @@ void ShellSurface::shell_surface_set_transient(Resource *resource, m_yOffset = y; if (flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE) surface()->setTransientInactive(true); + + if (m_surface->extendedSurface()) + m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false); } void ShellSurface::shell_surface_set_fullscreen(Resource *resource, @@ -240,6 +242,11 @@ void ShellSurface::shell_surface_set_fullscreen(Resource *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()); + + if (m_surface->extendedSurface()) + m_surface->extendedSurface()->setVisibility(QWindow::FullScreen, false); } void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t time, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) @@ -251,6 +258,9 @@ void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *inpu Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(flags); + + if (m_surface->extendedSurface()) + m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false); } void ShellSurface::shell_surface_set_maximized(Resource *resource, @@ -258,6 +268,11 @@ void ShellSurface::shell_surface_set_maximized(Resource *resource, { Q_UNUSED(resource); Q_UNUSED(output); + QSize defaultScreenSize = m_surface->compositor()->outputGeometry().size(); + send_configure(resize_bottom_right, defaultScreenSize.width(), defaultScreenSize.height()); + + if (m_surface->extendedSurface()) + m_surface->extendedSurface()->setVisibility(QWindow::Maximized, false); } void ShellSurface::shell_surface_pong(Resource *resource, @@ -281,175 +296,91 @@ void ShellSurface::shell_surface_set_class(Resource *resource, surface()->setClassName(className); } -Qt::MouseButton toQtButton(uint32_t button) -{ -#ifndef BTN_LEFT - static const uint32_t BTN_LEFT = 0x110; - static const uint32_t BTN_RIGHT = 0x111; - static const uint32_t BTN_MIDDLE = 0x112; -#endif - switch (button) { - case BTN_LEFT: - return Qt::LeftButton; - case BTN_RIGHT: - return Qt::RightButton; - case BTN_MIDDLE: - return Qt::MiddleButton; - default: - return Qt::NoButton; - } -} - -ShellSurfaceGrabber::ShellSurfaceGrabber(ShellSurface *shellSurface, const struct wl_pointer_grab_interface *interface) - : shell_surface(shellSurface) +ShellSurfaceGrabber::ShellSurfaceGrabber(ShellSurface *shellSurface) + : PointerGrabber() + , shell_surface(shellSurface) { - base()->interface = interface; - base()->focus = shell_surface->surface(); } ShellSurfaceGrabber::~ShellSurfaceGrabber() { } - -void ShellSurfaceGrabber::destroy(wl_listener *listener, wl_resource *resource, uint32_t time) -{ - Q_UNUSED(resource); - Q_UNUSED(time); - Q_UNUSED(listener); - //ShellSurfaceGrabber *shell_surface_grabber = container_of(listener, ShellSurfaceGrabber,surface_destroy_listener); - Q_ASSERT(false); //hasn't been enabled yet - //wl_input_device_end_grab(shell_surface_grabber->base()->input_device,Compositor::currentTimeMsecs()); -} - - ShellSurfaceResizeGrabber::ShellSurfaceResizeGrabber(ShellSurface *shellSurface) - : ShellSurfaceGrabber(shellSurface,&resize_grabber_interface) + : ShellSurfaceGrabber(shellSurface) { } -void ShellSurfaceResizeGrabber::focus(wl_pointer_grab *grab, wl_surface *surface, int32_t x, int32_t y) +void ShellSurfaceResizeGrabber::focus() { - Q_UNUSED(grab); - Q_UNUSED(surface); - Q_UNUSED(x); - Q_UNUSED(y); } -void ShellSurfaceResizeGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32_t x, int32_t y) +void ShellSurfaceResizeGrabber::motion(uint32_t time) { Q_UNUSED(time); - Q_UNUSED(x); - Q_UNUSED(y); - //Should be more structured - ShellSurfaceResizeGrabber *resize_grabber = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab); - ShellSurface *shell_surface = resize_grabber->shell_surface; - wl_pointer *pointer = grab->pointer; - int width_delta = wl_fixed_to_int(grab->x) - wl_fixed_to_int(pointer->x); - int height_delta = wl_fixed_to_int(grab->y) - wl_fixed_to_int(pointer->y); - int new_width = resize_grabber->width; - int new_height = resize_grabber->height; - if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT) { - if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) { - if (new_height + height_delta > 0) { - new_height += height_delta; - } else { - new_height = 1; - } - } - if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT) { - if (new_width + width_delta > 0) { - new_width += width_delta; - } else { - new_width = 1; - } - } - } - if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) { - if (new_height - height_delta > 0) { - new_height -= height_delta; - } else { - new_height = 1; - } - } - if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_RIGHT) { - if (new_width - width_delta > 0) { - new_width -= width_delta; - } else { - new_width =1; - } - } + int width_delta = point.x() - m_pointer->position().x(); + int height_delta = point.y() - m_pointer->position().y(); + + int new_height = height; + if (resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) + new_height = qMax(new_height + height_delta, 1); + else if (resize_edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) + new_height = qMax(new_height - height_delta, 1); - shell_surface->sendConfigure(resize_grabber->resize_edges,new_width,new_height); + int new_width = width; + if (resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT) + new_width = qMax(new_width + width_delta, 1); + else if (resize_edges & WL_SHELL_SURFACE_RESIZE_RIGHT) + new_width = qMax(new_width - width_delta, 1); + + shell_surface->sendConfigure(resize_edges, new_width, new_height); } -void ShellSurfaceResizeGrabber::button(wl_pointer_grab *grab, uint32_t time, uint32_t button, uint32_t state) +void ShellSurfaceResizeGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) { Q_UNUSED(time) - ShellSurfaceResizeGrabber *self = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab); - ShellSurface *shell_surface = self->shell_surface; - if (toQtButton(button) == Qt::LeftButton && !state) { - wl_pointer_end_grab(grab->pointer); + + if (button == Qt::LeftButton && !state) { + m_pointer->endGrab(); shell_surface->resetResizeGrabber(); - delete self; + delete this; } } -const struct wl_pointer_grab_interface ShellSurfaceResizeGrabber::resize_grabber_interface = { - ShellSurfaceResizeGrabber::focus, - ShellSurfaceResizeGrabber::motion, - ShellSurfaceResizeGrabber::button -}; - -ShellSurfaceMoveGrabber::ShellSurfaceMoveGrabber(ShellSurface *shellSurface) - : ShellSurfaceGrabber(shellSurface,&move_grabber_interface) +ShellSurfaceMoveGrabber::ShellSurfaceMoveGrabber(ShellSurface *shellSurface, const QPointF &offset) + : ShellSurfaceGrabber(shellSurface) + , m_offset(offset) { } -void ShellSurfaceMoveGrabber::focus(wl_pointer_grab *grab, wl_surface *surface, int32_t x, int32_t y) +void ShellSurfaceMoveGrabber::focus() { - Q_UNUSED(grab); - Q_UNUSED(surface); - Q_UNUSED(x); - Q_UNUSED(y); } -void ShellSurfaceMoveGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32_t x, int32_t y) +void ShellSurfaceMoveGrabber::motion(uint32_t time) { Q_UNUSED(time); - Q_UNUSED(x); - Q_UNUSED(y); - ShellSurfaceMoveGrabber *shell_surface_grabber = reinterpret_cast<ShellSurfaceMoveGrabber *>(grab); - ShellSurface *shell_surface = shell_surface_grabber->shell_surface; - wl_pointer *pointer = grab->pointer; - QPointF pos(wl_fixed_to_int(pointer->x) - shell_surface_grabber->offset_x, - wl_fixed_to_int(pointer->y) - shell_surface_grabber->offset_y); + + QPointF pos(m_pointer->position() - m_offset); shell_surface->surface()->setPos(pos); if (shell_surface->transientParent()) shell_surface->setOffset(pos - shell_surface->transientParent()->surface()->pos()); } -void ShellSurfaceMoveGrabber::button(wl_pointer_grab *grab, uint32_t time, uint32_t button, uint32_t state) +void ShellSurfaceMoveGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) { Q_UNUSED(time) - ShellSurfaceResizeGrabber *self = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab); - ShellSurface *shell_surface = self->shell_surface; - if (toQtButton(button) == Qt::LeftButton && !state) { - wl_pointer_set_focus(grab->pointer, 0, 0, 0); - wl_pointer_end_grab(grab->pointer); + + if (button == Qt::LeftButton && !state) { + m_pointer->setFocus(0, QPointF()); + m_pointer->endGrab(); shell_surface->resetMoveGrabber(); - delete self; + delete this; } } -const struct wl_pointer_grab_interface ShellSurfaceMoveGrabber::move_grabber_interface = { - ShellSurfaceMoveGrabber::focus, - ShellSurfaceMoveGrabber::motion, - ShellSurfaceMoveGrabber::button -}; - } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h index 4c296a97..91fb17c2 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlshellsurface_p.h @@ -42,8 +42,8 @@ #define WLSHELLSURFACE_H #include <wayland-server.h> -#include <qwaylandobject.h> #include <QPoint> +#include <private/qwlpointer_p.h> #include <qwayland-server-wayland.h> @@ -136,16 +136,12 @@ private: const QString &class_) Q_DECL_OVERRIDE; }; -class ShellSurfaceGrabber : public Object<struct ::wl_pointer_grab> +class ShellSurfaceGrabber : public PointerGrabber { public: - ShellSurfaceGrabber(ShellSurface *shellSurface, const struct wl_pointer_grab_interface *interface); + ShellSurfaceGrabber(ShellSurface *shellSurface); ~ShellSurfaceGrabber(); - struct wl_listener surface_destroy_listener; - static void destroy(struct wl_listener *listener, - struct wl_resource *resource, uint32_t time); - ShellSurface *shell_surface; }; @@ -154,35 +150,27 @@ class ShellSurfaceResizeGrabber : public ShellSurfaceGrabber public: ShellSurfaceResizeGrabber(ShellSurface *shellSurface); - + QPointF point; enum wl_shell_surface_resize resize_edges; int32_t width; int32_t height; - static void focus(struct wl_pointer_grab *grab, - struct wl_surface *surface, int32_t x, int32_t y); - static void motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t x, int32_t y); - static void button(struct wl_pointer_grab *grab, - uint32_t time, uint32_t mouse_grabber_button, uint32_t state); - static const struct wl_pointer_grab_interface resize_grabber_interface; + void focus() Q_DECL_OVERRIDE; + void motion(uint32_t time) Q_DECL_OVERRIDE; + void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; }; class ShellSurfaceMoveGrabber : public ShellSurfaceGrabber { public: - ShellSurfaceMoveGrabber(ShellSurface *shellSurface); - - int32_t offset_x; - int32_t offset_y; - - static void focus(struct wl_pointer_grab *grab, - struct wl_surface *surface, int32_t x, int32_t y); - static void motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t x, int32_t y); - static void button(struct wl_pointer_grab *grab, - uint32_t time, uint32_t mouse_grabber_button, uint32_t state); - static const struct wl_pointer_grab_interface move_grabber_interface; + ShellSurfaceMoveGrabber(ShellSurface *shellSurface, const QPointF &offset); + + void focus() Q_DECL_OVERRIDE; + void motion(uint32_t time) Q_DECL_OVERRIDE; + void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; + +private: + QPointF m_offset; }; } diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index 85dfddb4..f3a9aa4d 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -74,7 +74,7 @@ namespace QtWayland { static bool QT_WAYLAND_PRINT_BUFFERING_WARNINGS = qEnvironmentVariableIsSet("QT_WAYLAND_PRINT_BUFFERING_WARNINGS"); Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) - : QtWaylandServer::wl_surface(client, &base()->resource, id) + : QtWaylandServer::wl_surface(client, id) , m_compositor(compositor) , m_waylandSurface(new QWaylandSurface(this)) , m_backBuffer(0) @@ -95,7 +95,6 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) Surface::~Surface() { delete m_waylandSurface; - delete m_extendedSurface; delete m_subSurface; for (int i = 0; i < buffer_pool_size; i++) { @@ -302,11 +301,9 @@ bool Surface::advanceBufferQueue() if (m_backBuffer && !m_backBuffer->isDisplayed()) return true; if (m_bufferQueue.size()) { - int width = 0; - int height = 0; + QSize size; if (m_backBuffer && m_backBuffer->waylandBufferHandle()) { - width = m_backBuffer->width(); - height = m_backBuffer->height(); + size = m_backBuffer->size(); } if (!m_bufferQueue.first()->isComitted()) @@ -322,10 +319,9 @@ bool Surface::advanceBufferQueue() return false; //we have no new backbuffer; if (m_backBuffer->waylandBufferHandle()) { - width = m_backBuffer->width(); - height = m_backBuffer->height(); + size = m_backBuffer->size(); } - setSize(QSize(width,height)); + setSize(size); if (m_backBuffer && (!m_subSurface || !m_subSurface->parent()) && !m_surfaceMapped) { @@ -364,7 +360,7 @@ void Surface::doUpdate() { } } -SurfaceBuffer *Surface::createSurfaceBuffer(struct wl_buffer *buffer) +SurfaceBuffer *Surface::createSurfaceBuffer(struct ::wl_resource *buffer) { SurfaceBuffer *newBuffer = 0; for (int i = 0; i < Surface::buffer_pool_size; i++) { @@ -400,7 +396,7 @@ bool Surface::postBuffer() { return false; } -void Surface::attach(struct wl_buffer *buffer) +void Surface::attach(struct ::wl_resource *buffer) { SurfaceBuffer *last = m_bufferQueue.size()?m_bufferQueue.last():0; if (last) { @@ -459,7 +455,7 @@ void Surface::surface_attach(Resource *, struct wl_resource *buffer, int x, int Q_UNUSED(x); Q_UNUSED(y); - attach(buffer ? reinterpret_cast<wl_buffer *>(buffer->data) : 0); + attach(buffer); } void Surface::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index 0a4413ae..a4817d7b 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -42,7 +42,6 @@ #define WL_SURFACE_H #include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandobject.h> #include <private/qwlsurfacebuffer_p.h> #include <QtCompositor/qwaylandsurface.h> @@ -74,7 +73,7 @@ class ExtendedSurface; class SubSurface; class ShellSurface; -class Q_COMPOSITOR_EXPORT Surface : public Object<struct ::wl_surface>, public QtWaylandServer::wl_surface +class Q_COMPOSITOR_EXPORT Surface : public QtWaylandServer::wl_surface { public: Surface(struct wl_client *client, uint32_t id, Compositor *compositor); @@ -87,8 +86,6 @@ public: bool visible() const; - uint id() const { return ::wl_surface::resource.object.id; } - using QtWaylandServer::wl_surface::resource; QPointF pos() const; @@ -175,11 +172,11 @@ private: void damage(const QRect &rect); bool advanceBufferQueue(); void doUpdate(); - SurfaceBuffer *createSurfaceBuffer(struct wl_buffer *buffer); + SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer); void frameFinishedInternal(); bool postBuffer(); - void attach(struct wl_buffer *buffer); + void attach(struct ::wl_resource *buffer); void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index 064d7be7..9fafc39c 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -67,7 +67,9 @@ SurfaceBuffer::SurfaceBuffer(Surface *surface) , m_texture(0) , m_guard(0) , m_is_shm_resolved(false) - , m_is_shm(false) + , m_shmBuffer(0) + , m_isSizeResolved(false) + , m_size() , m_image(0) { } @@ -78,7 +80,7 @@ SurfaceBuffer::~SurfaceBuffer() destructBufferState(); } -void SurfaceBuffer::initialize(wl_buffer *buffer) +void SurfaceBuffer::initialize(struct ::wl_resource *buffer) { m_buffer = buffer; m_texture = 0; @@ -91,11 +93,13 @@ void SurfaceBuffer::initialize(wl_buffer *buffer) m_destroyed = false; m_handle = 0; m_is_shm_resolved = false; - m_is_shm = false; + m_shmBuffer = 0; + m_isSizeResolved = false; + m_size = QSize(); m_destroy_listener.surfaceBuffer = this; m_destroy_listener.listener.notify = destroy_listener_callback; if (buffer) - wl_signal_add(&buffer->resource.destroy_signal, &m_destroy_listener.listener); + wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener); m_damageRect = QRect(); } @@ -107,7 +111,7 @@ void SurfaceBuffer::destructBufferState() if (m_buffer) { if (m_handle) { - if (m_is_shm) { + if (m_shmBuffer) { delete static_cast<QImage *>(m_handle); #ifdef QT_COMPOSITOR_WAYLAND_GL } else { @@ -127,20 +131,40 @@ void SurfaceBuffer::destructBufferState() m_image = QImage(); } +QSize SurfaceBuffer::size() const +{ + if (!m_isSizeResolved) { + if (isShmBuffer()) { + m_size = QSize(wl_shm_buffer_get_width(m_shmBuffer), wl_shm_buffer_get_height(m_shmBuffer)); +#ifdef QT_COMPOSITOR_WAYLAND_GL + } else { + QWaylandGraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); + m_size = hwIntegration->bufferSize(m_buffer); +#endif + } + } + + return m_size; +} + bool SurfaceBuffer::isShmBuffer() const { if (!m_is_shm_resolved) { - SurfaceBuffer *that = const_cast<SurfaceBuffer *>(this); - that->m_is_shm = wl_buffer_is_shm(m_buffer); - that->m_is_shm_resolved = true; +#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2) + m_shmBuffer = wl_shm_buffer_get(m_buffer); +#else + if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data))) + m_shmBuffer = static_cast<struct ::wl_buffer*>(m_buffer->data); +#endif + m_is_shm_resolved = true; } - return m_is_shm; + return m_shmBuffer != 0; } void SurfaceBuffer::sendRelease() { Q_ASSERT(m_buffer); - wl_buffer_send_release(&m_buffer->resource); + wl_buffer_send_release(m_buffer); } void SurfaceBuffer::setPageFlipperHasBuffer(bool owns) @@ -221,10 +245,10 @@ void *SurfaceBuffer::handle() const if (!m_handle) { SurfaceBuffer *that = const_cast<SurfaceBuffer *>(this); if (isShmBuffer()) { - const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_buffer)); - int stride = wl_shm_buffer_get_stride(m_buffer); - int width = m_buffer->width; - int height = m_buffer->height; + const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer)); + int stride = wl_shm_buffer_get_stride(m_shmBuffer); + int width = wl_shm_buffer_get_width(m_shmBuffer); + int height = wl_shm_buffer_get_height(m_shmBuffer); QImage *image = new QImage(data,width,height,stride, QImage::Format_ARGB32_Premultiplied); that->m_handle = image; #ifdef QT_COMPOSITOR_WAYLAND_GL @@ -245,10 +269,10 @@ QImage SurfaceBuffer::image() if (m_image.isNull()) { - const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_buffer)); - int stride = wl_shm_buffer_get_stride(m_buffer); - int width = m_buffer->width; - int height = m_buffer->height; + const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer)); + int stride = wl_shm_buffer_get_stride(m_shmBuffer); + int width = wl_shm_buffer_get_width(m_shmBuffer); + int height = wl_shm_buffer_get_height(m_shmBuffer); m_image = QImage(data, width, height, stride, QImage::Format_ARGB32_Premultiplied); } diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 2595f1fd..93627f67 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -72,11 +72,10 @@ public: ~SurfaceBuffer(); - void initialize(struct wl_buffer *buffer); + void initialize(struct ::wl_resource *bufferResource); void destructBufferState(); - inline int32_t width() const { return m_buffer->width; } - inline int32_t height() const { return m_buffer->height; } + QSize size() const; bool isShmBuffer() const; @@ -104,7 +103,7 @@ public: inline GLuint texture() const; void destroyTexture(); - inline struct wl_buffer *waylandBufferHandle() const { return m_buffer; } + inline struct ::wl_resource *waylandBufferHandle() const { return m_buffer; } void handleAboutToBeDisplayed(); void handleDisplayed(); @@ -114,7 +113,7 @@ public: private: Surface *m_surface; Compositor *m_compositor; - struct wl_buffer *m_buffer; + struct ::wl_resource *m_buffer; struct surface_buffer_destroy_listener m_destroy_listener; QRect m_damageRect; bool m_committed; @@ -131,8 +130,16 @@ private: uint m_guard; #endif void *m_handle; - bool m_is_shm_resolved; - bool m_is_shm; + mutable bool m_is_shm_resolved; + +#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2) + mutable struct ::wl_shm_buffer *m_shmBuffer; +#else + mutable struct ::wl_buffer *m_shmBuffer; +#endif + + mutable bool m_isSizeResolved; + mutable QSize m_size; QImage m_image; diff --git a/src/compositor/wayland_wrapper/qwltouch.cpp b/src/compositor/wayland_wrapper/qwltouch.cpp index 7142c985..e595440d 100644 --- a/src/compositor/wayland_wrapper/qwltouch.cpp +++ b/src/compositor/wayland_wrapper/qwltouch.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Compositor. @@ -39,142 +40,66 @@ ****************************************************************************/ #include "qwltouch_p.h" -#include "qwlsurface_p.h" -#include <QTouchEvent> -#include <QWindow> -QT_BEGIN_NAMESPACE +#include "qwlcompositor_p.h" +#include "qwlsurface_p.h" namespace QtWayland { -static void dummy(wl_client *, wl_resource *) +Touch::Touch(Compositor *compositor) + : wl_touch() + , m_compositor(compositor) + , m_focus() + , m_focusResource() { } -const struct qt_touch_extension_interface TouchExtensionGlobal::touch_interface = { - dummy -}; - -static const int maxRawPos = 24; - -TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor) - : m_compositor(compositor), - m_flags(0) +void Touch::setFocus(Surface *surface) { - wl_array_init(&m_rawdata_array); - m_rawdata_ptr = static_cast<float *>(wl_array_add(&m_rawdata_array, maxRawPos * sizeof(float) * 2)); - - wl_display_add_global(compositor->wl_display(), - &qt_touch_extension_interface, - this, - TouchExtensionGlobal::bind_func); + m_focus = surface; + m_focusResource = surface ? resourceMap().value(surface->resource()->client()) : 0; } -TouchExtensionGlobal::~TouchExtensionGlobal() +void Touch::sendCancel() { - wl_array_release(&m_rawdata_array); + if (m_focusResource) + send_cancel(m_focusResource->handle); } -void TouchExtensionGlobal::destroy_resource(wl_resource *resource) +void Touch::sendFrame() { - TouchExtensionGlobal *self = static_cast<TouchExtensionGlobal *>(resource->data); - self->m_resources.removeOne(resource); - free(resource); + if (m_focusResource) + send_frame(m_focusResource->handle); } -void TouchExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) +void Touch::sendDown(int touch_id, const QPointF &position) { - Q_UNUSED(version); - wl_resource *resource = wl_client_add_object(client, &qt_touch_extension_interface, &touch_interface, id, data); - resource->destroy = destroy_resource; - TouchExtensionGlobal *self = static_cast<TouchExtensionGlobal *>(resource->data); - self->m_resources.append(resource); - qt_touch_extension_send_configure(resource, self->m_flags); + if (!m_focusResource || !m_focus) + return; + + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + + send_down(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), m_focus->resource()->handle, touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); } -static inline int toFixed(qreal f) +void Touch::sendMotion(int touch_id, const QPointF &position) { - return int(f * 10000); + if (!m_focusResource) + return; + + send_motion(m_focusResource->handle, Compositor::currentTimeMsecs(), touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); } -bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, Surface *surface) +void Touch::sendUp(int touch_id) { - const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); - const int pointCount = points.count(); - if (!pointCount) - return false; - - QPointF surfacePos = surface->pos(); - wl_client *surfaceClient = surface->resource()->client(); - uint32_t time = m_compositor->currentTimeMsecs(); - const int rescount = m_resources.count(); - - for (int res = 0; res < rescount; ++res) { - wl_resource *target = m_resources.at(res); - if (target->client != surfaceClient) - continue; - - // We will use no touch_frame type of event, to reduce the number of - // events flowing through the wire. Instead, the number of points sent is - // included in the touch point events. - int sentPointCount = 0; - for (int i = 0; i < pointCount; ++i) { - if (points.at(i).state() != Qt::TouchPointStationary) - ++sentPointCount; - } - - for (int i = 0; i < pointCount; ++i) { - const QTouchEvent::TouchPoint &tp(points.at(i)); - // Stationary points are never sent. They are cached on client side. - if (tp.state() == Qt::TouchPointStationary) - continue; - - uint32_t id = tp.id(); - uint32_t state = (tp.state() & 0xFFFF) | (sentPointCount << 16); - uint32_t flags = (tp.flags() & 0xFFFF) | (int(event->device()->capabilities()) << 16); - - QPointF p = tp.pos() - surfacePos; // surface-relative - int x = toFixed(p.x()); - int y = toFixed(p.y()); - int nx = toFixed(tp.normalizedPos().x()); - int ny = toFixed(tp.normalizedPos().y()); - int w = toFixed(tp.rect().width()); - int h = toFixed(tp.rect().height()); - int vx = toFixed(tp.velocity().x()); - int vy = toFixed(tp.velocity().y()); - uint32_t pressure = uint32_t(tp.pressure() * 255); - - wl_array *rawData = 0; - QVector<QPointF> rawPosList = tp.rawScreenPositions(); - int rawPosCount = rawPosList.count(); - if (rawPosCount) { - rawPosCount = qMin(maxRawPos, rawPosCount); - rawData = &m_rawdata_array; - rawData->size = rawPosCount * sizeof(float) * 2; - float *p = m_rawdata_ptr; - for (int rpi = 0; rpi < rawPosCount; ++rpi) { - const QPointF &rawPos(rawPosList.at(rpi)); - // This will stay in screen coordinates for performance - // reasons, clients using this data will presumably know - // what they are doing. - *p++ = float(rawPos.x()); - *p++ = float(rawPos.y()); - } - } - - qt_touch_extension_send_touch(target, - time, id, state, - x, y, nx, ny, w, h, - pressure, vx, vy, - flags, rawData); - } - - return true; - } - - return false; -} + if (!m_focusResource) + return; + + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_up(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), touch_id); } -QT_END_NAMESPACE +} // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwltouch_p.h b/src/compositor/wayland_wrapper/qwltouch_p.h index 955aa5f8..6b597e29 100644 --- a/src/compositor/wayland_wrapper/qwltouch_p.h +++ b/src/compositor/wayland_wrapper/qwltouch_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Compositor. @@ -38,48 +39,43 @@ ** ****************************************************************************/ -#ifndef WLTOUCH_H -#define WLTOUCH_H +#ifndef QTWAYLAND_QWLTOUCH_P_H +#define QTWAYLAND_QWLTOUCH_P_H -#include <private/qwlcompositor_p.h> -#include "wayland-touch-extension-server-protocol.h" -#include "wayland-util.h" +#include <QtCore/QPoint> + +#include <qwayland-server-wayland.h> QT_BEGIN_NAMESPACE +namespace QtWayland { + class Compositor; class Surface; -class QTouchEvent; - -namespace QtWayland { -class TouchExtensionGlobal +class Touch : public QtWaylandServer::wl_touch { public: - TouchExtensionGlobal(Compositor *compositor); - ~TouchExtensionGlobal(); + explicit Touch(Compositor *compositor); - bool postTouchEvent(QTouchEvent *event, Surface *surface); + void setFocus(Surface *surface); - void setFlags(int flags) { m_flags = flags; } + void sendCancel(); + void sendFrame(); -private: - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - - static void destroy_resource(wl_resource *resource); - - static const struct qt_touch_extension_interface touch_interface; + void sendDown(int touch_id, const QPointF &position); + void sendMotion(int touch_id, const QPointF &position); + void sendUp(int touch_id); +private: Compositor *m_compositor; - int m_flags; - QList<wl_resource *> m_resources; - wl_array m_rawdata_array; - float *m_rawdata_ptr; + + Surface *m_focus; + Resource *m_focusResource; }; -} +} // namespace QtWayland QT_END_NAMESPACE -#endif // WLTOUCH_H +#endif // QTWAYLAND_QWLTOUCH_P_H diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index c425e2e5..663638ec 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -17,8 +17,11 @@ HEADERS += \ wayland_wrapper/qwlextendedoutput_p.h \ wayland_wrapper/qwlextendedsurface_p.h \ wayland_wrapper/qwlinputdevice_p.h \ + wayland_wrapper/qwlkeyboard_p.h \ wayland_wrapper/qwloutput_p.h \ + wayland_wrapper/qwlpointer_p.h \ wayland_wrapper/qwlqtkey_p.h \ + wayland_wrapper/qwlqttouch_p.h \ wayland_wrapper/qwlregion_p.h \ wayland_wrapper/qwlshellsurface_p.h \ wayland_wrapper/qwlsubsurface_p.h \ @@ -36,8 +39,11 @@ SOURCES += \ wayland_wrapper/qwlextendedoutput.cpp \ wayland_wrapper/qwlextendedsurface.cpp \ wayland_wrapper/qwlinputdevice.cpp \ + wayland_wrapper/qwlkeyboard.cpp \ wayland_wrapper/qwloutput.cpp \ + wayland_wrapper/qwlpointer.cpp \ wayland_wrapper/qwlqtkey.cpp \ + wayland_wrapper/qwlqttouch.cpp \ wayland_wrapper/qwlregion.cpp \ wayland_wrapper/qwlshellsurface.cpp \ wayland_wrapper/qwlsubsurface.cpp \ diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp index e607d636..f2fa2140 100644 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp +++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp @@ -40,13 +40,12 @@ #include "waylandwindowmanagerintegration.h" -#include "wayland_wrapper/qwldisplay_p.h" -#include "wayland_wrapper/qwlcompositor_p.h" +#include <wayland_wrapper/qwldisplay_p.h> +#include <wayland_wrapper/qwlcompositor_p.h> -#include "compositor_api/qwaylandcompositor.h" +#include <compositor_api/qwaylandcompositor.h> -#include "wayland-server.h" -#include "wayland-windowmanager-server-protocol.h" +#include <wayland-server.h> #include <QUrl> @@ -54,6 +53,7 @@ QT_BEGIN_NAMESPACE WindowManagerServerIntegration::WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent) : QObject(parent) + , QtWaylandServer::qt_windowmanager() , m_showIsFullScreen(false) , m_compositor(compositor) { @@ -65,75 +65,47 @@ WindowManagerServerIntegration::~WindowManagerServerIntegration() void WindowManagerServerIntegration::initialize(QtWayland::Display *waylandDisplay) { - wl_display_add_global(waylandDisplay->handle(),&qt_windowmanager_interface,this,WindowManagerServerIntegration::bind_func); + init(waylandDisplay->handle()); } void WindowManagerServerIntegration::setShowIsFullScreen(bool value) { m_showIsFullScreen = value; - struct wl_resource *resource; - wl_list_for_each(resource,&client_resources, link) { - qt_windowmanager_send_hints(resource, int32_t(m_showIsFullScreen)); + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_hints(resource->handle, static_cast<int32_t>(m_showIsFullScreen)); } } void WindowManagerServerIntegration::sendQuitMessage(wl_client *client) { - struct wl_resource *resource; - wl_list_for_each(resource, &client_resources, link) { - if (resource->client == client) { - qt_windowmanager_send_quit(resource); - return; - } - } -} + Resource *resource = resourceMap().value(client); -struct WindowManagerServerIntegrationClientData -{ - QByteArray url; - WindowManagerServerIntegration *integration; -}; + if (resource) + send_quit(resource->handle); +} -void WindowManagerServerIntegration::bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id) +void WindowManagerServerIntegration::windowmanager_bind_resource(Resource *resource) { - Q_UNUSED(version); - - WindowManagerServerIntegrationClientData *clientData = new WindowManagerServerIntegrationClientData; - clientData->integration = static_cast<WindowManagerServerIntegration *>(data); - - wl_resource *resource = wl_client_add_object(client,&qt_windowmanager_interface,&windowmanager_interface,id,clientData); - resource->destroy = WindowManagerServerIntegration::destroy_resource; - clientData->integration->registerResource(resource); - qt_windowmanager_send_hints(resource, int32_t(clientData->integration->m_showIsFullScreen)); + send_hints(resource->handle, static_cast<int32_t>(m_showIsFullScreen)); } -void WindowManagerServerIntegration::destroy_resource(wl_resource *resource) +void WindowManagerServerIntegration::windowmanager_destroy_resource(Resource *resource) { - WindowManagerServerIntegrationClientData *data = static_cast<WindowManagerServerIntegrationClientData *>(resource->data); - - delete data; - free(resource); + m_urls.remove(resource); } -void WindowManagerServerIntegration::open_url(struct wl_client *client, - struct wl_resource *window_mgr_resource, - uint32_t remaining, - const char *url) +void WindowManagerServerIntegration::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) { - WindowManagerServerIntegrationClientData *data = static_cast<WindowManagerServerIntegrationClientData *>(window_mgr_resource->data); - WindowManagerServerIntegration *window_mgr = data->integration; + QString url = m_urls.value(resource, QString()); - data->url.append(url); + url.append(newUrl); - if (!remaining) { - window_mgr->m_compositor->openUrl(client, QUrl(QString::fromUtf8(data->url))); - data->url = QByteArray(); + if (remaining) + m_urls.insert(resource, url); + else { + m_urls.remove(resource); + m_compositor->openUrl(resource->client(), QUrl(url)); } } -const struct qt_windowmanager_interface WindowManagerServerIntegration::windowmanager_interface = { - WindowManagerServerIntegration::open_url -}; - QT_END_NAMESPACE diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h index 10a29a47..ccf5d4e8 100644 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h +++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h @@ -42,17 +42,10 @@ #define WAYLANDWINDOWMANAGERINTEGRATION_H #include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandresourcecollection.h> - -#include <qwindowdefs.h> -#include <stdint.h> +#include "qwayland-server-windowmanager.h" #include <QObject> #include <QMap> -#include <QVariant> - -struct wl_client; -struct wl_object; QT_BEGIN_NAMESPACE @@ -60,15 +53,13 @@ namespace QtWayland { class Display; } -class WindowManagerObject; -class WaylandManagedClient; class QWaylandCompositor; -class Q_COMPOSITOR_EXPORT WindowManagerServerIntegration : public QObject, private QtWayland::ResourceCollection +class Q_COMPOSITOR_EXPORT WindowManagerServerIntegration : public QObject, public QtWaylandServer::qt_windowmanager { Q_OBJECT public: - WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent = 0); + explicit WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent = 0); ~WindowManagerServerIntegration(); void initialize(QtWayland::Display *waylandDisplay); @@ -76,25 +67,15 @@ public: void setShowIsFullScreen(bool value); void sendQuitMessage(wl_client *client); +protected: + void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void windowmanager_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &url) Q_DECL_OVERRIDE; + private: bool m_showIsFullScreen; QWaylandCompositor *m_compositor; - - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - - static void destroy_resource(wl_resource *resource); - static void map_client_to_process(struct wl_client *client, - struct wl_resource *windowMgrResource, - uint32_t processId); - static void authenticate_with_token(struct wl_client *client, - struct wl_resource *windowMgrResource, - const char *wl_authentication_token); - static void open_url(struct wl_client *client, - struct wl_resource *window_mgr_resource, - uint32_t remaining, - const char *url); - static const struct qt_windowmanager_interface windowmanager_interface; + QMap<Resource*, QString> m_urls; }; QT_END_NAMESPACE diff --git a/src/extensions/surface-extension.xml b/src/extensions/surface-extension.xml index 269b4390..a2c9688c 100644 --- a/src/extensions/surface-extension.xml +++ b/src/extensions/surface-extension.xml @@ -55,6 +55,9 @@ <arg name="value" type="array"/> </event> + <event name="close"> + </event> + <request name="update_generic_property"> <arg name="name" type="string"/> <arg name="value" type="array"/> @@ -81,5 +84,11 @@ <arg name="flags" type="int"/> </request> + <request name="raise"> + </request> + + <request name="lower"> + </request> + </interface> </protocol> diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp index c5712d65..f82ad6f9 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp @@ -50,7 +50,7 @@ #include "wayland-brcm-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandBrcmEglIntegration::QWaylandBrcmEglIntegration(QWaylandDisplay *waylandDisplay) : m_waylandDisplay(waylandDisplay->wl_display()) @@ -62,13 +62,13 @@ QWaylandBrcmEglIntegration::QWaylandBrcmEglIntegration(QWaylandDisplay *waylandD void QWaylandBrcmEglIntegration::wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_brcm") { + if (interface == "qt_brcm") { QWaylandBrcmEglIntegration *integration = static_cast<QWaylandBrcmEglIntegration *>(data); - integration->m_waylandBrcm = static_cast<struct wl_brcm *>(wl_registry_bind(registry, id, &wl_brcm_interface, 1)); + integration->m_waylandBrcm = static_cast<struct qt_brcm *>(wl_registry_bind(registry, id, &qt_brcm_interface, 1)); } } -wl_brcm *QWaylandBrcmEglIntegration::waylandBrcm() const +qt_brcm *QWaylandBrcmEglIntegration::waylandBrcm() const { return m_waylandBrcm; } @@ -129,3 +129,4 @@ QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDispla return new QWaylandBrcmEglIntegration(waylandDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h index fd971ffb..f1100d8d 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWindow; -struct wl_brcm; +struct qt_brcm; class QWaylandBrcmEglIntegration : public QWaylandGLIntegration { @@ -74,7 +74,7 @@ public: EGLDisplay eglDisplay() const; - struct wl_brcm *waylandBrcm() const; + struct qt_brcm *waylandBrcm() const; PFNEGLFLUSHBRCMPROC eglFlushBRCM; PFNEGLCREATEGLOBALIMAGEBRCMPROC eglCreateGlobalImageBRCM; @@ -84,7 +84,7 @@ private: static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); struct wl_display *m_waylandDisplay; - struct wl_brcm *m_waylandBrcm; + struct qt_brcm *m_waylandBrcm; EGLDisplay m_eglDisplay; }; diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp index 0b2f4d31..31db4328 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp @@ -50,22 +50,18 @@ #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext_brcm.h> #include "wayland-brcm-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWaylandBrcmBuffer : public QWaylandBuffer { public: QWaylandBrcmBuffer(QWaylandDisplay *display, - struct wl_brcm *brcm, + struct qt_brcm *brcm, const QSize &size, EGLint *data, int count) @@ -79,7 +75,7 @@ public: for (int i = 0; i < count; ++i) m_data[i] = data[i]; - mBuffer = wl_brcm_create_buffer(brcm, size.width(), size.height(), &m_array); + mBuffer = qt_brcm_create_buffer(brcm, size.width(), size.height(), &m_array); static const struct wl_buffer_listener buffer_listener = { QWaylandBrcmBuffer::buffer_release @@ -294,3 +290,4 @@ bool QWaylandBrcmEglWindow::makeCurrent(EGLContext context) return eglMakeCurrent(m_eglIntegration->eglDisplay(), m_eglSurfaces[m_current], m_eglSurfaces[m_current], context); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h index e8fcfbaa..02abd244 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QWaylandGLContext; class QWaylandBrcmBuffer; -class QWaylandBrcmEglWindow : public QObject, public QWaylandWindow +class QWaylandBrcmEglWindow : public QWaylandWindow { Q_OBJECT public: diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp index 14b98987..dfb86e54 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp @@ -50,7 +50,7 @@ #include <qpa/qplatformopenglcontext.h> #include <QtGui/QSurfaceFormat> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE extern QSurfaceFormat brcmFixFormat(const QSurfaceFormat &format); @@ -102,3 +102,4 @@ EGLConfig QWaylandBrcmGLContext::eglConfig() const return m_config; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp b/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp index 7a65f89c..07f6d586 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp @@ -50,7 +50,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) : m_waylandDisplay(waylandDisplay) @@ -107,3 +107,5 @@ QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDispla { return new QWaylandEglIntegration(waylandDisplay->wl_display()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp index 9c39ec95..7829f381 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp @@ -52,11 +52,7 @@ #include <QOpenGLFramebufferObject> #include <QOpenGLContext> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) @@ -104,7 +100,7 @@ void QWaylandEglWindow::setGeometry(const QRect &rect) m_resize = true; } } else { - m_waylandEglWindow = wl_egl_window_create(wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(object(), sizeWithMargins.width(), sizeWithMargins.height()); } QWaylandWindow::setGeometry(rect); @@ -129,7 +125,7 @@ EGLSurface QWaylandEglWindow::eglSurface() const self->createDecoration(); QMargins margins = frameMargins(); QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); - m_waylandEglWindow = wl_egl_window_create(self->wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(self->object(), sizeWithMargins.width(), sizeWithMargins.height()); } if (!m_eglSurface) { @@ -171,3 +167,5 @@ void QWaylandEglWindow::bindContentFBO() m_contentFBO->bind(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp index e28f0d17..303e59f7 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp @@ -55,7 +55,7 @@ #include <QtGui/QSurfaceFormat> #include <QtGui/QOpenGLShaderProgram> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) : QPlatformOpenGLContext() @@ -64,7 +64,6 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) , m_blitProgram(0) , m_textureCache(0) - , m_currentOnSurface(0) { m_shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; @@ -93,20 +92,12 @@ QWaylandGLContext::~QWaylandGLContext() bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface); - if (m_currentOnSurface != window) { - if (m_currentOnSurface) { - QWaylandWindow *oldWindow = m_currentOnSurface; - m_currentOnSurface = 0; - oldWindow->resizeMutex()->unlock(); - } - window->resizeMutex()->lock(); - m_currentOnSurface = window; - } + + window->setCanResize(false); EGLSurface eglSurface = window->eglSurface(); if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) { qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); - m_currentOnSurface->resizeMutex()->unlock(); return false; } @@ -118,11 +109,6 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) void QWaylandGLContext::doneCurrent() { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (m_currentOnSurface) { - QWaylandWindow *window = m_currentOnSurface; - m_currentOnSurface = 0; - window->resizeMutex()->unlock(); - } } void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) @@ -218,11 +204,8 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) } eglSwapBuffers(m_eglDisplay, eglSurface); - if (m_currentOnSurface == window) { - m_currentOnSurface = 0; - window->resizeMutex()->unlock(); - } + window->setCanResize(true); } GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const @@ -250,3 +233,4 @@ EGLConfig QWaylandGLContext::eglConfig() const return m_config; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h index b4216830..bc231e82 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h @@ -86,8 +86,6 @@ private: QSurfaceFormat m_format; QOpenGLShaderProgram *m_blitProgram; QOpenGLTextureCache *m_textureCache; - - QWaylandWindow *m_currentOnSurface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro index e41cf59b..b691ec9d 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro @@ -6,10 +6,6 @@ include (../xcomposite_share/xcomposite_share.pri) OTHER_FILES += qwayland-xcomposite-egl.json -contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - WAYLANDCLIENTSOURCES += ../../../extensions/windowmanager.xml -} - !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += xcomposite egl x11 diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp index 635e47c0..8d4a99b9 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp @@ -48,7 +48,7 @@ #include <QtPlatformSupport/private/qeglconvenience_p.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) : QEGLPlatformContext(format, share, display, q_configFromGLFormat(display, format, true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT), EGL_OPENGL_ES_API) @@ -65,6 +65,7 @@ void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface) QSize size = w->geometry().size(); w->damage(QRect(QPoint(), size)); + w->commit(); w->waitForFrameSync(); } @@ -72,3 +73,5 @@ EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformS { return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface(); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp index c2ea9a93..cd3a06ff 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp @@ -47,7 +47,7 @@ #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { @@ -117,7 +117,7 @@ const struct qt_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_xcomposite") { + if (interface == "qt_xcomposite") { QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry,id,&qt_xcomposite_interface,1)); qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); @@ -143,3 +143,4 @@ void QWaylandXCompositeEGLIntegration::rootInformation(void *data, qt_xcomposite qDebug() << "ROOT INFORMATION" << integration->mDisplay << integration->mRootWindow << integration->mScreen; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h index d7d1d491..ba36fac3 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h @@ -58,7 +58,13 @@ #include <X11/Xlib.h> #include <EGL/egl.h> -struct wl_xcomposite; +// avoid clashes with Qt::CursorShape +#ifdef CursorShape +# define X_CursorShape CursorShape +# undef CursorShape +#endif + +struct qt_xcomposite; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp index f1768991..f0df2bd2 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -50,13 +50,9 @@ #include <X11/extensions/Xcomposite.h> #include "qwaylandxcompositeeglintegration.h" -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) : QWaylandWindow(window) @@ -138,11 +134,4 @@ void QWaylandXCompositeEGLWindow::createEglSurface() attach(m_buffer, 0, 0); } -void QWaylandXCompositeEGLWindow::requestActivateWindow() -{ -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mDisplay->windowManagerIntegration()->authenticateWithToken(); -#endif - - QWaylandWindow::requestActivateWindow(); -} +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h index 98f0ed73..8fb63118 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h @@ -57,7 +57,6 @@ public: WindowType windowType() const; void setGeometry(const QRect &rect); - void requestActivateWindow(); EGLSurface eglSurface() const; diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp index bc3167b9..6854dc3b 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp @@ -47,7 +47,7 @@ #include <QRegion> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen) : m_display(display) @@ -81,6 +81,7 @@ void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface) glXSwapBuffers(m_display, w->xWindow()); w->damage(QRect(QPoint(), size)); + w->commit(); w->waitForFrameSync(); } @@ -94,3 +95,4 @@ QSurfaceFormat QWaylandXCompositeGLXContext::format() const return m_format; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp index e3316d96..2e8b444f 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp @@ -47,7 +47,7 @@ #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { @@ -103,28 +103,28 @@ QWaylandDisplay * QWaylandXCompositeGLXIntegration::waylandDisplay() const { return mWaylandDisplay; } -wl_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const +qt_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const { return mWaylandComposite; } -const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = { +const struct qt_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = { QWaylandXCompositeGLXIntegration::rootInformation }; void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_xcomposite") { - qDebug("XComposite-GLX: got wl_xcomposite global"); + if (interface == "qt_xcomposite") { + qDebug("XComposite-GLX: got qt_xcomposite global"); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); - integration->mWaylandComposite = static_cast<struct wl_xcomposite *>(wl_registry_bind(registry, id, &wl_xcomposite_interface, 1)); - wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); + integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry, id, &qt_xcomposite_interface, 1)); + qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } } -void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +void QWaylandXCompositeGLXIntegration::rootInformation(void *data, qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window) { Q_UNUSED(xcomposite); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); @@ -136,3 +136,4 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite integration->mScreen = XDefaultScreen(integration->mDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h index 066295c1..aeb7c66d 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h @@ -53,7 +53,13 @@ #include <X11/Xlib.h> -struct wl_xcomposite; +// avoid clashes with Qt::CursorShape +#ifdef CursorShape +# define X_CursorShape CursorShape +# undef CursorShape +#endif + +struct qt_xcomposite; QT_BEGIN_NAMESPACE @@ -70,7 +76,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; - struct wl_xcomposite *waylandXComposite() const; + struct qt_xcomposite *waylandXComposite() const; Display *xDisplay() const; int screen() const; @@ -80,7 +86,7 @@ public: private: QWaylandDisplay *mWaylandDisplay; - struct wl_xcomposite *mWaylandComposite; + struct qt_xcomposite *mWaylandComposite; Display *mDisplay; int mScreen; @@ -89,9 +95,9 @@ private: static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); - static const struct wl_xcomposite_listener xcomposite_listener; + static const struct qt_xcomposite_listener xcomposite_listener; static void rootInformation(void *data, - struct wl_xcomposite *xcomposite, + struct qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window); }; diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp index c142a363..3a64961f 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp @@ -49,7 +49,7 @@ #include <X11/extensions/Xcomposite.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) : QWaylandWindow(window) @@ -120,3 +120,5 @@ void QWaylandXCompositeGLXWindow::createSurface() size); attach(m_buffer, 0, 0); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp index 31fe6045..4cf055d3 100644 --- a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp @@ -46,7 +46,7 @@ #include "qwaylanddatasource.h" #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) : mDisplay(display) @@ -82,3 +82,4 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp index 9ea1836b..e0abba30 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp @@ -51,7 +51,7 @@ #include <wayland-cursor.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) : mDisplay(screen->display()) @@ -74,12 +74,17 @@ QWaylandCursor::~QWaylandCursor() wl_cursor_theme_destroy(mCursorTheme); } -void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape) { - Q_UNUSED(window) - struct wl_cursor *waylandCursor = 0; - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + /* Hide cursor */ + if (newShape == Qt::BlankCursor) + { + mDisplay->setCursor(NULL, NULL); + return NULL; + } + if (newShape < Qt::BitmapCursor) { waylandCursor = requestCursor((WaylandCursor)newShape); } else if (newShape == Qt::BitmapCursor) { @@ -90,17 +95,31 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) if (!waylandCursor) { qDebug("Could not find cursor for shape %d", newShape); - return; + return NULL; } struct wl_cursor_image *image = waylandCursor->images[0]; - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); if (!buffer) { qDebug("Could not find buffer for cursor"); + return NULL; + } + + return image; +} + +void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + Q_UNUSED(window) + + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + struct wl_cursor_image *image = cursorImage(newShape); + if (!image) { return; } + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); mDisplay->setCursor(buffer, image); } @@ -132,9 +151,6 @@ void QWaylandCursor::setPos(const QPoint &pos) wl_cursor *QWaylandCursor::requestCursor(WaylandCursor shape) { - if (shape == BlankCursor) - return 0; - struct wl_cursor *cursor = mCursors.value(shape, 0); //If the cursor has not been loaded already, load it @@ -277,3 +293,5 @@ void QWaylandCursor::initCursorMap() mCursorNamesMap.insert(ResizeSouthWestCursor, "sw-resize"); mCursorNamesMap.insert(ResizeSouthWestCursor, "bottom_left_corner"); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.h b/src/plugins/platforms/wayland_common/qwaylandcursor.h index df5dcbe3..ceb6d748 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.h +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.h @@ -45,11 +45,14 @@ #include <qpa/qplatformcursor.h> #include <QMap> +struct wl_cursor; +struct wl_cursor_image; +struct wl_cursor_theme; + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandScreen; -struct wl_cursor_theme; class QWaylandCursor : public QPlatformCursor { @@ -62,6 +65,8 @@ public: QPoint pos() const; void setPos(const QPoint &pos); + struct wl_cursor_image *cursorImage(Qt::CursorShape shape); + private: enum WaylandCursor { ArrowCursor = Qt::ArrowCursor, diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp index 901069c5..8674aae9 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp @@ -58,12 +58,13 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataDeviceManager::data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *id) { + Q_UNUSED(data_device); QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data); new QWaylandDataOffer(handler->display(),id); @@ -322,4 +323,4 @@ struct wl_data_device_manager *QWaylandDataDeviceManager::handle() const return m_data_device_manager; } - +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp index d2080ea5..d98cfc2a 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataOffer::offer_sync_callback(void *data, struct wl_callback *callback, @@ -143,3 +143,5 @@ struct wl_data_offer *QWaylandDataOffer::handle() const { return m_data_offer; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h index fada683a..abc7c690 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h @@ -52,6 +52,9 @@ #include <stdint.h> struct wl_callback; +struct wl_callback_listener; +struct wl_data_offer; +struct wl_data_offer_listener; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp index ad280b03..7bf8b0c9 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp @@ -50,7 +50,7 @@ #include <unistd.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataSource::data_source_target(void *data, struct wl_data_source *wl_data_source, @@ -117,3 +117,5 @@ struct wl_data_source *QWaylandDataSource::handle() const { return m_data_source; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp index f5f79ae6..a4b97833 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp @@ -44,6 +44,7 @@ #include "qwaylandwindow.h" #include "qwaylandshellsurface.h" #include "qwaylandinputdevice.h" +#include "qwaylandscreen.h" #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -52,7 +53,7 @@ #include <QtGui/QPalette> #include <QtGui/QLinearGradient> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE #define BUTTON_SPACING 5 @@ -128,7 +129,6 @@ QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) , m_isDirty(true) , m_decorationContentImage(0) , m_margins(3,30,3,3) - , m_hasSetCursor(false) , m_mouseButtons(Qt::NoButton) { m_wayland_window->setDecoration(this); @@ -312,7 +312,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo // Figure out what area mouse is in if (closeButtonRect().contains(local) && isLeftClicked(b)) { - QCoreApplication::postEvent(m_window, new QCloseEvent()); + QWindowSystemInterface::handleCloseEvent(m_window); } else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) { m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized); } else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) { @@ -326,7 +326,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo } else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) { processMouseRight(inputDevice,local,b,mods); } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); return false; } @@ -334,15 +334,6 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo return true; } -void QWaylandDecoration::restoreMouseCursor() -{ - if (m_hasSetCursor) { - overrideCursor(Qt::ArrowCursor); - QGuiApplication::restoreOverrideCursor(); - m_hasSetCursor = false; - } -} - bool QWaylandDecoration::inMouseButtonPressedState() const { return m_mouseButtons & Qt::NoButton; @@ -370,19 +361,19 @@ void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const if (local.y() <= m_margins.bottom()) { if (local.x() <= margins().left()) { //top left bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //top right bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b); } else { //top reszie bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b); } } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); startMove(inputDevice,b); } @@ -393,15 +384,15 @@ void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, co Q_UNUSED(mods); if (local.x() <= margins().left()) { //bottom left bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //bottom right bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b); } else { //bottom bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b); } } @@ -410,7 +401,7 @@ void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, cons { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b); } @@ -418,7 +409,7 @@ void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, con { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b); } @@ -463,3 +454,5 @@ void QWaylandDecoration::setBackgroundColor(const QColor &c) { m_backgroundColor = c; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/plugins/platforms/wayland_common/qwaylanddecoration.h index 14755699..5efeab22 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.h @@ -60,6 +60,7 @@ class QWindow; class QPaintDevice; class QPainter; class QEvent; +class QWaylandScreen; class QWaylandWindow; class QWaylandInputDevice; @@ -73,7 +74,6 @@ public: bool isDirty() const; bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); - void restoreMouseCursor(); bool inMouseButtonPressedState() const; void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons); @@ -93,8 +93,6 @@ protected: void paint(QPaintDevice *device); private: - void overrideCursor(Qt::CursorShape shape); - void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); @@ -114,8 +112,6 @@ private: QImage m_decorationContentImage; QMargins m_margins; - bool m_hasSetCursor; - Qt::CursorShape m_cursorShape; Qt::MouseButtons m_mouseButtons; QColor m_foregroundColor; @@ -153,20 +149,6 @@ inline QColor QWaylandDecoration::backgroundColor() const return m_backgroundColor; } -inline void QWaylandDecoration::overrideCursor(Qt::CursorShape shape) -{ - if (m_hasSetCursor) { - if (m_cursorShape != shape) { - QGuiApplication::changeOverrideCursor(QCursor(shape)); - m_cursorShape = shape; - } - } else { - QGuiApplication::setOverrideCursor(QCursor(shape)); - m_hasSetCursor = true; - m_cursorShape = shape; - } -} - QT_END_NAMESPACE #endif // QWAYLANDDECORATION_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp index bb056c96..6cc01d0e 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp @@ -53,9 +53,7 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif +#include "qwaylandwindowmanagerintegration.h" #include "qwaylandextendedoutput.h" #include "qwaylandextendedsurface.h" @@ -68,7 +66,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) { @@ -84,12 +82,10 @@ QWaylandGLIntegration * QWaylandDisplay::eglIntegration() } #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() { return mWindowManagerIntegration; } -#endif QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const { @@ -139,9 +135,7 @@ QWaylandDisplay::QWaylandDisplay() mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); -#endif blockingReadEvents(); @@ -168,13 +162,15 @@ QWaylandDisplay::~QWaylandDisplay(void) void QWaylandDisplay::flushRequests() { - wl_display_dispatch_queue_pending(mDisplay, mEventQueue); + if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); wl_display_flush(mDisplay); } void QWaylandDisplay::blockingReadEvents() { - wl_display_dispatch_queue(mDisplay, mEventQueue); + if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const @@ -196,8 +192,20 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) void QWaylandDisplay::waitForScreens() { flushRequests(); - while (mScreens.isEmpty()) - blockingReadEvents(); + + while (true) { + bool screensReady = !mScreens.isEmpty(); + + for (int ii = 0; screensReady && ii < mScreens.count(); ++ii) { + if (mScreens.at(ii)->geometry() == QRect(0, 0, 0, 0)) + screensReady = false; + } + + if (!screensReady) + blockingReadEvents(); + else + return; + } } void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version) @@ -219,17 +227,17 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); - } else if (interface == "wl_output_extension") { + } else if (interface == "qt_output_extension") { mOutputExtension = new QtWayland::qt_output_extension(registry, id); foreach (QPlatformScreen *screen, screens()) static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); - } else if (interface == "wl_surface_extension") { + } else if (interface == "qt_surface_extension") { mWindowExtension = new QtWayland::qt_surface_extension(registry, id); - } else if (interface == "wl_sub_surface_extension") { + } else if (interface == "qt_sub_surface_extension") { mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); - } else if (interface == "wl_touch_extension") { + } else if (interface == "qt_touch_extension") { mTouchExtension = new QWaylandTouchExtension(this, id); - } else if (interface == "wl_qtkey_extension") { + } else if (interface == "qt_key_extension") { mQtKeyExtension = new QWaylandQtKeyExtension(this, id); } @@ -252,3 +260,4 @@ void QWaylandDisplay::forceRoundTrip() wl_display_roundtrip(mDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h index bb26be69..6b2cc89d 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h @@ -50,6 +50,8 @@ #include <wayland-client.h> #include <qwayland-wayland.h> +struct wl_cursor_image; + QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; @@ -96,9 +98,7 @@ public: QWaylandGLIntegration *eglIntegration(); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *windowManagerIntegration(); -#endif void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); @@ -162,6 +162,7 @@ private: QtWayland::qt_output_extension *mOutputExtension; QWaylandTouchExtension *mTouchExtension; QWaylandQtKeyExtension *mQtKeyExtension; + QWaylandWindowManagerIntegration *mWindowManagerIntegration; QSocketNotifier *mReadNotifier; int mFd; @@ -174,10 +175,6 @@ private: QWaylandGLIntegration *mEglIntegration; #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - QWaylandWindowManagerIntegration *mWindowManagerIntegration; -#endif - static void shellHandleConfigure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, struct wl_surface *surface, diff --git a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp index 790fbbd0..0dc80e63 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp @@ -43,7 +43,7 @@ #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) : m_display(display) @@ -93,3 +93,5 @@ Qt::DropAction QWaylandDrag::executedDropAction() const { return Qt::CopyAction; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp index 5c0a1d5b..ca968a2d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp @@ -1,11 +1,14 @@ #include "qwaylandeventthread.h" #include <QtCore/QSocketNotifier> +#include <QCoreApplication> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> +QT_BEGIN_NAMESPACE + QWaylandEventThread::QWaylandEventThread(QObject *parent) : QObject(parent) , m_display(0) @@ -29,7 +32,8 @@ void QWaylandEventThread::displayConnect() void QWaylandEventThread::readWaylandEvents() { - wl_display_dispatch(m_display); + if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) + QCoreApplication::quit(); emit newEventsRead(); } @@ -53,3 +57,5 @@ wl_display *QWaylandEventThread::display() const QMutexLocker displayLock(m_displayLock); return m_display; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.h b/src/plugins/platforms/wayland_common/qwaylandeventthread.h index bedf4ea5..f4aec744 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.h +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.h @@ -5,6 +5,8 @@ #include <QMutex> #include <wayland-client.h> +QT_BEGIN_NAMESPACE + class QSocketNotifier; class QWaylandEventThread : public QObject @@ -37,4 +39,6 @@ private: }; +QT_END_NAMESPACE + #endif // QWAYLANDEVENTTHREAD_H diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp index 24b264e2..d7c684be 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output) : QtWayland::qt_extended_output(extended_output) @@ -96,3 +96,5 @@ void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotatio } QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp index 46280bcf..58eb0a83 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp @@ -53,15 +53,19 @@ #include <qpa/qplatformnativeinterface.h> #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) : QtWayland::qt_extended_surface(extended_surface) , m_window(window) - , m_exposed(true) { } +QWaylandExtendedSurface::~QWaylandExtendedSurface() +{ + qt_extended_surface_destroy(object()); +} + void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) { QByteArray byteValue; @@ -107,18 +111,9 @@ QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant & return m_properties.value(name,defaultValue); } -void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visible) +void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility) { - // Do not send events when the state is not changing... - if (visible == m_exposed) - return; - - m_exposed = visible; - QWaylandWindow *w = m_window; - QWindowSystemInterface::handleExposeEvent(w->window(), - visible - ? QRegion(w->geometry()) - : QRegion()); + m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility)); } void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) @@ -136,6 +131,11 @@ void QWaylandExtendedSurface::extended_surface_set_generic_property(const QStrin nativeInterface->emitWindowPropertyChanged(m_window, name); } +void QWaylandExtendedSurface::extended_surface_close() +{ + QWindowSystemInterface::handleCloseEvent(m_window->window()); +} + Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) { uint wlFlags = 0; @@ -147,3 +147,5 @@ Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h index 9dbebaf4..4bef5e07 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h @@ -57,6 +57,7 @@ class QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); + ~QWaylandExtendedSurface(); void setContentOrientation(Qt::ScreenOrientation orientation); @@ -68,16 +69,13 @@ public: Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const { return m_exposed; } - private: - void extended_surface_onscreen_visibility(int32_t visible) Q_DECL_OVERRIDE; + void extended_surface_onscreen_visibility(int32_t visibility) Q_DECL_OVERRIDE; void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE; + void extended_surface_close() Q_DECL_OVERRIDE; QWaylandWindow *m_window; QVariantMap m_properties; - - bool m_exposed; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp index a4b3331c..bafb9944 100644 --- a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp @@ -41,7 +41,7 @@ #include "qwaylandglintegration.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration::QWaylandGLIntegration() { @@ -52,3 +52,5 @@ QWaylandGLIntegration::~QWaylandGLIntegration() { } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 62cbdf36..aab939f6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -46,6 +46,8 @@ #include "qwaylandbuffer.h" #include "qwaylanddatadevicemanager.h" #include "qwaylandtouch.h" +#include "qwaylandscreen.h" +#include "qwaylandcursor.h" #include <QtGui/private/qpixmap_raster_p.h> #include <qpa/qplatformwindow.h> @@ -53,6 +55,7 @@ #include <unistd.h> #include <fcntl.h> +#include <sys/mman.h> #include <wayland-cursor.h> @@ -63,18 +66,20 @@ #include <X11/keysym.h> #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) : QtWayland::wl_seat(display->wl_registry(), id) , mQDisplay(display) , mDisplay(display->wl_display()) + , mFocusCallback(0) , mCaps(0) , mTransferDevice(0) , mPointerFocus(0) , mKeyboardFocus(0) , mTouchFocus(0) , mButtons(0) + , mCursorSerial(0) , mTouchDevice(0) #ifndef QT_NO_WAYLAND_XKB , mXkbContext(0) @@ -90,7 +95,7 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) names.variant = strdup(""); names.options = strdup(""); - xkb_context *mXkbContext = xkb_context_new(xkb_context_flags(0)); + mXkbContext = xkb_context_new(xkb_context_flags(0)); if (mXkbContext) { mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); if (mXkbMap) { @@ -167,9 +172,28 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) mButtons = mButtons & !button; } +void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen) +{ + struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape); + if (!image) { + return; + } + + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + setCursor(buffer, image); +} + void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) { if (mCaps & WL_SEAT_CAPABILITY_POINTER) { + mCursorSerial = mEnterSerial; + /* Hide cursor */ + if (!buffer) + { + set_cursor(mEnterSerial, NULL, 0, 0); + return; + } + set_cursor(mEnterSerial, pointerSurface, image->hotspot_x, image->hotspot_y); wl_surface_attach(pointerSurface, buffer, 0, 0); @@ -187,16 +211,17 @@ void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surf if (!surface) return; - QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseEnter(); - window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->window()->setCursor(window->window()->cursor()); + mPointerFocus = window; mTime = QWaylandDisplay::currentTimeMillisec(); mSerial = serial; mEnterSerial = serial; + + window->handleMouseEnter(this); + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) @@ -206,10 +231,8 @@ void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surfac if (!surface) return; - QGuiApplication::restoreOverrideCursor(); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseLeave(); + window->handleMouseLeave(this); mPointerFocus = 0; mButtons = Qt::NoButton; @@ -401,30 +424,73 @@ static const uint32_t KeyTbl[] = { 0, 0 }; -static uint32_t translateKey(uint32_t sym, char *string, size_t size) +static int keysymToQtKey(xkb_keysym_t key) { - Q_UNUSED(size); - string[0] = '\0'; + int code = 0; + int i = 0; + while (KeyTbl[i]) { + if (key == KeyTbl[i]) { + code = (int)KeyTbl[i+1]; + break; + } + i += 2; + } - if (sym >= XK_F1 && sym <= XK_F35) - return Qt::Key_F1 + (int(sym) - XK_F1); + return code; +} - for (int i = 0; KeyTbl[i]; i += 2) - if (sym == KeyTbl[i]) - return KeyTbl[i + 1]; +static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text) +{ + int code = 0; + + if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { + code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1); + } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { + if (keysym >= XKB_KEY_KP_0) { + // numeric keypad keys + code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); + } else { + code = keysymToQtKey(keysym); + } + modifiers |= Qt::KeypadModifier; + } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f + && text.unicode()->unicode() != 0x7f + && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) { + code = text.unicode()->toUpper().unicode(); + } else { + // any other keys + code = keysymToQtKey(keysym); + } - string[0] = sym; - string[1] = '\0'; - return toupper(sym); + return code; } #endif // QT_NO_WAYLAND_XKB void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { +#ifndef QT_NO_WAYLAND_XKB + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + munmap(map_str, size); + close(fd); + + mXkbState = xkb_state_new(mXkbMap); +#else Q_UNUSED(format); Q_UNUSED(fd); Q_UNUSED(size); +#endif } void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) @@ -435,10 +501,14 @@ void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surfa if (!surface) return; + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); mKeyboardFocus = window; - mQDisplay->setLastKeyboardFocusInputDevice(this); - QWindowSystemInterface::handleWindowActivated(window->window()); + + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } } void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) @@ -447,7 +517,32 @@ void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surfa Q_UNUSED(surface); mKeyboardFocus = NULL; - mQDisplay->setLastKeyboardFocusInputDevice(0); + + // Use a callback to set the focus because we may get a leave/enter pair, and + // the latter one would be lost in the QWindowSystemInterface queue, if + // we issue the handleWindowActivated() calls immediately. + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } +} + +const wl_callback_listener QWaylandInputDevice::callback = { + QWaylandInputDevice::focusCallback +}; + +void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(callback); + QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); + if (self->mFocusCallback) { + wl_callback_destroy(self->mFocusCallback); + self->mFocusCallback = 0; + } + + self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0); + QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0); } void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) @@ -476,15 +571,15 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; - char s[2]; - sym = translateKey(sym, s, sizeof s); + uint utf32 = xkb_keysym_to_utf32(sym); + QString text = QString::fromUcs4(&utf32, 1); + + int qtkey = keysymToQtKey(sym, modifiers, text); - if (window) - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), - time, type, sym, - modifiers, - code, 0, 0, - QString::fromLatin1(s)); + QWindowSystemInterface::handleExtendedKeyEvent(window->window(), + time, type, qtkey, + modifiers, + code, 0, 0, text); } #else // Generic fallback for single hard keys: Assume 'key' is a Qt key code. @@ -621,7 +716,9 @@ void QWaylandInputDevice::touch_frame() return; } - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindow *window = mTouchFocus ? mTouchFocus->window() : 0; + + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); bool allReleased = true; for (int i = 0; i < mTouchPoints.count(); ++i) @@ -634,7 +731,9 @@ void QWaylandInputDevice::touch_frame() mTouchPoints.clear(); if (allReleased) { - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); mPrevTouchPoints.clear(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h index c0e57a90..c9202684 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h @@ -75,6 +75,7 @@ public: struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); } + void setCursor(Qt::CursorShape cursor, QWaylandScreen *screen); void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); @@ -84,10 +85,12 @@ public: void removeMouseButtonFromState(Qt::MouseButton button); uint32_t serial() const; + uint32_t cursorSerial() const { return mCursorSerial; } private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; + struct wl_callback *mFocusCallback; uint32_t mCaps; @@ -104,6 +107,7 @@ private: uint32_t mTime; uint32_t mSerial; uint32_t mEnterSerial; + uint32_t mCursorSerial; void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; @@ -152,6 +156,9 @@ private: void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); + static const wl_callback_listener callback; + static void focusCallback(void *data, struct wl_callback *callback, uint32_t time); + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; QTouchDevice *mTouchDevice; diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp index c3a479a2..b0d5b271 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp @@ -47,6 +47,7 @@ #include "qwaylandnativeinterface.h" #include "qwaylandclipboard.h" #include "qwaylanddnd.h" +#include "qwaylandwindowmanagerintegration.h" #include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h" #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> @@ -67,11 +68,37 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE + +class GenericWaylandTheme: public QGenericUnixTheme +{ +public: + static QStringList themeNames() + { + QStringList result; + + if (QGuiApplication::desktopSettingsAware()) { + const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); + + // Ignore X11 desktop environments + if (!desktopEnvironment.isEmpty() && + desktopEnvironment != QByteArrayLiteral("UNKNOWN") && + desktopEnvironment != QByteArrayLiteral("KDE") && + desktopEnvironment != QByteArrayLiteral("GNOME") && + desktopEnvironment != QByteArrayLiteral("UNITY") && + desktopEnvironment != QByteArrayLiteral("MATE") && + desktopEnvironment != QByteArrayLiteral("XFCE") && + desktopEnvironment != QByteArrayLiteral("LXDE")) + result.push_back(desktopEnvironment.toLower()); + } + + if (result.isEmpty()) + result.push_back(QLatin1String(QGenericUnixTheme::name)); + + return result; + } +}; QWaylandIntegration::QWaylandIntegration() : mFontDb(new QGenericUnixFontDatabase()) @@ -84,7 +111,6 @@ QWaylandIntegration::QWaylandIntegration() #endif { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - QGuiApplication::setDesktopSettingsAware(false); mDisplay = new QWaylandDisplay(); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); @@ -184,10 +210,9 @@ QPlatformInputContext *QWaylandIntegration::inputContext() const QVariant QWaylandIntegration::styleHint(StyleHint hint) const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration()) return mDisplay->windowManagerIntegration()->showIsFullScreen(); -#endif + return QPlatformIntegration::styleHint(hint); } @@ -198,11 +223,7 @@ QPlatformAccessibility *QWaylandIntegration::accessibility() const QPlatformServices *QWaylandIntegration::services() const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT return mDisplay->windowManagerIntegration(); -#else - return QWaylandIntegration::services(); -#endif } QWaylandDisplay *QWaylandIntegration::display() const @@ -212,10 +233,12 @@ QWaylandDisplay *QWaylandIntegration::display() const QStringList QWaylandIntegration::themeNames() const { - return QGenericUnixTheme::themeNames(); + return GenericWaylandTheme::themeNames(); } QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) const { - return QGenericUnixTheme::createUnixTheme(name); + return GenericWaylandTheme::createUnixTheme(name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp index 31d25c0f..354e8dba 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp @@ -45,12 +45,11 @@ #include "qwaylandextendedsurface.h" #include "qwaylandintegration.h" #include "qwaylanddisplay.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QScreen> -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandNativeInterface::QWaylandNativeInterface(QWaylandIntegration *integration) : m_integration(integration) @@ -78,7 +77,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc if (lowerCaseResource == "compositor") return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { - return ((QWaylandWindow *) window->handle())->wl_surface(); + return ((QWaylandWindow *) window->handle())->object(); } return NULL; @@ -131,3 +130,5 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, { emit windowPropertyChanged(window,name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp index d9f2071e..e723078c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp @@ -42,7 +42,7 @@ #include "qwaylandqtkey.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_key_extension(display->wl_registry(), id) @@ -63,7 +63,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, { QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_qtkey_extension: handle_qtkey: No input device"); + qWarning("qt_key_extension: handle_qtkey: No input device"); return; } @@ -71,7 +71,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, QWaylandWindow *win = dev->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_qtkey_extension: handle_qtkey: No keyboard focus"); + qWarning("qt_key_extension: handle_qtkey: No keyboard focus"); return; } @@ -80,3 +80,5 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp index 1cb1b9cf..5956c2fd 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp @@ -47,7 +47,7 @@ #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) : QtWayland::wl_output(waylandDisplay->wl_registry(), id) @@ -56,6 +56,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) , mDepth(32) , mRefreshRate(60000) , mFormat(QImage::Format_ARGB32_Premultiplied) + , mOutputName(QStringLiteral("Screen%1").arg(id)) , mWaylandCursor(new QWaylandCursor(this)) { // handle case of output extension global being sent after outputs @@ -138,11 +139,12 @@ void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refr if (size != mGeometry.size()) { mGeometry.setSize(size); QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } if (refresh != mRefreshRate) { mRefreshRate = refresh; - QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); + QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate()); } } @@ -155,9 +157,11 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, { Q_UNUSED(subpixel); Q_UNUSED(make); - Q_UNUSED(model); Q_UNUSED(transform); + if (!model.isEmpty()) + mOutputName = model; + QRect geom(x, y, width, height); if (mGeometry == geom) @@ -165,4 +169,7 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, mGeometry = geom; QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/plugins/platforms/wayland_common/qwaylandscreen.h index 005f25ee..91848ad0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.h @@ -69,7 +69,10 @@ public: Qt::ScreenOrientation orientation() const; qreal refreshRate() const; + QString name() const { return mOutputName; } + QPlatformCursor *cursor() const; + QWaylandCursor *waylandCursor() const { return mWaylandCursor; }; ::wl_output *output() { return object(); } @@ -94,6 +97,7 @@ private: int mRefreshRate; QImage::Format mFormat; QSize mPhysicalSize; + QString mOutputName; QWaylandCursor *mWaylandCursor; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index 98689073..6e638e6b 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -49,7 +49,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) : QtWayland::wl_shell_surface(shell_surface) @@ -114,7 +114,7 @@ void QWaylandShellSurface::setTopLevel() void QWaylandShellSurface::updateTransientParent(QWindow *parent) { QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle()); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + if (!parent_wayland_window) return; // set_transient expects a position relative to the parent @@ -132,7 +132,7 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) || wf.testFlag(Qt::WindowTransparentForInput)) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - set_transient(parent_wayland_window->wl_surface(), + set_transient(parent_wayland_window->object(), transientPos.x(), transientPos.y(), flags); @@ -140,8 +140,8 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) { - QWaylandWindow *parent_wayland_window = parent->topLevelWindow(); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + QWaylandWindow *parent_wayland_window = parent; + if (!parent_wayland_window) return; // set_popup expects a position relative to the parent @@ -152,19 +152,8 @@ void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - wl_shell_surface_set_popup(object(), device->wl_seat(), serial, - parent_wayland_window->wl_surface(), - transientPos.x(), transientPos.y(), 0); -} - -void QWaylandShellSurface::setClassName(const char *className) -{ - set_class(className); -} - -void QWaylandShellSurface::setTitle(const char *title) -{ - set_title(title); + set_popup(device->wl_seat(), serial, parent_wayland_window->object(), + transientPos.x(), transientPos.y(), 0); } void QWaylandShellSurface::shell_surface_ping(uint32_t serial) @@ -183,3 +172,5 @@ void QWaylandShellSurface::shell_surface_popup_done() { QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index 9e886cf0..172a0f96 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -76,10 +76,6 @@ private: void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); - void setClassName(const char *_class); - - void setTitle(const char *title); - QWaylandWindow *m_window; bool m_maximized; bool m_fullscreen; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp index 93161a3f..00a4b13a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp @@ -172,11 +172,13 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &) waylandWindow->waitForFrameSync(); } + waylandWindow()->setCanResize(false); } void QWaylandShmBackingStore::endPaint() { mPainting = false; + waylandWindow()->setCanResize(true); } void QWaylandShmBackingStore::ensureSize() @@ -224,8 +226,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons waylandWindow()->damage(rect); } } + waylandWindow()->commit(); mFrontBufferIsDirty = false; - waylandWindow()->doResize(); } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) @@ -299,18 +301,17 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t wl_callback_destroy(self->mFrameCallback); self->mFrameCallback = 0; - if (self->mFrontBuffer != window->attached()) { - delete window->attached(); - } - - if (window->attached() != self->mFrontBuffer) - window->attachOffset(self->mFrontBuffer); if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; - self->mFrameCallback = wl_surface_frame(window->wl_surface()); + self->mFrameCallback = wl_surface_frame(window->object()); wl_callback_add_listener(self->mFrameCallback,&self->frameCallbackListener,self); + if (self->mFrontBuffer != window->attached()) { + delete window->attached(); + } + window->attachOffset(self->mFrontBuffer); window->damage(QRect(QPoint(0,0),self->mFrontBuffer->size())); + window->commit(); } } @@ -319,4 +320,3 @@ const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener }; QT_END_NAMESPACE - diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp index f4a0ede0..48a1bfd5 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShmWindow::QWaylandShmWindow(QWindow *window) : QWaylandWindow(window) @@ -69,3 +69,5 @@ void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp index 99713bb6..0e9d575a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp @@ -45,7 +45,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface) : QtWayland::qt_sub_surface(sub_surface) @@ -87,3 +87,5 @@ void QWaylandSubSurface::adjustPositionOfChildren() } setPositionToParent(m_window); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp index b19165d6..5835d9d3 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp @@ -42,7 +42,7 @@ #include "qwaylandtouch.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_touch_extension(display->wl_registry(), id), @@ -78,7 +78,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!mInputDevice) { QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_touch_extension: handle_touch: No input devices"); + qWarning("qt_touch_extension: handle_touch: No input devices"); return; } mInputDevice = inputDevices.first(); @@ -89,7 +89,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!win) win = mInputDevice->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_touch_extension: handle_touch: No pointer focus"); + qWarning("qt_touch_extension: handle_touch: No pointer focus"); return; } mTargetWindow = win->window(); @@ -205,3 +205,5 @@ void QWaylandTouchExtension::touch_extension_configure(uint32_t flags) { mFlags = flags; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index 66622210..27b624fb 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -49,25 +49,23 @@ #include "qwaylandextendedsurface.h" #include "qwaylandsubsurface.h" #include "qwaylanddecoration.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtCore/QFileInfo> #include <QtGui/QWindow> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - -#include <QCoreApplication> +#include <QGuiApplication> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandWindow::QWaylandWindow(QWindow *window) : QObject() , QPlatformWindow(window) - , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) + , mScreen(QWaylandScreen::waylandScreenFromWindow(window)) + , mDisplay(mScreen->display()) , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) @@ -77,7 +75,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) - , mResizeExposedSent(false) + , mRequestResizeSent(false) + , mCanResize(true) , mSentInitialResize(false) , mMouseDevice(0) , mMouseSerial(0) @@ -88,25 +87,26 @@ QWaylandWindow::QWaylandWindow(QWindow *window) static WId id = 1; mWindowId = id++; - if (mDisplay->shell() && !(window->flags() & Qt::BypassWindowManagerHint)) - mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(wl_surface()), this); + if (mDisplay->shell() && window->type() & Qt::Window && !(window->flags() & Qt::BypassWindowManagerHint)) + mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(object()), this); if (mDisplay->windowExtension()) - mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(wl_surface())); + mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object())); if (mDisplay->subSurfaceExtension()) - mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(wl_surface())); + mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object())); if (mShellSurface) { // Set surface class to the .desktop file name (obtained from executable name) QFileInfo exeFileInfo(qApp->applicationFilePath()); QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); - mShellSurface->setClassName(className.toUtf8().constData()); + mShellSurface->set_class(className); } if (QPlatformWindow::parent() && mSubSurfaceWindow) { mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent())); - } else if (window->transientParent()) { - if (window->transientParent() && mShellSurface) + } else if (window->transientParent() && mShellSurface) { + if (window->type() != Qt::Popup) { mShellSurface->updateTransientParent(window->transientParent()); + } } else if (mShellSurface) { mShellSurface->setTopLevel(); } @@ -123,10 +123,18 @@ QWaylandWindow::~QWaylandWindow() delete mExtendedWindow; destroy(); } + if (mFrameCallback) + wl_callback_destroy(mFrameCallback); QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); for (int i = 0; i < inputDevices.size(); ++i) inputDevices.at(i)->handleWindowDestroyed(this); + + const QWindow *parent = window(); + foreach (QWindow *w, QGuiApplication::topLevelWindows()) { + if (w->transientParent() == parent) + QWindowSystemInterface::handleCloseEvent(w); + } } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -150,8 +158,7 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent) void QWaylandWindow::setWindowTitle(const QString &title) { if (mShellSurface) { - QByteArray titleUtf8 = title.toUtf8(); - mShellSurface->setTitle(titleUtf8.constData()); + mShellSurface->set_title(title); } if (mWindowDecoration && window()->isVisible()) @@ -175,6 +182,11 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (mWindowDecoration && window()->isVisible()) mWindowDecoration->update(); + + if (mConfigure.isEmpty()) { + QWindowSystemInterface::handleGeometryChange(window(), rect); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect)); + } } void QWaylandWindow::setVisible(bool visible) @@ -201,38 +213,42 @@ void QWaylandWindow::setVisible(bool visible) // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). } else { - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); attach(static_cast<QWaylandBuffer *>(0), 0, 0); } damage(QRect(QPoint(0,0),geometry().size())); + commit(); } -bool QWaylandWindow::isExposed() const +void QWaylandWindow::raise() { - if (!window()->isVisible()) - return false; if (mExtendedWindow) - return mExtendedWindow->isExposed(); - return true; + mExtendedWindow->raise(); } +void QWaylandWindow::lower() +{ + if (mExtendedWindow) + mExtendedWindow->lower(); +} + void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { + QMutexLocker resizeLocker(&mResizeLock); mConfigure.edges |= edges; mConfigure.width = width; mConfigure.height = height; - if (!mResizeExposedSent) { - mResizeExposedSent = true; - QMetaObject::invokeMethod(this, "doResize", Qt::QueuedConnection); + if (!mRequestResizeSent && !mConfigure.isEmpty()) { + mRequestResizeSent= true; + QMetaObject::invokeMethod(this, "requestResize", Qt::QueuedConnection); } } void QWaylandWindow::doResize() { - mResizeExposedSent = false; if (mConfigure.isEmpty()) { return; } @@ -255,13 +271,34 @@ void QWaylandWindow::doResize() } mOffset += QPoint(x, y); - mResizeLock.lock(); setGeometry(geometry); - mResizeLock.unlock(); mConfigure.clear(); QWindowSystemInterface::handleGeometryChange(window(), geometry); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry)); +} + +void QWaylandWindow::setCanResize(bool canResize) +{ + QMutexLocker lock(&mResizeLock); + mCanResize = canResize; + + if (canResize && !mConfigure.isEmpty()) { + doResize(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); + } +} + +void QWaylandWindow::requestResize() +{ + QMutexLocker lock(&mResizeLock); + + if (mCanResize) { + doResize(); + } + + mRequestResizeSent = false; + lock.unlock(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -269,8 +306,10 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; - if (window()->isVisible()) + if (mBuffer) attach(mBuffer->buffer(), x, y); + else + QtWayland::wl_surface::attach(0, 0, 0); } void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) @@ -293,9 +332,9 @@ void QWaylandWindow::damage(const QRect &rect) wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this); mWaitingForFrameSync = true; } - - damage(rect.x(), rect.y(), rect.width(), rect.height()); - commit(); + if (mBuffer) { + damage(rect.x(), rect.y(), rect.width(), rect.height()); + } } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -379,6 +418,9 @@ void QWaylandWindow::setWindowState(Qt::WindowState state) default: mShellSurface->setNormal(); } + + QWindowSystemInterface::handleWindowStateChanged(window(), mState); + QWindowSystemInterface::flushWindowSystemEvents(); // Required for oldState to work on WindowStateChanged } void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) @@ -434,21 +476,20 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) } } -QWaylandWindow *QWaylandWindow::topLevelWindow() +static QWindow *topLevelWindow(QWindow *window) { - QWaylandWindow *w = this; - while (w->QPlatformWindow::parent()) { - w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); - } - return w; + while (QWindow *parent = window->parent()) + window = parent; + return window; } QWaylandWindow *QWaylandWindow::transientParent() const { if (window()->transientParent()) { - // Take the top level window here, since the transient parent may be some non-native - // QWindow, which cannot have the mMouseDevice and mMouseSerial - return static_cast<QWaylandWindow *>(window()->transientParent()->handle())->topLevelWindow(); + // Take the top level window here, since the transient parent may be a QWidgetWindow + // or some other window without a shell surface, which is then not able to get mouse + // events, nor set mMouseSerial and mMouseDevice. + return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle()); } return 0; } @@ -468,23 +509,24 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timesta QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods); } -void QWaylandWindow::handleMouseEnter() +void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice) { if (!mWindowDecoration) { QWindowSystemInterface::handleEnterEvent(window()); } + restoreMouseCursor(inputDevice); } -void QWaylandWindow::handleMouseLeave() +void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice) { if (mWindowDecoration) { if (mMouseEventsInContentArea) { QWindowSystemInterface::handleLeaveEvent(window()); } - mWindowDecoration->restoreMouseCursor(); } else { QWindowSystemInterface::handleLeaveEvent(window()); } + restoreMouseCursor(inputDevice); } void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) @@ -505,7 +547,7 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe globalTranslated.setX(globalTranslated.x() - marg.left()); globalTranslated.setY(globalTranslated.y() - marg.top()); if (!mMouseEventsInContentArea) { - mWindowDecoration->restoreMouseCursor(); + restoreMouseCursor(inputDevice); QWindowSystemInterface::handleEnterEvent(window()); } QWindowSystemInterface::handleMouseEvent(window(), timestamp, localTranslated, globalTranslated, b, mods); @@ -519,3 +561,18 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe mWindowDecoration->handleMouse(inputDevice,local,global,b,mods); } } + +void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape) +{ + if (m_cursorShape != shape || device->serial() > device->cursorSerial()) { + device->setCursor(shape, mScreen); + m_cursorShape = shape; + } +} + +void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) +{ + setMouseCursor(device, window()->cursor().shape()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index 3cd891f6..8fd104d0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -122,10 +122,6 @@ public: QMargins frameMargins() const; - // TODO: remove? - struct ::wl_surface *wl_surface() { return object(); } - const struct ::wl_surface *wl_surface() const { return object(); } - static QWaylandWindow *fromWlSurface(::wl_surface *surface); QWaylandShellSurface *shellSurface() const; @@ -137,7 +133,8 @@ public: void setWindowState(Qt::WindowState state); void setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); @@ -149,25 +146,27 @@ public: const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods); - void handleMouseEnter(); - void handleMouseLeave(); + void handleMouseEnter(QWaylandInputDevice *inputDevice); + void handleMouseLeave(QWaylandInputDevice *inputDevice); bool createDecoration(); inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } - QWaylandWindow *topLevelWindow(); + void setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape); + void restoreMouseCursor(QWaylandInputDevice *device); + QWaylandWindow *transientParent() const; QMutex *resizeMutex() { return &mResizeLock; } - -public slots: void doResize(); + void setCanResize(bool canResize); +public slots: + void requestResize(); protected: - virtual void createDecorationInstance() {} - + QWaylandScreen *mScreen; QWaylandDisplay *mDisplay; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; @@ -176,6 +175,7 @@ protected: QWaylandDecoration *mWindowDecoration; bool mMouseEventsInContentArea; Qt::MouseButtons mMousePressedInContentArea; + Qt::CursorShape m_cursorShape; QWaylandBuffer *mBuffer; WId mWindowId; @@ -185,7 +185,8 @@ protected: QMutex mResizeLock; QWaylandWindowConfigure mConfigure; - bool mResizeExposedSent; + bool mRequestResizeSent; + bool mCanResize; bool mSentInitialResize; QPoint mOffset; diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp index 673400bd..7543ba13 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp @@ -54,7 +54,7 @@ #include <QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWaylandWindowManagerIntegrationPrivate { public: @@ -93,7 +93,7 @@ bool QWaylandWindowManagerIntegration::showIsFullScreen() const void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_windowmanager") + if (interface == "qt_windowmanager") static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } @@ -108,6 +108,27 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() QGuiApplication::quit(); } +QByteArray QWaylandWindowManagerIntegration::desktopEnvironment() const +{ + const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + if (!xdgCurrentDesktop.isEmpty()) + return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE... + + // Classic fallbacks + if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION")) + return QByteArrayLiteral("KDE"); + if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID")) + return QByteArrayLiteral("GNOME"); + + // Fallback to checking $DESKTOP_SESSION (unreliable) + const QByteArray desktopSession = qgetenv("DESKTOP_SESSION"); + if (desktopSession == "gnome") + return QByteArrayLiteral("GNOME"); + if (desktopSession == "xfce") + return QByteArrayLiteral("XFCE"); + + return QByteArrayLiteral("UNKNOWN"); +} void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { @@ -134,3 +155,5 @@ bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url) openUrl_helper(url); return true; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h index 0982632d..4524ce12 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h @@ -65,6 +65,8 @@ public: explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); virtual ~QWaylandWindowManagerIntegration(); + QByteArray desktopEnvironment() const; + bool openUrl(const QUrl &url); bool openDocument(const QUrl &url); diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro index 4a1b0e88..d8aedb65 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ b/src/plugins/platforms/wayland_common/wayland_common.pro @@ -2,7 +2,6 @@ TEMPLATE = lib CONFIG += staticlib include ($$PWD/wayland_common_share.pri) -include (windowmanager_integration/windowmanager_integration.pri) SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ @@ -26,7 +25,8 @@ SOURCES += qwaylandintegration.cpp \ qwaylandqtkey.cpp \ ../../../shared/qwaylandmimehelper.cpp \ qwaylanddecoration.cpp \ - qwaylandeventthread.cpp + qwaylandeventthread.cpp\ + qwaylandwindowmanagerintegration.cpp HEADERS += qwaylandintegration.h \ qwaylandnativeinterface.h \ @@ -51,7 +51,8 @@ HEADERS += qwaylandintegration.h \ qwaylandqtkey.h \ ../../../shared/qwaylandmimehelper.h \ qwaylanddecoration.h \ - qwaylandeventthread.h + qwaylandeventthread.h \ + qwaylandwindowmanagerintegration.h contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { SOURCES += qwaylandglintegration.cpp @@ -64,6 +65,7 @@ WAYLANDCLIENTSOURCES += \ ../../../extensions/output-extension.xml \ ../../../extensions/touch-extension.xml \ ../../../extensions/qtkey-extension.xml \ + ../../../extensions/windowmanager.xml \ PLUGIN_TYPE = platforms diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri deleted file mode 100644 index 9228358e..00000000 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri +++ /dev/null @@ -1,16 +0,0 @@ -DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT - -contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - - WAYLANDCLIENTSOURCES += $$PWD/../../../../extensions/windowmanager.xml - - HEADERS += \ - $$PWD/qwaylandwindowmanagerintegration.h - - SOURCES += \ - $$PWD/qwaylandwindowmanagerintegration.cpp - -} - - - diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp index 3e18eaef..c65ad4a1 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -44,7 +44,7 @@ #include "wayland-client.h" #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(qt_xcomposite *xcomposite, uint32_t window, const QSize &size) :mSize(size) @@ -59,3 +59,5 @@ QSize QWaylandXCompositeBuffer::size() const { return mSize; } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp index 7f5c3893..e4fbfb55 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp +++ b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp @@ -45,17 +45,14 @@ #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext_brcm.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE -BrcmBuffer::BrcmBuffer(QtWayland::Compositor *compositor, const QSize &size, EGLint *data, size_t count) - : m_invertedY(false) +BrcmBuffer::BrcmBuffer(struct ::wl_client *client, uint32_t id, const QSize &size, EGLint *data, size_t count) + : QtWaylandServer::wl_buffer(client, id) , m_handle(count) + , m_invertedY(false) + , m_size(size) { - Q_UNUSED(compositor); - - base()->height = size.height(); - base()->width = size.width(); - for (size_t i = 0; i < count; ++i) m_handle[i] = data[i]; } @@ -65,17 +62,14 @@ BrcmBuffer::~BrcmBuffer() eglDestroyGlobalImageBRCM(handle()); } -struct wl_buffer_interface BrcmBuffer::buffer_interface = { - BrcmBuffer::buffer_interface_destroy -}; - -void BrcmBuffer::buffer_interface_destroy(wl_client *client, wl_resource *buffer) +void BrcmBuffer::buffer_destroy_resource(Resource *) { - Q_UNUSED(client); - Q_UNUSED(buffer); + delete this; } -void BrcmBuffer::delete_resource(struct wl_resource *resource) +void BrcmBuffer::buffer_destroy(Resource *resource) { - delete reinterpret_cast<BrcmBuffer *>(resource); + wl_resource_destroy(resource->handle); } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h index 11f49d4a..6ec5868f 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h +++ b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h @@ -41,8 +41,8 @@ #ifndef BRCMBUFFER_H #define BRCMBUFFER_H -#include <QtCompositor/qwaylandobject.h> #include <QtCompositor/private/qwlcompositor_p.h> +#include <qwayland-server-wayland.h> #include <QtCore/QSize> #include <QtCore/QVector> @@ -51,26 +51,29 @@ QT_BEGIN_NAMESPACE -class BrcmBuffer : public QtWayland::Object<struct wl_buffer> +class BrcmBuffer : public QtWaylandServer::wl_buffer { public: - BrcmBuffer(QtWayland::Compositor *compositor, const QSize &size, EGLint *data, size_t count); + BrcmBuffer(struct ::wl_client *client, uint32_t id, const QSize &size, EGLint *data, size_t count); ~BrcmBuffer(); - static struct wl_buffer_interface buffer_interface; - static void delete_resource(struct wl_resource *resource); - bool isYInverted() const { return m_invertedY; } void setInvertedY(bool inverted) { m_invertedY = inverted; } EGLint *handle() { return m_handle.data(); } - static void buffer_interface_destroy(struct wl_client *client, - struct wl_resource *buffer); + QSize size() { return m_size; } + + static BrcmBuffer *fromResource(struct ::wl_resource *resource) { return static_cast<BrcmBuffer*>(Resource::fromResource(resource)->buffer); } + +protected: + void buffer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void buffer_destroy(Resource *resource) Q_DECL_OVERRIDE; private: QVector<EGLint> m_handle; bool m_invertedY; + QSize m_size; }; QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp index 531bdc41..0ef8318f 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp +++ b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp @@ -58,9 +58,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#include "wayland-brcm-server-protocol.h" - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class BrcmEglIntegrationPrivate { @@ -79,6 +77,7 @@ public: BrcmEglIntegration::BrcmEglIntegration() : QWaylandGraphicsHardwareIntegration() + , QtWaylandServer::qt_brcm() , d_ptr(new BrcmEglIntegrationPrivate) { } @@ -121,12 +120,11 @@ void BrcmEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) return; } d->valid = true; + init(waylandDisplay->handle()); } - - wl_display_add_global(waylandDisplay->handle(), &wl_brcm_interface, this, brcm_bind_func); } -GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context) +GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { Q_D(BrcmEglIntegration); if (!d->valid) { @@ -134,7 +132,7 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLCon return 0; } - BrcmBuffer *brcmBuffer = QtWayland::wayland_cast<BrcmBuffer>(buffer); + BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); if (!d->eglQueryGlobalImageBRCM(brcmBuffer->handle(), brcmBuffer->handle() + 2)) { qWarning("eglQueryGlobalImageBRCM failed!"); @@ -162,34 +160,25 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLCon return textureId; } -void BrcmEglIntegration::create_buffer(struct wl_client *client, - struct wl_resource *brcm, - uint32_t id, - int32_t width, - int32_t height, - wl_array *data) +bool BrcmEglIntegration::isYInverted(struct ::wl_resource *) const { - BrcmEglIntegration *that = static_cast<BrcmEglIntegration *>(brcm->data); - BrcmBuffer *buffer = new BrcmBuffer(that->m_compositor->handle(), QSize(width, height), static_cast<EGLint *>(data->data), data->size / sizeof(EGLint)); - buffer->addClientResource(client, &buffer->base()->resource, - id, &wl_buffer_interface, - &BrcmBuffer::buffer_interface, - BrcmBuffer::delete_resource); + return false; } -static struct wl_brcm_interface brcm_interface = { - BrcmEglIntegration::create_buffer -}; +void BrcmEglIntegration::brcm_bind_resource(Resource *) +{ +} -void BrcmEglIntegration::brcm_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id) +void BrcmEglIntegration::brcm_create_buffer(Resource *resource, uint32_t id, int32_t width, int32_t height, wl_array *data) { - Q_UNUSED(version); - BrcmEglIntegration *integration = static_cast<BrcmEglIntegration *>(data); - wl_client_add_object(client, &wl_brcm_interface, &brcm_interface, id, integration); + new BrcmBuffer(resource->client(), id, QSize(width, height), static_cast<EGLint *>(data->data), data->size / sizeof(EGLint)); } -bool BrcmEglIntegration::isYInverted(struct wl_buffer *buffer) const +QSize BrcmEglIntegration::bufferSize(struct ::wl_resource *buffer) const { - Q_UNUSED(buffer); - return false; + BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); + + return brcmBuffer->size(); } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h index 8ed7f07a..22990561 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h +++ b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h @@ -42,31 +42,30 @@ #define BRCMEGLINTEGRATION_H #include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include "qwayland-server-brcm.h" + #include <QtCore/QScopedPointer> QT_BEGIN_NAMESPACE class BrcmEglIntegrationPrivate; -class BrcmEglIntegration : public QWaylandGraphicsHardwareIntegration +class BrcmEglIntegration : public QWaylandGraphicsHardwareIntegration, public QtWaylandServer::qt_brcm { Q_DECLARE_PRIVATE(BrcmEglIntegration) public: BrcmEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(struct wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; - static void create_buffer(struct wl_client *client, - struct wl_resource *brcm, - uint32_t id, - int32_t width, - int32_t height, - wl_array *data); + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; - static void brcm_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); +protected: + void brcm_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void brcm_create_buffer(Resource *resource, uint32_t id, int32_t width, int32_t height, wl_array *data) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(BrcmEglIntegration) diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp index 2a923cef..abf12fad 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp +++ b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp @@ -60,6 +60,7 @@ #ifndef EGL_WL_bind_wayland_display typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_buffer *buffer, EGLint attribute, EGLint *value); #endif #ifndef EGL_KHR_image @@ -72,7 +73,7 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class WaylandEglIntegrationPrivate { @@ -80,28 +81,30 @@ public: WaylandEglIntegrationPrivate() : egl_display(EGL_NO_DISPLAY) , valid(false) + , display_bound(false) , flipperConnected(false) , egl_bind_wayland_display(0) , egl_unbind_wayland_display(0) + , egl_query_wayland_buffer(0) , egl_create_image(0) , egl_destroy_image(0) , gl_egl_image_target_texture_2d(0) { } EGLDisplay egl_display; bool valid; + bool display_bound; bool flipperConnected; #ifdef EGL_WL_request_client_buffer_format QPointer<WaylandSurface> directRenderSurface; #endif PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; + PFNEGLQUERYWAYLANDBUFFERWL egl_query_wayland_buffer; PFNEGLCREATEIMAGEKHRPROC egl_create_image; PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d; - - QPlatformNativeInterface::NativeResourceForContextFunction get_egl_context; }; WaylandEglIntegration::WaylandEglIntegration() @@ -114,47 +117,66 @@ void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDispla { Q_D(WaylandEglIntegration); + const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty(); + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - if (nativeInterface) { - d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window()); - if (d->egl_display) { - const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); - if (extensionString && strstr(extensionString, "EGL_WL_bind_wayland_display")) - { - d->get_egl_context = nativeInterface->nativeResourceFunctionForContext("get_egl_context"); - if (!d->get_egl_context) { - qWarning("Failed to retrieve the get_egl_context function"); - } - d->egl_bind_wayland_display = - reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); - d->egl_unbind_wayland_display = - reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); - d->egl_create_image = - reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); - d->egl_destroy_image = - reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); - d->gl_egl_image_target_texture_2d = - reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); - - if (d->egl_bind_wayland_display - && d->get_egl_context - && d->egl_unbind_wayland_display - && d->egl_create_image - && d->egl_destroy_image - && d->gl_egl_image_target_texture_2d) { - if (d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle())) { - d->valid = true; - } - } - } - } + if (!nativeInterface) { + qWarning("Failed to initialize egl display. No native platform interface available.\n"); + return; + } + + d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window()); + if (!d->egl_display) { + qWarning("Failed to initialize egl display. Could not get EglDisplay for window.\n"); + return; + } + + const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); + if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) { + qWarning("Failed to initialize egl display. There is no EGL_WL_bind_wayland_display extension.\n"); + return; + } - if (!d->valid) - qWarning("Failed to initialize egl display\n"); + d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); + d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); + if (!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display && !ignoreBindDisplay) { + qWarning("Failed to initialize egl display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.\n"); + return; } + + d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL>(eglGetProcAddress("eglQueryWaylandBufferWL")); + if (!d->egl_query_wayland_buffer) { + qWarning("Failed to initialize egl display. Could not find eglQueryWaylandBufferWL.\n"); + return; + } + + d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + if (!d->egl_create_image || !d->egl_destroy_image) { + qWarning("Failed to initialize egl display. Could not find eglCreateImageKHR and eglDestroyImageKHR.\n"); + return; + } + + d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + if (!d->gl_egl_image_target_texture_2d) { + qWarning("Failed to initialize egl display. Could not find glEGLImageTargetTexture2DOES.\n"); + return; + } + + if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) { + d->display_bound = d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle()); + if (!d->display_bound || ignoreBindDisplay) { + qWarning("Failed to initialize egl display. Could not bind Wayland display.\n"); + return; + } + } + + d->valid = true; + + qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : ""); } -GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context) +GLuint WaylandEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { Q_D(WaylandEglIntegration); if (!d->valid) { @@ -162,10 +184,7 @@ GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGL return 0; } - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - EGLContext egl_context = d->get_egl_context(context); - - EGLImageKHR image = d->egl_create_image(d->egl_display, egl_context, + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); @@ -186,7 +205,7 @@ GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGL return textureId; } -bool WaylandEglIntegration::isYInverted(struct wl_buffer *buffer) const +bool WaylandEglIntegration::isYInverted(struct ::wl_resource *buffer) const { #ifdef EGL_WL_request_client_buffer_format return eglGetBufferYInvertedWL(buffer); @@ -203,7 +222,7 @@ bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) QPlatformScreen *screen = QPlatformScreen::platformScreenForWindow(m_compositor->window()); QPlatformScreenPageFlipper *flipper = screen ? screen->pageFlipper() : 0; if (flipper && !d->flipperConnected) { - QObject::connect(flipper, SIGNAL(bufferReleased(void*)), m_compositor->handle(), SLOT(releaseBuffer(void*))); + QObject::connect(flipper, SIGNAL(bufferReleased(QPlatformScreenBuffer*)), m_compositor->handle(), SLOT(releaseBuffer(QPlatformScreenBuffer*))); d->flipperConnected = true; } #ifdef EGL_WL_request_client_buffer_format @@ -225,14 +244,11 @@ bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) return flipper; } -void *WaylandEglIntegration::lockNativeBuffer(struct wl_buffer *buffer, QOpenGLContext *context) const +void *WaylandEglIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const { Q_D(const WaylandEglIntegration); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - EGLContext egl_context = d->get_egl_context(context); - - EGLImageKHR image = d->egl_create_image(d->egl_display, egl_context, + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); return image; @@ -246,3 +262,15 @@ void WaylandEglIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLConte d->egl_destroy_image(d->egl_display, image); } +QSize WaylandEglIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + Q_D(const WaylandEglIntegration); + + int width, height; + d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_WIDTH, &width); + d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_HEIGHT, &height); + + return QSize(width, height); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h index c22ff315..ce328429 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h +++ b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h @@ -54,15 +54,17 @@ class WaylandEglIntegration : public QWaylandGraphicsHardwareIntegration public: WaylandEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(struct wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; - bool setDirectRenderSurface(QWaylandSurface *); + bool setDirectRenderSurface(QWaylandSurface *) Q_DECL_OVERRIDE; - virtual void *lockNativeBuffer(struct wl_buffer *buffer, QOpenGLContext *context) const; - virtual void unlockNativeBuffer(void *native_buffer, QOpenGLContext *context) const; + void *lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) const Q_DECL_OVERRIDE; + void unlockNativeBuffer(void *native_buffer, QOpenGLContext *context) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(WaylandEglIntegration) diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp index 72f2fbc2..b80858b2 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp @@ -40,7 +40,6 @@ #include "xcompositeeglintegration.h" -#include <QtCompositor/qwaylandobject.h> #include "wayland-xcomposite-server-protocol.h" #include <QtCompositor/private/qwlcompositor_p.h> @@ -54,7 +53,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QVector<EGLint> eglbuildSpec() { @@ -92,9 +91,9 @@ void XCompositeEglIntegration::initializeHardware(QtWayland::Display *) new XCompositeHandler(m_compositor->handle(), mDisplay); } -GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *) +GLuint XCompositeEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<EGLint> eglConfigSpec = eglbuildSpec(); @@ -135,8 +134,17 @@ GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpe return textureId; } -bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const +bool XCompositeEglIntegration::isYInverted(struct ::wl_resource *buffer) const { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); return compositorBuffer->isYInverted(); } + +QSize XCompositeEglIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); + + return compositorBuffer->size(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h index 7a9ac449..562fce14 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h +++ b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h @@ -54,10 +54,12 @@ class XCompositeEglIntegration : public QWaylandGraphicsHardwareIntegration public: XCompositeEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: Display *mDisplay; diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp index 41d29120..421e5df1 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp @@ -40,7 +40,6 @@ #include "xcompositeglxintegration.h" -#include <QtCompositor/qwaylandobject.h> #include <QtCompositor/private/qwlcompositor_p.h> #include "wayland-xcomposite-server-protocol.h" @@ -54,7 +53,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QVector<int> qglx_buildSpec() { @@ -113,9 +112,9 @@ void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *) delete glContext; } -GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_buffer *buffer, QOpenGLContext *) +GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<int> glxConfigSpec = qglx_buildSpec(); @@ -146,7 +145,16 @@ GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_buffer *buf return textureId; } -bool XCompositeGLXIntegration::isYInverted(wl_buffer *buffer) const +bool XCompositeGLXIntegration::isYInverted(struct ::wl_resource *buffer) const { - return static_cast<XCompositeBuffer *>(buffer)->isYInverted(); + return XCompositeBuffer::fromResource(buffer)->isYInverted(); } + +QSize XCompositeGLXIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); + + return compositorBuffer->size(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h index 8e4db393..11146ef2 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h +++ b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h @@ -59,10 +59,12 @@ public: XCompositeGLXIntegration(); ~XCompositeGLXIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: PFNGLXBINDTEXIMAGEEXTPROC m_glxBindTexImageEXT; diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp index d7196b79..0457214b 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp @@ -40,41 +40,30 @@ #include "xcompositebuffer.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE XCompositeBuffer::XCompositeBuffer(Window window, const QSize &size, struct ::wl_client *client, uint32_t id) - : mWindow(window) + : QtWaylandServer::wl_buffer(client, id) + , mWindow(window) , mInvertedY(false) + , mSize(size) { - base()->height = size.height(); - base()->width = size.width(); - - base()->resource.object.id = id; - base()->resource.object.interface = &::wl_buffer_interface; - base()->resource.object.implementation = (void (**)(void))&buffer_interface; - base()->resource.data = base(); - wl_client_add_resource(client, &base()->resource); - - base()->resource.destroy = delete_resource; } -struct wl_buffer_interface XCompositeBuffer::buffer_interface = { - XCompositeBuffer::buffer_interface_destroy -}; - -void XCompositeBuffer::buffer_interface_destroy(wl_client *client, wl_resource *buffer) +void XCompositeBuffer::buffer_destroy_resource(Resource *) { - Q_UNUSED(client); - Q_UNUSED(buffer); + delete this; } -void XCompositeBuffer::delete_resource(struct wl_resource *resource) +void XCompositeBuffer::buffer_destroy(Resource *resource) { - delete static_cast<XCompositeBuffer *>(static_cast<wl_buffer *>(resource->data)); + wl_resource_destroy(resource->handle); } Window XCompositeBuffer::window() { return mWindow; } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h index 2a42aeb1..20cf399b 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h @@ -41,8 +41,8 @@ #ifndef XCOMPOSITEBUFFER_H #define XCOMPOSITEBUFFER_H -#include <QtCompositor/qwaylandobject.h> #include <private/qwlcompositor_p.h> +#include <qwayland-server-wayland.h> #include <QtCore/QSize> @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE -class XCompositeBuffer : public QtWayland::Object<struct wl_buffer> +class XCompositeBuffer : public QtWaylandServer::wl_buffer { public: XCompositeBuffer(Window window, const QSize &size, @@ -63,18 +63,21 @@ public: Window window(); - static struct wl_buffer_interface buffer_interface; - static void delete_resource(struct wl_resource *resource); - bool isYInverted() const { return mInvertedY; } void setInvertedY(bool inverted) { mInvertedY = inverted; } + QSize size() const { return mSize; } + + static XCompositeBuffer *fromResource(struct ::wl_resource *resource) { return static_cast<XCompositeBuffer*>(Resource::fromResource(resource)->buffer); } + +protected: + void buffer_destroy_resource(Resource *) Q_DECL_OVERRIDE; + void buffer_destroy(Resource *) Q_DECL_OVERRIDE; + private: Window mWindow; bool mInvertedY; - - static void buffer_interface_destroy(struct wl_client *client, - struct wl_resource *buffer); + QSize mSize; }; QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp index 10a76075..0f10d38d 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp @@ -45,7 +45,7 @@ #include "xcompositebuffer.h" #include <X11/extensions/Xcomposite.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display) : QtWaylandServer::qt_xcomposite(compositor->wl_display()) @@ -74,3 +74,5 @@ void XCompositeHandler::xcomposite_create_buffer(Resource *resource, uint32_t id { new XCompositeBuffer(Window(window), QSize(width, height), resource->client(), id); } + +QT_END_NAMESPACE diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index 6f1516f4..7264950e 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -75,7 +75,7 @@ bool parseOption(const char *str, Option *option) struct WaylandEnumEntry { QByteArray name; - int value; + QByteArray value; QByteArray summary; }; @@ -157,7 +157,7 @@ WaylandEnum readEnum(QXmlStreamReader &xml) if (xml.name() == "entry") { WaylandEnumEntry entry; entry.name = byteArrayValue(xml, "name"); - entry.value = intValue(xml, "value"); + entry.value = byteArrayValue(xml, "value"); entry.summary = byteArrayValue(xml, "summary"); result.entries << entry; } @@ -172,7 +172,7 @@ WaylandInterface readInterface(QXmlStreamReader &xml) { WaylandInterface interface; interface.name = byteArrayValue(xml, "name"); - interface.version = intValue(xml, "name", 1); + interface.version = intValue(xml, "version", 1); while (xml.readNextStartElement()) { if (xml.name() == "event") @@ -304,7 +304,7 @@ void printEnums(const QList<WaylandEnum> &enums) printf(" enum %s {\n", e.name.constData()); for (int i = 0; i < e.entries.size(); ++i) { const WaylandEnumEntry &entry = e.entries.at(i); - printf(" %s_%s = %d", e.name.constData(), entry.name.constData(), entry.value); + printf(" %s_%s = %s", e.name.constData(), entry.name.constData(), entry.value.constData()); if (i < e.entries.size() - 1) printf(","); if (!entry.summary.isNull()) @@ -364,10 +364,19 @@ void process(QXmlStreamReader &xml) printf("#define %s\n", inclusionGuard.constData()); printf("\n"); printf("#include \"wayland-server.h\"\n"); - printf("#include \"wayland-server-protocol.h\"\n"); printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); printf("#include <QByteArray>\n"); + printf("#include <QMultiMap>\n"); printf("#include <QString>\n"); + + printf("\n"); + printf("#ifndef WAYLAND_VERSION_CHECK\n"); + printf("#define WAYLAND_VERSION_CHECK(major, minor, micro) \\\n"); + printf(" ((WAYLAND_VERSION_MAJOR > (major)) || \\\n"); + printf(" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR > (minor)) || \\\n"); + printf(" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR == (minor) && WAYLAND_VERSION_MICRO >= (micro)))\n"); + printf("#endif\n"); + printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); printf("\n"); @@ -386,7 +395,6 @@ void process(QXmlStreamReader &xml) printf(" class %s\n {\n", interfaceName); printf(" public:\n"); - printf(" %s(struct ::wl_client *client, struct ::wl_resource *resource, int id);\n", interfaceName); printf(" %s(struct ::wl_client *client, int id);\n", interfaceName); printf(" %s(struct ::wl_display *display);\n", interfaceName); printf(" %s();\n", interfaceName); @@ -407,7 +415,6 @@ void process(QXmlStreamReader &xml) printf(" static Resource *fromResource(struct ::wl_resource *resource) { return static_cast<Resource *>(resource->data); }\n"); printf(" };\n"); printf("\n"); - printf(" void init(struct ::wl_client *client, struct ::wl_resource *resource, int id);\n"); printf(" void init(struct ::wl_client *client, int id);\n"); printf(" void init(struct ::wl_display *display);\n"); printf("\n"); @@ -417,8 +424,8 @@ void process(QXmlStreamReader &xml) printf(" Resource *resource() { return m_resource; }\n"); printf(" const Resource *resource() const { return m_resource; }\n"); printf("\n"); - printf(" struct ::wl_list *resourceList() { return &m_resource_list; }\n"); - printf(" const struct ::wl_list *resourceList() const { return &m_resource_list; }\n"); + printf(" QMultiMap<struct ::wl_client*, Resource*> resourceMap() { return m_resource_map; }\n"); + printf(" const QMultiMap<struct ::wl_client*, Resource*> resourceMap() const { return m_resource_map; }\n"); printf("\n"); printf(" bool isGlobal() const { return m_global != 0; }\n"); printf(" bool isResource() const { return m_resource != 0; }\n"); @@ -462,7 +469,7 @@ void process(QXmlStreamReader &xml) printf(" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n"); printf(" static void destroy_func(struct ::wl_resource *client_resource);\n"); printf("\n"); - printf(" Resource *bind(struct ::wl_client *client, struct ::wl_resource *resource, uint32_t id);\n"); + printf(" Resource *bind(struct ::wl_client *client, uint32_t id);\n"); if (hasRequests) { printf("\n"); @@ -479,9 +486,8 @@ void process(QXmlStreamReader &xml) } printf("\n"); + printf(" QMultiMap<struct ::wl_client*, Resource*> m_resource_map;\n"); printf(" Resource *m_resource;\n"); - printf(" bool m_ownResource;\n"); - printf(" struct ::wl_list m_resource_list;\n"); printf(" struct ::wl_global *m_global;\n"); printf(" };\n"); @@ -520,41 +526,29 @@ void process(QXmlStreamReader &xml) QByteArray stripped = stripInterfaceName(interface.name); const char *interfaceNameStripped = stripped.constData(); - printf(" %s::%s(struct ::wl_client *client, struct ::wl_resource *resource, int id)\n", interfaceName, interfaceName); - printf(" : m_resource(0)\n"); - printf(" , m_ownResource(false)\n"); - printf(" , m_global(0)\n"); - printf(" {\n"); - printf(" wl_list_init(&m_resource_list);\n"); - printf(" init(client, resource, id);\n"); - printf(" }\n"); - printf("\n"); - printf(" %s::%s(struct ::wl_client *client, int id)\n", interfaceName, interfaceName); - printf(" : m_resource(0)\n"); - printf(" , m_ownResource(true)\n"); + printf(" : m_resource_map()\n"); + printf(" , m_resource(0)\n"); printf(" , m_global(0)\n"); printf(" {\n"); - printf(" wl_list_init(&m_resource_list);\n"); printf(" init(client, id);\n"); printf(" }\n"); printf("\n"); printf(" %s::%s(struct ::wl_display *display)\n", interfaceName, interfaceName); - printf(" : m_resource(0)\n"); - printf(" , m_ownResource(true)\n"); + printf(" : m_resource_map()\n"); + printf(" , m_resource(0)\n"); printf(" , m_global(0)\n"); printf(" {\n"); - printf(" wl_list_init(&m_resource_list);\n"); printf(" init(display);\n"); printf(" }\n"); printf("\n"); printf(" %s::%s()\n", interfaceName, interfaceName); - printf(" : m_resource(0)\n"); + printf(" : m_resource_map()\n"); + printf(" , m_resource(0)\n"); printf(" , m_global(0)\n"); printf(" {\n"); - printf(" wl_list_init(&m_resource_list);\n"); printf(" }\n"); printf("\n"); @@ -563,28 +557,16 @@ void process(QXmlStreamReader &xml) printf(" }\n"); printf("\n"); - printf(" void %s::init(struct ::wl_client *client, struct ::wl_resource *resource, int id)\n", interfaceName); - printf(" {\n"); - printf(" m_resource = bind(client, resource, id);\n"); - printf(" }\n"); - printf("\n"); - printf(" void %s::init(struct ::wl_client *client, int id)\n", interfaceName); printf(" {\n"); - printf(" m_resource = bind(client, 0, id);\n"); + printf(" m_resource = bind(client, id);\n"); printf(" }\n"); printf("\n"); printf(" %s::Resource *%s::add(struct ::wl_client *client, int id)\n", interfaceName, interfaceName); printf(" {\n"); - printf(" return add(&m_resource_list, client, id);\n"); - printf(" }\n"); - printf("\n"); - - printf(" %s::Resource *%s::add(struct wl_list *resource_list, struct ::wl_client *client, int id)\n", interfaceName, interfaceName); - printf(" {\n"); - printf(" Resource *resource = bind(client, 0, id);\n"); - printf(" wl_list_insert(resource_list, &resource->handle->link);\n"); + printf(" Resource *resource = bind(client, id);\n"); + printf(" m_resource_map.insert(client, resource);\n"); printf(" return resource;\n"); printf(" }\n"); printf("\n"); @@ -614,7 +596,7 @@ void process(QXmlStreamReader &xml) printf(" void %s::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id)\n", interfaceName); printf(" {\n"); printf(" Q_UNUSED(version);\n"); - printf(" static_cast<%s *>(data)->bind(client, 0, id);\n", interfaceName); + printf(" static_cast<%s *>(data)->add(client, id);\n", interfaceName); printf(" }\n"); printf("\n"); @@ -622,13 +604,12 @@ void process(QXmlStreamReader &xml) printf(" {\n"); printf(" Resource *resource = Resource::fromResource(client_resource);\n"); printf(" %s *that = resource->%s;\n", interfaceName, interfaceNameStripped); - printf(" bool ownResource = that->m_ownResource;\n"); + printf(" that->m_resource_map.remove(resource->client(), resource);\n"); printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped); - printf(" if (client_resource->link.next)\n"); - printf(" wl_list_remove(&client_resource->link);\n"); printf(" delete resource;\n"); - printf(" if (ownResource)\n"); - printf(" free(client_resource);\n"); + printf("#if !WAYLAND_VERSION_CHECK(1, 2, 0)\n"); + printf(" free(client_resource);\n"); + printf("#endif\n"); printf(" }\n"); printf("\n"); @@ -636,25 +617,16 @@ void process(QXmlStreamReader &xml) QByteArray interfaceMember = hasRequests ? "&m_" + interface.name + "_interface" : QByteArray("0"); - printf(" %s::Resource *%s::bind(struct ::wl_client *client, struct ::wl_resource *handle, uint32_t id)\n", interfaceName, interfaceName); + printf(" %s::Resource *%s::bind(struct ::wl_client *client, uint32_t id)\n", interfaceName, interfaceName); printf(" {\n"); printf(" Resource *resource = %s_allocate();\n", interfaceNameStripped); printf(" resource->%s = this;\n", interfaceNameStripped); printf("\n"); - printf(" if (handle) {\n"); - printf(" handle->object.id = id;\n"); - printf(" handle->object.interface = &::%s_interface;\n", interfaceName); - printf(" handle->object.implementation = (void (**)(void))%s;\n", interfaceMember.constData()); - printf(" handle->data = resource;\n"); - printf(" wl_client_add_resource(client, handle);\n"); - printf(" } else {\n"); - printf(" handle = wl_client_add_object(client, &::%s_interface, %s, id, resource);\n", interfaceName, interfaceMember.constData()); - printf(" }\n"); + printf(" struct ::wl_resource *handle = wl_client_add_object(client, &::%s_interface, %s, id, resource);\n", interfaceName, interfaceMember.constData()); printf("\n"); printf(" handle->destroy = destroy_func;\n"); printf(" resource->handle = handle;\n"); printf(" %s_bind_resource(resource);\n", interfaceNameStripped); - printf(" wl_list_init(&resource->handle->link);\n"); printf(" return resource;\n"); printf(" }\n"); diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp index d7e51144..94a107c8 100644 --- a/src/shared/qwaylandmimehelper.cpp +++ b/src/shared/qwaylandmimehelper.cpp @@ -46,7 +46,7 @@ #include <QBuffer> #include <QImageWriter> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &mimeType) { @@ -83,3 +83,5 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString & } return content; } + +QT_END_NAMESPACE |