From d9b023b5d38d858f29e7095aeb25a84f09a19c13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
Date: Thu, 15 Jul 2010 16:57:07 +0200
Subject: Eventloop integration in Lighthouse

This is exprimental and does not work with the glib eventloop.
---
 src/gui/kernel/kernel.pri                          |   6 +-
 src/gui/kernel/qeventdispatcher_glib_qpa.cpp       |   8 +
 src/gui/kernel/qeventdispatcher_qpa.cpp            | 186 +++++++++++++++++++--
 src/gui/kernel/qeventdispatcher_qpa_p.h            |   6 +-
 .../kernel/qplatformeventloopintegration_qpa.cpp   |   0
 src/gui/kernel/qplatformeventloopintegration_qpa.h |  13 ++
 src/gui/kernel/qplatformintegration_qpa.cpp        |   5 +
 src/gui/kernel/qplatformintegration_qpa.h          |   5 +
 src/plugins/platforms/openkode/openkode.pro        |   6 +-
 .../openkode/qopenkodeeventloopintegration.cpp     |  29 ++++
 .../openkode/qopenkodeeventloopintegration.h       |  17 ++
 .../platforms/openkode/qopenkodeintegration.cpp    |  42 +----
 .../platforms/openkode/qopenkodeintegration.h      |   4 +-
 src/plugins/platforms/openkode/qopenkodewindow.cpp |   1 -
 .../platforms/openkode/qopenkodewindowsurface.cpp  |   6 +-
 15 files changed, 272 insertions(+), 62 deletions(-)
 create mode 100644 src/gui/kernel/qplatformeventloopintegration_qpa.cpp
 create mode 100644 src/gui/kernel/qplatformeventloopintegration_qpa.h
 create mode 100644 src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp
 create mode 100644 src/plugins/platforms/openkode/qopenkodeeventloopintegration.h

diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 02badee..ba86c1c 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -219,7 +219,8 @@ qpa {
                 kernel/qplatformwindow_qpa.h \
                 kernel/qplatformwindowformat_qpa.h \
                 kernel/qplatformglcontext_qpa.h \
-                kernel/qdesktopwidget_qpa_p.h
+                kernel/qdesktopwidget_qpa_p.h \
+                kernel/qplatformeventloopintegration_qpa.h
 
 	SOURCES += \
 		kernel/qapplication_qpa.cpp \
@@ -238,7 +239,8 @@ qpa {
                 kernel/qplatformintegrationfactory_qpa.cpp \
                 kernel/qplatformintegrationplugin_qpa.cpp \
                 kernel/qplatformwindow_qpa.cpp \
-                kernel/qplatformwindowformat_qpa.cpp
+                kernel/qplatformwindowformat_qpa.cpp \
+                kernel/qplatformeventloopintegration_qpa.cpp
 
         contains(QT_CONFIG, glib) {
             SOURCES += \
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
index 9585b26..981991d 100644
--- a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
@@ -133,6 +133,14 @@ QPAEventDispatcherGlib::~QPAEventDispatcherGlib()
 
 bool QPAEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
 {
+    static bool init = false;
+    if (!init) {
+        if (QApplicationPrivate::platformIntegration()->createEventLoopIntegration()) {
+            qWarning("Eventloop integration is not supported by the glib event dispatcher");
+            qWarning("Use the UNIX event dispatcher by defining environment variable QT_NO_GLIB=1");
+        }
+        init = true;
+    }
     return QEventDispatcherGlib::processEvents(flags);
 }
 
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
index 5740548..f7f3db3 100644
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_qpa.cpp
@@ -44,24 +44,135 @@
 #include "qeventdispatcher_qpa_p.h"
 #include "private/qeventdispatcher_unix_p.h"
 #include "qapplication_p.h"
-#ifndef QT_NO_THREAD
-#  include "qmutex.h"
-#endif
+#include "qplatformeventloopintegration_qpa.h"
+
 #include <QWindowSystemInterface>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QAtomicInt>
+#include <QtCore/QSemaphore>
 
 #include <errno.h>
+
 QT_BEGIN_NAMESPACE
 
 QT_USE_NAMESPACE
 
+class Rendezvous
+{
+public:
+    void checkpoint()
+    {
+        if (state.testAndSetOrdered(0,1)) {
+            semaphore.acquire();
+        } else if (state.testAndSetAcquire(1,0)) {
+            semaphore.release();
+        } else {
+            qWarning("Barrier internal error");
+        }
+    }
+private:
+    QSemaphore semaphore;
+    QAtomicInt state;
+};
+
+class SelectWorker : public QThread
+{
+public:
+    SelectWorker(QEventDispatcherQPAPrivate *eventDispatcherPrivate)
+        : QThread(),
+          m_edPrivate(eventDispatcherPrivate),
+          m_retVal(0)
+    {
+    }
+
+    void setSelectValues(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
+    {
+        m_nfds = nfds;
+        m_readfds = readfds;
+        m_writefds = writefds;
+        m_exceptfds = exceptfds;
+
+
+    }
+
+    int retVal() const {
+        return m_retVal;
+    }
+
+protected:
+    void run();
+
+private:
+    QEventDispatcherQPAPrivate *m_edPrivate;
+    int m_retVal;
+
+    int m_nfds;
+    fd_set *m_readfds, *m_writefds, *m_exceptfds;
+};
+
 class QEventDispatcherQPAPrivate : public QEventDispatcherUNIXPrivate
 {
     Q_DECLARE_PUBLIC(QEventDispatcherQPA)
 public:
-    inline QEventDispatcherQPAPrivate()
-    { }
-};
+    QEventDispatcherQPAPrivate()
+        :  eventLoopIntegration(0),
+           barrierBeforeBlocking(0),
+           barrierReturnValue(0),
+           selectReturnMutex(0),
+           selectWorkerNeedsSync(true),
+           selectWorkerHasResult(false),
+           m_integrationInitialised(false),
+           m_hasIntegration(false)
+    {
 
+    }
+
+    ~QEventDispatcherQPAPrivate()
+    {
+        delete selectWorker;
+        delete eventLoopIntegration;
+        delete barrierBeforeBlocking;
+        delete barrierReturnValue;
+        delete selectReturnMutex;
+    }
+
+    bool hasIntegration() const
+    {
+        if (!m_integrationInitialised) {
+            QEventDispatcherQPAPrivate *that = const_cast<QEventDispatcherQPAPrivate *>(this);
+            if (qApp && (qApp->thread() == QThread::currentThread())) { // guiThread
+                if (QApplicationPrivate::platformIntegration()) {
+                    that->eventLoopIntegration = QApplicationPrivate::platformIntegration()->createEventLoopIntegration();
+                    if (that->eventLoopIntegration) {
+                        that->selectWorker = new SelectWorker(that);
+                        that->barrierBeforeBlocking = new Rendezvous;
+                        that->barrierReturnValue = new Rendezvous;
+                        that->selectReturnMutex = new QMutex;
+                        that->selectWorker->start();
+                        that->m_hasIntegration = true;
+                        if (!QElapsedTimer::isMonotonic())
+                            qWarning("Having eventloop integration without monotonic timers can lead to undefined behaviour");
+                    }
+                }
+            }
+            that->m_integrationInitialised = true;
+        }
+        return m_hasIntegration;
+    }
+
+    QPlatformEventLoopIntegration *eventLoopIntegration;
+    Rendezvous *barrierBeforeBlocking;
+    Rendezvous *barrierReturnValue;
+
+    QMutex *selectReturnMutex;
+    bool selectWorkerNeedsSync;
+    bool selectWorkerHasResult;
+
+    SelectWorker *selectWorker;
+private:
+    bool m_integrationInitialised;
+    bool m_hasIntegration;
+};
 
 QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent)
     : QEventDispatcherUNIX(*new QEventDispatcherQPAPrivate, parent)
@@ -70,10 +181,6 @@ QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent)
 QEventDispatcherQPA::~QEventDispatcherQPA()
 { }
 
-
-
-//#define ZERO_FOR_THE_MOMENT
-
 bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
 {
     Q_D(QEventDispatcherQPA);
@@ -115,17 +222,24 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
 bool QEventDispatcherQPA::hasPendingEvents()
 {
     extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
-    return qGlobalPostedEventsCount() || QWindowSystemInterfacePrivate::userEventsQueued();;
+    return qGlobalPostedEventsCount() || QWindowSystemInterfacePrivate::userEventsQueued();
 }
 
-void QEventDispatcherQPA::startingUp()
+void QEventDispatcherQPA::registerSocketNotifier(QSocketNotifier *notifier)
 {
+    Q_D(QEventDispatcherQPA);
+    QEventDispatcherUNIX::registerSocketNotifier(notifier);
+    if (d->hasIntegration())
+        wakeUp();
 
 }
 
-void QEventDispatcherQPA::closingDown()
+void QEventDispatcherQPA::unregisterSocketNotifier(QSocketNotifier *notifier)
 {
-
+    Q_D(QEventDispatcherQPA);
+    QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
+    if (d->hasIntegration())
+        wakeUp();
 }
 
 void QEventDispatcherQPA::flush()
@@ -138,7 +252,49 @@ void QEventDispatcherQPA::flush()
 int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
                                 timeval *timeout)
 {
-    return QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout);
+    Q_D(QEventDispatcherQPA);
+    int retVal = 0;
+    if (d->hasIntegration()) {
+        qint64 timeoutmsec = timeout->tv_sec * 1000 + (timeout->tv_usec/1000);
+        d->selectReturnMutex->lock();
+        if (d->selectWorkerNeedsSync) {
+            if (d->selectWorkerHasResult) {
+                retVal = d->selectWorker->retVal();
+                d->selectWorkerHasResult = false;
+
+                d->selectReturnMutex->unlock();
+                d->barrierReturnValue->checkpoint();
+                return retVal;
+            } else {
+                d->selectWorkerNeedsSync = false;
+                d->selectWorker->setSelectValues(nfds,readfds, writefds, exceptfds);
+                d->barrierBeforeBlocking->checkpoint();
+            }
+        }
+        d->selectReturnMutex->unlock();
+        d->eventLoopIntegration->processEvents(timeoutmsec);
+        retVal = 0; //is 0 if select has not returned
+    } else {
+        retVal = QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout);
+    }
+    return retVal;
 }
 
+void SelectWorker::run()
+{
+    while(true) {
+        m_retVal = 0;
+        m_edPrivate->barrierBeforeBlocking->checkpoint(); // wait for mainthread
+        int tmpRet = qt_safe_select(m_nfds,m_readfds,m_writefds,m_exceptfds,0);
+        m_edPrivate->selectReturnMutex->lock();
+        m_edPrivate->eventLoopIntegration->wakeup();
+
+        m_edPrivate->selectWorkerNeedsSync = true;
+        m_edPrivate->selectWorkerHasResult = true;
+        m_retVal = tmpRet;
+
+        m_edPrivate->selectReturnMutex->unlock();
+        m_edPrivate->barrierReturnValue->checkpoint();
+    }
+}
 QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_qpa_p.h b/src/gui/kernel/qeventdispatcher_qpa_p.h
index 878daaa..8065c3e 100644
--- a/src/gui/kernel/qeventdispatcher_qpa_p.h
+++ b/src/gui/kernel/qeventdispatcher_qpa_p.h
@@ -71,10 +71,10 @@ public:
     bool processEvents(QEventLoop::ProcessEventsFlags flags);
     bool hasPendingEvents();
 
-    void flush();
+    void registerSocketNotifier(QSocketNotifier *notifier);
+    void unregisterSocketNotifier(QSocketNotifier *notifier);
 
-    void startingUp();
-    void closingDown();
+    void flush();
 
 protected:
     int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h
new file mode 100644
index 0000000..5e4c227
--- /dev/null
+++ b/src/gui/kernel/qplatformeventloopintegration_qpa.h
@@ -0,0 +1,13 @@
+#ifndef QPLATFORMEVENTLOOPINTEGRATION_QPA_H
+#define QPLATFORMEVENTLOOPINTEGRATION_QPA_H
+
+#include <qglobal.h>
+
+class QPlatformEventLoopIntegration
+{
+public:
+    virtual void processEvents( qint64 msec ) = 0;
+    virtual void wakeup() = 0;
+};
+
+#endif // QPLATFORMEVENTLOOPINTEGRATION_QPA_H
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index 8666911..b3f46ce 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -56,6 +56,11 @@ QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, in
     return QPixmap();
 }
 
+QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration() const
+{
+    return 0;
+}
+
 bool QPlatformIntegration::hasOpenGL() const
 {
     return false;
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 8c1659f..11377e7 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -55,6 +55,7 @@ class QPlatformWindow;
 class QWindowSurface;
 class QBlittable;
 class QWidget;
+class QPlatformEventLoopIntegration;
 
 class Q_GUI_EXPORT QPlatformIntegration
 {
@@ -73,8 +74,12 @@ public:
     virtual bool isVirtualDesktop() { return false; }
     virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
 
+// Experimental
+    virtual QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+
     virtual bool hasOpenGL() const;
 
+
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/openkode.pro b/src/plugins/platforms/openkode/openkode.pro
index c039131..2d90b15 100644
--- a/src/plugins/platforms/openkode/openkode.pro
+++ b/src/plugins/platforms/openkode/openkode.pro
@@ -10,13 +10,15 @@ SOURCES =   main.cpp \
             qopenkodewindowsurface.cpp \
             qopenkodewindow.cpp \
             ../eglconvenience/qeglplatformcontext.cpp \
-            ../eglconvenience/qeglconvenience.cpp
+            ../eglconvenience/qeglconvenience.cpp \
+            qopenkodeeventloopintegration.cpp
 
 HEADERS =   qopenkodeintegration.h \
             qopenkodewindowsurface.h \
             qopenkodewindow.h \
             ../eglconvenience/qeglplatformcontext.h \
-            ../eglconvenience/qeglconvenience.h
+            ../eglconvenience/qeglconvenience.h \
+            qopenkodeeventloopintegration.h
 
 RESOURCES = resources.qrc
 
diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp
new file mode 100644
index 0000000..467b5b5
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp
@@ -0,0 +1,29 @@
+#include "qopenkodeeventloopintegration.h"
+
+#include <KD/kd.h>
+
+#include <QtCore/QDebug>
+
+QOpenKODEEventLoopIntegration::QOpenKODEEventLoopIntegration()
+{
+    m_kdThread = kdThreadSelf();
+}
+
+void QOpenKODEEventLoopIntegration::processEvents(qint64 msec)
+{
+    if (msec == 0)
+        msec = -1;
+    const KDEvent *event = kdWaitEvent(msec*1000);
+    if (event) {
+        kdDefaultEvent(event);
+        while ((event = kdWaitEvent(0)) != 0) {
+            kdDefaultEvent(event);
+        }
+    }
+}
+
+void QOpenKODEEventLoopIntegration::wakeup()
+{
+    KDEvent *event = kdCreateEvent();
+    kdPostThreadEvent(event,m_kdThread);
+}
diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h
new file mode 100644
index 0000000..ef04640
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h
@@ -0,0 +1,17 @@
+#ifndef QOPENKODEEVENTLOOPINTEGRATION_H
+#define QOPENKODEEVENTLOOPINTEGRATION_H
+
+#include <QtGui/QPlatformEventLoopIntegration>
+
+class KDThread;
+class QOpenKODEEventLoopIntegration : public QPlatformEventLoopIntegration
+{
+public:
+    QOpenKODEEventLoopIntegration();
+    void processEvents(qint64 msec);
+    void wakeup();
+private:
+    KDThread *m_kdThread;
+};
+
+#endif // QOPENKODEEVENTLOOPINTEGRATION_H
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
index 270763b..5dada28 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
@@ -42,6 +42,7 @@
 #include "qopenkodeintegration.h"
 #include "qopenkodewindowsurface.h"
 #include "qopenkodewindow.h"
+#include "qopenkodeeventloopintegration.h"
 
 #include <QtOpenGL/private/qpixmapdata_gl_p.h>
 #include <QtOpenGL/private/qwindowsurface_gl_p.h>
@@ -184,41 +185,11 @@ static GLuint loadShaders(const QString &vertexShader, const QString &fragmentSh
     return prog;
 }
 
-class QOpenKODEEventLoopHelper : public QThread
-{
-public:
-    QOpenKODEEventLoopHelper(QSemaphore *m)
-            : eventMutex(m)
-    {
-        m->acquire();
-    }
-
-protected:
-    void run()
-    {
-        if (kdInitializeNV() == KD_ENOTINITIALIZED) {
-            qFatal("Did not manage to initialize openkode");
-        }
-        eventMutex->release();
-
-        const KDEvent *event;
-        while ((event = kdWaitEvent(-1)) != 0) {
-            qDebug() << "!!! received event!";
-            kdDefaultEvent(event);
-        }
-    }
-
-private:
-    QSemaphore *eventMutex;
-};
-
 QOpenKODEIntegration::QOpenKODEIntegration()
-    : eventMutex(1)
 {
-    QOpenKODEEventLoopHelper *loop = new QOpenKODEEventLoopHelper(&eventMutex);
-    loop->start();
-    eventMutex.acquire(); // block until initialization done
-
+    if (kdInitializeNV() == KD_ENOTINITIALIZED) {
+        qFatal("Did not manage to initialize openkode");
+    }
     QOpenKODEScreen *mPrimaryScreen = new QOpenKODEScreen();
 
     mScreens.append(mPrimaryScreen);
@@ -265,6 +236,11 @@ bool QOpenKODEIntegration::hasOpenGL() const
     return true;
 }
 
+QPlatformEventLoopIntegration *QOpenKODEIntegration::createEventLoopIntegration() const
+{
+    return new QOpenKODEEventLoopIntegration;
+}
+
 GLuint QOpenKODEIntegration::blitterProgram()
 {
     static GLuint shaderProgram = 0;
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.h b/src/plugins/platforms/openkode/qopenkodeintegration.h
index 9029086..0eaf127 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.h
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.h
@@ -86,7 +86,8 @@ public:
     QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
 
     bool hasOpenGL() const;
-    QPlatformGLContext * createGLContext();
+
+    QPlatformEventLoopIntegration *createEventLoopIntegration() const;
 
     virtual QList<QPlatformScreen *> screens() const { return mScreens; }
 
@@ -94,7 +95,6 @@ public:
 
 private:
     QList<QPlatformScreen *> mScreens;
-    QSemaphore eventMutex;
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp
index 2213a8f..faba2fb 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.cpp
+++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp
@@ -60,7 +60,6 @@
 QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw)
     : QPlatformWindow(tlw)
 {
-
     if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenVG) {
         m_eglApi = EGL_OPENVG_API;
     } else {
diff --git a/src/plugins/platforms/openkode/qopenkodewindowsurface.cpp b/src/plugins/platforms/openkode/qopenkodewindowsurface.cpp
index a349031..84e27f5 100644
--- a/src/plugins/platforms/openkode/qopenkodewindowsurface.cpp
+++ b/src/plugins/platforms/openkode/qopenkodewindowsurface.cpp
@@ -93,8 +93,6 @@ void QOpenKODEWindowSurface::flush(QWidget *widget, const QRegion &region, const
         y = boundingRect.y();
     }
 
-    qDebug() << "flush" << widget << offset << region.boundingRect() << mImage.format() << blitImage.format();
-
     GLuint shaderProgram = QOpenKODEIntegration::blitterProgram();
 
     glUseProgram(shaderProgram);
@@ -125,7 +123,7 @@ void QOpenKODEWindowSurface::flush(QWidget *widget, const QRegion &region, const
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mImage.bits());
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, mImage.bits());
 
     // Enable vertex attribute associated with vertex position
     glEnableVertexAttribArray(posId);
@@ -166,7 +164,7 @@ void QOpenKODEWindowSurface::beginPaint(const QRegion &region)
     Q_UNUSED(region);
     if (mImage.isNull())  {
         m_platformGLContext = window()->platformWindow()->glContext();
-        mImage = QImage(size(),QImage::Format_RGB32);
+        mImage = QImage(size(),QImage::Format_RGB888);
     }
 }
 
-- 
cgit v0.12


From a7182f757e5414d7baf21fdc098f3f6649e6a1d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
Date: Tue, 20 Jul 2010 13:16:09 +0200
Subject: Cleanup directfb input handling in lighthouse

---
 src/plugins/platforms/directfb/qdirectfbinput.cpp  | 97 +++++++---------------
 src/plugins/platforms/directfb/qdirectfbinput.h    | 42 +++-------
 .../platforms/directfb/qdirectfbintegration.cpp    | 24 +++++-
 .../platforms/directfb/qdirectfbintegration.h      |  6 +-
 src/plugins/platforms/directfb/qdirectfbwindow.cpp |  8 +-
 src/plugins/platforms/directfb/qdirectfbwindow.h   |  5 +-
 6 files changed, 74 insertions(+), 108 deletions(-)

diff --git a/src/plugins/platforms/directfb/qdirectfbinput.cpp b/src/plugins/platforms/directfb/qdirectfbinput.cpp
index 90c3348..7101b7b 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbinput.cpp
@@ -10,89 +10,61 @@
 
 #include <directfb.h>
 
-InputSocketWaiter::InputSocketWaiter(IDirectFBEventBuffer *eventBuffer, QObject *parent)
-    : QThread(parent), m_eventBuffer(eventBuffer),m_shouldStop(false)
+QDirectFbInput::QDirectFbInput(QObject *parent)
+    : QObject(parent), m_shouldStop(false)
 {
-    this->start();
-}
+    m_dfbInterface = QDirectFbConvenience::dfbInterface();
 
-InputSocketWaiter::~InputSocketWaiter()
-{
-    m_shouldStop = true;
-    m_eventBuffer->WakeUp(m_eventBuffer);
-    m_cleanupMutex.lock();
-}
+    DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface,&m_eventBuffer);
+    if (ok != DFB_OK)
+        DirectFBError("Failed to initialise eventbuffer", ok);
+
+    m_dfbInterface->GetDisplayLayer(m_dfbInterface,DLID_PRIMARY, &m_dfbDisplayLayer);
 
-void InputSocketWaiter::continueWaitingForEvents()
-{
-    m_finishedProcessingEvents.wakeAll();
 }
 
-void InputSocketWaiter::run()
+void QDirectFbInput::runInputEventLoop()
 {
-    m_cleanupMutex.lock();
-    while (1) {
+    while (true) {
         m_eventBuffer->WaitForEvent(m_eventBuffer);
-        if (m_shouldStop)
+        if (m_shouldStop) {
+            m_waitStop.release();
             break;
-        emit newEvent();
-        QMutex waitForProcessingMutex;
-        waitForProcessingMutex.lock();
-        m_finishedProcessingEvents.wait(&waitForProcessingMutex);
-    }
-    m_cleanupMutex.unlock();
-}
-
-QDirectFbInput *QDirectFbInput::instance()
-{
-    static QDirectFbInput *input = 0;
-    if (!input) {
-        input = new QDirectFbInput();
+        }
+        handleEvents();
     }
-    return input;
 }
 
-QDirectFbInput::QDirectFbInput()
-    : QObject()
+void QDirectFbInput::stopInputEventLoop()
 {
-    dfbInterface = QDirectFbConvenience::dfbInterface();
-
-    DFBResult ok = dfbInterface->CreateEventBuffer(dfbInterface,&eventBuffer);
-    if (ok != DFB_OK)
-        DirectFBError("Failed to initialise eventbuffer", ok);
-
-    dfbInterface->GetDisplayLayer(dfbInterface,DLID_PRIMARY, &dfbDisplayLayer);
-
-    m_inputHandler = new InputSocketWaiter(eventBuffer,this);
-    connect(m_inputHandler,SIGNAL(newEvent()),this,SLOT(handleEvents()));
-
-    connect(QApplication::instance(),SIGNAL(aboutToQuit()),SLOT(applicationEnd()));
+    m_shouldStop = true;
+    m_waitStop.acquire();
 }
 
 void QDirectFbInput::addWindow(DFBWindowID id, QWidget *tlw)
 {
-    tlwMap.insert(id,tlw);
+    m_tlwMap.insert(id,tlw);
     IDirectFBWindow *window;
-    dfbDisplayLayer->GetWindow(dfbDisplayLayer,id,&window);
+    m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,id,&window);
 
-    window->AttachEventBuffer(window,eventBuffer);
+    window->AttachEventBuffer(window,m_eventBuffer);
 }
 
 void QDirectFbInput::removeWindow(WId wId)
 {
     IDirectFBWindow *window;
-    dfbDisplayLayer->GetWindow(dfbDisplayLayer,wId, &window);
+    m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,wId, &window);
 
-    window->DetachEventBuffer(window,eventBuffer);
-    tlwMap.remove(wId);
+    window->DetachEventBuffer(window,m_eventBuffer);
+    m_tlwMap.remove(wId);
 }
 
 void QDirectFbInput::handleEvents()
 {
-    DFBResult hasEvent = eventBuffer->HasEvent(eventBuffer);
+    DFBResult hasEvent = m_eventBuffer->HasEvent(m_eventBuffer);
     while(hasEvent == DFB_OK){
         DFBEvent event;
-        DFBResult ok = eventBuffer->GetEvent(eventBuffer,&event);
+        DFBResult ok = m_eventBuffer->GetEvent(m_eventBuffer,&event);
         if (ok != DFB_OK)
             DirectFBError("Failed to get event",ok);
         if (event.clazz == DFEC_WINDOW) {
@@ -118,9 +90,8 @@ void QDirectFbInput::handleEvents()
 
         }
 
-        hasEvent = eventBuffer->HasEvent(eventBuffer);
+        hasEvent = m_eventBuffer->HasEvent(m_eventBuffer);
     }
-    m_inputHandler->continueWaitingForEvents();
 }
 
 void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
@@ -140,22 +111,16 @@ void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
     } else if (event.window.type == DWET_BUTTONUP) {
         window->UngrabPointer(window);
     }
-    QWidget *tlw = tlwMap.value(event.window.window_id);
+    QWidget *tlw = m_tlwMap.value(event.window.window_id);
     QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons);
 }
 
-void QDirectFbInput::applicationEnd()
-{
-    delete m_inputHandler;
-    m_inputHandler = 0;
-}
-
 void QDirectFbInput::handleWheelEvent(const DFBEvent &event)
 {
     QPoint p(event.window.cx, event.window.cy);
     QPoint globalPos = globalPoint(event);
     long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
-    QWidget *tlw = tlwMap.value(event.window.window_id);
+    QWidget *tlw = m_tlwMap.value(event.window.window_id);
     QWindowSystemInterface::handleWheelEvent(tlw, timestamp, p, globalPos,
                                           event.window.step*120,
                                           Qt::Vertical);
@@ -172,13 +137,13 @@ void QDirectFbInput::handleKeyEvents(const DFBEvent &event)
     QChar character;
     if (DFB_KEY_TYPE(event.window.key_symbol) == DIKT_UNICODE)
         character = QChar(event.window.key_symbol);
-    QWidget *tlw = tlwMap.value(event.window.window_id);
+    QWidget *tlw = m_tlwMap.value(event.window.window_id);
     QWindowSystemInterface::handleKeyEvent(tlw, timestamp, type, key, modifiers, character);
 }
 
 void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
 {
-    QWidget *tlw = tlwMap.value(event.window.window_id);
+    QWidget *tlw = m_tlwMap.value(event.window.window_id);
     switch (event.window.type) {
     case DWET_ENTER:
         QWindowSystemInterface::handleEnterEvent(tlw);
@@ -194,7 +159,7 @@ void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
 inline QPoint QDirectFbInput::globalPoint(const DFBEvent &event) const
 {
     IDirectFBWindow *window;
-    dfbDisplayLayer->GetWindow(dfbDisplayLayer,event.window.window_id,&window);
+    m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,event.window.window_id,&window);
     int x,y;
     window->GetPosition(window,&x,&y);
     return QPoint(event.window.cx +x, event.window.cy + y);
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.h b/src/plugins/platforms/directfb/qdirectfbinput.h
index 016e7f1..0b2e7ed 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.h
+++ b/src/plugins/platforms/directfb/qdirectfbinput.h
@@ -1,9 +1,7 @@
 #ifndef QDIRECTFBINPUT_H
 #define QDIRECTFBINPUT_H
 
-#include <QThread>
-#include <QMutex>
-#include <QWaitCondition>
+#include <QSemaphore>
 #include <QObject>
 #include <QHash>
 #include <QPoint>
@@ -13,53 +11,35 @@
 
 #include <directfb.h>
 
-class InputSocketWaiter : public QThread
-{
-    Q_OBJECT
-public:
-    InputSocketWaiter(IDirectFBEventBuffer *eventBuffer, QObject *parent);
-    virtual ~InputSocketWaiter();
-    void continueWaitingForEvents();
-protected:
-    void run();
-signals:
-    void newEvent();
-private:
-     IDirectFBEventBuffer *m_eventBuffer;
-     bool m_shouldStop;
-     QMutex m_cleanupMutex;
-     QWaitCondition m_finishedProcessingEvents;
-};
-
 class QDirectFbInput : public QObject
 {
     Q_OBJECT
 public:
-    static QDirectFbInput *instance();
+    QDirectFbInput(QObject *parent);
     void addWindow(DFBWindowID id, QWidget *tlw);
     void removeWindow(WId wId);
 
 public slots:
+    void runInputEventLoop();
+    void stopInputEventLoop();
     void handleEvents();
-    void applicationEnd();
 
 private:
-    QDirectFbInput();
-
     void handleMouseEvents(const DFBEvent &event);
     void handleWheelEvent(const DFBEvent &event);
     void handleKeyEvents(const DFBEvent &event);
     void handleEnterLeaveEvents(const DFBEvent &event);
-    IDirectFB *dfbInterface;
-    IDirectFBDisplayLayer *dfbDisplayLayer;
-    IDirectFBEventBuffer *eventBuffer;
+    inline QPoint globalPoint(const DFBEvent &event) const;
 
-    QHash<DFBWindowID,QWidget *>tlwMap;
 
-    inline QPoint globalPoint(const DFBEvent &event) const;
+    IDirectFB *m_dfbInterface;
+    IDirectFBDisplayLayer *m_dfbDisplayLayer;
+    IDirectFBEventBuffer *m_eventBuffer;
 
-    InputSocketWaiter *m_inputHandler;
+    bool m_shouldStop;
+    QSemaphore m_waitStop;
 
+    QHash<DFBWindowID,QWidget *>m_tlwMap;
 };
 
 #endif // QDIRECTFBINPUT_H
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
index 60fce7e..c47fc8d 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -49,9 +49,10 @@
 #include <private/qwindowsurface_raster_p.h>
 #include <private/qpixmap_raster_p.h>
 
-#include <private/qpixmap_blitter_p.h>
-#include <private/qpixmapdata_p.h>
-#include <QCoreApplication>
+#include <QtGui/private/qpixmap_blitter_p.h>
+#include <QtGui/private/qpixmapdata_p.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
 
 QT_BEGIN_NAMESPACE
 
@@ -94,8 +95,22 @@ QDirectFbIntegration::QDirectFbIntegration()
     }
     delete[] argv;
 
+
     QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
     mScreens.append(primaryScreen);
+
+    mInputRunner = new QThread;
+    mInput = new QDirectFbInput(0);
+    mInput->moveToThread(mInputRunner);
+    QObject::connect(mInputRunner,SIGNAL(started()),mInput,SLOT(runInputEventLoop()));
+    mInputRunner->start();
+}
+
+QDirectFbIntegration::~QDirectFbIntegration()
+{
+    mInput->stopInputEventLoop();
+    delete mInputRunner;
+    delete mInput;
 }
 
 QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) const
@@ -109,7 +124,8 @@ QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type)
 QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
 {
     Q_UNUSED(winId);
-    return new QDirectFbWindow(widget);
+    QDirectFbInput *input = const_cast<QDirectFbInput *>(mInput);//gah
+    return new QDirectFbWindow(widget,input);
 }
 
 QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId winId) const
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
index c0e770f..27847e2 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.h
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -50,6 +50,7 @@
 
 QT_BEGIN_NAMESPACE
 
+class QThread;
 class QDirectFBCursor;
 
 class QDirectFbScreen : public QPlatformScreen
@@ -81,6 +82,7 @@ class QDirectFbIntegration : public QPlatformIntegration
 {
 public:
     QDirectFbIntegration();
+    ~QDirectFbIntegration();
 
     QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
     QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
@@ -89,10 +91,10 @@ public:
 
     QList<QPlatformScreen *> screens() const { return mScreens; }
 
-
-
 private:
     QList<QPlatformScreen *> mScreens;
+    QDirectFbInput *mInput;
+    QThread *mInputRunner;
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
index d88953e..30e6f5a 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
@@ -45,8 +45,8 @@
 
 #include <directfb.h>
 
-QDirectFbWindow::QDirectFbWindow(QWidget *tlw)
-    : QPlatformWindow(tlw)
+QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
+    : QPlatformWindow(tlw), m_inputHandler(inputhandler)
 {
     IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
     DFBDisplayLayerConfig layerConfig;
@@ -83,12 +83,12 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw)
 
     DFBWindowID id;
     m_dfbWindow->GetID(m_dfbWindow, &id);
-    QDirectFbInput::instance()->addWindow(id,tlw);
+    m_inputHandler->addWindow(id,tlw);
 }
 
 QDirectFbWindow::~QDirectFbWindow()
 {
-    QDirectFbInput::instance()->removeWindow(winId());
+    m_inputHandler->removeWindow(winId());
     m_dfbWindow->Destroy(m_dfbWindow);
 }
 
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.h b/src/plugins/platforms/directfb/qdirectfbwindow.h
index d5fd408..b512afd 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.h
@@ -45,13 +45,14 @@
 #include <QPlatformWindow>
 
 #include "qdirectfbconvenience.h"
+#include "qdirectfbinput.h"
 
 QT_BEGIN_NAMESPACE
 
 class QDirectFbWindow : public QPlatformWindow
 {
 public:
-    QDirectFbWindow(QWidget *tlw);
+    QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler);
     ~QDirectFbWindow();
 
     void setGeometry(const QRect &rect);
@@ -66,6 +67,8 @@ public:
 
 private:
     IDirectFBWindow *m_dfbWindow;
+    QDirectFbInput *m_inputHandler;
+
 };
 
 QT_END_NAMESPACE
-- 
cgit v0.12


From bc786ded04aa316f99cf9ac4cf8b714ee46575b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
Date: Tue, 20 Jul 2010 14:38:12 +0200
Subject: Made the rest of QWindowSystemInterface callback functions thread
 safe

and cleaned up the headerfile
---
 src/gui/kernel/kernel.pri                     |   7 +-
 src/gui/kernel/qapplication_p.h               |  29 +--
 src/gui/kernel/qapplication_qpa.cpp           | 133 ++++++++------
 src/gui/kernel/qeventdispatcher_glib_qpa.cpp  |  10 +-
 src/gui/kernel/qeventdispatcher_qpa.cpp       |  10 +-
 src/gui/kernel/qwindowsysteminterface.cpp     | 186 -------------------
 src/gui/kernel/qwindowsysteminterface.h       | 169 ------------------
 src/gui/kernel/qwindowsysteminterface_qpa.cpp | 246 ++++++++++++++++++++++++++
 src/gui/kernel/qwindowsysteminterface_qpa.h   |  96 ++++++++++
 src/gui/kernel/qwindowsysteminterface_qpa_p.h | 201 +++++++++++++++++++++
 10 files changed, 657 insertions(+), 430 deletions(-)
 delete mode 100644 src/gui/kernel/qwindowsysteminterface.cpp
 delete mode 100644 src/gui/kernel/qwindowsysteminterface.h
 create mode 100644 src/gui/kernel/qwindowsysteminterface_qpa.cpp
 create mode 100644 src/gui/kernel/qwindowsysteminterface_qpa.h
 create mode 100644 src/gui/kernel/qwindowsysteminterface_qpa_p.h

diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index ba86c1c..43b1ab8 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -48,7 +48,7 @@ HEADERS += \
 	kernel/qgesturemanager_p.h \
 	kernel/qsoftkeymanager_p.h \
     kernel/qsoftkeymanager_common_p.h \
-	kernel/qguiplatformplugin_p.h
+	kernel/qguiplatformplugin_p.h \
 
 SOURCES += \
 	kernel/qaction.cpp \
@@ -211,7 +211,8 @@ qpa {
 		kernel/qgenericpluginfactory_qpa.h \
                 kernel/qgenericplugin_qpa.h \
                 kernel/qeventdispatcher_qpa_p.h \
-                kernel/qwindowsysteminterface.h \
+                kernel/qwindowsysteminterface_qpa.h \
+                kernel/qwindowsysteminterface_qpa_p.h \
                 kernel/qplatformintegration_qpa.h \
                 kernel/qplatformscreen_qpa.h \
                 kernel/qplatformintegrationfactory_qpa_p.h \
@@ -233,7 +234,7 @@ qpa {
 		kernel/qkeymapper_qws.cpp \
                 kernel/qwidget_qpa.cpp \
                 kernel/qeventdispatcher_qpa.cpp \
-                kernel/qwindowsysteminterface.cpp \
+                kernel/qwindowsysteminterface_qpa.cpp \
                 kernel/qplatformintegration_qpa.cpp \
                 kernel/qplatformscreen_qpa.cpp \
                 kernel/qplatformintegrationfactory_qpa.cpp \
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 68ec648..0602d82 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -78,6 +78,7 @@
 #endif
 #ifdef Q_WS_QPA
 #include <QWindowSystemInterface>
+#include "qwindowsysteminterface_qpa_p.h"
 #include "QtGui/qplatformintegration_qpa.h"
 #endif
 
@@ -490,19 +491,27 @@ public:
 #endif
 
 #ifdef Q_WS_QPA
-    static void processMouseEvent(QWindowSystemInterface::MouseEvent *e);
-    static void processKeyEvent(QWindowSystemInterface::KeyEvent *e);
-    static void processWheelEvent(QWindowSystemInterface::WheelEvent *e);
-    static void processTouchEvent(QWindowSystemInterface::TouchEvent *e);
+    static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e);
+    static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e);
+    static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e);
+    static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e);
 
-    static void processCloseEvent(QWidget *tlw);
-    static void processGeometryChange(QWidget *tlw, const QRect &newRect);
+    static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e);
 
-    static void processUserEvent(QWindowSystemInterface::UserEvent *e);
+    static void processMoveEvent(QWindowSystemInterfacePrivate::MoveEvent *e);
+    static void processResizeEvent(QWindowSystemInterfacePrivate::ResizeEvent *e);
 
-    static void reportScreenCount(int count);
-    static void reportGeometryChange(int screenIndex);
-    static void reportAvailableGeometryChange(int screenIndex);
+    static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
+    static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
+
+    static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
+
+//    static void reportScreenCount(int count);
+    static void reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e);
+//    static void reportGeometryChange(int screenIndex);
+    static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
+//    static void reportAvailableGeometryChange(int screenIndex);
+    static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
 
 #endif
 
diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp
index 2adcfc1..42907ae 100644
--- a/src/gui/kernel/qapplication_qpa.cpp
+++ b/src/gui/kernel/qapplication_qpa.cpp
@@ -60,6 +60,7 @@
 #include <QPlatformCursor>
 #include <qdebug.h>
 #include <QWindowSystemInterface>
+#include "qwindowsysteminterface_qpa_p.h"
 #include <QPlatformIntegration>
 
 #include "qdesktopwidget_qpa_p.h"
@@ -86,26 +87,48 @@ static int mousePressX;
 static int mousePressY;
 static int mouse_double_click_distance = 5;
 
-void QApplicationPrivate::processUserEvent(QWindowSystemInterface::UserEvent *e)
+void QApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
 {
     switch(e->type) {
-    case QEvent::MouseButtonDblClick: // if mouse event, calculate appropriate widget and local coordinates
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseButtonRelease:
-    case QEvent::MouseMove:
-        QApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterface::MouseEvent *>(e));
+    case QWindowSystemInterfacePrivate::Mouse:
+        QApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
         break;
-    case QEvent::Wheel:
-        QApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterface::WheelEvent *>(e));
+    case QWindowSystemInterfacePrivate::Wheel:
+        QApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
         break;
-    case QEvent::KeyPress:
-    case QEvent::KeyRelease:
-        QApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterface::KeyEvent *>(e));
+    case QWindowSystemInterfacePrivate::Key:
+        QApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Touch:
+        QApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Move:
+        QApplicationPrivate::processMoveEvent(static_cast<QWindowSystemInterfacePrivate::MoveEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Resize:
+        QApplicationPrivate::processResizeEvent(static_cast<QWindowSystemInterfacePrivate::ResizeEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Enter:
+        QApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Leave:
+        QApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::Close:
+        QApplicationPrivate::processCloseEvent(
+                static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::ScreenCountChange:
+        QApplicationPrivate::reportScreenCount(
+                static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
         break;
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate:
-    case QEvent::TouchEnd:
-        QApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterface::TouchEvent *>(e));
+    case QWindowSystemInterfacePrivate::ScreenGeometry:
+        QApplicationPrivate::reportGeometryChange(
+                static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
+        break;
+    case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
+        QApplicationPrivate::reportAvailableGeometryChange(
+                static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
         break;
     default:
         qWarning() << "Unknown user input event type:" << e->type;
@@ -570,7 +593,7 @@ void QApplication::setMainWidget(QWidget *mainWidget)
 }
 #endif
 
-void QApplicationPrivate::processMouseEvent(QWindowSystemInterface::MouseEvent *e)
+void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
 {
     // qDebug() << "handleMouseEvent" << tlw << ev.pos() << ev.globalPos() << hex << ev.buttons();
     static QWeakPointer<QWidget> implicit_mouse_grabber;
@@ -579,8 +602,9 @@ void QApplicationPrivate::processMouseEvent(QWindowSystemInterface::MouseEvent *
     // move first
     Qt::MouseButtons stateChange = e->buttons ^ buttons;
     if (e->globalPos != QPoint(qt_last_x, qt_last_y) && (stateChange != Qt::NoButton)) {
-        QWindowSystemInterface::MouseEvent * newMouseEvent = new QWindowSystemInterface::MouseEvent(e->widget.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
-        QWindowSystemInterfacePrivate::userEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
+        QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
+                new QWindowSystemInterfacePrivate::MouseEvent(e->widget.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
+        QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
         stateChange = Qt::NoButton;
     }
 
@@ -639,7 +663,7 @@ void QApplicationPrivate::processMouseEvent(QWindowSystemInterface::MouseEvent *
         implicit_mouse_grabber.clear();
         //### how should popup mode and implicit mouse grab interact?
 
-    } else if (tlw && app_do_modal && !qt_try_modal(tlw, e->type) ) {
+    } else if (tlw && app_do_modal && !qt_try_modal(tlw, QEvent::MouseButtonRelease) ) {
         //even if we're blocked by modality, we should deliver the mouse release event..
         //### this code is not completely correct: multiple buttons can be pressed simultaneously
         if (!(implicit_mouse_grabber && buttons == Qt::NoButton)) {
@@ -717,7 +741,7 @@ void QApplicationPrivate::processMouseEvent(QWindowSystemInterface::MouseEvent *
 
 //### there's a lot of duplicated logic here -- refactoring required!
 
-void QApplicationPrivate::processWheelEvent(QWindowSystemInterface::WheelEvent *e)
+void QApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
 {
 //    QPoint localPoint = ev.pos();
     QPoint globalPoint = e->globalPos;
@@ -739,7 +763,7 @@ void QApplicationPrivate::processWheelEvent(QWindowSystemInterface::WheelEvent *
 
      mouseWidget = mouseWindow;
 
-     if (app_do_modal && !qt_try_modal(mouseWindow, e->type) ) {
+     if (app_do_modal && !qt_try_modal(mouseWindow, QEvent::Wheel) ) {
          qDebug() << "modal blocked wheel event" << mouseWindow;
          return;
      }
@@ -759,7 +783,7 @@ void QApplicationPrivate::processWheelEvent(QWindowSystemInterface::WheelEvent *
 
 // Remember, Qt convention is:  keyboard state is state *before*
 
-void QApplicationPrivate::processKeyEvent(QWindowSystemInterface::KeyEvent *e)
+void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
 {
     QWidget *focusW = 0;
     if (self->inPopupMode()) {
@@ -778,50 +802,54 @@ void QApplicationPrivate::processKeyEvent(QWindowSystemInterface::KeyEvent *e)
 
     if (!focusW)
         return;
-    if (app_do_modal && !qt_try_modal(focusW, e->type))
+    if (app_do_modal && !qt_try_modal(focusW, e->keyType))
         return;
 
     modifiers = e->modifiers;
-    QKeyEvent ev(e->type, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
+    QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
     QApplication::sendSpontaneousEvent(focusW, &ev);
 }
 
-void QApplicationPrivate::processGeometryChange(QWidget *tlw, const QRect &newRect)
+void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
 {
-    if (!tlw->isWindow())
-        return; //geo of native child widgets is controlled by lighthouse
-                //so we already have sent the events; besides this new rect
-                //is not mapped to parent
+    QApplicationPrivate::dispatchEnterLeave(e->enter.data(),0);
+    qt_last_mouse_receiver = e->enter.data();
+}
 
-    QRect cr(tlw->geometry());
+void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
+{
+    QApplicationPrivate::dispatchEnterLeave(0,qt_last_mouse_receiver);
 
-    bool isResize = cr.size() != newRect.size();
-    bool isMove = cr.topLeft() != newRect.topLeft();
-    tlw->data->crect = newRect;
-    if (isResize) {
-        QResizeEvent e(tlw->data->crect.size(), cr.size());
-        QApplication::sendSpontaneousEvent(tlw, &e);
-        tlw->update();
-    }
+    if (e->leave.data() && !e->leave.data()->isAncestorOf(qt_last_mouse_receiver)) //(???) this should not happen
+        QApplicationPrivate::dispatchEnterLeave(0, e->leave.data());
+    qt_last_mouse_receiver = 0;
 
-    if (isMove) {
-        //### frame geometry
-        QMoveEvent e(tlw->data->crect.topLeft(), cr.topLeft());
-        QApplication::sendSpontaneousEvent(tlw, &e);
-    }
 }
 
-void QApplicationPrivate::processCloseEvent(QWidget *tlw)
+void QApplicationPrivate::processMoveEvent(QWindowSystemInterfacePrivate::MoveEvent *moveEvent)
+{
+        QMoveEvent e(moveEvent->moved.data()->geometry().topLeft(), moveEvent->newPos);
+        QApplication::sendSpontaneousEvent(moveEvent->moved.data(), &e);
+}
+
+void QApplicationPrivate::processResizeEvent(QWindowSystemInterfacePrivate::ResizeEvent *e)
+{
+    QResizeEvent resizeEvent(e->sizeChanged.data()->data->crect.size(), e->newSize);
+    QApplication::sendSpontaneousEvent(e->sizeChanged.data(), &resizeEvent);
+    e->sizeChanged.data()->update();
+}
+
+void QApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
 {
-    tlw->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+    e->topLevel.data()->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
 }
 
-void QApplicationPrivate::processTouchEvent(QWindowSystemInterface::TouchEvent *e)
+void QApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
 {
     translateRawTouchEvent(e->widget.data(), e->devType, e->points);
 }
 
-void QApplicationPrivate::reportScreenCount(int count)
+void QApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e)
 {
     // This operation only makes sense after the QApplication constructor runs
     if (QCoreApplication::startingUp())
@@ -830,10 +858,10 @@ void QApplicationPrivate::reportScreenCount(int count)
     QApplication::desktop()->d_func()->updateScreenList();
     // signal anything listening for creation or deletion of screens
     QDesktopWidget *desktop = QApplication::desktop();
-    emit desktop->screenCountChanged(count);
+    emit desktop->screenCountChanged(e->count);
 }
 
-void QApplicationPrivate::reportGeometryChange(int screenIndex)
+void QApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
 {
     // This operation only makes sense after the QApplication constructor runs
     if (QCoreApplication::startingUp())
@@ -843,7 +871,7 @@ void QApplicationPrivate::reportGeometryChange(int screenIndex)
 
     // signal anything listening for screen geometry changes
     QDesktopWidget *desktop = QApplication::desktop();
-    emit desktop->resized(screenIndex);
+    emit desktop->resized(e->index);
 
     // make sure maximized and fullscreen windows are updated
     QWidgetList list = QApplication::topLevelWidgets();
@@ -856,7 +884,8 @@ void QApplicationPrivate::reportGeometryChange(int screenIndex)
     }
 }
 
-void QApplicationPrivate::reportAvailableGeometryChange(int screenIndex)
+void QApplicationPrivate::reportAvailableGeometryChange(
+        QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
 {
     // This operation only makes sense after the QApplication constructor runs
     if (QCoreApplication::startingUp())
@@ -866,7 +895,7 @@ void QApplicationPrivate::reportAvailableGeometryChange(int screenIndex)
 
     // signal anything listening for screen geometry changes
     QDesktopWidget *desktop = QApplication::desktop();
-    emit desktop->workAreaResized(screenIndex);
+    emit desktop->workAreaResized(e->index);
 
     // make sure maximized and fullscreen windows are updated
     QWidgetList list = QApplication::topLevelWidgets();
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
index 981991d..01d40ca 100644
--- a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
@@ -64,7 +64,7 @@ static gboolean userEventSourcePrepare(GSource *s, gint *timeout)
     Q_UNUSED(s)
     Q_UNUSED(timeout)
 
-    return QWindowSystemInterfacePrivate::userEventsQueued() > 0;
+    return QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0;
 }
 
 static gboolean userEventSourceCheck(GSource *source)
@@ -76,9 +76,9 @@ static gboolean userEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
 {
     GUserEventSource * source = reinterpret_cast<GUserEventSource *>(s);
 
-    QWindowSystemInterface::UserEvent * event;
-    while (QWindowSystemInterfacePrivate::userEventsQueued()) {
-        event = QWindowSystemInterfacePrivate::getUserEvent();
+    QWindowSystemInterfacePrivate::WindowSystemEvent * event;
+    while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) {
+        event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
         if (!event)
             break;
 
@@ -87,7 +87,7 @@ static gboolean userEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
             delete event;
             continue;
         }
-        QApplicationPrivate::processUserEvent(event);
+        QApplicationPrivate::processWindowSystemEvent(event);
         delete event;
     }
 
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
index f7f3db3..4464036 100644
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_qpa.cpp
@@ -191,11 +191,11 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
     QApplication::sendPostedEvents();
 
     while (!d->interrupt) {        // also flushes output buffer ###can be optimized
-        QWindowSystemInterface::UserEvent *event;
+        QWindowSystemInterfacePrivate::WindowSystemEvent *event;
         if (!(flags & QEventLoop::ExcludeUserInputEvents)
-            && QWindowSystemInterfacePrivate::userEventsQueued() > 0) {
+            && QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0) {
             // process a pending user input event
-            event = QWindowSystemInterfacePrivate::getUserEvent();
+            event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
             if (!event)
                 break;
         } else {
@@ -208,7 +208,7 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
         }
         nevents++;
 
-        QApplicationPrivate::processUserEvent(event);
+        QApplicationPrivate::processWindowSystemEvent(event);
         delete event;
     }
 
@@ -222,7 +222,7 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
 bool QEventDispatcherQPA::hasPendingEvents()
 {
     extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
-    return qGlobalPostedEventsCount() || QWindowSystemInterfacePrivate::userEventsQueued();
+    return qGlobalPostedEventsCount() || QWindowSystemInterfacePrivate::windowSystemEventsQueued();
 }
 
 void QEventDispatcherQPA::registerSocketNotifier(QSocketNotifier *notifier)
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
deleted file mode 100644
index 4cf9ded..0000000
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qwindowsysteminterface.h"
-#include "qapplication_p.h"
-#include <QAbstractEventDispatcher>
-
-QT_BEGIN_NAMESPACE
-
-
-QTime QWindowSystemInterface::eventTime;
-
-//------------------------------------------------------------
-//
-// Callback functions for plugins:
-//
-
-QList<QWindowSystemInterface::UserEvent *> QWindowSystemInterfacePrivate::userEventQueue;
-QMutex QWindowSystemInterfacePrivate::queueMutex;
-
-extern QPointer<QWidget> qt_last_mouse_receiver;
-/*!
-
-\a tlw == 0 means that \a ev is in global coords only
-
-
-*/
-
-
-void QWindowSystemInterface::handleEnterEvent(QWidget *tlw)
-{
-    if (tlw) {
-        QApplicationPrivate::dispatchEnterLeave(tlw, 0);
-        qt_last_mouse_receiver = tlw;
-    }
-}
-
-void QWindowSystemInterface::handleLeaveEvent(QWidget *tlw)
-{
-    QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
-    if (tlw && !tlw->isAncestorOf(qt_last_mouse_receiver)) //(???) this should not happen
-        QApplicationPrivate::dispatchEnterLeave(0, tlw);
-    qt_last_mouse_receiver = 0;
-}
-
-void QWindowSystemInterface::handleGeometryChange(QWidget *tlw, const QRect &newRect)
-{
-    if (tlw)
-        QApplicationPrivate::processGeometryChange(tlw, newRect);
-}
-
-
-void QWindowSystemInterface::handleCloseEvent(QWidget *tlw)
-{
-    if (tlw)
-        QApplicationPrivate::processCloseEvent(tlw);
-}
-
-void QWindowSystemInterface::handleMouseEvent(QWidget *tlw, ulong timestamp, const QPoint & local, const QPoint & global, Qt::MouseButtons b)
-{
-    MouseEvent * e = new MouseEvent(tlw, timestamp, local, global, b);
-    QWindowSystemInterfacePrivate::queueUserEvent(e);
-}
-
-void QWindowSystemInterface::handleKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
-{
-    KeyEvent * e = new KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
-    QWindowSystemInterfacePrivate::queueUserEvent(e);
-}
-
-void QWindowSystemInterface::handleWheelEvent(QWidget *tlw, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o)
-{
-    WheelEvent *e = new WheelEvent(tlw, timestamp, local, global, d, o);
-    QWindowSystemInterfacePrivate::queueUserEvent(e);
-}
-
-QWindowSystemInterface::UserEvent * QWindowSystemInterfacePrivate::getUserEvent()
-{
-    queueMutex.lock();
-    QWindowSystemInterface::UserEvent *ret;
-    if (userEventQueue.isEmpty())
-        ret = 0;
-    else
-        ret = userEventQueue.takeFirst();
-    queueMutex.unlock();
-    return ret;
-}
-
-void QWindowSystemInterfacePrivate::queueUserEvent(QWindowSystemInterface::UserEvent *ev)
-{
-    queueMutex.lock();
-    userEventQueue.append(ev);
-    queueMutex.unlock();
-
-    QAbstractEventDispatcher *dispatcher = QApplicationPrivate::qt_qpa_core_dispatcher();
-    if (dispatcher)
-        dispatcher->wakeUp();
-}
-
-void QWindowSystemInterface::handleTouchEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
-{
-    if (!points.size()) // Touch events must have at least one point
-        return;
-
-    QList<QTouchEvent::TouchPoint> touchPoints;
-    Qt::TouchPointStates states;
-    QTouchEvent::TouchPoint p;
-
-    int primaryPoint = -1;
-    QList<struct TouchPoint>::const_iterator point = points.constBegin();
-    QList<struct TouchPoint>::const_iterator end = points.constEnd();
-    while (point != end) {
-        p.setId(point->id);
-        p.setPressure(point->pressure);
-        states |= point->state;
-        Qt::TouchPointStates state = point->state;
-        if (point->isPrimary) {
-            state |= Qt::TouchPointPrimary;
-            primaryPoint = point->id;
-        }
-        p.setState(state);
-        p.setRect(point->area);
-        p.setScreenPos(point->area.center());
-        p.setNormalizedPos(point->normalPosition);
-
-        touchPoints.append(p);
-        ++point;
-    }
-
-    TouchEvent *e = new TouchEvent(tlw, timestamp, type, devType, touchPoints);
-    QWindowSystemInterfacePrivate::queueUserEvent(e);
-}
-
-void QWindowSystemInterface::handleScreenGeometryChange(int screenIndex)
-{
-    QApplicationPrivate::reportGeometryChange(screenIndex);
-}
-
-void QWindowSystemInterface::handleScreenAvailableGeometryChange(int screenIndex)
-{
-    QApplicationPrivate::reportAvailableGeometryChange(screenIndex);
-}
-
-void QWindowSystemInterface::handleScreenCountChange(int count)
-{
-    QApplicationPrivate::reportScreenCount(count);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
deleted file mode 100644
index 614f983..0000000
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QWINDOWSYSTEMINTERFACE_H
-#define QWINDOWSYSTEMINTERFACE_H
-
-#include <QtCore/QTime>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/QEvent>
-#include <QtGui/QWidget>
-#include <QtCore/QWeakPointer>
-#include <QtCore/QMutex>
-#include <QtGui/QTouchEvent>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QWindowSystemInterface
-{
-public:
-    static void handleMouseEvent(QWidget *w, const QPoint & local, const QPoint & global, Qt::MouseButtons b) {
-        handleMouseEvent(w, eventTime.elapsed(), local, global, b);
-    }
-
-    static void handleMouseEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, Qt::MouseButtons b);
-
-    static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1) {
-        handleKeyEvent(w, eventTime.elapsed(), t, k, mods, text, autorep, count);
-    }
-
-    static void handleKeyEvent(QWidget *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
-
-    static void handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o) {
-        handleWheelEvent(w, eventTime.elapsed(), local, global, d, o);
-    }
-
-    static void handleWheelEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o);
-
-    struct TouchPoint {
-        int id;                 // for application use
-        bool isPrimary;         // for application use
-        QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1)
-        QRectF area;            // the touched area, centered at position in screen coordinates
-        qreal pressure;         // 0 to 1
-        Qt::TouchPointStates state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
-    };
-
-    static void handleTouchEvent(QWidget *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
-        handleTouchEvent(w, eventTime.elapsed(), type, devType, points);
-    }
-
-    static void handleTouchEvent(QWidget *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
-
-    // delivered directly by the plugin via spontaneous events
-    static void handleGeometryChange(QWidget *w, const QRect &newRect);
-    static void handleCloseEvent(QWidget *w);
-    static void handleEnterEvent(QWidget *w);
-    static void handleLeaveEvent(QWidget *w);
-
-    // Changes to the screen
-    static void handleScreenGeometryChange(int screenIndex);
-    static void handleScreenAvailableGeometryChange(int screenIndex);
-    static void handleScreenCountChange(int count);
-
-    class UserEvent {
-    public:
-        UserEvent(QWidget * w, ulong time, QEvent::Type t)
-            { widget = QWeakPointer<QWidget>(w); type = t; timestamp = time; }
-        QWeakPointer<QWidget> widget;
-        QEvent::Type type;
-        unsigned long timestamp;
-    };
-
-    class MouseEvent : public UserEvent {
-    public:
-        MouseEvent(QWidget * w, ulong time, const QPoint & local, const QPoint & global, Qt::MouseButtons b)
-            : UserEvent(w, time, QEvent::MouseMove){ localPos = local; globalPos = global; buttons = b; }
-        QPoint localPos;
-        QPoint globalPos;
-        Qt::MouseButtons buttons;
-    };
-
-    class WheelEvent : public UserEvent {
-    public:
-        WheelEvent(QWidget *w, ulong time, const QPoint & local, const QPoint & global, int d, Qt::Orientation o)
-            : UserEvent(w, time, QEvent::Wheel) { localPos = local; globalPos = global; delta = d; orient = o; }
-        int delta;
-        QPoint localPos;
-        QPoint globalPos;
-        Qt::Orientation orient;
-    };
-
-    class KeyEvent : public UserEvent {
-    public:
-        KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
-            :UserEvent(w, time, t){ key = k; unicode = text; repeat = autorep; repeatCount = count; modifiers = mods; }
-        int key;
-        QString unicode;
-        bool repeat;
-        ushort repeatCount;
-        Qt::KeyboardModifiers modifiers;
-    };
-
-    class TouchEvent : public UserEvent {
-    public:
-        TouchEvent(QWidget *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p)
-            :UserEvent(w, time, t) { devType = d; points = p; }
-        QTouchEvent::DeviceType devType;
-        QList<QTouchEvent::TouchPoint> points;
-    };
-
-private:
-    static QTime eventTime;
-
-};
-
-class QWindowSystemInterfacePrivate {
-public:
-    static QList<QWindowSystemInterface::UserEvent *> userEventQueue;
-    static QMutex queueMutex;
-
-    static int userEventsQueued() { queueMutex.lock(); int ret = userEventQueue.count(); queueMutex.unlock(); return ret; }
-    static QWindowSystemInterface::UserEvent * getUserEvent();
-    static void queueUserEvent(QWindowSystemInterface::UserEvent *ev);
-};
-
-QT_END_NAMESPACE
-QT_END_HEADER
-#endif // QWINDOWSYSTEMINTERFACE_H
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
new file mode 100644
index 0000000..dd78e8e
--- /dev/null
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qwindowsysteminterface_qpa.h"
+#include "qwindowsysteminterface_qpa_p.h"
+#include "qapplication_p.h"
+#include <QAbstractEventDispatcher>
+
+QT_BEGIN_NAMESPACE
+
+
+QTime QWindowSystemInterfacePrivate::eventTime;
+
+//------------------------------------------------------------
+//
+// Callback functions for plugins:
+//
+
+QList<QWindowSystemInterfacePrivate::WindowSystemEvent *> QWindowSystemInterfacePrivate::windowSystemEventQueue;
+QMutex QWindowSystemInterfacePrivate::queueMutex;
+
+extern QPointer<QWidget> qt_last_mouse_receiver;
+
+
+void QWindowSystemInterface::handleEnterEvent(QWidget *tlw)
+{
+    if (tlw) {
+        QWindowSystemInterfacePrivate::EnterEvent *e = new QWindowSystemInterfacePrivate::EnterEvent(tlw);
+        QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+    }
+}
+
+void QWindowSystemInterface::handleLeaveEvent(QWidget *tlw)
+{
+    QWindowSystemInterfacePrivate::LeaveEvent *e = new QWindowSystemInterfacePrivate::LeaveEvent(tlw);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGeometryChange(QWidget *tlw, const QRect &newRect)
+{
+    if (!tlw)
+        return;
+    if (!tlw->isWindow())
+        return; //geo of native child widgets is controlled by lighthouse
+                //so we already have sent the events; besides this new rect
+                //is not mapped to parent
+
+    QRect cr(tlw->geometry());
+
+    bool isResize = cr.size() != newRect.size();
+    bool isMove = cr.topLeft() != newRect.topLeft();
+    if (isResize) {
+        QWindowSystemInterfacePrivate::ResizeEvent *resizeEvent =
+                new QWindowSystemInterfacePrivate::ResizeEvent(tlw,newRect.size());
+        QWindowSystemInterfacePrivate::queueWindowSystemEvent(resizeEvent);
+    }
+
+    if (isMove) {
+        QWindowSystemInterfacePrivate::MoveEvent *moveEvent =
+                new QWindowSystemInterfacePrivate::MoveEvent(tlw,newRect.topLeft());
+        QWindowSystemInterfacePrivate::queueWindowSystemEvent(moveEvent);
+    }
+}
+
+
+void QWindowSystemInterface::handleCloseEvent(QWidget *tlw)
+{
+    if (tlw) {
+        QWindowSystemInterfacePrivate::CloseEvent *e =
+                new QWindowSystemInterfacePrivate::CloseEvent(tlw);
+        QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+    }
+}
+
+/*!
+
+\a tlw == 0 means that \a ev is in global coords only
+
+
+*/
+void QWindowSystemInterface::handleMouseEvent(QWidget *w, const QPoint & local, const QPoint & global, Qt::MouseButtons b) {
+    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+    handleMouseEvent(w, time, local, global, b);
+}
+
+void QWindowSystemInterface::handleMouseEvent(QWidget *tlw, ulong timestamp, const QPoint & local, const QPoint & global, Qt::MouseButtons b)
+{
+    QWindowSystemInterfacePrivate::MouseEvent * e =
+            new QWindowSystemInterfacePrivate::MouseEvent(tlw, timestamp, local, global, b);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
+    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+    handleKeyEvent(w, time, t, k, mods, text, autorep, count);
+}
+
+void QWindowSystemInterface::handleKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
+{
+    QWindowSystemInterfacePrivate::KeyEvent * e =
+            new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o) {
+    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+    handleWheelEvent(w, time, local, global, d, o);
+}
+
+void QWindowSystemInterface::handleWheelEvent(QWidget *tlw, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o)
+{
+    QWindowSystemInterfacePrivate::WheelEvent *e =
+            new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, d, o);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
+{
+    queueMutex.lock();
+    int ret = windowSystemEventQueue.count();
+    queueMutex.unlock();
+    return ret;
+}
+
+QWindowSystemInterfacePrivate::WindowSystemEvent * QWindowSystemInterfacePrivate::getWindowSystemEvent()
+{
+    queueMutex.lock();
+    QWindowSystemInterfacePrivate::WindowSystemEvent *ret;
+    if (windowSystemEventQueue.isEmpty())
+        ret = 0;
+    else
+        ret = windowSystemEventQueue.takeFirst();
+    queueMutex.unlock();
+    return ret;
+}
+
+void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+{
+    queueMutex.lock();
+    windowSystemEventQueue.append(ev);
+    queueMutex.unlock();
+
+    QAbstractEventDispatcher *dispatcher = QApplicationPrivate::qt_qpa_core_dispatcher();
+    if (dispatcher)
+        dispatcher->wakeUp();
+}
+
+void QWindowSystemInterface::handleTouchEvent(QWidget *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
+    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+    handleTouchEvent(w, time, type, devType, points);
+}
+
+void QWindowSystemInterface::handleTouchEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
+{
+    if (!points.size()) // Touch events must have at least one point
+        return;
+
+    QList<QTouchEvent::TouchPoint> touchPoints;
+    Qt::TouchPointStates states;
+    QTouchEvent::TouchPoint p;
+
+    int primaryPoint = -1;
+    QList<struct TouchPoint>::const_iterator point = points.constBegin();
+    QList<struct TouchPoint>::const_iterator end = points.constEnd();
+    while (point != end) {
+        p.setId(point->id);
+        p.setPressure(point->pressure);
+        states |= point->state;
+        Qt::TouchPointStates state = point->state;
+        if (point->isPrimary) {
+            state |= Qt::TouchPointPrimary;
+            primaryPoint = point->id;
+        }
+        p.setState(state);
+        p.setRect(point->area);
+        p.setScreenPos(point->area.center());
+        p.setNormalizedPos(point->normalPosition);
+
+        touchPoints.append(p);
+        ++point;
+    }
+
+    QWindowSystemInterfacePrivate::TouchEvent *e =
+            new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, devType, touchPoints);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleScreenGeometryChange(int screenIndex)
+{
+    QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
+            new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screenIndex);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleScreenAvailableGeometryChange(int screenIndex)
+{
+    QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e =
+            new QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent(screenIndex);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleScreenCountChange(int count)
+{
+    QWindowSystemInterfacePrivate::ScreenCountEvent *e =
+            new QWindowSystemInterfacePrivate::ScreenCountEvent(count);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
new file mode 100644
index 0000000..e57fa8e
--- /dev/null
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QWINDOWSYSTEMINTERFACE_H
+#define QWINDOWSYSTEMINTERFACE_H
+
+#include <QtCore/QTime>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/QEvent>
+#include <QtGui/QWidget>
+#include <QtCore/QWeakPointer>
+#include <QtCore/QMutex>
+#include <QtGui/QTouchEvent>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QWindowSystemInterface
+{
+public:
+    static void handleMouseEvent(QWidget *w, const QPoint & local, const QPoint & global, Qt::MouseButtons b);
+    static void handleMouseEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, Qt::MouseButtons b);
+
+    static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+    static void handleKeyEvent(QWidget *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+
+    static void handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o);
+    static void handleWheelEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o);
+
+    struct TouchPoint {
+        int id;                 // for application use
+        bool isPrimary;         // for application use
+        QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1)
+        QRectF area;            // the touched area, centered at position in screen coordinates
+        qreal pressure;         // 0 to 1
+        Qt::TouchPointStates state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
+    };
+
+    static void handleTouchEvent(QWidget *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+    static void handleTouchEvent(QWidget *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+
+    // delivered directly by the plugin via spontaneous events
+    static void handleGeometryChange(QWidget *w, const QRect &newRect);
+    static void handleCloseEvent(QWidget *w);
+    static void handleEnterEvent(QWidget *w);
+    static void handleLeaveEvent(QWidget *w);
+
+    // Changes to the screen
+    static void handleScreenGeometryChange(int screenIndex);
+    static void handleScreenAvailableGeometryChange(int screenIndex);
+    static void handleScreenCountChange(int count);
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+#endif // QWINDOWSYSTEMINTERFACE_H
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
new file mode 100644
index 0000000..90d1702
--- /dev/null
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QWINDOWSYSTEMINTERFACE_QPA_P_H
+#define QWINDOWSYSTEMINTERFACE_QPA_P_H
+
+#include "qwindowsysteminterface_qpa.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QWindowSystemInterfacePrivate {
+public:
+    Q_ENUMS(EventType);
+
+    enum EventType {
+        Close,
+        Resize,
+        Move,
+        Enter,
+        Leave,
+        Mouse,
+        Wheel,
+        Key,
+        Touch,
+        ScreenGeometry,
+        ScreenAvailableGeometry,
+        ScreenCountChange
+    };
+
+    class WindowSystemEvent {
+    public:
+        WindowSystemEvent(EventType t)
+            : type(t) { }
+        EventType type;
+    };
+
+    class CloseEvent : public WindowSystemEvent {
+    public:
+        CloseEvent(QWidget *tlw)
+            : WindowSystemEvent(Close), topLevel(tlw) { }
+        QWeakPointer<QWidget> topLevel;
+    };
+
+    class ResizeEvent : public WindowSystemEvent {
+    public:
+        ResizeEvent(QWidget *sizeChanged, const QSize &newSize)
+            : WindowSystemEvent(Resize), sizeChanged(sizeChanged), newSize(newSize)
+        { }
+        QWeakPointer<QWidget> sizeChanged;
+        QSize newSize;
+    };
+
+    class MoveEvent : public WindowSystemEvent {
+    public:
+        MoveEvent(QWidget *moved, const QPoint &newPos)
+            : WindowSystemEvent(Move), moved(moved), newPos(newPos)
+        { }
+        QWeakPointer<QWidget> moved;
+        QPoint newPos;
+    };
+
+    class EnterEvent : public WindowSystemEvent {
+    public:
+        EnterEvent(QWidget *enter)
+            : WindowSystemEvent(Enter), enter(enter)
+        { }
+        QWeakPointer<QWidget> enter;
+    };
+
+    class LeaveEvent : public WindowSystemEvent {
+    public:
+        LeaveEvent(QWidget *leave)
+            : WindowSystemEvent(Leave), leave(leave)
+        { }
+        QWeakPointer<QWidget> leave;
+    };
+
+    class UserEvent : public WindowSystemEvent {
+    public:
+        UserEvent(QWidget * w, ulong time, EventType t)
+            : WindowSystemEvent(t), widget(w), timestamp(time) { }
+        QWeakPointer<QWidget> widget;
+        unsigned long timestamp;
+    };
+
+    class MouseEvent : public UserEvent {
+    public:
+        MouseEvent(QWidget * w, ulong time, const QPoint & local, const QPoint & global, Qt::MouseButtons b)
+            : UserEvent(w, time, Mouse), localPos(local), globalPos(global), buttons(b) { }
+        QPoint localPos;
+        QPoint globalPos;
+        Qt::MouseButtons buttons;
+    };
+
+    class WheelEvent : public UserEvent {
+    public:
+        WheelEvent(QWidget *w, ulong time, const QPoint & local, const QPoint & global, int d, Qt::Orientation o)
+            : UserEvent(w, time, Wheel), delta(d), localPos(local), globalPos(global), orient(o) { }
+        int delta;
+        QPoint localPos;
+        QPoint globalPos;
+        Qt::Orientation orient;
+    };
+
+    class KeyEvent : public UserEvent {
+    public:
+        KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
+            :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
+             repeatCount(count), modifiers(mods), keyType(t) { }
+        int key;
+        QString unicode;
+        bool repeat;
+        ushort repeatCount;
+        Qt::KeyboardModifiers modifiers;
+        QEvent::Type keyType;
+    };
+
+    class TouchEvent : public UserEvent {
+    public:
+        TouchEvent(QWidget *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p)
+            :UserEvent(w, time, Touch), devType(d), points(p), touchType(t) { }
+        QTouchEvent::DeviceType devType;
+        QList<QTouchEvent::TouchPoint> points;
+        QEvent::Type touchType;
+
+    };
+
+    class ScreenCountEvent : public WindowSystemEvent {
+    public:
+        ScreenCountEvent (int count)
+            : WindowSystemEvent(ScreenCountChange) , count(count) { }
+        int count;
+    };
+
+    class ScreenGeometryEvent : public WindowSystemEvent {
+    public:
+        ScreenGeometryEvent(int index)
+            : WindowSystemEvent(ScreenGeometry), index(index) { }
+        int index;
+    };
+
+    class ScreenAvailableGeometryEvent : public WindowSystemEvent {
+    public:
+        ScreenAvailableGeometryEvent(int index)
+            : WindowSystemEvent(ScreenAvailableGeometry), index(index) { }
+        int index;
+    };
+
+    static QList<WindowSystemEvent *> windowSystemEventQueue;
+    static QMutex queueMutex;
+
+    static int windowSystemEventsQueued();
+    static WindowSystemEvent * getWindowSystemEvent();
+    static void queueWindowSystemEvent(WindowSystemEvent *ev);
+
+    static QTime eventTime;
+};
+
+QT_END_HEADER
+QT_END_NAMESPACE
+
+#endif // QWINDOWSYSTEMINTERFACE_QPA_P_H
-- 
cgit v0.12


From a17b1d7c18737de1b3c6122a1f9766cbaa0d7c26 Mon Sep 17 00:00:00 2001
From: Paul Olav Tvete <paul.tvete@nokia.com>
Date: Wed, 21 Jul 2010 10:14:18 +0200
Subject: Less ugly hack to make QtOpenGL compile on Lighthouse

This cleans up after commit bc5f5d99078d9ca1f4fc80fc7d0fe753d5ef396a
---
 src/gui/painting/qwindowsurface_p.h | 1 +
 src/opengl/qwindowsurface_gl.cpp    | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
index da02f5a..c845021 100644
--- a/src/gui/painting/qwindowsurface_p.h
+++ b/src/gui/painting/qwindowsurface_p.h
@@ -86,6 +86,7 @@ public:
 #else
     virtual void resize(const QSize &size);
     QSize size() const;
+    inline QRect geometry() const { return QRect(QPoint(), size()); }     //### cleanup before Qt 5
 #endif
 
     virtual bool scroll(const QRegion &area, int dx, int dy);
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 8c54fd1..6571a76 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -499,13 +499,11 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
                 }
             }
 #endif
-#ifndef Q_WS_QPA //###############################################
             if (d_ptr->paintedRegion.boundingRect() != geometry()) {
                 // Emits warning if not supported. Should never happen unless
                 // setPartialUpdateSupport(true) has been called.
                 context()->d_func()->swapRegion(&d_ptr->paintedRegion);
             } else
-#endif                
                 context()->swapBuffers();
 
             d_ptr->paintedRegion = QRegion();
-- 
cgit v0.12


From 77d17d054b8baff411613206a099af36f8e0bc43 Mon Sep 17 00:00:00 2001
From: Paul Olav Tvete <paul.tvete@nokia.com>
Date: Wed, 21 Jul 2010 16:07:34 +0200
Subject: Quick-and-dirty grabWindoe() implementation for the VNC plugin

---
 src/plugins/platforms/vnc/qvncintegration.cpp | 44 +++++++++++++++++++++------
 src/plugins/platforms/vnc/qvncintegration.h   |  2 ++
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index 16fa5bb..331c16a 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -156,16 +156,6 @@ QPixmapData *QVNCIntegration::createPixmapData(QPixmapData::PixelType type) cons
     return new QRasterPixmapData(type);
 }
 
-// QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget) const
-// {
-//     if (widget->windowType() == Qt::Desktop)
-//         return 0;   // Don't create an explicit window surface for the destkop.
-//     QFbWindowSurface * surface;
-//     surface = new QFbWindowSurface(mPrimaryScreen, widget);
-//     mPrimaryScreen->addWindowSurface(surface);
-//     return surface;
-// }
-
 QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
 {
     QFbWindowSurface * surface;
@@ -192,6 +182,40 @@ QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*wi
     return w;
 }
 
+QPixmap QVNCIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+{
+//    qDebug() << "QVNCIntegration::grabWindow" << window << x << y << width << height;
+
+    if (window == 0) { //desktop
+        QImage *desktopImage = mPrimaryScreen->image();
+        if (x==0 && y == 0 && width < 0 && height < 0) {
+            return QPixmap::fromImage(*desktopImage);
+        }
+        if (width < 0)
+            width = desktopImage->width() - x;
+        if (height < 0)
+            height = desktopImage->height() - y;
+        int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
+        QImage img(desktopImage->scanLine(y) + bytesPerPixel*x, width, height, desktopImage->bytesPerLine(), desktopImage->format());
+        return QPixmap::fromImage(img);
+    }
+    QWidget *win = QWidget::find(window);
+    if (win) {
+        QRect r = win->geometry();
+        if (width < 0)
+            width = r.width() - x;
+        if (height < 0)
+            height = r.height() - y;
+        QImage *desktopImage = mPrimaryScreen->image();
+        int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
+
+        QImage img(desktopImage->scanLine(r.top() + y) + bytesPerPixel*(r.left()+x), width, height, desktopImage->bytesPerLine(), desktopImage->format());
+          return QPixmap::fromImage(img);
+    }
+    return QPixmap();
+}
+
+
 void QVNCIntegration::moveToScreen(QWidget *window, int screen)
 {
     if (virtualDesktop) {   // all windows exist on all screens in virtual desktop mode
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index d49e051..241993d 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -84,6 +84,8 @@ public:
     QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
     QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
 
+    QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
     QList<QPlatformScreen *> screens() const { return mScreens; }
 
     bool isVirtualDesktop() { return virtualDesktop; }
-- 
cgit v0.12