Process screen events in the main thread

Screen events are still read in the screen event thread but are
processed in the main thread to make it possible to support
QAbstractNativeEventFilter for screen events later.

Implementation is similar to the xcb platform plugin.

Change-Id: I7bade3e13e51c6d70bb608727a93bbd3aabc5d47
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
This commit is contained in:
Jan Arne Petersen 2013-10-29 10:10:32 +01:00 committed by The Qt Project
parent 161e8653c3
commit 6802f34bed
4 changed files with 99 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -43,6 +43,7 @@
#define QQNXSCREENEVENTTHREAD_H
#include <QtCore/QThread>
#include <QtCore/QMutex>
#include <screen/screen.h>
@ -50,21 +51,33 @@ QT_BEGIN_NAMESPACE
class QQnxScreenEventHandler;
typedef QVarLengthArray<screen_event_t, 64> 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;
};