summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qt-compositor/compositor_api/waylandcompositor.cpp37
-rw-r--r--src/qt-compositor/compositor_api/waylandcompositor.h20
-rw-r--r--src/qt-compositor/compositor_api/waylandsurfaceitem.cpp68
-rw-r--r--src/qt-compositor/compositor_api/waylandsurfaceitem.h18
-rw-r--r--src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbbuffer.h2
-rw-r--r--src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbhwintegration.cpp12
-rw-r--r--src/qt-compositor/hardware_integration/hardware_integration.pri4
-rw-r--r--src/qt-compositor/hardware_integration/wayland_egl/wayland_egl.pri (renamed from src/qt-compositor/hardware_integration/mesa_egl/mesa_egl.pri)4
-rw-r--r--src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp (renamed from src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.cpp)35
-rw-r--r--src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.h (renamed from src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.h)18
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp11
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_glx/xcompositeglxintegration.cpp14
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_share/xcomposite_share.pri2
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_share/xcompositebuffer.h2
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.cpp9
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.h6
-rw-r--r--src/qt-compositor/hardware_integration/xcomposite_share/xlibinclude.h1
-rw-r--r--src/qt-compositor/qt-compositor.pri5
-rw-r--r--src/qt-compositor/qt-compositor.pro3
-rw-r--r--src/qt-compositor/wayland_wrapper/wayland_wrapper.pri6
-rw-r--r--src/qt-compositor/wayland_wrapper/wlcompositor.cpp54
-rw-r--r--src/qt-compositor/wayland_wrapper/wlcompositor.h10
-rw-r--r--src/qt-compositor/wayland_wrapper/wldrag.cpp271
-rw-r--r--src/qt-compositor/wayland_wrapper/wldrag.h95
-rw-r--r--src/qt-compositor/wayland_wrapper/wloutput.cpp12
-rw-r--r--src/qt-compositor/wayland_wrapper/wlshmbuffer.cpp14
-rw-r--r--src/qt-compositor/wayland_wrapper/wlshmbuffer.h6
-rw-r--r--src/qt-compositor/wayland_wrapper/wlsurface.cpp38
-rw-r--r--src/qt-compositor/wayland_wrapper/wlsurface.h3
29 files changed, 651 insertions, 129 deletions
diff --git a/src/qt-compositor/compositor_api/waylandcompositor.cpp b/src/qt-compositor/compositor_api/waylandcompositor.cpp
index ee3e949..a682237 100644
--- a/src/qt-compositor/compositor_api/waylandcompositor.cpp
+++ b/src/qt-compositor/compositor_api/waylandcompositor.cpp
@@ -44,14 +44,16 @@
#include "wayland_wrapper/wlsurface.h"
#include "wayland_wrapper/wlselection.h"
#include <QtCore/QCoreApplication>
+#include <QDebug>
#ifdef QT_COMPOSITOR_DECLARATIVE
#include "waylandsurfaceitem.h"
#endif
-WaylandCompositor::WaylandCompositor(QWidget *topLevelWidget, const char *socketName)
+WaylandCompositor::WaylandCompositor(QWindow *window, QOpenGLContext *context, const char *socketName)
: m_compositor(0)
- , m_toplevel_widget(topLevelWidget)
+ , m_glContext(context)
+ , m_toplevel_widget(window)
, m_socket_name(socketName)
{
QStringList arguments = QCoreApplication::instance()->arguments();
@@ -108,7 +110,12 @@ WaylandSurface *WaylandCompositor::directRenderSurface() const
return surf ? surf->handle() : 0;
}
-QWidget * WaylandCompositor::topLevelWidget() const
+QOpenGLContext * WaylandCompositor::glContext() const
+{
+ return m_glContext;
+}
+
+QWindow * WaylandCompositor::window() const
{
return m_toplevel_widget;
}
@@ -151,3 +158,27 @@ void WaylandCompositor::setOutputGeometry(const QRect &geometry)
{
m_compositor->setOutputGeometry(geometry);
}
+
+bool WaylandCompositor::isDragging() const
+{
+ return m_compositor->isDragging();
+}
+
+void WaylandCompositor::sendDragMoveEvent(const QPoint &global, const QPoint &local,
+ WaylandSurface *surface)
+{
+ m_compositor->sendDragMoveEvent(global, local, surface ? surface->handle() : 0);
+}
+
+void WaylandCompositor::sendDragEndEvent()
+{
+ m_compositor->sendDragEndEvent();
+}
+
+void WaylandCompositor::changeCursor(const QImage &image, int hotspotX, int hotspotY)
+{
+ Q_UNUSED(image);
+ Q_UNUSED(hotspotX);
+ Q_UNUSED(hotspotY);
+ qDebug() << "changeCursor" << image.size() << hotspotX << hotspotY;
+}
diff --git a/src/qt-compositor/compositor_api/waylandcompositor.h b/src/qt-compositor/compositor_api/waylandcompositor.h
index 1075265..11660b8 100644
--- a/src/qt-compositor/compositor_api/waylandcompositor.h
+++ b/src/qt-compositor/compositor_api/waylandcompositor.h
@@ -44,11 +44,9 @@
#include <QObject>
#include <QImage>
#include <QRect>
+#include <QOpenGLContext>
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-#include <QtOpenGL/QGLContext>
-#endif
-
+class QGLContext;
class QWidget;
class QMimeData;
class WaylandSurface;
@@ -61,7 +59,7 @@ namespace Wayland
class WaylandCompositor
{
public:
- WaylandCompositor(QWidget *topLevelWidget = 0, const char *socketName = 0);
+ WaylandCompositor(QWindow *window = 0, QOpenGLContext *context = 0, const char *socketName = 0);
virtual ~WaylandCompositor();
void frameFinished(WaylandSurface *surface = 0);
@@ -73,7 +71,8 @@ public:
void setDirectRenderSurface(WaylandSurface *surface);
WaylandSurface *directRenderSurface() const;
- QWidget *topLevelWidget()const;
+ QOpenGLContext *glContext() const;
+ QWindow *window()const;
virtual void surfaceCreated(WaylandSurface *surface) = 0;
@@ -87,11 +86,18 @@ public:
void setScreenOrientation(qint32 orientationInDegrees);
void setOutputGeometry(const QRect &outputGeometry);
+ bool isDragging() const;
+ void sendDragMoveEvent(const QPoint &global, const QPoint &local, WaylandSurface *surface);
+ void sendDragEndEvent();
+
+ virtual void changeCursor(const QImage &image, int hotspotX, int hotspotY);
+
private:
static void retainedSelectionChanged(QMimeData *mimeData, void *param);
Wayland::Compositor *m_compositor;
- QWidget *m_toplevel_widget;
+ QOpenGLContext *m_glContext;
+ QWindow *m_toplevel_widget;
QByteArray m_socket_name;
};
diff --git a/src/qt-compositor/compositor_api/waylandsurfaceitem.cpp b/src/qt-compositor/compositor_api/waylandsurfaceitem.cpp
index e503a03..31889d7 100644
--- a/src/qt-compositor/compositor_api/waylandsurfaceitem.cpp
+++ b/src/qt-compositor/compositor_api/waylandsurfaceitem.cpp
@@ -49,29 +49,32 @@
#include <QtDeclarative/QSGSimpleRectNode>
#include <QtDeclarative/QSGCanvas>
-void WaylandSurfaceItem::surfaceDamaged(const QRect &)
+class WaylandSurfaceTextureProvider : public QSGTextureProvider
{
- QSGTexture *oldTexture = m_texture;
-
- if (m_surface->type() == WaylandSurface::Texture) {
- QSGEngine::TextureOption opt = useTextureAlpha() ? QSGEngine::TextureHasAlphaChannel : QSGEngine::TextureOption(0);
+public:
+ WaylandSurfaceTextureProvider() : t(0) { }
- m_texture = canvas()->sceneGraphEngine()->createTextureFromId(m_surface->texture(),
- m_surface->geometry().size(),
- opt);
- } else {
- m_texture = canvas()->sceneGraphEngine()->createTextureFromImage(m_surface->image());
+ QSGTexture *texture() const {
+ if (t)
+ t->setFiltering(smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+ return t;
}
- delete oldTexture;
+ QSGTexture *t;
+ bool smooth;
+};
- emit textureChanged();
+void WaylandSurfaceItem::surfaceDamaged(const QRect &)
+{
+ m_damaged = true;
+ update();
}
WaylandSurfaceItem::WaylandSurfaceItem(QSGItem *parent)
: QSGItem(parent)
, m_surface(0)
, m_texture(0)
+ , m_provider(0)
, m_paintEnabled(true)
, m_touchEventsEnabled(false)
{
@@ -81,6 +84,7 @@ WaylandSurfaceItem::WaylandSurfaceItem(WaylandSurface *surface, QSGItem *parent)
: QSGItem(parent)
, m_surface(0)
, m_texture(0)
+ , m_provider(0)
, m_paintEnabled(true)
, m_touchEventsEnabled(false)
{
@@ -102,14 +106,15 @@ void WaylandSurfaceItem::init(WaylandSurface *surface)
setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
connect(surface, SIGNAL(mapped(const QSize &)), this, SLOT(surfaceMapped(const QSize &)));
connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
- connect(this, SIGNAL(textureChanged()), this, SLOT(update()));
connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
+ m_damaged = false;
+
}
WaylandSurfaceItem::~WaylandSurfaceItem()
{
- delete m_texture;
+ m_texture->deleteLater();
}
void WaylandSurfaceItem::setSurface(WaylandSurface *surface)
@@ -122,26 +127,26 @@ bool WaylandSurfaceItem::isYInverted() const
return m_surface->isYInverted();
}
-QSGTexture *WaylandSurfaceItem::texture() const
+QSGTextureProvider *WaylandSurfaceItem::textureProvider() const
{
- if (m_texture)
- m_texture->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
- return m_texture;
+ if (!m_provider)
+ m_provider = new WaylandSurfaceTextureProvider();
+ return m_provider;
}
-void WaylandSurfaceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void WaylandSurfaceItem::mousePressEvent(QMouseEvent *event)
{
if (m_surface)
m_surface->sendMousePressEvent(toSurface(event->pos()), event->button());
}
-void WaylandSurfaceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void WaylandSurfaceItem::mouseMoveEvent(QMouseEvent *event)
{
if (m_surface)
m_surface->sendMouseMoveEvent(toSurface(event->pos()));
}
-void WaylandSurfaceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void WaylandSurfaceItem::mouseReleaseEvent(QMouseEvent *event)
{
if (m_surface)
m_surface->sendMouseReleaseEvent(toSurface(event->pos()), event->button());
@@ -216,6 +221,25 @@ QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa
{
QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
+ if (m_damaged) {
+ QSGTexture *oldTexture = m_texture;
+ if (m_surface->type() == WaylandSurface::Texture) {
+ QSGEngine::TextureOption opt = useTextureAlpha() ? QSGEngine::TextureHasAlphaChannel : QSGEngine::TextureOption(0);
+ m_texture = canvas()->sceneGraphEngine()->createTextureFromId(m_surface->texture(),
+ m_surface->geometry().size(),
+ opt);
+ } else {
+ m_texture = canvas()->sceneGraphEngine()->createTextureFromImage(m_surface->image());
+ }
+ delete oldTexture;
+ m_damaged = false;
+ }
+
+ if (m_provider) {
+ m_provider->t = m_texture;
+ m_provider->smooth = smooth();
+ }
+
if (!m_texture || !m_paintEnabled) {
delete oldNode;
return 0;
@@ -255,7 +279,7 @@ void WaylandSurfaceItem::setClientRenderingEnabled(bool enabled)
m_surface->sendOnScreenVisibilityChange(enabled);
}
- emit clientRenderingEnabledChanged();
+ emit clientRenderingEnabledChanged();
}
}
diff --git a/src/qt-compositor/compositor_api/waylandsurfaceitem.h b/src/qt-compositor/compositor_api/waylandsurfaceitem.h
index bc296b5..95b1429 100644
--- a/src/qt-compositor/compositor_api/waylandsurfaceitem.h
+++ b/src/qt-compositor/compositor_api/waylandsurfaceitem.h
@@ -47,12 +47,13 @@
#include <private/qsgtextureprovider_p.h>
class WaylandSurface;
+class WaylandSurfaceTextureProvider;
+
Q_DECLARE_METATYPE(WaylandSurface*)
-class WaylandSurfaceItem : public QSGItem, public QSGTextureProvider
+class WaylandSurfaceItem : public QSGItem
{
Q_OBJECT
- Q_INTERFACES(QSGTextureProvider)
Q_PROPERTY(WaylandSurface* surface READ surface WRITE setSurface)
Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled)
Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged)
@@ -69,8 +70,8 @@ public:
Q_INVOKABLE bool isYInverted() const;
- QSGTexture *texture() const;
- const char *textureChangedSignal() const { return SIGNAL(textureChanged()); }
+ bool isTextureProvider() const { return true; }
+ QSGTextureProvider *textureProvider() const;
bool paintEnabled() const;
bool useTextureAlpha() const { return m_useTextureAlpha; }
@@ -82,9 +83,9 @@ public:
void setTouchEventsEnabled(bool enabled);
protected:
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
@@ -101,7 +102,6 @@ private slots:
void surfaceDamaged(const QRect &);
signals:
- void textureChanged();
void useTextureAlphaChanged();
void clientRenderingEnabledChanged();
void touchEventsEnabledChanged();
@@ -115,10 +115,12 @@ private:
WaylandSurface *m_surface;
QSGTexture *m_texture;
+ mutable WaylandSurfaceTextureProvider *m_provider;
bool m_paintEnabled;
bool m_useTextureAlpha;
bool m_clientRenderingEnabled;
bool m_touchEventsEnabled;
+ bool m_damaged;
};
#endif
diff --git a/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbbuffer.h b/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbbuffer.h
index d2649ce..61d431d 100644
--- a/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbbuffer.h
+++ b/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbbuffer.h
@@ -7,7 +7,7 @@
#include <wayland-server.h>
#include <QtCore/QSize>
-#include <QtGui/QApplication>
+#include <QtWidgets/QApplication>
#include <QtCore/QTextStream>
#include <QtGui/QPlatformNativeInterface>
diff --git a/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbhwintegration.cpp b/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbhwintegration.cpp
index 6e6bb53..0b021d3 100644
--- a/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbhwintegration.cpp
+++ b/src/qt-compositor/hardware_integration/dri2_xcb/dri2xcbhwintegration.cpp
@@ -22,15 +22,15 @@ GraphicsHardwareIntegration * GraphicsHardwareIntegration::createGraphicsHardwar
class DrmObject : public Wayland::Object<struct wl_object>
{
public:
- DrmObject(Wayland::Compositor *compositor, QWidget *topLevelWidget)
+ DrmObject(Wayland::Compositor *compositor, QWidget *window)
:m_compositor(compositor)
{
QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface();
- char *deviceName = static_cast<char *>(nativeInterface->nativeResourceForWidget("GraphicsDevice",topLevelWidget));
+ char *deviceName = static_cast<char *>(nativeInterface->nativeResourceForWidget("GraphicsDevice",window));
m_device_name = QByteArray(deviceName);
- m_connection = static_cast<xcb_connection_t *>(nativeInterface->nativeResourceForWidget("Connection",topLevelWidget));
- m_egl_display = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EglDisplay",topLevelWidget));
+ m_connection = static_cast<xcb_connection_t *>(nativeInterface->nativeResourceForWidget("Connection",window));
+ m_egl_display = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EglDisplay",window));
}
QByteArray deviceName()
{
@@ -108,10 +108,10 @@ Dri2XcbHWIntegration::Dri2XcbHWIntegration(WaylandCompositor *compositor)
void Dri2XcbHWIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
//we need a winId now.
- m_compositor->topLevelWidget()->winId();
+ m_compositor->window()->winId();
- m_drm_object = new DrmObject(m_compositor->handle(),m_compositor->topLevelWidget());
+ m_drm_object = new DrmObject(m_compositor->handle(),m_compositor->window());
waylandDisplay->addGlobalObject(m_drm_object->base(),&wl_drm_interface,&drm_interface,post_drm_device);
}
diff --git a/src/qt-compositor/hardware_integration/hardware_integration.pri b/src/qt-compositor/hardware_integration/hardware_integration.pri
index f5a1568..c67d99c 100644
--- a/src/qt-compositor/hardware_integration/hardware_integration.pri
+++ b/src/qt-compositor/hardware_integration/hardware_integration.pri
@@ -1,6 +1,6 @@
isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
-contains(QT_CONFIG, opengl):!isEqual(QT_WAYLAND_GL_CONFIG,nogl) {
+!mac:contains(QT_CONFIG, opengl):!isEqual(QT_WAYLAND_GL_CONFIG,nogl) {
HEADERS += \
$$PWD/graphicshardwareintegration.h
@@ -35,7 +35,7 @@ contains(QT_CONFIG, opengl):!isEqual(QT_WAYLAND_GL_CONFIG,nogl) {
}
mesa_egl {
- include (mesa_egl/mesa_egl.pri)
+ include (wayland_egl/wayland_egl.pri)
}
dri2_xcb {
include (dri2_xcb/dri2_xcb.pri)
diff --git a/src/qt-compositor/hardware_integration/mesa_egl/mesa_egl.pri b/src/qt-compositor/hardware_integration/wayland_egl/wayland_egl.pri
index 1ac2dad..2589239 100644
--- a/src/qt-compositor/hardware_integration/mesa_egl/mesa_egl.pri
+++ b/src/qt-compositor/hardware_integration/wayland_egl/wayland_egl.pri
@@ -3,7 +3,7 @@ LIBS += -lEGL
DEFINES += QT_COMPOSITOR_MESA_EGL
SOURCES += \
- $$PWD/mesaeglintegration.cpp
+ $$PWD/waylandeglintegration.cpp
HEADERS += \
- $$PWD/mesaeglintegration.h
+ $$PWD/waylandeglintegration.h
diff --git a/src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.cpp b/src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp
index c47754c..e20c262 100644
--- a/src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.cpp
+++ b/src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp
@@ -38,10 +38,11 @@
**
****************************************************************************/
-#include "mesaeglintegration.h"
+#include "waylandeglintegration.h"
-#include <QtGui/QApplication>
#include <QtGui/QPlatformNativeInterface>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QOpenGLContext>
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
@@ -53,13 +54,13 @@
GraphicsHardwareIntegration * GraphicsHardwareIntegration::createGraphicsHardwareIntegration(WaylandCompositor *compositor)
{
- return new MesaEglIntegration(compositor);
+ return new WaylandEglIntegration(compositor);
}
-class MesaEglIntegrationPrivate
+class WaylandEglIntegrationPrivate
{
public:
- MesaEglIntegrationPrivate()
+ WaylandEglIntegrationPrivate()
: egl_display(EGL_NO_DISPLAY)
, egl_context(EGL_NO_CONTEXT)
{ }
@@ -68,22 +69,22 @@ public:
bool valid;
};
-MesaEglIntegration::MesaEglIntegration(WaylandCompositor *compositor)
+WaylandEglIntegration::WaylandEglIntegration(WaylandCompositor *compositor)
: GraphicsHardwareIntegration(compositor)
- , d_ptr(new MesaEglIntegrationPrivate)
+ , d_ptr(new WaylandEglIntegrationPrivate)
{
d_ptr->valid = false;
}
-void MesaEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
+void WaylandEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
- Q_D(MesaEglIntegration);
+ Q_D(WaylandEglIntegration);
//We need a window id now :)
- m_compositor->topLevelWidget()->winId();
+ m_compositor->window()->winId();
- QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
if (nativeInterface) {
- d->egl_display = nativeInterface->nativeResourceForWidget("EglDisplay",m_compositor->topLevelWidget());
+ 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")
@@ -94,17 +95,17 @@ void MesaEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
}
if (!d->valid)
- fprintf(stderr, "Failed to initialize egl display\n");
+ qWarning("Failed to initialize egl display\n");
- d->egl_context = nativeInterface->nativeResourceForWidget("EglContext",m_compositor->topLevelWidget());
+ d->egl_context = nativeInterface->nativeResourceForContext("EglContext", m_compositor->glContext());
}
}
-GLuint MesaEglIntegration::createTextureFromBuffer(wl_buffer *buffer)
+GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer)
{
- Q_D(MesaEglIntegration);
+ Q_D(WaylandEglIntegration);
if (!d->valid) {
- fprintf(stderr, "createTextureFromBuffer() failed\n");
+ qWarning("createTextureFromBuffer() failed\n");
return 0;
}
diff --git a/src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.h b/src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.h
index a70fc85..f727051 100644
--- a/src/qt-compositor/hardware_integration/mesa_egl/mesaeglintegration.h
+++ b/src/qt-compositor/hardware_integration/wayland_egl/waylandeglintegration.h
@@ -38,27 +38,27 @@
**
****************************************************************************/
-#ifndef MESAEGLINTEGRATION_H
-#define MESAEGLINTEGRATION_H
+#ifndef WAYLANDEGLINTEGRATION_H
+#define WAYLANDEGLINTEGRATION_H
#include "hardware_integration/graphicshardwareintegration.h"
#include <QtCore/QScopedPointer>
-class MesaEglIntegrationPrivate;
+class WaylandEglIntegrationPrivate;
-class MesaEglIntegration : public GraphicsHardwareIntegration
+class WaylandEglIntegration : public GraphicsHardwareIntegration
{
- Q_DECLARE_PRIVATE(MesaEglIntegration)
+ Q_DECLARE_PRIVATE(WaylandEglIntegration)
public:
- MesaEglIntegration(WaylandCompositor *compositor);
+ WaylandEglIntegration(WaylandCompositor *compositor);
void initializeHardware(Wayland::Display *waylandDisplay);
GLuint createTextureFromBuffer(wl_buffer *buffer);
private:
- Q_DISABLE_COPY(MesaEglIntegration)
- QScopedPointer<MesaEglIntegrationPrivate> d_ptr;
+ Q_DISABLE_COPY(WaylandEglIntegration)
+ QScopedPointer<WaylandEglIntegrationPrivate> d_ptr;
};
-#endif // MESAEGLINTEGRATION_H
+#endif // WAYLANDEGLINTEGRATION_H
diff --git a/src/qt-compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp b/src/qt-compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp
index 511072d..3f47fd9 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp
+++ b/src/qt-compositor/hardware_integration/xcomposite_egl/xcompositeeglintegration.cpp
@@ -4,7 +4,7 @@
#include "wayland_wrapper/wlcompositor.h"
#include "wayland-xcomposite-server-protocol.h"
-#include <QtGui/QApplication>
+#include <QtWidgets/QApplication>
#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QPlatformGLContext>
@@ -42,10 +42,10 @@ XCompositeEglIntegration::XCompositeEglIntegration(WaylandCompositor *compositor
{
QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
if (nativeInterface) {
- mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWidget("Display",m_compositor->topLevelWidget()));
+ mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWidget("Display",m_compositor->window()));
if (!mDisplay)
qFatal("could not retireve Display from platform integration");
- mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EGLDisplay",m_compositor->topLevelWidget()));
+ mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EGLDisplay",m_compositor->window()));
if (!mEglDisplay)
qFatal("could not retrieve EGLDisplay from plaform integration");
} else {
@@ -56,11 +56,8 @@ XCompositeEglIntegration::XCompositeEglIntegration(WaylandCompositor *compositor
void XCompositeEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
- XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->topLevelWidget());
+ XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window());
waylandDisplay->addGlobalObject(handler->base(), &wl_xcomposite_interface, &XCompositeHandler::xcomposite_interface,XCompositeHandler::send_root_information);
-
- QPlatformGLContext *glContext = m_compositor->topLevelWidget()->platformWindow()->glContext();
-
}
GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer)
diff --git a/src/qt-compositor/hardware_integration/xcomposite_glx/xcompositeglxintegration.cpp b/src/qt-compositor/hardware_integration/xcomposite_glx/xcompositeglxintegration.cpp
index 9ce38a9..f109414 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_glx/xcompositeglxintegration.cpp
+++ b/src/qt-compositor/hardware_integration/xcomposite_glx/xcompositeglxintegration.cpp
@@ -4,9 +4,8 @@
#include "wayland_wrapper/wlcompositor.h"
#include "wayland-xcomposite-server-protocol.h"
-#include <QtGui/QApplication>
#include <QtGui/QPlatformNativeInterface>
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QOpenGLContext>
#include "xcompositebuffer.h"
#include "xcompositehandler.h"
@@ -43,9 +42,9 @@ XCompositeGLXIntegration::XCompositeGLXIntegration(WaylandCompositor *compositor
: GraphicsHardwareIntegration(compositor)
, mDisplay(0)
{
- QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface();
if (nativeInterface) {
- mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWidget("Display",m_compositor->topLevelWidget()));
+ mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window()));
if (!mDisplay)
qFatal("could not retireve Display from platform integration");
} else {
@@ -56,10 +55,11 @@ XCompositeGLXIntegration::XCompositeGLXIntegration(WaylandCompositor *compositor
void XCompositeGLXIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
- XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->topLevelWidget());
+ XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window());
waylandDisplay->addGlobalObject(handler->base(), &wl_xcomposite_interface, &XCompositeHandler::xcomposite_interface,XCompositeHandler::send_root_information);
- QPlatformGLContext *glContext = m_compositor->topLevelWidget()->platformWindow()->glContext();
+ QOpenGLContext *glContext = new QOpenGLContext();
+ glContext->create();
m_glxBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT"));
if (!m_glxBindTexImageEXT) {
@@ -69,6 +69,8 @@ void XCompositeGLXIntegration::initializeHardware(Wayland::Display *waylandDispl
if (!m_glxReleaseTexImageEXT) {
qDebug() << "Did not find glxReleaseTexImageExt";
}
+
+ delete glContext;
}
GLuint XCompositeGLXIntegration::createTextureFromBuffer(wl_buffer *buffer)
diff --git a/src/qt-compositor/hardware_integration/xcomposite_share/xcomposite_share.pri b/src/qt-compositor/hardware_integration/xcomposite_share/xcomposite_share.pri
index 31faa90..e4001a5 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_share/xcomposite_share.pri
+++ b/src/qt-compositor/hardware_integration/xcomposite_share/xcomposite_share.pri
@@ -10,3 +10,5 @@ SOURCES += \
$$PWD/wayland-xcomposite-protocol.c \
$$PWD/xcompositebuffer.cpp \
$$PWD/xcompositehandler.cpp
+
+QT += gui-private
diff --git a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositebuffer.h b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositebuffer.h
index 42b20ee..5c34e4b 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositebuffer.h
+++ b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositebuffer.h
@@ -10,7 +10,7 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtWidgets/QWidget>
#include <X11/X.h>
diff --git a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.cpp b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.cpp
index bb10bba..4a64eb8 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.cpp
+++ b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.cpp
@@ -5,14 +5,13 @@
#include "xcompositebuffer.h"
#include <X11/extensions/Xcomposite.h>
-XCompositeHandler::XCompositeHandler(Wayland::Compositor *compositor, Display *display, QWidget *topLevelWidget)
+XCompositeHandler::XCompositeHandler(Wayland::Compositor *compositor, Display *display, QWindow *window)
: mCompositor(compositor)
- , mTopLevelWidget(topLevelWidget)
+ , mwindow(window)
, mDisplay(display)
{
- mFakeRootWidget = new QWidget(mCompositor->topLevelWidget());
- mFakeRootWidget->setGeometry(-1,-1,1,1);
- mFakeRootWidget->setAttribute(Qt::WA_NativeWindow);
+ mFakeRootWidget = new QWindow(mCompositor->window());
+ mFakeRootWidget->setGeometry(QRect(-1,-1,1,1));
int composite_event_base, composite_error_base;
if (XCompositeQueryExtension(mDisplay, &composite_event_base, &composite_error_base)) {
diff --git a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.h b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.h
index dc85473..7126e14 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.h
+++ b/src/qt-compositor/hardware_integration/xcomposite_share/xcompositehandler.h
@@ -8,7 +8,7 @@
class XCompositeHandler : public Wayland::Object<struct wl_object>
{
public:
- XCompositeHandler(Wayland::Compositor *compositor, Display *display, QWidget *topLevelWidget);
+ XCompositeHandler(Wayland::Compositor *compositor, Display *display, QWindow *window);
void createBuffer(struct wl_client *client, uint32_t id, Window window, const QSize &size, struct wl_visual *visual);
static void send_root_information(struct wl_client *client, struct wl_object *global, uint32_t version);
@@ -16,8 +16,8 @@ public:
private:
Wayland::Compositor *mCompositor;
- QWidget *mTopLevelWidget;
- QWidget *mFakeRootWidget;
+ QWindow *mwindow;
+ QWindow *mFakeRootWidget;
Display *mDisplay;
static void create_buffer(struct wl_client *client,
diff --git a/src/qt-compositor/hardware_integration/xcomposite_share/xlibinclude.h b/src/qt-compositor/hardware_integration/xcomposite_share/xlibinclude.h
index 9253776..dfb0c29 100644
--- a/src/qt-compositor/hardware_integration/xcomposite_share/xlibinclude.h
+++ b/src/qt-compositor/hardware_integration/xcomposite_share/xlibinclude.h
@@ -7,6 +7,7 @@
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
#include <QtGui/QCursor>
+#include <QtGui/private/qguiapplication_p.h>
#include <X11/Xlib.h>
#include "X11/extensions/Xcomposite.h"
diff --git a/src/qt-compositor/qt-compositor.pri b/src/qt-compositor/qt-compositor.pri
index ee143e3..a791985 100644
--- a/src/qt-compositor/qt-compositor.pri
+++ b/src/qt-compositor/qt-compositor.pri
@@ -1,10 +1,9 @@
INCLUDEPATH += $$PWD
DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT
-use_pkgconfig {
+!mac:use_pkgconfig {
QMAKE_CXXFLAGS += $$system(pkg-config --cflags wayland-server)
- #for some reason this is not included in the cflags line
- INCLUDEPATH += $$system(pkg-config --variable=includedir wayland-server)
+
LIBS += $$system(pkg-config --libs wayland-server)
#set the rpath
diff --git a/src/qt-compositor/qt-compositor.pro b/src/qt-compositor/qt-compositor.pro
index 1e11e89..d24766d 100644
--- a/src/qt-compositor/qt-compositor.pro
+++ b/src/qt-compositor/qt-compositor.pro
@@ -11,3 +11,6 @@ headers.path = $$headers_path/qt-compositor
headers.files = $$HEADERS
INSTALLS = target headers
+
+QT += gui-private
+QT += widgets-private
diff --git a/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri b/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
index 348267e..16a0e7e 100644
--- a/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
@@ -4,7 +4,8 @@ HEADERS += \
$$PWD/wloutput.h \
$$PWD/wlshmbuffer.h \
$$PWD/wlsurface.h \
- $$PWD/wlselection.h
+ $$PWD/wlselection.h \
+ $$PWD/wldrag.h
SOURCES += \
$$PWD/wlcompositor.cpp \
@@ -12,4 +13,5 @@ SOURCES += \
$$PWD/wloutput.cpp \
$$PWD/wlshmbuffer.cpp \
$$PWD/wlsurface.cpp \
- $$PWD/wlselection.cpp
+ $$PWD/wlselection.cpp \
+ $$PWD/wldrag.cpp
diff --git a/src/qt-compositor/wayland_wrapper/wlcompositor.cpp b/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
index 032e14d..453a9ac 100644
--- a/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
@@ -45,11 +45,9 @@
#include "wlshmbuffer.h"
#include "wlsurface.h"
#include "wlselection.h"
+#include "wldrag.h"
#include "waylandcompositor.h"
-#include <QApplication>
-#include <QDesktopWidget>
-
#include <QSocketNotifier>
#include <QDebug>
@@ -72,6 +70,18 @@
namespace Wayland {
+static Compositor *compositor;
+
+static ShmBuffer *currentCursor;
+
+static void shmBufferDestroyed(ShmBuffer *buf)
+{
+ if (currentCursor == buf) {
+ compositor->qtCompositor()->changeCursor(QImage(), 0, 0);
+ currentCursor = 0;
+ }
+}
+
void input_device_attach(struct wl_client *client,
struct wl_input_device *device_base,
uint32_t time,
@@ -80,11 +90,16 @@ void input_device_attach(struct wl_client *client,
Q_UNUSED(client);
Q_UNUSED(device_base);
Q_UNUSED(time);
- Q_UNUSED(buffer);
Q_UNUSED(x);
Q_UNUSED(y);
- qDebug() << "Client %p input device attach" << client;
+ qDebug() << "Client input device attach" << client << buffer << x << y;
+
+ ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(buffer->user_data);
+ if (shmBuffer) {
+ compositor->qtCompositor()->changeCursor(shmBuffer->image(), x, y);
+ currentCursor = shmBuffer;
+ }
}
const static struct wl_input_device_interface input_device_interface = {
@@ -142,10 +157,9 @@ void shell_drag(struct wl_client *client,
struct wl_shell *shell,
uint32_t id)
{
- Q_UNUSED(client);
Q_UNUSED(shell);
- Q_UNUSED(id);
qDebug() << "shellDrag";
+ Drag::instance()->create(client, id);
}
void shell_selection(struct wl_client *client,
@@ -189,8 +203,6 @@ const static struct wl_shell_interface shell_interface = {
set_fullscreen
};
-static Compositor *compositor;
-
Compositor *Compositor::instance()
{
return compositor;
@@ -208,11 +220,14 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
#if defined (QT_COMPOSITOR_WAYLAND_GL)
, m_graphics_hw_integration(0)
#endif
+ , m_dragActive(false)
{
compositor = this;
+ m_shm.addDestroyCallback(shmBufferDestroyed);
#if defined (QT_COMPOSITOR_WAYLAND_GL)
- if (qt_compositor->topLevelWidget()->platformWindowFormat().windowApi() != QPlatformWindowFormat::Raster)
+ QWindow *window = qt_compositor->window();
+ if (window && window->surfaceType() != QWindow::RasterSurface)
m_graphics_hw_integration = GraphicsHardwareIntegration::createGraphicsHardwareIntegration(qt_compositor);
#endif
m_windowManagerWaylandProtocol = new WindowManagerServerIntegration(this);
@@ -396,9 +411,9 @@ Surface *Compositor::pointerFocus() const
return m_pointerFocusSurface;
}
-QWidget * Compositor::topLevelWidget() const
+QWindow *Compositor::window() const
{
- return m_qt_compositor->topLevelWidget();
+ return m_qt_compositor->window();
}
GraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const
@@ -480,3 +495,18 @@ QList<Wayland::Surface *> Wayland::Compositor::surfacesForClient(wl_client *clie
return ret;
}
+bool Wayland::Compositor::isDragging() const
+{
+ return m_dragActive;
+}
+
+void Wayland::Compositor::sendDragMoveEvent(const QPoint &global, const QPoint &local,
+ Surface *surface)
+{
+ Drag::instance()->dragMove(global, local, surface);
+}
+
+void Wayland::Compositor::sendDragEndEvent()
+{
+ Drag::instance()->dragEnd();
+}
diff --git a/src/qt-compositor/wayland_wrapper/wlcompositor.h b/src/qt-compositor/wayland_wrapper/wlcompositor.h
index 647bdf6..6f357ab 100644
--- a/src/qt-compositor/wayland_wrapper/wlcompositor.h
+++ b/src/qt-compositor/wayland_wrapper/wlcompositor.h
@@ -51,7 +51,6 @@
class WaylandCompositor;
class GraphicsHardwareIntegration;
-class QWidget;
class WindowManagerServerIntegration;
namespace Wayland {
@@ -88,7 +87,7 @@ public:
static uint currentTimeMsecs();
- QWidget *topLevelWidget() const;
+ QWindow *window() const;
GraphicsHardwareIntegration *graphicsHWIntegration() const;
void initializeHardwareIntegration();
@@ -110,6 +109,10 @@ public:
void setScreenOrientation(qint32 orientationInDegrees);
void setOutputGeometry(const QRect &geometry);
+ bool isDragging() const;
+ void sendDragMoveEvent(const QPoint &global, const QPoint &local, Surface *surface);
+ void sendDragEndEvent();
+
signals:
void clientAdded(wl_client *client);
@@ -149,6 +152,9 @@ private:
GraphicsHardwareIntegration *m_graphics_hw_integration;
#endif
WindowManagerServerIntegration *m_windowManagerWaylandProtocol;
+
+ bool m_dragActive;
+ friend class Drag;
};
}
diff --git a/src/qt-compositor/wayland_wrapper/wldrag.cpp b/src/qt-compositor/wayland_wrapper/wldrag.cpp
new file mode 100644
index 0000000..734d617
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldrag.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** 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 Nokia Corporation 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.
+**
+****************************************************************************/
+
+#include "wldrag.h"
+#include "wlcompositor.h"
+#include "wlsurface.h"
+#include <wayland-util.h>
+#include <string.h>
+#include <unistd.h>
+#include <QDebug>
+
+namespace Wayland {
+
+void Drag::dragOfferAccept(struct wl_client *client,
+ struct wl_drag_offer *offer, uint32_t time, const char *type)
+{
+ qDebug() << "dragOfferAccept" << client << offer << type;
+ Q_UNUSED(time);
+ Drag *self = Drag::instance();
+ struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
+ drag->target = client;
+ QString wantedType = QString::fromLatin1(type);
+ if (!self->m_offerList.contains(wantedType)) {
+ qWarning("dragOfferAccept: Client accepted type '%s' that has not been offered",
+ qPrintable(type));
+ type = 0;
+ }
+ wl_client_post_event(drag->source->client, &drag->resource.object,
+ WL_DRAG_TARGET, type);
+}
+
+void Drag::dragOfferReceive(struct wl_client *client,
+ struct wl_drag_offer *offer, int fd)
+{
+ qDebug() << "dragOfferReceive" << client << offer << fd;
+ Q_UNUSED(client);
+ struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
+ wl_client_post_event(drag->source->client, &drag->resource.object,
+ WL_DRAG_FINISH, fd);
+ close(fd);
+}
+
+void Drag::dragOfferReject(struct wl_client *client, struct wl_drag_offer *offer)
+{
+ qDebug() << "dragOfferReject" << client << offer;
+ Q_UNUSED(client);
+ struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
+ if (drag->target == client)
+ drag->target = 0;
+ wl_client_post_event(drag->source->client, &drag->resource.object,
+ WL_DRAG_REJECT);
+}
+
+const struct wl_drag_offer_interface Drag::dragOfferInterface = {
+ Drag::dragOfferAccept,
+ Drag::dragOfferReceive,
+ Drag::dragOfferReject
+};
+
+void Drag::dragOffer(struct wl_client *client, struct wl_drag *drag, const char *type)
+{
+ qDebug() << "dragOffer" << client << drag << type;
+ Q_UNUSED(client);
+ Q_UNUSED(drag);
+ instance()->m_offerList.append(QString::fromLatin1(type));
+}
+
+void Drag::dragActivate(struct wl_client *client,
+ struct wl_drag *drag,
+ struct wl_surface *surface,
+ struct wl_input_device *device, uint32_t time)
+{
+ qDebug() << "dragActivate" << client << drag << surface;
+ Q_UNUSED(client);
+ Q_UNUSED(device);
+ Q_UNUSED(time);
+ Drag *self = Drag::instance();
+ drag->source = surface;
+ drag->drag_offer.object.interface = &wl_drag_offer_interface;
+ drag->drag_offer.object.implementation = (void (**)()) &dragOfferInterface;
+ wl_display *dpy = Compositor::instance()->wl_display();
+ wl_display_add_object(dpy, &drag->drag_offer.object);
+ wl_display_add_global(dpy, &drag->drag_offer.object, 0);
+ Surface *focus = Compositor::instance()->pointerFocus();
+ QPoint pos;
+ if (focus)
+ pos = focus->lastMousePos();
+ // ### Sending local as global, which is wrong, but oh well.
+ self->setPointerFocus(surface, pos, pos);
+}
+
+void Drag::setPointerFocus(wl_surface *surface, const QPoint &global, const QPoint &local)
+{
+ if (!m_drag)
+ return;
+
+ if (m_drag->drag_focus == surface)
+ return;
+
+ uint timestamp = Compositor::currentTimeMsecs();
+ if (m_drag->drag_focus
+ && (!surface || m_drag->drag_focus->client != surface->client)) {
+ qDebug() << "WL_DRAG_OFFER_POINTER_FOCUS with null";
+ wl_client_post_event(m_drag->drag_focus->client,
+ &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_POINTER_FOCUS,
+ timestamp, 0, 0, 0, 0, 0);
+ }
+ if (surface
+ && (!m_drag->drag_focus || m_drag->drag_focus->client != surface->client)) {
+ wl_client_post_global(surface->client,
+ &m_drag->drag_offer.object);
+ foreach (const QString &format, m_offerList) {
+ QByteArray mimeTypeBa = format.toLatin1();
+ qDebug() << "WL_DRAG_OFFER_OFFER" << mimeTypeBa;
+ wl_client_post_event(surface->client, &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_OFFER, mimeTypeBa.constData());
+ }
+ }
+
+ if (surface) {
+ qDebug() << "WL_DRAG_OFFER_POINTER_FOCUS" << surface << global << local;
+ wl_client_post_event(surface->client,
+ &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_POINTER_FOCUS,
+ timestamp, surface,
+ global.x(), global.y(), local.x(), local.y());
+ Compositor::instance()->m_dragActive = true;
+ }
+
+ m_drag->drag_focus = surface;
+ m_drag->target = 0;
+}
+
+void Drag::dragDestroy(struct wl_client *client, struct wl_drag *drag)
+{
+ qDebug() << "dragDestroy";
+ wl_resource_destroy(&drag->resource, client, Compositor::currentTimeMsecs());
+}
+
+const struct wl_drag_interface Drag::dragInterface = {
+ Drag::dragOffer,
+ Drag::dragActivate,
+ Drag::dragDestroy
+};
+
+void Drag::destroyDrag(struct wl_resource *resource, struct wl_client *client)
+{
+ Q_UNUSED(client);
+ struct wl_drag *drag = container_of(resource, struct wl_drag, resource);
+ wl_display *dpy = Compositor::instance()->wl_display();
+ wl_display_remove_global(dpy, &drag->drag_offer.object);
+ delete drag;
+}
+
+void Drag::create(struct wl_client *client, uint32_t id)
+{
+ Q_UNUSED(client);
+ m_offerList.clear();
+ wl_drag *drag = new wl_drag;
+ memset(drag, 0, sizeof *drag);
+ drag->resource.object.id = id;
+ drag->resource.object.interface = &wl_drag_interface;
+ drag->resource.object.implementation = (void (**)()) &dragInterface;
+ drag->resource.destroy = destroyDrag;
+ wl_client_add_resource(client, &drag->resource);
+ m_drag = drag;
+}
+
+void Drag::done(bool sending)
+{
+ qDebug() << "drag done";
+ Compositor::instance()->m_dragActive = false;
+ if (!sending) {
+ setPointerFocus(0, QPoint(), QPoint());
+ // ### hack: Send a pointerFocus with null surface to the source too, this is
+ // mandatory even if the previous pointerFocus went to the same client, otherwise
+ // Qt will not know the drag is over without a drop.
+ wl_client_post_event(m_drag->source->client,
+ &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_POINTER_FOCUS,
+ Compositor::instance()->currentTimeMsecs(),
+ 0, 0, 0, 0, 0);
+ }
+ m_drag = 0;
+}
+
+void Drag::dragMove(const QPoint &global, const QPoint &local, Surface *surface)
+{
+ if (!m_drag)
+ return;
+// qDebug() << "dragMove" << global << local << surface;
+ if (surface) {
+ setPointerFocus(surface->base(), global, local);
+ uint timestamp = Compositor::currentTimeMsecs();
+ wl_client_post_event(surface->base()->client,
+ &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_MOTION,
+ timestamp,
+ global.x(), global.y(), local.x(), local.y());
+ } else {
+ setPointerFocus(0, global, local);
+ }
+}
+
+void Drag::dragEnd()
+{
+ qDebug() << "dragEnd";
+ if (!m_drag)
+ return;
+ if (m_drag->target) {
+ qDebug() << "WL_DRAG_OFFER_DROP" << m_drag->target;
+ wl_client_post_event(m_drag->target,
+ &m_drag->drag_offer.object,
+ WL_DRAG_OFFER_DROP);
+ done(true);
+ } else {
+ done(false);
+ }
+}
+
+Q_GLOBAL_STATIC(Drag, globalInstance)
+
+Drag *Drag::instance()
+{
+ return globalInstance();
+}
+
+Drag::Drag()
+ : m_drag(0)
+{
+}
+
+}
diff --git a/src/qt-compositor/wayland_wrapper/wldrag.h b/src/qt-compositor/wayland_wrapper/wldrag.h
new file mode 100644
index 0000000..e9a2b9a
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldrag.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** 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 Nokia Corporation 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.
+**
+****************************************************************************/
+
+#ifndef WLDRAG_H
+#define WLDRAG_H
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QMimeData>
+#include <wayland-server.h>
+
+QT_BEGIN_NAMESPACE
+class QSocketNotifier;
+QT_END_NAMESPACE
+
+namespace Wayland {
+
+class Surface;
+
+class Drag : public QObject
+{
+ Q_OBJECT
+
+public:
+ static Drag *instance();
+ Drag();
+ void create(struct wl_client *client, uint32_t id);
+ void dragMove(const QPoint &global, const QPoint &local, Surface *surface);
+ void dragEnd();
+
+private:
+ static void destroyDrag(struct wl_resource *resource, struct wl_client *client);
+
+ static void dragOffer(struct wl_client *client, struct wl_drag *drag, const char *type);
+ static void dragActivate(struct wl_client *client,
+ struct wl_drag *drag,
+ struct wl_surface *surface,
+ struct wl_input_device *device, uint32_t time);
+ static void dragDestroy(struct wl_client *client, struct wl_drag *drag);
+ static const struct wl_drag_interface dragInterface;
+
+ static void dragOfferAccept(struct wl_client *client,
+ struct wl_drag_offer *offer, uint32_t time, const char *type);
+ static void dragOfferReceive(struct wl_client *client,
+ struct wl_drag_offer *offer, int fd);
+ static void dragOfferReject(struct wl_client *client, struct wl_drag_offer *offer);
+ static const struct wl_drag_offer_interface dragOfferInterface;
+
+ void setPointerFocus(wl_surface *surface, const QPoint &global, const QPoint &local);
+ void done(bool sending);
+
+ QStringList m_offerList;
+ wl_drag *m_drag;
+};
+
+}
+
+#endif // WLDRAG_H
diff --git a/src/qt-compositor/wayland_wrapper/wloutput.cpp b/src/qt-compositor/wayland_wrapper/wloutput.cpp
index 39bf7c9..ba3e45a 100644
--- a/src/qt-compositor/wayland_wrapper/wloutput.cpp
+++ b/src/qt-compositor/wayland_wrapper/wloutput.cpp
@@ -39,9 +39,9 @@
****************************************************************************/
#include "wloutput.h"
-
-#include <QtGui/QApplication>
-#include <QtGui/QDesktopWidget>
+#include <QGuiApplication>
+#include <QtGui/QScreen>
+#include <QRect>
namespace Wayland {
@@ -58,11 +58,11 @@ void output_post_geometry(struct wl_client *client, struct wl_object *global, ui
Output::Output()
- : m_geometry(QPoint(0,0), QApplication::desktop()->screenGeometry().size())
- , m_displayId(-1)
+ : m_displayId(-1)
, m_numQueued(0)
{
-
+ QScreen *screen = QGuiApplication::primaryScreen();
+ m_geometry = QRect(QPoint(0, 0), screen->availableGeometry().size());
}
void Output::setGeometry(const QRect &geometry)
diff --git a/src/qt-compositor/wayland_wrapper/wlshmbuffer.cpp b/src/qt-compositor/wayland_wrapper/wlshmbuffer.cpp
index e3fb4bd..2ecb2b0 100644
--- a/src/qt-compositor/wayland_wrapper/wlshmbuffer.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlshmbuffer.cpp
@@ -93,9 +93,12 @@ void ShmBuffer::damage()
}
+static ShmHandler *handlerInstance;
+
ShmHandler::ShmHandler(Display *display)
: m_display(display)
{
+ handlerInstance = this;
m_shm = wl_shm_init(m_display->handle(),&shm_callbacks);
}
@@ -133,7 +136,16 @@ void ShmHandler::buffer_damaged_callback(struct wl_buffer *buffer,
void ShmHandler::buffer_destroyed_callback(struct wl_buffer *buffer)
{
- delete static_cast<ShmBuffer *>(buffer->user_data);
+ ShmBuffer *shmbuf = static_cast<ShmBuffer *>(buffer->user_data);
+ for (int i = 0; i < handlerInstance->m_extraCallbacks.count(); ++i)
+ handlerInstance->m_extraCallbacks.at(i)(shmbuf);
+ delete shmbuf;
+}
+
+void ShmHandler::addDestroyCallback(DestroyCallback callback)
+{
+ if (!m_extraCallbacks.contains(callback))
+ m_extraCallbacks.append(callback);
}
}
diff --git a/src/qt-compositor/wayland_wrapper/wlshmbuffer.h b/src/qt-compositor/wayland_wrapper/wlshmbuffer.h
index ee3184d..e8092ce 100644
--- a/src/qt-compositor/wayland_wrapper/wlshmbuffer.h
+++ b/src/qt-compositor/wayland_wrapper/wlshmbuffer.h
@@ -76,6 +76,9 @@ public:
ShmHandler(Display *display);
~ShmHandler();
+ typedef void (*DestroyCallback)(ShmBuffer *);
+ void addDestroyCallback(DestroyCallback callback);
+
private:
Display *m_display;
struct wl_shm *m_shm;
@@ -86,8 +89,9 @@ private:
int32_t x, int32_t y,
int32_t width, int32_t height);
static void buffer_destroyed_callback(struct wl_buffer *buffer);
-
+ QList<DestroyCallback> m_extraCallbacks;
};
+
}
#endif //WL_SHMBUFFER_H
diff --git a/src/qt-compositor/wayland_wrapper/wlsurface.cpp b/src/qt-compositor/wayland_wrapper/wlsurface.cpp
index f13466d..f8862ee 100644
--- a/src/qt-compositor/wayland_wrapper/wlsurface.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlsurface.cpp
@@ -49,11 +49,13 @@
#include <wayland-server.h>
+#ifdef Q_OS_LINUX
#include <linux/input.h>
+#endif
#ifdef QT_COMPOSITOR_WAYLAND_GL
#include "hardware_integration/graphicshardwareintegration.h"
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#endif
#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
@@ -71,6 +73,7 @@ public:
, textureCreatedForBuffer(false)
, directRenderBuffer(0)
, processId(0)
+ , previousBuffer(0)
, surfaceBuffer(0)
, surfaceType(WaylandSurface::Invalid)
@@ -96,6 +99,10 @@ public:
void attach(struct wl_buffer *buffer) {
bool emitMap = !surfaceBuffer;
+ if (surfaceBuffer && ! textureCreatedForBuffer) {
+ qWarning() << "### WaylandSurface::attach() releasing undisplayed buffer ###";
+ wl_client_post_event(client,&surfaceBuffer->resource.object,WL_BUFFER_RELEASE);
+ }
surfaceBuffer = buffer;
surfaceType = WaylandSurface::Invalid;
textureCreatedForBuffer = false;
@@ -114,11 +121,14 @@ public:
GLuint texture_id;
#endif
bool textureCreatedForBuffer;
- wl_buffer *directRenderBuffer;
+ struct wl_buffer *directRenderBuffer;
qint64 processId;
QByteArray authenticationToken;
QVariantMap windowProperties;
+ QPoint lastMousePos;
+
+ struct wl_buffer *previousBuffer;
private:
struct wl_buffer *surfaceBuffer;
WaylandSurface::Type surfaceType;
@@ -202,8 +212,13 @@ void Surface::damage(const QRect &rect)
glDeleteTextures(1,&d->texture_id);
d->textureCreatedForBuffer = false;
}
- if (d->compositor->graphicsHWIntegration()->postBuffer(d->directRenderBuffer))
+ if (d->compositor->graphicsHWIntegration()->postBuffer(d->buffer())) {
+ if (d->previousBuffer) {
+ wl_client_post_event(d->client,&d->previousBuffer->resource.object,WL_BUFFER_RELEASE);
+ }
+ d->previousBuffer = d->buffer();
return;
+ }
}
#endif
@@ -229,8 +244,12 @@ GLuint Surface::textureId() const
if (d->compositor->graphicsHWIntegration() && d->type() == WaylandSurface::Texture
&& !d->textureCreatedForBuffer) {
glDeleteTextures(1,&d->texture_id);
+ if (d->previousBuffer) {
+ wl_client_post_event(d->client,&d->previousBuffer->resource.object,WL_BUFFER_RELEASE);
+ }
Surface *that = const_cast<Surface *>(this);
GraphicsHardwareIntegration *hwIntegration = d->compositor->graphicsHWIntegration();
+ that->d_func()->previousBuffer = d->buffer();
that->d_func()->texture_id = hwIntegration->createTextureFromBuffer(d->buffer());
that->d_func()->textureCreatedForBuffer = true;
}
@@ -297,6 +316,11 @@ void Surface::setWindowProperty(const QString &name, const QVariant &value, bool
uint32_t toWaylandButton(Qt::MouseButton button)
{
+#ifndef BTN_LEFT
+uint32_t BTN_LEFT = 0x110;
+uint32_t BTN_RIGHT = 0x111;
+uint32_t BTN_MIDDLE = 0x112;
+#endif
switch (button) {
case Qt::LeftButton:
return BTN_LEFT;
@@ -305,6 +329,13 @@ uint32_t toWaylandButton(Qt::MouseButton button)
default:
return BTN_MIDDLE;
}
+
+}
+
+QPoint Surface::lastMousePos() const
+{
+ Q_D(const Surface);
+ return d->lastMousePos;
}
void Surface::sendMousePressEvent(int x, int y, Qt::MouseButton button)
@@ -333,6 +364,7 @@ void Surface::sendMouseMoveEvent(int x, int y)
{
Q_D(Surface);
if (d->client) {
+ d->lastMousePos = QPoint(x, y);
uint32_t time = d->compositor->currentTimeMsecs();
d->compositor->setPointerFocus(this, QPoint(x, y));
wl_client_post_event(d->client, &d->compositor->defaultInputDevice()->object,
diff --git a/src/qt-compositor/wayland_wrapper/wlsurface.h b/src/qt-compositor/wayland_wrapper/wlsurface.h
index c921496..31e10c7 100644
--- a/src/qt-compositor/wayland_wrapper/wlsurface.h
+++ b/src/qt-compositor/wayland_wrapper/wlsurface.h
@@ -104,6 +104,7 @@ public:
qint64 processId() const;
void setProcessId(qint64 processId);
QByteArray authenticationToken() const;
+ void setAuthenticationToken(const QByteArray &authenticationToken);
QVariantMap windowProperties() const;
QVariant windowProperty(const QString &propertyName) const;
@@ -111,6 +112,8 @@ public:
void setSurfaceCreationFinished(bool isCreated);
+ QPoint lastMousePos() const;
+
protected:
QScopedPointer<SurfacePrivate> d_ptr;
private: