summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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