summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 10:46:23 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 10:46:23 +0200
commit21a2ce41a8efb6c5ab4ab2674458309bc9f031b7 (patch)
tree927045bf52f3367551cb4af17aa6b5738408c1bb
parente47eb9057bf08834885ba6ef5e593d6f1844405c (diff)
parentaf711da1389c86c969d4872ec0936a90c46e1343 (diff)
Merge branch 'refactor'
Conflicts: src/qt-compositor/compositor_api/waylandcompositor.cpp src/qt-compositor/wayland_wrapper/wloutput.cpp
-rw-r--r--examples/qml-compositor/main.cpp20
-rw-r--r--examples/qml-compositor/qml-compositor.pro7
-rw-r--r--examples/qwidget-compositor-mdi/main.cpp21
-rw-r--r--examples/qwidget-compositor-mdi/qt-compositor.pro2
-rw-r--r--examples/qwidget-compositor/main.cpp208
-rw-r--r--examples/qwidget-compositor/qwidget-compositor.pro15
-rw-r--r--examples/qwindow-compositor/main.cpp62
-rw-r--r--examples/qwindow-compositor/qopenglwindow.cpp13
-rw-r--r--examples/qwindow-compositor/qopenglwindow.h22
-rw-r--r--examples/qwindow-compositor/qwindow-compositor.pro48
-rw-r--r--examples/qwindow-compositor/qwindowcompositor.cpp91
-rw-r--r--examples/qwindow-compositor/qwindowcompositor.h37
-rw-r--r--examples/qwindow-compositor/surfacerenderer.cpp109
-rw-r--r--examples/qwindow-compositor/surfacerenderer.h29
-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
43 files changed, 1226 insertions, 238 deletions
diff --git a/examples/qml-compositor/main.cpp b/examples/qml-compositor/main.cpp
index 066cfee..fdf27b3 100644
--- a/examples/qml-compositor/main.cpp
+++ b/examples/qml-compositor/main.cpp
@@ -57,14 +57,13 @@ class QmlCompositor : public QSGView, public WaylandCompositor
{
Q_OBJECT
public:
- QmlCompositor() : WaylandCompositor(this) {
- setMouseTracking(true);
+ QmlCompositor() : WaylandCompositor(this, const_cast<QOpenGLContext *>(QOpenGLContext::currentContext())) {
+ //setMouseTracking(true);
setSource(QUrl(QLatin1String("qrc:qml/QmlCompositor/main.qml")));
setResizeMode(QSGView::SizeRootObjectToView);
winId();
- if (platformWindow()) {
- platformWindow()->glContext();
- }
+
+ connect(this, SIGNAL(frameSwapped()), this, SLOT(frameSwappedSlot()));
}
signals:
@@ -103,17 +102,15 @@ private slots:
emit windowDestroyed(QVariant::fromValue(static_cast<QSGItem *>(item)));
}
+ void frameSwappedSlot() {
+ frameFinished();
+ }
+
protected:
void surfaceCreated(WaylandSurface *surface) {
connect(surface, SIGNAL(mapped(const QSize &)), this, SLOT(surfaceMapped(const QSize &)));
}
- void paintEvent(QPaintEvent *event) {
- QSGView::paintEvent(event);
- frameFinished();
- glFinish();
- }
-
private:
QMap<QObject *, WaylandSurfaceItem *> m_windowMap;
};
@@ -133,7 +130,6 @@ int main(int argc, char *argv[])
QObject::connect(&compositor, SIGNAL(windowResized(QVariant)), compositor.rootObject(), SLOT(windowResized(QVariant)));
return app.exec();
-
}
#include "main.moc"
diff --git a/examples/qml-compositor/qml-compositor.pro b/examples/qml-compositor/qml-compositor.pro
index 7aed420..4390133 100644
--- a/examples/qml-compositor/qml-compositor.pro
+++ b/examples/qml-compositor/qml-compositor.pro
@@ -17,6 +17,13 @@ LIBS += -L ../../lib
QT += declarative
QT += opengl
+# to be removed once scenegraph gets rid of its widget dependencies
+QT += widgets widgets-private
+
+!isEmpty(QT.core.MAJOR_VERSION):greaterThan(QT.core.MAJOR_VERSION, 4) {
+ QT += core-private gui-private declarative-private opengl-private
+}
+
include (../../src/qt-compositor/qt-compositor.pri)
# Input
diff --git a/examples/qwidget-compositor-mdi/main.cpp b/examples/qwidget-compositor-mdi/main.cpp
index 7f32c09..752014a 100644
--- a/examples/qwidget-compositor-mdi/main.cpp
+++ b/examples/qwidget-compositor-mdi/main.cpp
@@ -51,13 +51,12 @@
#include <QPainter>
#include <QMouseEvent>
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-#include <QGLContext>
-#include <QGLWidget>
-#endif
-
#include <QDebug>
+// This has no GL support, meaning only readback-based GL clients will work.
+// Others, e.g. xcomposite-glx, will typically crash the client as there is no
+// corresponding integration on the compositor side.
+
class QSurfaceWidget : public QWidget
{
Q_OBJECT
@@ -70,6 +69,12 @@ public:
private slots:
void surfaceDamaged(const QRect &rect) {
+
+ // NB! This is dangerous. There may be no paintEvent() called, for
+ // example if the mdi subwindow is completely covered by another one.
+ // And in that case there is no frameFinished() -> the client may block
+ // in its waitForFrameSync() for a long time...
+
update(rect);
}
@@ -133,9 +138,9 @@ private slots:
void surfaceMapped(const QSize &size) {
m_surface->setInputFocus();
- widget()->setMinimumSize(size);
- resize(sizeHint());
- show();
+ widget()->setMinimumSize(size);
+ resize(sizeHint());
+ show();
}
void surfaceDamaged(const QRect &) {
diff --git a/examples/qwidget-compositor-mdi/qt-compositor.pro b/examples/qwidget-compositor-mdi/qt-compositor.pro
index 59db258..3cd110b 100644
--- a/examples/qwidget-compositor-mdi/qt-compositor.pro
+++ b/examples/qwidget-compositor-mdi/qt-compositor.pro
@@ -10,6 +10,8 @@ DESTDIR=$$PWD/../../bin/
include (../../src/qt-compositor/qt-compositor.pri)
+QT += widgets gui-private widgets-private
+
# Input
SOURCES += main.cpp
diff --git a/examples/qwidget-compositor/main.cpp b/examples/qwidget-compositor/main.cpp
index 13b4b57..8e71860 100644
--- a/examples/qwidget-compositor/main.cpp
+++ b/examples/qwidget-compositor/main.cpp
@@ -55,23 +55,23 @@
#include <QDebug>
-#include "qtouchscreen.h"
-
-static int touch_x_min, touch_x_max, touch_y_min, touch_y_max;
-
-class QWidgetCompositor;
-
-class TouchObserver : public QTouchScreenObserver
-{
-public:
- TouchObserver(QWidgetCompositor *compositor)
- : m_compositor(compositor) { }
- void touch_configure(int x_min, int x_max, int y_min, int y_max);
- void touch_point(QEvent::Type state, const QList<QWindowSystemInterface::TouchPoint> &points);
-
-private:
- QWidgetCompositor *m_compositor;
-};
+//#include "qtouchscreen.h"
+//
+//static int touch_x_min, touch_x_max, touch_y_min, touch_y_max;
+//
+//class QWidgetCompositor;
+//
+//class TouchObserver : public QTouchScreenObserver
+//{
+//public:
+// TouchObserver(QWidgetCompositor *compositor)
+// : m_compositor(compositor) { }
+// void touch_configure(int x_min, int x_max, int y_min, int y_max);
+// void touch_point(QEvent::Type state, const QList<QWindowSystemInterface::TouchPoint> &points);
+//
+//private:
+// QWidgetCompositor *m_compositor;
+//};
#ifdef QT_COMPOSITOR_WAYLAND_GL
class QWidgetCompositor : public QGLWidget, public WaylandCompositor
@@ -81,7 +81,11 @@ class QWidgetCompositor : public QWidget, public WaylandCompositor
{
Q_OBJECT
public:
- QWidgetCompositor() : WaylandCompositor(this), m_dragSurface(0) {
+ QWidgetCompositor()
+ : WaylandCompositor(windowHandle(),const_cast<QGLContext *>(context())->contextHandle())
+ , m_moveSurface(0)
+ , m_dragSourceSurface(0)
+ {
setMouseTracking(true);
setRetainedSelectionEnabled(true);
m_background = QImage(QLatin1String("background.jpg"));
@@ -89,8 +93,8 @@ public:
//so that clients can successfully initialize egl
winId();
#ifdef QT_COMPOSITOR_WAYLAND_GL
- if (platformWindow()) {
- platformWindow()->glContext();
+ if (windowHandle()) {
+// windowHandle()->surfaceHandle();
}
#endif
}
@@ -151,12 +155,7 @@ protected:
for (int i = 0; i < m_surfaces.size(); ++i) {
if (m_surfaces.at(i)->type() == WaylandSurface::Texture) {
#ifdef QT_COMPOSITOR_WAYLAND_GL
- QPlatformGLContext *glcontext = platformWindow()->glContext();
- if (glcontext) {
- QGLContext *context = QGLContext::fromPlatformGLContext(glcontext);
- context->makeCurrent();
- context->drawTexture(m_surfaces.at(i)->geometry(),m_surfaces.at(i)->texture());
- }
+ drawTexture(m_surfaces.at(i)->geometry(), m_surfaces.at(i)->texture());
break;
#endif //QT_COMPOSITOR_WAYLAND_GL
} else if (m_surfaces.at(i)->type() == WaylandSurface::Shm) {
@@ -165,6 +164,9 @@ protected:
}
}
+ if (!m_cursor.isNull())
+ p.drawImage(m_cursorPos - m_cursorHotspot, m_cursor);
+
frameFinished();
#ifdef QT_COMPOSITOR_WAYLAND_GL
@@ -190,12 +192,15 @@ protected:
}
void mousePressEvent(QMouseEvent *e) {
+ m_cursorPos = e->pos();
+ if (!m_cursor.isNull())
+ update();
QPoint local;
if (WaylandSurface *surface = surfaceAt(e->pos(), &local)) {
raise(surface);
if (e->modifiers() & Qt::ControlModifier) {
- m_dragSurface = surface;
- m_dragOffset = local;
+ m_moveSurface = surface;
+ m_moveOffset = local;
} else {
surface->sendMousePressEvent(local, e->button());
}
@@ -203,10 +208,27 @@ protected:
}
void mouseMoveEvent(QMouseEvent *e) {
- if (m_dragSurface) {
- QRect geometry = m_dragSurface->geometry();
- geometry.moveTo(e->pos() - m_dragOffset);
- m_dragSurface->setGeometry(geometry);
+ m_cursorPos = e->pos();
+ if (!m_cursor.isNull())
+ update();
+ if (isDragging()) {
+ QPoint global = e->pos(); // "global" here means the window of the compositor
+ QPoint local;
+ WaylandSurface *surface = surfaceAt(e->pos(), &local);
+ if (surface) {
+ if (!m_dragSourceSurface)
+ m_dragSourceSurface = surface;
+ if (m_dragSourceSurface == surface)
+ m_lastDragSourcePos = local;
+ raise(surface);
+ }
+ sendDragMoveEvent(global, local, surface);
+ return;
+ }
+ if (m_moveSurface) {
+ QRect geometry = m_moveSurface->geometry();
+ geometry.moveTo(e->pos() - m_moveOffset);
+ m_moveSurface->setGeometry(geometry);
update();
return;
}
@@ -216,8 +238,16 @@ protected:
}
void mouseReleaseEvent(QMouseEvent *e) {
- if (m_dragSurface) {
- m_dragSurface = 0;
+ if (isDragging()) {
+ sendDragEndEvent();
+ if (m_dragSourceSurface) {
+ // Must send a release event to the source too, no matter where the cursor is now.
+ m_dragSourceSurface->sendMouseReleaseEvent(m_lastDragSourcePos, e->button());
+ m_dragSourceSurface = 0;
+ }
+ }
+ if (m_moveSurface) {
+ m_moveSurface = 0;
return;
}
QPoint local;
@@ -250,64 +280,76 @@ protected:
return 0;
}
+ void changeCursor(const QImage &image, int hotspotX, int hotspotY) {
+ m_cursor = image;
+ m_cursorHotspot = QPoint(hotspotX, hotspotY);
+ update();
+ }
+
private:
QImage m_background;
QPixmap m_backgroundScaled;
QList<WaylandSurface *> m_surfaces;
- WaylandSurface *m_dragSurface;
- QPoint m_dragOffset;
+ WaylandSurface *m_moveSurface;
+ QPoint m_moveOffset;
+ WaylandSurface *m_dragSourceSurface;
+ QPoint m_lastDragSourcePos;
+
+ QImage m_cursor;
+ QPoint m_cursorPos;
+ QPoint m_cursorHotspot;
friend class TouchObserver;
};
-void TouchObserver::touch_configure(int x_min, int x_max, int y_min, int y_max)
-{
- touch_x_min = x_min;
- touch_x_max = x_max;
- touch_y_min = y_min;
- touch_y_max = y_max;
-}
-
-void TouchObserver::touch_point(QEvent::Type state, const QList<QWindowSystemInterface::TouchPoint> &points)
-{
- Q_UNUSED(state);
- WaylandSurface *focusSurface = m_compositor->inputFocus();
- if (focusSurface) {
- if (points.isEmpty())
- return;
- for (int i = 0; i < points.count(); ++i) {
- const QWindowSystemInterface::TouchPoint &point(points.at(i));
-
- // These are hw coordinates.
- int x = int(point.area.left());
- int y = int(point.area.top());
-
- // Wayland expects surface-relative coordinates.
-
- // Translate so that (0, 0) is the top-left corner.
- x = qBound(touch_x_min, x, touch_x_max) - touch_x_min;
- y = qBound(touch_y_min, y, touch_y_max) - touch_y_min;
-
- // Get a normalized position in range 0..1.
- const int hw_w = touch_x_max - touch_x_min;
- const int hw_h = touch_y_max - touch_y_min;
- const qreal nx = x / qreal(hw_w);
- const qreal ny = y / qreal(hw_h);
-
- // Map to surface.
- QRect winRect(focusSurface->geometry());
- x = int(nx * winRect.width());
- y = int(ny * winRect.height());
-
- focusSurface->sendTouchPointEvent(point.id,
- x, y,
- point.state);
- }
- focusSurface->sendTouchFrameEvent();
- }
-}
+//void TouchObserver::touch_configure(int x_min, int x_max, int y_min, int y_max)
+//{
+// touch_x_min = x_min;
+// touch_x_max = x_max;
+// touch_y_min = y_min;
+// touch_y_max = y_max;
+//}
+
+//void TouchObserver::touch_point(QEvent::Type state, const QList<QWindowSystemInterface::TouchPoint> &points)
+//{
+// Q_UNUSED(state);
+// WaylandSurface *focusSurface = m_compositor->inputFocus();
+// if (focusSurface) {
+// if (points.isEmpty())
+// return;
+// for (int i = 0; i < points.count(); ++i) {
+// const QWindowSystemInterface::TouchPoint &point(points.at(i));
+
+// // These are hw coordinates.
+// int x = int(point.area.left());
+// int y = int(point.area.top());
+
+// // Wayland expects surface-relative coordinates.
+
+// // Translate so that (0, 0) is the top-left corner.
+// x = qBound(touch_x_min, x, touch_x_max) - touch_x_min;
+// y = qBound(touch_y_min, y, touch_y_max) - touch_y_min;
+
+// // Get a normalized position in range 0..1.
+// const int hw_w = touch_x_max - touch_x_min;
+// const int hw_h = touch_y_max - touch_y_min;
+// const qreal nx = x / qreal(hw_w);
+// const qreal ny = y / qreal(hw_h);
+
+// // Map to surface.
+// QRect winRect(focusSurface->geometry());
+// x = int(nx * winRect.width());
+// y = int(ny * winRect.height());
+
+// focusSurface->sendTouchPointEvent(point.id,
+// x, y,
+// point.state);
+// }
+// focusSurface->sendTouchFrameEvent();
+// }
+//}
int main(int argc, char *argv[])
{
@@ -317,7 +359,7 @@ int main(int argc, char *argv[])
compositor.resize(800, 600);
compositor.show();
- QTouchScreenHandlerThread t(QString(), new TouchObserver(&compositor));
+// QTouchScreenHandlerThread t(QString(), new TouchObserver(&compositor));
return app.exec();
}
diff --git a/examples/qwidget-compositor/qwidget-compositor.pro b/examples/qwidget-compositor/qwidget-compositor.pro
index 353b34c..88dd757 100644
--- a/examples/qwidget-compositor/qwidget-compositor.pro
+++ b/examples/qwidget-compositor/qwidget-compositor.pro
@@ -23,9 +23,12 @@ isEmpty(QT_SOURCE_TREE) {
} else {
QTBASE = $$QT_SOURCE_TREE
}
-TOUCHSCREEN_BASE = $$QTBASE/src/plugins/generic/touchscreen
-SOURCES += $$TOUCHSCREEN_BASE/qtouchscreen.cpp
-HEADERS += $$TOUCHSCREEN_BASE/qtouchscreen.h
-INCLUDEPATH += $$TOUCHSCREEN_BASE
-LIBS += -ludev -lmtdev
-QT += gui-private
+#TOUCHSCREEN_BASE = $$QTBASE/src/plugins/generic/touchscreen
+#SOURCES += $$TOUCHSCREEN_BASE/qtouchscreen.cpp
+#HEADERS += $$TOUCHSCREEN_BASE/qtouchscreen.h
+#INCLUDEPATH += $$TOUCHSCREEN_BASE
+#LIBS += -ludev -lmtdev
+QT += gui-private widgets widgets-private
+
+target.path += $$[QT_INSTALL_DATA]/bin
+INSTALLS += target
diff --git a/examples/qwindow-compositor/main.cpp b/examples/qwindow-compositor/main.cpp
new file mode 100644
index 0000000..d9e8b47
--- /dev/null
+++ b/examples/qwindow-compositor/main.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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 "qopenglwindow.h"
+#include "qwindowcompositor.h"
+
+#include <QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/QSurfaceFormat>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ QRect screenGeometry = screen->availableGeometry();
+
+ QSurfaceFormat format;
+ format.setDepthBufferSize(16);
+
+ QOpenGLWindow *window = new QOpenGLWindow(format, screenGeometry);
+
+ QWindowCompositor compositor(window);
+ window->show();
+
+ return app.exec();
+}
diff --git a/examples/qwindow-compositor/qopenglwindow.cpp b/examples/qwindow-compositor/qopenglwindow.cpp
new file mode 100644
index 0000000..2a53c4c
--- /dev/null
+++ b/examples/qwindow-compositor/qopenglwindow.cpp
@@ -0,0 +1,13 @@
+#include "qopenglwindow.h"
+
+QOpenGLWindow::QOpenGLWindow(const QSurfaceFormat &format, const QRect &geometry)
+ : m_format(format)
+{
+ setSurfaceType(QWindow::OpenGLSurface);
+ setGeometry(geometry);
+ setFormat(format);
+ create();
+ m_context = new QOpenGLContext;
+ m_context->setFormat(format);
+ m_context->create();
+}
diff --git a/examples/qwindow-compositor/qopenglwindow.h b/examples/qwindow-compositor/qopenglwindow.h
new file mode 100644
index 0000000..12ccb45
--- /dev/null
+++ b/examples/qwindow-compositor/qopenglwindow.h
@@ -0,0 +1,22 @@
+#ifndef QOPENGLWINDOW_H
+#define QOPENGLWINDOW_H
+
+#include <QWindow>
+#include <QOpenGLContext>
+#include <QSurfaceFormat>
+
+class QOpenGLWindow : public QWindow
+{
+public:
+ QOpenGLWindow(const QSurfaceFormat &format, const QRect &geometry);
+public:
+ QOpenGLContext* context() { return m_context; }
+ bool makeCurrent() { return m_context->makeCurrent(this); }
+ void swapBuffers() { m_context->swapBuffers(this); }
+
+private:
+ QOpenGLContext *m_context;
+ QSurfaceFormat m_format;
+};
+
+#endif // QOPENGLWINDOW_H
diff --git a/examples/qwindow-compositor/qwindow-compositor.pro b/examples/qwindow-compositor/qwindow-compositor.pro
new file mode 100644
index 0000000..5b160a8
--- /dev/null
+++ b/examples/qwindow-compositor/qwindow-compositor.pro
@@ -0,0 +1,48 @@
+TEMPLATE = app
+TARGET = qwindow-compositor
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# comment out the following to not use pkg-config in the pri files
+CONFIG += use_pkgconfig
+
+DESTDIR=$$PWD/../../bin/
+
+include (../../src/qt-compositor/qt-compositor.pri)
+
+# Input
+SOURCES += main.cpp \
+ qopenglwindow.cpp \
+ surfacerenderer.cpp \
+ qwindowcompositor.cpp
+
+CONFIG += qt warn_on debug create_prl link_prl
+OBJECTS_DIR = .obj/release-shared
+MOC_DIR = .moc/release-shared
+
+# Touch support
+isEmpty(QT_SOURCE_TREE) {
+ QTBASE = $$[QT_INSTALL_DATA]
+} else {
+ QTBASE = $$QT_SOURCE_TREE
+}
+#TOUCHSCREEN_BASE = $$QTBASE/src/plugins/generic/touchscreen
+#SOURCES += $$TOUCHSCREEN_BASE/qtouchscreen.cpp
+#HEADERS += $$TOUCHSCREEN_BASE/qtouchscreen.h
+#INCLUDEPATH += $$TOUCHSCREEN_BASE
+#LIBS += -ludev -lmtdev
+QT += gui opengl
+
+target.path += $$[QT_INSTALL_BINS]
+INSTALLS += target
+
+HEADERS += \
+ qopenglwindow.h \
+ surfacerenderer.h \
+ qwindowcompositor.h
+
+
+
+
+
+
diff --git a/examples/qwindow-compositor/qwindowcompositor.cpp b/examples/qwindow-compositor/qwindowcompositor.cpp
new file mode 100644
index 0000000..1b0c002
--- /dev/null
+++ b/examples/qwindow-compositor/qwindowcompositor.cpp
@@ -0,0 +1,91 @@
+#include "qwindowcompositor.h"
+
+QWindowCompositor::QWindowCompositor(QOpenGLWindow *window)
+ : WaylandCompositor(window, window->context())
+ , m_window(window)
+{
+ m_backgroundImage = QImage(QLatin1String("background.jpg"));
+ m_renderer = new SurfaceRenderer(m_window->context(), m_window);
+ m_backgroundTexture = m_renderer->textureFromImage(m_backgroundImage);
+
+ render();
+}
+
+void QWindowCompositor::surfaceDestroyed(QObject *object)
+{
+ WaylandSurface *surface = static_cast<WaylandSurface *>(object);
+ m_surfaces.removeAll(surface);
+ render();
+}
+
+void QWindowCompositor::surfaceMapped(const QSize &size)
+{
+ WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender());
+ QPoint pos;
+ if (!m_surfaces.contains(surface)) {
+ uint px = 1 + (qrand() % (m_window->width() - size.width() - 2));
+ uint py = 1 + (qrand() % (m_window->height() - size.height() - 2));
+ pos = QPoint(px, py);
+ surface->setGeometry(QRect(pos, size));
+ m_surfaces.append(surface);
+ } else {
+ surface->setGeometry(QRect(window()->geometry().topLeft(),size));
+ }
+ setInputFocus(surface);
+ render();
+}
+
+void QWindowCompositor::surfaceDamaged(const QRect &rect)
+{
+ WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender());
+ surfaceDamaged(surface, rect);
+}
+
+void QWindowCompositor::surfaceDamaged(WaylandSurface *surface, const QRect &rect)
+{
+ Q_UNUSED(surface)
+ Q_UNUSED(rect)
+ render();
+}
+
+void QWindowCompositor::surfaceCreated(WaylandSurface *surface)
+{
+ connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
+ connect(surface, SIGNAL(mapped(const QSize &)), this, SLOT(surfaceMapped(const QSize &)));
+ connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
+ render();
+}
+
+WaylandSurface * QWindowCompositor::surfaceAt(const QPoint &point, QPoint *local)
+{
+ for (int i = m_surfaces.size() - 1; i >= 0; --i) {
+ if (m_surfaces.at(i)->geometry().contains(point)) {
+ if (local)
+ *local = point - m_surfaces.at(i)->geometry().topLeft();
+ return m_surfaces.at(i);
+ }
+ }
+ return 0;
+}
+
+void QWindowCompositor::render()
+{
+ m_window->makeCurrent();
+
+ //Draw the background Image texture
+ m_renderer->drawTexture(m_backgroundTexture, m_window->geometry(), 0);
+
+ //Iterate all surfaces in m_surfaces
+ //If type == WaylandSurface::Texture draw textureId at geometry
+ foreach (WaylandSurface *surface, m_surfaces) {
+ if (surface->type() == WaylandSurface::Texture)
+ m_renderer->drawTexture(surface->texture(), surface->geometry(), 1); //depth argument should be dynamic (focused should be top).
+ else if (surface->type() == WaylandSurface::Shm)
+ m_renderer->drawImage(surface->image(), surface->geometry());
+ }
+ frameFinished();
+ glFinish();
+ m_window->swapBuffers();
+ m_window->context()->doneCurrent();
+}
+
diff --git a/examples/qwindow-compositor/qwindowcompositor.h b/examples/qwindow-compositor/qwindowcompositor.h
new file mode 100644
index 0000000..efb448e
--- /dev/null
+++ b/examples/qwindow-compositor/qwindowcompositor.h
@@ -0,0 +1,37 @@
+#ifndef QWINDOWCOMPOSITOR_H
+#define QWINDOWCOMPOSITOR_H
+
+#include "waylandcompositor.h"
+#include "waylandsurface.h"
+#include "surfacerenderer.h"
+#include "qopenglwindow.h"
+
+#include <QObject>
+
+class QWindowCompositor : public QObject, public WaylandCompositor
+{
+ Q_OBJECT
+public:
+ QWindowCompositor(QOpenGLWindow *window);
+private slots:
+ void surfaceDestroyed(QObject *object);
+ void surfaceMapped(const QSize &size);
+ void surfaceDamaged(const QRect &rect);
+
+protected:
+ void surfaceDamaged(WaylandSurface *surface, const QRect &rect);
+ void surfaceCreated(WaylandSurface *surface);
+
+ WaylandSurface* surfaceAt(const QPoint &point, QPoint *local = 0);
+
+ void render();
+
+private:
+ QOpenGLWindow *m_window;
+ QImage m_backgroundImage;
+ GLuint m_backgroundTexture;
+ QList<WaylandSurface *> m_surfaces;
+ SurfaceRenderer *m_renderer;
+};
+
+#endif // QWINDOWCOMPOSITOR_H
diff --git a/examples/qwindow-compositor/surfacerenderer.cpp b/examples/qwindow-compositor/surfacerenderer.cpp
new file mode 100644
index 0000000..10ed41e
--- /dev/null
+++ b/examples/qwindow-compositor/surfacerenderer.cpp
@@ -0,0 +1,109 @@
+#include "surfacerenderer.h"
+
+#include <QOpenGLFunctions>
+
+SurfaceRenderer::SurfaceRenderer(QOpenGLContext *context, QWindow *surface)
+ : m_context(context)
+ , m_surface(surface)
+{
+ const char *textureVertexProgram =
+ "uniform highp mat4 matrix;\n"
+ "attribute highp vec3 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = matrix * vec4(vertexCoordEntry, 1);\n"
+ "}\n";
+
+ const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, textureCoord);\n"
+ "}\n";
+
+ m_context->makeCurrent(m_surface);
+
+ //Enable transparent windows
+ glEnable(GL_BLEND);
+ glBlendFunc (GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
+
+ //May need to manually set context here
+ m_shaderProgram = new QGLShaderProgram();
+
+ m_shaderProgram->addShaderFromSourceCode(QGLShader::Vertex, textureVertexProgram);
+ m_shaderProgram->addShaderFromSourceCode(QGLShader::Fragment, textureFragmentProgram);
+ m_shaderProgram->link();
+ m_shaderProgram->bind();
+
+ m_vertexCoordEntry = m_shaderProgram->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_shaderProgram->attributeLocation("textureCoordEntry");
+ m_matrixLocation = m_shaderProgram->uniformLocation("matrix");
+
+}
+
+void SurfaceRenderer::drawImage(const QImage &image, const QRect &geometry)
+{
+ drawTexture(textureFromImage(image), geometry);
+}
+
+void SurfaceRenderer::drawTexture(int textureId, const QRect &geometry, int depth)
+{
+ GLfloat zValue = depth / 1000.0f;
+ //Set Texture and Vertex coordinates
+ GLfloat textureCoordinates[] = { 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+
+ GLfloat vertexCoordinates[] = { geometry.left(), geometry.top(), zValue,
+ geometry.right(), geometry.top(), zValue,
+ geometry.right(), geometry.bottom(), zValue,
+ geometry.left(), geometry.bottom(), zValue
+ };
+
+ //Set matrix to transfrom geometry values into gl coordinate space.
+ m_transformMatrix.setToIdentity();
+ m_transformMatrix.scale( 2.0f / m_surface->geometry().width(), 2.0f / m_surface->geometry().height());
+ m_transformMatrix.translate(-m_surface->geometry().width() / 2.0f, -m_surface->geometry().height() / 2.0f);
+
+ m_shaderProgram->bind();
+
+ //attach the data!
+ m_context->functions()->glEnableVertexAttribArray(m_vertexCoordEntry);
+ m_context->functions()->glEnableVertexAttribArray(m_textureCoordEntry);
+
+ m_context->functions()->glVertexAttribPointer(m_vertexCoordEntry, 3, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ m_context->functions()->glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_shaderProgram->setUniformValue(m_matrixLocation, m_transformMatrix);
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ m_context->functions()->glDisableVertexAttribArray(m_vertexCoordEntry);
+ m_context->functions()->glDisableVertexAttribArray(m_textureCoordEntry);
+ m_shaderProgram->release();
+}
+
+GLuint SurfaceRenderer::textureFromImage(const QImage &image)
+{
+ //TODO: Replace this line
+ QImage convertedImage = QGLWidget::convertToGLFormat(image);
+
+ GLuint textureId;
+ //Copy QImage data to Texture
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, convertedImage.width(), convertedImage.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, convertedImage.constBits());
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ return textureId;
+}
diff --git a/examples/qwindow-compositor/surfacerenderer.h b/examples/qwindow-compositor/surfacerenderer.h
new file mode 100644
index 0000000..df60b9d
--- /dev/null
+++ b/examples/qwindow-compositor/surfacerenderer.h
@@ -0,0 +1,29 @@
+#ifndef SURFACERENDERER_H
+#define SURFACERENDERER_H
+
+#include <QOpenGLContext>
+#include <QGLShaderProgram>
+#include <QWindow>
+
+class SurfaceRenderer
+{
+public:
+ SurfaceRenderer(QOpenGLContext *context, QWindow *surface);
+
+ void drawImage(const QImage &image, const QRect &geometry);
+ void drawTexture(int textureId, const QRect &geometry, int depth = 0);
+ GLuint textureFromImage(const QImage &image);
+
+private:
+
+ QOpenGLContext *m_context;
+ QWindow *m_surface;
+ QGLShaderProgram *m_shaderProgram;
+ QMatrix4x4 m_transformMatrix;
+
+ int m_matrixLocation;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+};
+
+#endif // SURFACERENDERER_H
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: