diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/wayland/qwaylanddisplay.cpp | 101 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylanddisplay.h | 30 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandscreen.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandshmsurface.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandshmwindow.cpp | 37 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandshmwindow.h | 9 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow.cpp | 56 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow.h | 14 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/wayland.pro | 6 |
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 ®ion, 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 ®ion) -{ - 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 ®ion); - 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 ®ion) +{ + //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 ®ion); + + 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 |