summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Krammer <kevin.krammer.qnx@kdab.com>2012-03-28 13:20:40 +0200
committerQt by Nokia <qt-info@nokia.com>2012-03-28 19:34:42 +0200
commita80a2c6da241dac77f533bc702a1c7d94349a812 (patch)
treeddd6e4091c57d521535566d3bf49328a1acbba80
parentf5c5708f6e56eb0de5c1d0556218af4680d8fd1f (diff)
Move screen event processing into its own class
The event handler class can then be reused when we have proper BPS event support available from corelib Change-Id: Iafe645e69248597377045c711108ce0acbe3984b Reviewed-by: Sean Harmer <sh@theharmers.co.uk> Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
-rw-r--r--src/plugins/platforms/qnx/qnx.pro7
-rw-r--r--src/plugins/platforms/qnx/qqnxeventthread.cpp473
-rw-r--r--src/plugins/platforms/qnx/qqnxeventthread.h21
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp473
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h82
6 files changed, 592 insertions, 466 deletions
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 588464fc47..185934c1d1 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -20,6 +20,7 @@ QT += opengl opengl-private platformsupport platformsupport-private widgets-priv
#DEFINES += QQNXRASTERBACKINGSTORE_DEBUG
#DEFINES += QQNXROOTWINDOW_DEBUG
#DEFINES += QQNXSCREEN_DEBUG
+#DEFINES += QQNXSCREENEVENT_DEBUG
#DEFINES += QQNXVIRTUALKEYBOARD_DEBUG
#DEFINES += QQNXWINDOW_DEBUG
@@ -35,7 +36,8 @@ SOURCES = main.cpp \
qqnxrasterbackingstore.cpp \
qqnxvirtualkeyboard.cpp \
qqnxclipboard.cpp \
- qqnxrootwindow.cpp
+ qqnxrootwindow.cpp \
+ qqnxscreeneventhandler.cpp
HEADERS = qqnxbuffer.h \
@@ -50,7 +52,8 @@ HEADERS = qqnxbuffer.h \
qqnxrasterbackingstore.h \
qqnxvirtualkeyboard.h \
qqnxclipboard.h \
- qqnxrootwindow.h
+ qqnxrootwindow.h \
+ qqnxscreeneventhandler.h
CONFIG(blackberry) {
SOURCES += qqnxservices.cpp
diff --git a/src/plugins/platforms/qnx/qqnxeventthread.cpp b/src/plugins/platforms/qnx/qqnxeventthread.cpp
index cd30da1971..1e08dbcd9c 100644
--- a/src/plugins/platforms/qnx/qqnxeventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxeventthread.cpp
@@ -40,53 +40,20 @@
****************************************************************************/
#include "qqnxeventthread.h"
-#include "qqnxintegration.h"
-#include "qqnxkeytranslator.h"
-
-#if defined(QQNX_IMF)
-#include "qqnxinputcontext_imf.h"
-#else
-#include "qqnxinputcontext_noimf.h"
-#endif
-
-#include <QtGui/QWindow>
-#include <QtGui/QPlatformScreen>
-#include <QtGui/QGuiApplication>
+#include "qqnxscreeneventhandler.h"
#include <QtCore/QDebug>
#include <errno.h>
#include <unistd.h>
-#include <sys/keycodes.h>
#include <cctype>
-QQnxEventThread::QQnxEventThread(screen_context_t context, QPlatformScreen& screen)
+QQnxEventThread::QQnxEventThread(screen_context_t context)
: QThread(),
m_screenContext(context),
- m_platformScreen(screen),
- m_quit(false),
- m_lastButtonState(Qt::NoButton),
- m_lastMouseWindow(0)
+ m_quit(false)
{
- // Create a touch device
- m_touchDevice = new QTouchDevice;
- m_touchDevice->setType(QTouchDevice::TouchScreen);
- m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
- QWindowSystemInterface::registerTouchDevice(m_touchDevice);
-
- // initialize array of touch points
- for (int i = 0; i < MaximumTouchPoints; i++) {
-
- // map array index to id
- m_touchPoints[i].id = i;
-
- // pressure is not supported - use default
- m_touchPoints[i].pressure = 1.0;
-
- // nothing touching
- m_touchPoints[i].state = Qt::TouchPointReleased;
- }
}
QQnxEventThread::~QQnxEventThread()
@@ -95,16 +62,21 @@ QQnxEventThread::~QQnxEventThread()
shutdown();
}
+void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
+{
+ QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap);
+}
+
void QQnxEventThread::run()
{
+ QQnxScreenEventHandler eventHandler;
screen_event_t event;
// create screen event
errno = 0;
int result = screen_create_event(&event);
- if (result) {
+ if (result)
qFatal("QQNX: failed to create event, errno=%d", errno);
- }
#if defined(QQNXEVENTTHREAD_DEBUG)
qDebug() << "QQNX: event loop started";
@@ -116,12 +88,26 @@ void QQnxEventThread::run()
// block until screen event is available
errno = 0;
result = screen_get_event(m_screenContext, event, -1);
- if (result) {
+ if (result)
qFatal("QQNX: failed to get event, errno=%d", errno);
- }
// process received event
- dispatchEvent(event);
+ // get the event type
+ errno = 0;
+ int qnxType;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
+ if (result)
+ qFatal("QQNX: failed to query event type, errno=%d", errno);
+
+ if (qnxType == SCREEN_EVENT_USER) {
+ // treat all user events as shutdown requests
+ #if defined(QQNXEVENTTHREAD_DEBUG)
+ qDebug() << "QQNX: QNX user event";
+ #endif
+ m_quit = true;
+ } else {
+ eventHandler.handleEvent(event, qnxType);
+ }
}
#if defined(QQNXEVENTTHREAD_DEBUG)
@@ -139,26 +125,23 @@ void QQnxEventThread::shutdown()
// create screen event
errno = 0;
int result = screen_create_event(&event);
- if (result) {
+ if (result)
qFatal("QQNX: failed to create event, errno=%d", errno);
- }
// set the event type as user
errno = 0;
int type = SCREEN_EVENT_USER;
result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type);
- if (result) {
+ if (result)
qFatal("QQNX: failed to set event type, errno=%d", errno);
- }
// NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events
// post event to event loop so it will wake up and die
errno = 0;
result = screen_send_event(m_screenContext, event, getpid());
- if (result) {
+ if (result)
qFatal("QQNX: failed to set event type, errno=%d", errno);
- }
// cleanup
screen_destroy_event(event);
@@ -174,399 +157,3 @@ void QQnxEventThread::shutdown()
qDebug() << "QQNX: event loop shutdown end";
#endif
}
-
-void QQnxEventThread::dispatchEvent(screen_event_t event)
-{
- // get the event type
- errno = 0;
- int qnxType;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
- if (result) {
- qFatal("QQNX: failed to query event type, errno=%d", errno);
- }
-
- switch (qnxType) {
- case SCREEN_EVENT_MTOUCH_TOUCH:
- case SCREEN_EVENT_MTOUCH_MOVE:
- case SCREEN_EVENT_MTOUCH_RELEASE:
- handleTouchEvent(event, qnxType);
- break;
-
- case SCREEN_EVENT_KEYBOARD:
- handleKeyboardEvent(event);
- break;
-
- case SCREEN_EVENT_POINTER:
- handlePointerEvent(event);
- break;
-
- case SCREEN_EVENT_CLOSE:
- handleCloseEvent(event);
- break;
-
- case SCREEN_EVENT_USER:
- // treat all user events as shutdown requests
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: QNX user event";
-#endif
- m_quit = true;
- break;
-
- default:
- // event ignored
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: QNX unknown event";
-#endif
- break;
- }
-}
-
-void QQnxEventThread::handleKeyboardEvent(screen_event_t event)
-{
- // get flags of key event
- errno = 0;
- int flags;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
- if (result) {
- qFatal("QQNX: failed to query event flags, errno=%d", errno);
- }
-
- // get key code
- errno = 0;
- int sym;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
- if (result) {
- qFatal("QQNX: failed to query event sym, errno=%d", errno);
- }
-
- int modifiers;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
- if (result) {
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
- }
-
- int scan;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
- if (result) {
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
- }
-
- int cap;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
- if (result) {
- qFatal("QQNX: failed to query event cap, errno=%d", errno);
- }
-
- injectKeyboardEvent(flags, sym, modifiers, scan, cap);
-}
-
-void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap)
-{
- Q_UNUSED(scan);
-
- Qt::KeyboardModifiers qtMod = Qt::NoModifier;
- if (modifiers & KEYMOD_SHIFT)
- qtMod |= Qt::ShiftModifier;
- if (modifiers & KEYMOD_CTRL)
- qtMod |= Qt::ControlModifier;
- if (modifiers & KEYMOD_ALT)
- qtMod |= Qt::AltModifier;
-
- // determine event type
- QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease;
-
- // Check if the key cap is valid
- if (flags & KEY_CAP_VALID) {
- Qt::Key key;
- QString keyStr;
-
- if (cap >= 0x20 && cap <= 0x0ff) {
- key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case.
-
- if ( qtMod & Qt::ControlModifier ) {
- keyStr = QChar((int)(key & 0x3f));
- } else {
- if (flags & KEY_SYM_VALID) {
- keyStr = QChar(sym);
- }
- }
- } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) {
- key = (Qt::Key)cap;
- keyStr = QChar(sym);
- } else {
- if (isKeypadKey(cap))
- qtMod |= Qt::KeypadModifier; // Is this right?
- key = keyTranslator(cap);
- }
-
- QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
-#endif
- }
-}
-
-void QQnxEventThread::handlePointerEvent(screen_event_t event)
-{
- errno = 0;
-
- // Query the window that was clicked
- screen_window_t qnxWindow;
- void *handle;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result) {
- qFatal("QQNX: failed to query event window, errno=%d", errno);
- }
- qnxWindow = static_cast<screen_window_t>(handle);
-
- // Query the button states
- int buttonState = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState);
- if (result) {
- qFatal("QQNX: failed to query event button state, errno=%d", errno);
- }
-
- // Query the window position
- int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result) {
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
- }
-
- // Query the screen position
- int pos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result) {
- qFatal("QQNX: failed to query event position, errno=%d", errno);
- }
-
- // Query the wheel delta
- int wheelDelta = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta);
- if (result) {
- qFatal("QQNX: failed to query event wheel delta, errno=%d", errno);
- }
-
- // Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
-
- // Generate enter and leave events as needed.
- if (qnxWindow != m_lastMouseWindow) {
- QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
-
- if (wOld) {
- QWindowSystemInterface::handleLeaveEvent(wOld);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt leave, w=" << wOld;
-#endif
- }
-
- if (w) {
- QWindowSystemInterface::handleEnterEvent(w);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt enter, w=" << w;
-#endif
- }
- }
- m_lastMouseWindow = qnxWindow;
-
- // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale
- // this via a system preference at some point. But for now this is a sane value and makes
- // the wheel usable.
- wheelDelta *= -10;
-
- // convert point to local coordinates
- QPoint globalPoint(pos[0], pos[1]);
- QPoint localPoint(windowPos[0], windowPos[1]);
-
- // Convert buttons.
- // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit,
- // so we may receive events as shown. (If this is wrong, the fix is easy.)
- // QNX Button mask is 8 buttons wide, with a maximum value of x080.
- Qt::MouseButtons buttons = Qt::NoButton;
- if (buttonState & 0x01)
- buttons |= Qt::LeftButton;
- if (buttonState & 0x02)
- buttons |= Qt::MidButton;
- if (buttonState & 0x04)
- buttons |= Qt::RightButton;
- if (buttonState & 0x08)
- buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton'
- if (buttonState & 0x10)
- buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton'
- if (buttonState & 0x20)
- buttons |= Qt::ExtraButton3;
- if (buttonState & 0x40)
- buttons |= Qt::ExtraButton4;
- if (buttonState & 0x80)
- buttons |= Qt::ExtraButton5;
-
- if (w) {
- // Inject mouse event into Qt only if something has changed.
- if (m_lastGlobalMousePoint != globalPoint ||
- m_lastLocalMousePoint != localPoint ||
- m_lastButtonState != buttons) {
- QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast<int>(buttons);
-#endif
- }
-
- if (wheelDelta) {
- // Screen only supports a single wheel, so we will assume Vertical orientation for
- // now since that is pretty much standard.
- QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast<int>(wheelDelta);
-#endif
- }
- }
-
- m_lastGlobalMousePoint = globalPoint;
- m_lastLocalMousePoint = localPoint;
- m_lastButtonState = buttons;
-}
-
-void QQnxEventThread::handleTouchEvent(screen_event_t event, int qnxType)
-{
- // get display coordinates of touch
- errno = 0;
- int pos[2];
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result) {
- qFatal("QQNX: failed to query event position, errno=%d", errno);
- }
-
- // get window coordinates of touch
- errno = 0;
- int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result) {
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
- }
-
- // determine which finger touched
- errno = 0;
- int touchId;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId);
- if (result) {
- qFatal("QQNX: failed to query event touch id, errno=%d", errno);
- }
-
- // determine which window was touched
- errno = 0;
- void *handle;
- result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result) {
- qFatal("QQNX: failed to query event window, errno=%d", errno);
- }
- screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
-
- // check if finger is valid
- if (touchId < MaximumTouchPoints) {
-
- // Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
-
- // Generate enter and leave events as needed.
- if (qnxWindow != m_lastMouseWindow) {
- QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
-
- if (wOld) {
- QWindowSystemInterface::handleLeaveEvent(wOld);
- #if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt leave, w=" << wOld;
- #endif
- }
-
- if (w) {
- QWindowSystemInterface::handleEnterEvent(w);
- #if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt enter, w=" << w;
- #endif
- }
- }
- m_lastMouseWindow = qnxWindow;
-
- if (w) {
- // convert primary touch to mouse event
- if (touchId == 0) {
-
- // convert point to local coordinates
- QPoint globalPoint(pos[0], pos[1]);
- QPoint localPoint(windowPos[0], windowPos[1]);
-
- // map touch state to button state
- Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton;
-
- // inject event into Qt
- QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons;
-#endif
- }
-
- // get size of screen which contains window
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w);
- QSizeF screenSize = platformScreen->physicalSize();
-
- // update cached position of current touch point
- m_touchPoints[touchId].normalPosition = QPointF( static_cast<qreal>(pos[0]) / screenSize.width(), static_cast<qreal>(pos[1]) / screenSize.height() );
- m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 );
-
- // determine event type and update state of current touch point
- QEvent::Type type = QEvent::None;
- switch (qnxType) {
- case SCREEN_EVENT_MTOUCH_TOUCH:
- m_touchPoints[touchId].state = Qt::TouchPointPressed;
- type = QEvent::TouchBegin;
- break;
- case SCREEN_EVENT_MTOUCH_MOVE:
- m_touchPoints[touchId].state = Qt::TouchPointMoved;
- type = QEvent::TouchUpdate;
- break;
- case SCREEN_EVENT_MTOUCH_RELEASE:
- m_touchPoints[touchId].state = Qt::TouchPointReleased;
- type = QEvent::TouchEnd;
- break;
- }
-
- // build list of active touch points
- QList<QWindowSystemInterface::TouchPoint> pointList;
- for (int i = 0; i < MaximumTouchPoints; i++) {
- if (i == touchId) {
- // current touch point is always active
- pointList.append(m_touchPoints[i]);
- } else if (m_touchPoints[i].state != Qt::TouchPointReleased) {
- // finger is down but did not move
- m_touchPoints[i].state = Qt::TouchPointStationary;
- pointList.append(m_touchPoints[i]);
- }
- }
-
- // inject event into Qt
- QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList);
-#if defined(QQNXEVENTTHREAD_DEBUG)
- qDebug() << "QQNX: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type;
-#endif
- }
- }
-}
-
-void QQnxEventThread::handleCloseEvent(screen_event_t event)
-{
- // Query the window that was closed
- void *handle;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result != 0) {
- qFatal("QQNX: failed to query event window, errno=%d", errno);
- }
- screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
-
- // Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
- if (w != 0) {
- QWindowSystemInterface::handleCloseEvent(w);
- }
-}
-
diff --git a/src/plugins/platforms/qnx/qqnxeventthread.h b/src/plugins/platforms/qnx/qqnxeventthread.h
index 61831233e9..9724587c37 100644
--- a/src/plugins/platforms/qnx/qqnxeventthread.h
+++ b/src/plugins/platforms/qnx/qqnxeventthread.h
@@ -44,9 +44,6 @@
#include <QtCore/QThread>
-#include <QtGui/QPlatformScreen>
-#include <QtGui/QWindowSystemInterface>
-
#include <screen/screen.h>
QT_BEGIN_NAMESPACE
@@ -54,7 +51,7 @@ QT_BEGIN_NAMESPACE
class QQnxEventThread : public QThread
{
public:
- QQnxEventThread(screen_context_t context, QPlatformScreen& screen);
+ explicit QQnxEventThread(screen_context_t context);
virtual ~QQnxEventThread();
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
@@ -63,26 +60,10 @@ protected:
virtual void run();
private:
- enum {
- MaximumTouchPoints = 10
- };
-
void shutdown();
- void dispatchEvent(screen_event_t event);
- void handleKeyboardEvent(screen_event_t event);
- void handlePointerEvent(screen_event_t event);
- void handleTouchEvent(screen_event_t event, int type);
- void handleCloseEvent(screen_event_t event);
screen_context_t m_screenContext;
- QPlatformScreen& m_platformScreen;
bool m_quit;
- QPoint m_lastGlobalMousePoint;
- QPoint m_lastLocalMousePoint;
- Qt::MouseButtons m_lastButtonState;
- screen_window_t m_lastMouseWindow;
- QTouchDevice *m_touchDevice;
- QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 5ef34f3aea..00ba7d825e 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -108,7 +108,7 @@ QQnxIntegration::QQnxIntegration()
QQnxGLContext::initialize();
// Create/start event thread
- m_eventThread = new QQnxEventThread(m_screenContext, *QQnxScreen::primaryDisplay());
+ m_eventThread = new QQnxEventThread(m_screenContext);
m_eventThread->start();
// Create/start navigator event handler
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
new file mode 100644
index 0000000000..9ac5ca4a05
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -0,0 +1,473 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxscreeneventhandler.h"
+#include "qqnxintegration.h"
+#include "qqnxkeytranslator.h"
+
+#include <QDebug>
+#include <QGuiApplication>
+
+#include <errno.h>
+#include <sys/keycodes.h>
+
+QT_BEGIN_NAMESPACE
+
+QQnxScreenEventHandler::QQnxScreenEventHandler()
+ : m_lastButtonState(Qt::NoButton)
+ , m_lastMouseWindow(0)
+ , m_touchDevice(0)
+{
+ // Create a touch device
+ m_touchDevice = new QTouchDevice;
+ m_touchDevice->setType(QTouchDevice::TouchScreen);
+ m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
+
+ // initialize array of touch points
+ for (int i = 0; i < MaximumTouchPoints; i++) {
+
+ // map array index to id
+ m_touchPoints[i].id = i;
+
+ // pressure is not supported - use default
+ m_touchPoints[i].pressure = 1.0;
+
+ // nothing touching
+ m_touchPoints[i].state = Qt::TouchPointReleased;
+ }
+}
+
+bool QQnxScreenEventHandler::handleEvent(screen_event_t event)
+{
+ // get the event type
+ errno = 0;
+ int qnxType;
+ int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
+ if (result) {
+ qFatal("QQNX: failed to query event type, errno=%d", errno);
+ }
+
+ return handleEvent(event, qnxType);
+}
+
+bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
+{
+ switch (qnxType) {
+ case SCREEN_EVENT_MTOUCH_TOUCH:
+ case SCREEN_EVENT_MTOUCH_MOVE:
+ case SCREEN_EVENT_MTOUCH_RELEASE:
+ handleTouchEvent(event, qnxType);
+ break;
+
+ case SCREEN_EVENT_KEYBOARD:
+ handleKeyboardEvent(event);
+ break;
+
+ case SCREEN_EVENT_POINTER:
+ handlePointerEvent(event);
+ break;
+
+ case SCREEN_EVENT_CLOSE:
+ handleCloseEvent(event);
+ break;
+
+ default:
+ // event ignored
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: QNX unknown event";
+#endif
+ return false;
+ }
+
+ return true;
+}
+
+void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap)
+{
+ Q_UNUSED(scan);
+
+ Qt::KeyboardModifiers qtMod = Qt::NoModifier;
+ if (modifiers & KEYMOD_SHIFT)
+ qtMod |= Qt::ShiftModifier;
+ if (modifiers & KEYMOD_CTRL)
+ qtMod |= Qt::ControlModifier;
+ if (modifiers & KEYMOD_ALT)
+ qtMod |= Qt::AltModifier;
+
+ // determine event type
+ QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease;
+
+ // Check if the key cap is valid
+ if (flags & KEY_CAP_VALID) {
+ Qt::Key key;
+ QString keyStr;
+
+ if (cap >= 0x20 && cap <= 0x0ff) {
+ key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case.
+
+ if ( qtMod & Qt::ControlModifier ) {
+ keyStr = QChar((int)(key & 0x3f));
+ } else {
+ if (flags & KEY_SYM_VALID) {
+ keyStr = QChar(sym);
+ }
+ }
+ } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) {
+ key = (Qt::Key)cap;
+ keyStr = QChar(sym);
+ } else {
+ if (isKeypadKey(cap))
+ qtMod |= Qt::KeypadModifier; // Is this right?
+ key = keyTranslator(cap);
+ }
+
+ QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
+#endif
+ }
+}
+
+void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
+{
+ // get flags of key event
+ errno = 0;
+ int flags;
+ int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
+ if (result) {
+ qFatal("QQNX: failed to query event flags, errno=%d", errno);
+ }
+
+ // get key code
+ errno = 0;
+ int sym;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
+ if (result) {
+ qFatal("QQNX: failed to query event sym, errno=%d", errno);
+ }
+
+ int modifiers;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
+ if (result) {
+ qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ }
+
+ int scan;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
+ if (result) {
+ qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ }
+
+ int cap;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
+ if (result) {
+ qFatal("QQNX: failed to query event cap, errno=%d", errno);
+ }
+
+ injectKeyboardEvent(flags, sym, modifiers, scan, cap);
+}
+
+void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
+{
+ errno = 0;
+
+ // Query the window that was clicked
+ screen_window_t qnxWindow;
+ void *handle;
+ int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
+ if (result) {
+ qFatal("QQNX: failed to query event window, errno=%d", errno);
+ }
+ qnxWindow = static_cast<screen_window_t>(handle);
+
+ // Query the button states
+ int buttonState = 0;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState);
+ if (result) {
+ qFatal("QQNX: failed to query event button state, errno=%d", errno);
+ }
+
+ // Query the window position
+ int windowPos[2];
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
+ if (result) {
+ qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ }
+
+ // Query the screen position
+ int pos[2];
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
+ if (result) {
+ qFatal("QQNX: failed to query event position, errno=%d", errno);
+ }
+
+ // Query the wheel delta
+ int wheelDelta = 0;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta);
+ if (result) {
+ qFatal("QQNX: failed to query event wheel delta, errno=%d", errno);
+ }
+
+ // Map window handle to top-level QWindow
+ QWindow *w = QQnxIntegration::window(qnxWindow);
+
+ // Generate enter and leave events as needed.
+ if (qnxWindow != m_lastMouseWindow) {
+ QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
+
+ if (wOld) {
+ QWindowSystemInterface::handleLeaveEvent(wOld);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt leave, w=" << wOld;
+#endif
+ }
+
+ if (w) {
+ QWindowSystemInterface::handleEnterEvent(w);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt enter, w=" << w;
+#endif
+ }
+ }
+ m_lastMouseWindow = qnxWindow;
+
+ // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale
+ // this via a system preference at some point. But for now this is a sane value and makes
+ // the wheel usable.
+ wheelDelta *= -10;
+
+ // convert point to local coordinates
+ QPoint globalPoint(pos[0], pos[1]);
+ QPoint localPoint(windowPos[0], windowPos[1]);
+
+ // Convert buttons.
+ // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit,
+ // so we may receive events as shown. (If this is wrong, the fix is easy.)
+ // QNX Button mask is 8 buttons wide, with a maximum value of x080.
+ Qt::MouseButtons buttons = Qt::NoButton;
+ if (buttonState & 0x01)
+ buttons |= Qt::LeftButton;
+ if (buttonState & 0x02)
+ buttons |= Qt::MidButton;
+ if (buttonState & 0x04)
+ buttons |= Qt::RightButton;
+ if (buttonState & 0x08)
+ buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton'
+ if (buttonState & 0x10)
+ buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton'
+ if (buttonState & 0x20)
+ buttons |= Qt::ExtraButton3;
+ if (buttonState & 0x40)
+ buttons |= Qt::ExtraButton4;
+ if (buttonState & 0x80)
+ buttons |= Qt::ExtraButton5;
+
+ if (w) {
+ // Inject mouse event into Qt only if something has changed.
+ if (m_lastGlobalMousePoint != globalPoint ||
+ m_lastLocalMousePoint != localPoint ||
+ m_lastButtonState != buttons) {
+ QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast<int>(buttons);
+#endif
+ }
+
+ if (wheelDelta) {
+ // Screen only supports a single wheel, so we will assume Vertical orientation for
+ // now since that is pretty much standard.
+ QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast<int>(wheelDelta);
+#endif
+ }
+ }
+
+ m_lastGlobalMousePoint = globalPoint;
+ m_lastLocalMousePoint = localPoint;
+ m_lastButtonState = buttons;
+}
+
+void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
+{
+ // get display coordinates of touch
+ errno = 0;
+ int pos[2];
+ int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
+ if (result) {
+ qFatal("QQNX: failed to query event position, errno=%d", errno);
+ }
+
+ // get window coordinates of touch
+ errno = 0;
+ int windowPos[2];
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
+ if (result) {
+ qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ }
+
+ // determine which finger touched
+ errno = 0;
+ int touchId;
+ result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId);
+ if (result) {
+ qFatal("QQNX: failed to query event touch id, errno=%d", errno);
+ }
+
+ // determine which window was touched
+ errno = 0;
+ void *handle;
+ result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
+ if (result) {
+ qFatal("QQNX: failed to query event window, errno=%d", errno);
+ }
+ screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
+
+ // check if finger is valid
+ if (touchId < MaximumTouchPoints) {
+
+ // Map window handle to top-level QWindow
+ QWindow *w = QQnxIntegration::window(qnxWindow);
+
+ // Generate enter and leave events as needed.
+ if (qnxWindow != m_lastMouseWindow) {
+ QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
+
+ if (wOld) {
+ QWindowSystemInterface::handleLeaveEvent(wOld);
+ #if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt leave, w=" << wOld;
+ #endif
+ }
+
+ if (w) {
+ QWindowSystemInterface::handleEnterEvent(w);
+ #if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt enter, w=" << w;
+ #endif
+ }
+ }
+ m_lastMouseWindow = qnxWindow;
+
+ if (w) {
+ // convert primary touch to mouse event
+ if (touchId == 0) {
+
+ // convert point to local coordinates
+ QPoint globalPoint(pos[0], pos[1]);
+ QPoint localPoint(windowPos[0], windowPos[1]);
+
+ // map touch state to button state
+ Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton;
+
+ // inject event into Qt
+ QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons;
+#endif
+ }
+
+ // get size of screen which contains window
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w);
+ QSizeF screenSize = platformScreen->physicalSize();
+
+ // update cached position of current touch point
+ m_touchPoints[touchId].normalPosition = QPointF( static_cast<qreal>(pos[0]) / screenSize.width(), static_cast<qreal>(pos[1]) / screenSize.height() );
+ m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 );
+
+ // determine event type and update state of current touch point
+ QEvent::Type type = QEvent::None;
+ switch (qnxType) {
+ case SCREEN_EVENT_MTOUCH_TOUCH:
+ m_touchPoints[touchId].state = Qt::TouchPointPressed;
+ type = QEvent::TouchBegin;
+ break;
+ case SCREEN_EVENT_MTOUCH_MOVE:
+ m_touchPoints[touchId].state = Qt::TouchPointMoved;
+ type = QEvent::TouchUpdate;
+ break;
+ case SCREEN_EVENT_MTOUCH_RELEASE:
+ m_touchPoints[touchId].state = Qt::TouchPointReleased;
+ type = QEvent::TouchEnd;
+ break;
+ }
+
+ // build list of active touch points
+ QList<QWindowSystemInterface::TouchPoint> pointList;
+ for (int i = 0; i < MaximumTouchPoints; i++) {
+ if (i == touchId) {
+ // current touch point is always active
+ pointList.append(m_touchPoints[i]);
+ } else if (m_touchPoints[i].state != Qt::TouchPointReleased) {
+ // finger is down but did not move
+ m_touchPoints[i].state = Qt::TouchPointStationary;
+ pointList.append(m_touchPoints[i]);
+ }
+ }
+
+ // inject event into Qt
+ QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList);
+#if defined(QQNXSCREENEVENT_DEBUG)
+ qDebug() << "QQNX: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type;
+#endif
+ }
+ }
+}
+
+void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
+{
+ // Query the window that was closed
+ void *handle;
+ int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
+ if (result != 0) {
+ qFatal("QQNX: failed to query event window, errno=%d", errno);
+ }
+ screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
+
+ // Map window handle to top-level QWindow
+ QWindow *w = QQnxIntegration::window(qnxWindow);
+ if (w != 0) {
+ QWindowSystemInterface::handleCloseEvent(w);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
new file mode 100644
index 0000000000..365351766c
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXSCREENEVENTHANDLER_H
+#define QQNXSCREENEVENTHANDLER_H
+
+#include <QWindowSystemInterface>
+
+#include <screen/screen.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQnxScreenEventHandler
+{
+public:
+ QQnxScreenEventHandler();
+
+ bool handleEvent(screen_event_t event);
+ bool handleEvent(screen_event_t event, int qnxType);
+
+ static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+
+private:
+ void handleKeyboardEvent(screen_event_t event);
+ void handlePointerEvent(screen_event_t event);
+ void handleTouchEvent(screen_event_t event, int qnxType);
+ void handleCloseEvent(screen_event_t event);
+
+private:
+ enum {
+ MaximumTouchPoints = 10
+ };
+
+ QPoint m_lastGlobalMousePoint;
+ QPoint m_lastLocalMousePoint;
+ Qt::MouseButtons m_lastButtonState;
+ screen_window_t m_lastMouseWindow;
+ QTouchDevice *m_touchDevice;
+ QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
+};
+
+QT_END_NAMESPACE
+
+#endif // QQNXSCREENEVENTHANDLER_H