summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/kernel.pri13
-rw-r--r--src/gui/kernel/qapplication_p.h29
-rw-r--r--src/gui/kernel/qapplication_qpa.cpp133
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qpa.cpp18
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp194
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa_p.h6
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.cpp0
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.h13
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp5
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h5
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp186
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp246
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h (renamed from src/gui/kernel/qwindowsysteminterface.h)81
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h201
-rw-r--r--src/gui/painting/qwindowsurface_p.h1
-rw-r--r--src/opengl/qwindowsurface_gl.cpp2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.cpp97
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.h42
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp24
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h6
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.cpp8
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.h5
-rw-r--r--src/plugins/platforms/openkode/openkode.pro6
-rw-r--r--src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp29
-rw-r--r--src/plugins/platforms/openkode/qopenkodeeventloopintegration.h17
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.cpp42
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.h4
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.cpp1
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindowsurface.cpp6
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp44
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h2
31 files changed, 947 insertions, 519 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 45ffba3..af7d86c 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 \
@@ -219,7 +220,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 \
@@ -232,13 +234,14 @@ 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 \
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/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 962b79e..4f30bb8 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 9585b26..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;
}
@@ -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..4464036 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);
@@ -84,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 {
@@ -101,7 +208,7 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
}
nevents++;
- QApplicationPrivate::processUserEvent(event);
+ QApplicationPrivate::processWindowSystemEvent(event);
delete event;
}
@@ -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::windowSystemEventsQueued();
}
-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
--- /dev/null
+++ b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
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/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_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.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 614f983..e57fa8e 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -58,22 +58,13 @@ 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, 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) {
- handleKeyEvent(w, eventTime.elapsed(), t, k, mods, text, autorep, count);
- }
-
+ 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) {
- handleWheelEvent(w, eventTime.elapsed(), local, global, d, o);
- }
-
+ 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 {
@@ -85,10 +76,7 @@ public:
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, 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
@@ -101,67 +89,6 @@ public:
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
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
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();
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
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);
}
}
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; }