summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp101
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h30
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.cpp4
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp37
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h9
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp56
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h14
-rw-r--r--src/plugins/platforms/wayland/wayland.pro6
9 files changed, 104 insertions, 154 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 1c1702f..4f456c9 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -45,11 +45,14 @@
#include "qwaylandscreen.h"
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
+#include "qwaylandeventthread.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
#endif
+#include <QtGui/QApplication>
+
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
@@ -110,117 +113,53 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = {
QWaylandDisplay::shellHandleConfigure,
};
-void QWaylandDisplay::outputHandleGeometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- QWaylandDisplay *waylandDisplay = (QWaylandDisplay *) data;
-
- QRect outputRect = QRect(x, y, width, height);
- waylandDisplay->createNewScreen(output, outputRect);
-}
-
-const struct wl_output_listener QWaylandDisplay::outputListener = {
- QWaylandDisplay::outputHandleGeometry
-};
-
-void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
- uint32_t id,
- const char *interface,
- uint32_t version, void *data)
+void QWaylandDisplay::displayHandleGlobal(uint32_t id, QByteArray interface, uint32_t version)
{
Q_UNUSED(version);
- QWaylandDisplay *qwd = (QWaylandDisplay *) data;
-
- if (strcmp(interface, "compositor") == 0) {
- qwd->mCompositor = wl_compositor_create(display, id);
- } else if (strcmp(interface, "shm") == 0) {
- qwd->mShm = wl_shm_create(display, id);
- } else if (strcmp(interface, "shell") == 0) {
- qwd->mShell = wl_shell_create(display, id);
- wl_shell_add_listener(qwd->mShell, &shellListener, qwd);
- } else if (strcmp(interface, "output") == 0) {
- struct wl_output *output = wl_output_create(display, id);
- wl_output_add_listener(output, &outputListener, qwd);
- } else if (strcmp(interface, "input_device") == 0) {
+
+ if (interface == "compositor") {
+ mCompositor = wl_compositor_create(mDisplay, id);
+ } else if (interface == "shm") {
+ mShm = wl_shm_create(mDisplay, id);
+ } else if (interface == "shell"){
+ mShell = wl_shell_create(mDisplay, id);
+ wl_shell_add_listener(mShell, &shellListener, this);
+ } else if (interface == "input_device") {
QWaylandInputDevice *inputDevice =
- new QWaylandInputDevice(display, id);
- qwd->mInputDevices.append(inputDevice);
+ new QWaylandInputDevice(mDisplay, id);
+ mInputDevices.append(inputDevice);
}
}
-void QWaylandDisplay::iterate()
-{
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE);
-}
-
-void QWaylandDisplay::readEvents(void)
-{
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
-}
-
-int
-QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
-{
- QWaylandDisplay *qwd = (QWaylandDisplay *) data;
-
- /* FIXME: We get a callback here when we ask wl_display for the
- * fd, but at that point we don't have the socket notifier as we
- * need the fd to create that. We'll probably need to split that
- * API into get_fd and set_update_func functions. */
- if (qwd->mWriteNotifier == NULL)
- return 0;
-
- qwd->mWriteNotifier->setEnabled(mask & WL_DISPLAY_WRITABLE);
-
- return 0;
-}
-
-void QWaylandDisplay::flushRequests(void)
-{
- wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
-}
-
QWaylandDisplay::QWaylandDisplay(void)
- : mWriteNotifier(0)
{
mDisplay = wl_display_connect(NULL);
if (mDisplay == NULL) {
qErrnoWarning(errno, "Failed to create display");
qFatal("No wayland connection available.");
}
-
- wl_display_add_global_listener(mDisplay,
- QWaylandDisplay::displayHandleGlobal, this);
-
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
- readEvents();
+ mEventThread = new QWaylandEventThread(this);
+
+
+ mEventThread->waitForScreens();
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration->initialize();
#endif
- int fd = wl_display_get_fd(mDisplay, sourceUpdate, this);
- mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mReadNotifier,
- SIGNAL(activated(int)), this, SLOT(readEvents()));
- mWriteNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this);
- connect(mWriteNotifier,
- SIGNAL(activated(int)), this, SLOT(flushRequests()));
- mWriteNotifier->setEnabled(false);
}
QWaylandDisplay::~QWaylandDisplay(void)
{
- close(mFd);
#ifdef QT_WAYLAND_GL_SUPPORT
delete mEglIntegration;
#endif
+ delete mEventThread;
wl_display_destroy(mDisplay);
}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index 481f829..4cfb7b5 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -45,6 +45,8 @@
#include <QtCore/QObject>
#include <QtCore/QRect>
+#include <QtCore/QWaitCondition>
+
#include <wayland-client.h>
class QWaylandInputDevice;
@@ -53,6 +55,7 @@ class QWaylandBuffer;
class QPlatformScreen;
class QWaylandScreen;
class QWaylandGLIntegration;
+class QWaylandEventThread;
class QWaylandDisplay : public QObject {
Q_OBJECT
@@ -61,7 +64,6 @@ public:
QWaylandDisplay(void);
~QWaylandDisplay(void);
- void createNewScreen(struct wl_output *output, QRect geometry);
QList<QPlatformScreen *> screens() const { return mScreens; }
struct wl_surface *createSurface(void *handle);
struct wl_buffer *createShmBuffer(int fd, int width, int height,
@@ -76,49 +78,33 @@ public:
#endif
void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y);
+
void syncCallback(wl_display_sync_func_t func, void *data);
void frameCallback(wl_display_frame_func_t func, void *data);
- void iterate();
-
struct wl_display *wl_display() const { return mDisplay; }
public slots:
- void readEvents(void);
- void flushRequests(void);
+ void createNewScreen(struct wl_output *output, QRect geometry);
+ void displayHandleGlobal(uint32_t id, QByteArray interface, uint32_t version);
private:
struct wl_display *mDisplay;
+ QWaylandEventThread *mEventThread;
struct wl_compositor *mCompositor;
struct wl_shm *mShm;
struct wl_shell *mShell;
- char *mDeviceName;
- int mFd;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
- QSocketNotifier *mReadNotifier;
- QSocketNotifier *mWriteNotifier;
+
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *mEglIntegration;
#endif
- static void displayHandleGlobal(struct wl_display *display,
- uint32_t id,
- const char *interface,
- uint32_t version, void *data);
-
- static void outputHandleGeometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height);
-
static void shellHandleConfigure(void *data, struct wl_shell *shell,
uint32_t time, uint32_t edges,
struct wl_surface *surface,
int32_t width, int32_t height);
- static int sourceUpdate(uint32_t mask, void *data);
-
- static const struct wl_output_listener outputListener;
static const struct wl_shell_listener shellListener;
};
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
index 35e2532..4f50cb6 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.cpp
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -53,6 +53,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mWaylandCursor(new QWaylandCursor(this))
{
+ moveToThread(waylandDisplay->thread());
}
QWaylandScreen::~QWaylandScreen()
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
index cc6b2a1..34f4436 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
@@ -111,9 +111,7 @@ void QWaylandShmWindowSurface::beginPaint(const QRegion &)
{
QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
- while (waylandWindow->waitingForFrameSync()) {
- mDisplay->iterate();
- }
+ waylandWindow->waitForFrameSync();
}
void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
index 2808ed6..c083e58 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -45,10 +45,10 @@
#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
: QWaylandWindow(widget)
- , mBuffer(0)
- , mWaitingForFrameSync(false)
{
newSurfaceCreated();
}
@@ -69,36 +69,3 @@ QPlatformGLContext * QWaylandShmWindow::glContext() const
return 0;
}
-void QWaylandShmWindow::attach(QWaylandBuffer *buffer)
-{
- mBuffer = buffer;
- if (mSurface) {
- wl_surface_attach(mSurface, buffer->buffer(),0,0);
- }
-}
-
-
-void QWaylandShmWindow::damage(const QRegion &region)
-{
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); i++) {
- const QRect rect = rects.at(i);
- wl_surface_damage(mSurface,
- rect.x(), rect.y(), rect.width(), rect.height());
- }
- mWaitingForFrameSync = true;
- mDisplay->frameCallback(QWaylandShmWindow::frameCallback, this);
-}
-
-void QWaylandShmWindow::newSurfaceCreated()
-{
- if (mBuffer) {
- wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
- }
-}
-
-void QWaylandShmWindow::frameCallback(void *data, uint32_t time)
-{
- QWaylandShmWindow *self = static_cast<QWaylandShmWindow*>(data);
- self->mWaitingForFrameSync = false;
-}
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
index 3876c52..5dc6351 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -53,15 +53,6 @@ public:
WindowType windowType() const;
QPlatformGLContext *glContext() const;
- void attach(QWaylandBuffer *buffer);
- void damage(const QRegion &region);
- bool waitingForFrameSync() const { return mWaitingForFrameSync; }
-protected:
- void newSurfaceCreated();
-private:
- static void frameCallback(void *data, uint32_t time);
- QWaylandBuffer *mBuffer;
- bool mWaitingForFrameSync;
};
#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index e994616..aa72ad5 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -43,6 +43,7 @@
#include "qwaylanddisplay.h"
#include "qwaylandscreen.h"
+#include "qwaylandbuffer.h"
#include <QtGui/QWidget>
#include <QtGui/QWindowSystemInterface>
@@ -52,6 +53,8 @@
QWaylandWindow::QWaylandWindow(QWidget *window)
: QPlatformWindow(window)
, mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mBuffer(0)
+ , mWaitingForFrameSync(false)
{
static WId id = 1;
mWindowId = id++;
@@ -73,7 +76,7 @@ WId QWaylandWindow::winId() const
void QWaylandWindow::setParent(const QPlatformWindow *parent)
{
Q_UNUSED(parent);
- qWarning("Trying to add a raster window as a sub-window");
+ qWarning("Sub window is not supported");
}
void QWaylandWindow::setVisible(bool visible)
@@ -103,3 +106,54 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
QWindowSystemInterface::handleGeometryChange(widget(), geometry);
}
+
+void QWaylandWindow::attach(QWaylandBuffer *buffer)
+{
+ mBuffer = buffer;
+ if (mSurface) {
+ wl_surface_attach(mSurface, buffer->buffer(),0,0);
+ }
+}
+
+
+void QWaylandWindow::damage(const QRegion &region)
+{
+ //We have to do sync stuff before calling damage, or we might
+ //get a frame callback before we get the timestamp
+ mDisplay->frameCallback(QWaylandWindow::frameCallback, this);
+ mWaitingForFrameSync = true;
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.size(); i++) {
+ const QRect rect = rects.at(i);
+ wl_surface_damage(mSurface,
+ rect.x(), rect.y(), rect.width(), rect.height());
+ }
+}
+
+void QWaylandWindow::newSurfaceCreated()
+{
+ if (mBuffer) {
+ wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
+ }
+}
+
+void QWaylandWindow::frameCallback(void *data, uint32_t time)
+{
+ Q_UNUSED(time);
+ QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
+ if (self->mWaitingForFrameSync) {
+ self->mWaitingForFrameSync = false;
+ self->mFrameSyncWait.wakeAll();
+ }
+}
+
+void QWaylandWindow::waitForFrameSync()
+{
+ if (!mWaitingForFrameSync) {
+ return;
+ }
+ QMutex lock;
+ lock.lock();
+ mFrameSyncWait.wait(&lock);
+}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index afc214e..ad4bba4 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -43,6 +43,8 @@
#define QWAYLANDWINDOW_H
#include <QtGui/QPlatformWindow>
+#include <QtCore/QWaitCondition>
+#include <QtCore/QMutex>
#include "qwaylanddisplay.h"
@@ -69,11 +71,21 @@ public:
void configure(uint32_t time, uint32_t edges,
int32_t x, int32_t y, int32_t width, int32_t height);
+ void attach(QWaylandBuffer *buffer);
+ void damage(const QRegion &region);
+
+ void waitForFrameSync();
protected:
struct wl_surface *mSurface;
- virtual void newSurfaceCreated() = 0;
+ virtual void newSurfaceCreated();
QWaylandDisplay *mDisplay;
+ QWaylandBuffer *mBuffer;
WId mWindowId;
+ bool mWaitingForFrameSync;
+ QWaitCondition mFrameSyncWait;
+
+private:
+ static void frameCallback(void *data, uint32_t time);
};
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index e5c866b..849299a 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -14,7 +14,8 @@ SOURCES = main.cpp \
qwaylanddisplay.cpp \
qwaylandwindow.cpp \
qwaylandscreen.cpp \
- qwaylandshmwindow.cpp
+ qwaylandshmwindow.cpp \
+ qwaylandeventthread.cpp
HEADERS = qwaylandintegration.h \
qwaylandcursor.h \
@@ -23,7 +24,8 @@ HEADERS = qwaylandintegration.h \
qwaylandscreen.h \
qwaylandshmsurface.h \
qwaylandbuffer.h \
- qwaylandshmwindow.h
+ qwaylandshmwindow.h \
+ qwaylandeventthread.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND