diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 129f149ca1..efffd26981 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -40,6 +40,9 @@ ****************************************************************************/ #include "qqnxscreeneventhandler.h" +#if defined(QQNX_SCREENEVENTTHREAD) +#include "qqnxscreeneventthread.h" +#endif #include "qqnxintegration.h" #include "qqnxkeytranslator.h" #include "qqnxscreen.h" @@ -63,6 +66,9 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration) , m_lastButtonState(Qt::NoButton) , m_lastMouseWindow(0) , m_touchDevice(0) +#if defined(QQNX_SCREENEVENTTHREAD) + , m_eventThread(0) +#endif { // Create a touch device m_touchDevice = new QTouchDevice; @@ -182,6 +188,39 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie } } +#if defined(QQNX_SCREENEVENTTHREAD) +void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread) +{ + m_eventThread = eventThread; +} + +void QQnxScreenEventHandler::processEventsFromScreenThread() +{ + if (!m_eventThread) + return; + + QQnxScreenEventArray *events = m_eventThread->lock(); + + for (int i = 0; i < events->size(); ++i) { + screen_event_t event = events->at(i); + if (!event) + continue; + (*events)[i] = 0; + + m_eventThread->unlock(); + + handleEvent(event); + screen_destroy_event(event); + + m_eventThread->lock(); + } + + events->clear(); + + m_eventThread->unlock(); +} +#endif + void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) { // get flags of key event diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h index 7ceb32fcec..1fdb2c83cd 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h @@ -49,6 +49,9 @@ QT_BEGIN_NAMESPACE class QQnxIntegration; +#if defined(QQNX_SCREENEVENTTHREAD) +class QQnxScreenEventThread; +#endif class QQnxScreenEventHandler : public QObject { @@ -61,10 +64,19 @@ public: static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); +#if defined(QQNX_SCREENEVENTTHREAD) + void setScreenEventThread(QQnxScreenEventThread *eventThread); +#endif + Q_SIGNALS: void newWindowCreated(void *window); void windowClosed(void *window); +#if defined(QQNX_SCREENEVENTTHREAD) +private Q_SLOTS: + void processEventsFromScreenThread(); +#endif + private: void handleKeyboardEvent(screen_event_t event); void handlePointerEvent(screen_event_t event); @@ -87,6 +99,9 @@ private: screen_window_t m_lastMouseWindow; QTouchDevice *m_touchDevice; QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; +#if defined(QQNX_SCREENEVENTTHREAD) + QQnxScreenEventThread *m_eventThread; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp index f3f660bc03..25a597bab9 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp @@ -61,6 +61,9 @@ QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context, QQnxScree m_screenEventHandler(screenEventHandler), m_quit(false) { + screenEventHandler->setScreenEventThread(this); + connect(this, SIGNAL(eventPending()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); + connect(this, SIGNAL(finished()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); } QQnxScreenEventThread::~QQnxScreenEventThread() @@ -74,20 +77,31 @@ void QQnxScreenEventThread::injectKeyboardEvent(int flags, int sym, int mod, int QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap); } +QQnxScreenEventArray *QQnxScreenEventThread::lock() +{ + m_mutex.lock(); + return &m_events; +} + +void QQnxScreenEventThread::unlock() +{ + m_mutex.unlock(); +} + void QQnxScreenEventThread::run() { - screen_event_t event; - - // create screen event - errno = 0; - int result = screen_create_event(&event); - if (result) - qFatal("QQNX: failed to create screen event, errno=%d", errno); - qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread started"; // loop indefinitely while (!m_quit) { + screen_event_t event; + + // create screen event + errno = 0; + int result = screen_create_event(&event); + if (result) + qFatal("QQNX: failed to create screen event, errno=%d", errno); + // block until screen event is available errno = 0; @@ -108,14 +122,22 @@ void QQnxScreenEventThread::run() qScreenEventThreadDebug() << Q_FUNC_INFO << "QNX user screen event"; m_quit = true; } else { - m_screenEventHandler->handleEvent(event, qnxType); + m_mutex.lock(); + m_events << event; + m_mutex.unlock(); + emit eventPending(); } } qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread stopped"; // cleanup - screen_destroy_event(event); + m_mutex.lock(); + Q_FOREACH (screen_event_t event, m_events) { + screen_destroy_event(event); + } + m_events.clear(); + m_mutex.unlock(); } void QQnxScreenEventThread::shutdown() diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h index 5e931819be..cbdb505b3b 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h @@ -43,6 +43,7 @@ #define QQNXSCREENEVENTTHREAD_H #include +#include #include @@ -50,21 +51,33 @@ QT_BEGIN_NAMESPACE class QQnxScreenEventHandler; +typedef QVarLengthArray QQnxScreenEventArray; + class QQnxScreenEventThread : public QThread { + Q_OBJECT + public: QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler); ~QQnxScreenEventThread(); static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); + QQnxScreenEventArray *lock(); + void unlock(); + protected: void run(); +Q_SIGNALS: + void eventPending(); + private: void shutdown(); screen_context_t m_screenContext; + QMutex m_mutex; + QQnxScreenEventArray m_events; QQnxScreenEventHandler *m_screenEventHandler; bool m_quit; };