diff options
7 files changed, 348 insertions, 207 deletions
diff --git a/src/plugins/platforms/blackberry/blackberry.pro b/src/plugins/platforms/blackberry/blackberry.pro index 7ffb7f4..cded59c 100644 --- a/src/plugins/platforms/blackberry/blackberry.pro +++ b/src/plugins/platforms/blackberry/blackberry.pro @@ -12,6 +12,7 @@ SOURCES = main.cpp \ qbbinputcontext.cpp \ qbbintegration.cpp \ qbbnavigatoreventhandler.cpp \ + qbbnavigatoreventnotifier.cpp \ qbbscreen.cpp \ qbbwindow.cpp \ qbbrasterwindowsurface.cpp \ @@ -28,6 +29,7 @@ HEADERS = qbbbuffer.h \ qbbinputcontext.h \ qbbintegration.h \ qbbnavigatoreventhandler.h \ + qbbnavigatoreventnotifier.h \ qbbglcontext.h \ qbbglwindowsurface.h \ qbbscreen.h \ diff --git a/src/plugins/platforms/blackberry/qbbintegration.cpp b/src/plugins/platforms/blackberry/qbbintegration.cpp index 4482e8e..32c795b 100644 --- a/src/plugins/platforms/blackberry/qbbintegration.cpp +++ b/src/plugins/platforms/blackberry/qbbintegration.cpp @@ -45,6 +45,7 @@ #include "qbbglcontext.h" #include "qbbglwindowsurface.h" #include "qbbnavigatoreventhandler.h" +#include "qbbnavigatoreventnotifier.h" #include "qbbrasterwindowsurface.h" #include "qbbscreen.h" #include "qbbscreeneventhandler.h" @@ -74,6 +75,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_METATYPE(screen_window_t); QBBIntegration::QBBIntegration() : + mNavigatorEventHandler(new QBBNavigatorEventHandler()), mFontDb(new QGenericUnixFontDatabase()), mScreenEventHandler(new QBBScreenEventHandler()), mPaintUsingOpenGL(getenv("QBB_USE_OPENGL") != NULL), @@ -99,13 +101,12 @@ QBBIntegration::QBBIntegration() : qFatal("QBB: failed to connect to composition manager, errno=%d", errno); } - // Create/start navigator event handler - // Not on BlackBerry, it has specialised event dispatcher which also handles navigator events - mNavigatorEventHandler = new QBBNavigatorEventHandler; + // Create/start navigator event notifier + mNavigatorEventNotifier = new QBBNavigatorEventNotifier(mNavigatorEventHandler); // delay invocation of start() to the time the event loop is up and running // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(mNavigatorEventHandler, "start", Qt::QueuedConnection); + QMetaObject::invokeMethod(mNavigatorEventNotifier, "start", Qt::QueuedConnection); // Create displays for all possible screens (which may not be attached) createDisplays(); @@ -159,7 +160,8 @@ QBBIntegration::~QBBIntegration() // stop/destroy event thread delete mEventThread; - // stop/destroy navigator thread + // stop/destroy navigator event handling classes + delete mNavigatorEventNotifier; delete mNavigatorEventHandler; delete mScreenEventHandler; diff --git a/src/plugins/platforms/blackberry/qbbintegration.h b/src/plugins/platforms/blackberry/qbbintegration.h index 4b52fcc..ac51f0f 100644 --- a/src/plugins/platforms/blackberry/qbbintegration.h +++ b/src/plugins/platforms/blackberry/qbbintegration.h @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE class QBBEventThread; class QBBNavigatorEventHandler; +class QBBNavigatorEventNotifier; class QBBLocaleThread; class QBBAbstractVirtualKeyboard; class QBBScreen; @@ -89,6 +90,7 @@ private: screen_context_t mContext; QBBEventThread *mEventThread; QBBNavigatorEventHandler *mNavigatorEventHandler; + QBBNavigatorEventNotifier *mNavigatorEventNotifier; QBBLocaleThread *mLocaleThread; QPlatformFontDatabase *mFontDb; QList<QPlatformScreen*> mScreens; diff --git a/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.cpp b/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.cpp index bac680a..4f740b3 100644 --- a/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.cpp +++ b/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2012 Research In Motion ** ** Contact: Research In Motion <blackberry-qt@qnx.com> ** Contact: Klarälvdalens Datakonsult AB <info@kdab.com> @@ -39,219 +39,63 @@ //#define QBBNAVIGATOREVENTHANDLER_DEBUG - #include "qbbnavigatoreventhandler.h" -#include <QtCore/private/qcore_unix_p.h> -#include <QtGui/QApplication> -#include <QtGui/QWidget> -#include <QtGui/QWindowSystemInterface> -#include <QByteArray> -#include <QList> +#include <QApplication> #include <QDebug> -#include <QSocketNotifier> - -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> +#include <QWidget> +#include <QWindowSystemInterface> -#define NAV_CONTROL_PATH "/pps/services/navigator/control" -#define PPS_BUFFER_SIZE 4096 +QT_BEGIN_NAMESPACE QBBNavigatorEventHandler::QBBNavigatorEventHandler(QObject *parent) - : QObject(parent), - mFd(-1), - mReadNotifier(0) + : QObject(parent) { } -QBBNavigatorEventHandler::~QBBNavigatorEventHandler() +bool QBBNavigatorEventHandler::handleOrientationCheck(int angle) { - delete mReadNotifier; - - if (mFd != -1) - close(mFd); - #if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "QBB: navigator event handler stopped"; + qDebug() << Q_FUNC_INFO << "angle=" << angle; +#else + Q_UNUSED(angle); #endif -} -void QBBNavigatorEventHandler::start() -{ -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "QBB: navigator event handler started"; -#endif - - // open connection to navigator - errno = 0; - mFd = open(NAV_CONTROL_PATH, O_RDWR); - if (mFd == -1) { - qWarning("QBB: failed to open navigator pps, errno=%d", errno); - return; - } - - mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read); - connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readData())); + // reply to navigator that (any) orientation is acceptable + // TODO: check if top window flags prohibit orientation change + return true; } -void QBBNavigatorEventHandler::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) +void QBBNavigatorEventHandler::handleOrientationChange(int angle) { + // update screen geometry and reply to navigator that we're ready #if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: data=" << ppsData; + qDebug() << Q_FUNC_INFO << "angle=" << angle; #endif - // tokenize pps data into lines - QList<QByteArray> lines = ppsData.split('\n'); - - // validate pps object - if (lines.size() == 0 || lines.at(0) != "@control") { - qFatal("QBB: unrecognized pps object, data=%s", ppsData.constData()); - } - - // parse pps object attributes and extract values - for (int i = 1; i < lines.size(); i++) { - - // tokenize current attribute - const QByteArray &attr = lines.at(i); - -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: attr=" << attr; -#endif - - int firstColon = attr.indexOf(':'); - if (firstColon == -1) { - // abort - malformed attribute - continue; - } - - int secondColon = attr.indexOf(':', firstColon + 1); - if (secondColon == -1) { - // abort - malformed attribute - continue; - } - - QByteArray key = attr.left(firstColon); - QByteArray value = attr.mid(secondColon + 1); - -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: key=" << key; - qDebug() << "PPS: val=" << value; -#endif - - // save attribute value - if (key == "msg") { - msg = value; - } else if (key == "dat") { - dat = value; - } else if (key == "id") { - id = value; - } else { - qFatal("QBB: unrecognized pps attribute, attr=%s", key.constData()); - } - } + emit rotationChanged(angle); } -void QBBNavigatorEventHandler::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) +void QBBNavigatorEventHandler::handleSwipeDown() { - // construct pps message - QByteArray ppsData = "res::"; - ppsData += res; - ppsData += "\nid::"; - ppsData += id; - if (!dat.isEmpty()) { - ppsData += "\ndat::"; - ppsData += dat; - } - ppsData += "\n"; - + // simulate menu key press #if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS reply=" << ppsData; + qDebug() << Q_FUNC_INFO; #endif - // send pps message to navigator - errno = 0; - int bytes = write(mFd, ppsData.constData(), ppsData.size()); - if (bytes == -1) { - qFatal("QBB: failed to write navigator pps, errno=%d", errno); - } + QWidget *w = QApplication::activeWindow(); + QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier); + QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyRelease, Qt::Key_Menu, Qt::NoModifier); } -void QBBNavigatorEventHandler::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) +void QBBNavigatorEventHandler::handleExit() { + // shutdown everything #if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id; + qDebug() << Q_FUNC_INFO; #endif - // check message type - if (msg == "orientationCheck") { - - // reply to navigator that (any) orientation is acceptable -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: orientation check, o=" << dat; -#endif - replyPPS(msg, id, "true"); - - } else if (msg == "orientation") { - - // update screen geometry and reply to navigator that we're ready -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: orientation, o=" << dat; -#endif - emit rotationChanged(dat.toInt()); - replyPPS(msg, id, ""); - - } else if (msg == "SWIPE_DOWN") { - - // simulate menu key press -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: menu"; -#endif - QWidget *w = QApplication::activeWindow(); - QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier); - QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyRelease, Qt::Key_Menu, Qt::NoModifier); - - } else if (msg == "exit") { - - // shutdown everything -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "PPS: exit"; -#endif - QApplication::quit(); - } + QApplication::quit(); } -void QBBNavigatorEventHandler::readData() -{ -#if defined(QBBNAVIGATOREVENTHANDLER_DEBUG) - qDebug() << "QBB: reading navigator data"; -#endif - - // allocate buffer for pps data - char buffer[PPS_BUFFER_SIZE]; - - // attempt to read pps data - errno = 0; - int bytes = qt_safe_read(mFd, buffer, PPS_BUFFER_SIZE - 1); - if (bytes == -1) { - qFatal("QBB: failed to read navigator pps, errno=%d", errno); - } - - // check if pps data was received - if (bytes > 0) { - - // ensure data is null terminated - buffer[bytes] = '\0'; - - // process received message - QByteArray ppsData(buffer); - QByteArray msg; - QByteArray dat; - QByteArray id; - parsePPS(ppsData, msg, dat, id); - handleMessage(msg, dat, id); - } - -} +QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.h b/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.h index 948f6e3..b2f6eda 100644 --- a/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.h +++ b/src/plugins/platforms/blackberry/qbbnavigatoreventhandler.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2012 Research In Motion ** ** Contact: Research In Motion <blackberry-qt@qnx.com> ** Contact: Klarälvdalens Datakonsult AB <info@kdab.com> @@ -44,31 +44,19 @@ QT_BEGIN_NAMESPACE -class QSocketNotifier; - class QBBNavigatorEventHandler : public QObject { Q_OBJECT public: explicit QBBNavigatorEventHandler(QObject *parent = 0); - ~QBBNavigatorEventHandler(); + + bool handleOrientationCheck(int angle); + void handleOrientationChange(int angle); + void handleSwipeDown(); + void handleExit(); Q_SIGNALS: void rotationChanged(int angle); - -public Q_SLOTS: - void start(); - -private Q_SLOTS: - void readData(); - -private: - int mFd; - QSocketNotifier *mReadNotifier; - - void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id); - void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); - void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.cpp b/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.cpp new file mode 100644 index 0000000..1516c5b --- /dev/null +++ b/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** +** Contact: Research In Motion <blackberry-qt@qnx.com> +** Contact: Klarälvdalens Datakonsult AB <info@kdab.com> +** +** This file is part of the QtCore module 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. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//#define QBBNAVIGATOREVENTNOTIFIER_DEBUG + + +#include "qbbnavigatoreventnotifier.h" +#include "qbbnavigatoreventhandler.h" + +#include <QtCore/private/qcore_unix_p.h> +#include <QByteArray> +#include <QList> +#include <QDebug> +#include <QSocketNotifier> + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#define NAV_CONTROL_PATH "/pps/services/navigator/control" +#define PPS_BUFFER_SIZE 4096 + +QBBNavigatorEventNotifier::QBBNavigatorEventNotifier(QBBNavigatorEventHandler *eventHandler, QObject *parent) + : QObject(parent), + mEventHandler(eventHandler), + mFd(-1), + mReadNotifier(0) +{ +} + +QBBNavigatorEventNotifier::~QBBNavigatorEventNotifier() +{ + delete mReadNotifier; + + if (mFd != -1) + qt_safe_close(mFd); + +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "QBB: navigator event notifier stopped"; +#endif +} + +void QBBNavigatorEventNotifier::start() +{ +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "QBB: navigator event notifier started"; +#endif + + // open connection to navigator + errno = 0; + mFd = qt_safe_open(NAV_CONTROL_PATH, O_RDWR); + if (mFd == -1) { + qWarning("QBB: failed to open navigator pps, errno=%d", errno); + return; + } + + mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read); + connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readData())); +} + +void QBBNavigatorEventNotifier::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) +{ +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "PPS: data=" << ppsData; +#endif + + // tokenize pps data into lines + QList<QByteArray> lines = ppsData.split('\n'); + + // validate pps object + if (lines.size() == 0 || lines.at(0) != "@control") + qFatal("QBB: unrecognized pps object, data=%s", ppsData.constData()); + + // parse pps object attributes and extract values + for (int i = 1; i < lines.size(); i++) { + + // tokenize current attribute + const QByteArray &attr = lines.at(i); + +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "PPS: attr=" << attr; +#endif + + int firstColon = attr.indexOf(':'); + if (firstColon == -1) { + // abort - malformed attribute + continue; + } + + int secondColon = attr.indexOf(':', firstColon + 1); + if (secondColon == -1) { + // abort - malformed attribute + continue; + } + + QByteArray key = attr.left(firstColon); + QByteArray value = attr.mid(secondColon + 1); + +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "PPS: key=" << key; + qDebug() << "PPS: val=" << value; +#endif + + // save attribute value + if (key == "msg") + msg = value; + else if (key == "dat") + dat = value; + else if (key == "id") + id = value; + else + qFatal("QBB: unrecognized pps attribute, attr=%s", key.constData()); + } +} + +void QBBNavigatorEventNotifier::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) +{ + // construct pps message + QByteArray ppsData = "res::"; + ppsData += res; + ppsData += "\nid::"; + ppsData += id; + if (!dat.isEmpty()) { + ppsData += "\ndat::"; + ppsData += dat; + } + ppsData += "\n"; + +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "PPS reply=" << ppsData; +#endif + + // send pps message to navigator + errno = 0; + int bytes = write(mFd, ppsData.constData(), ppsData.size()); + if (bytes == -1) + qFatal("QBB: failed to write navigator pps, errno=%d", errno); +} + +void QBBNavigatorEventNotifier::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) +{ +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id; +#endif + + // check message type + if (msg == "orientationCheck") { + const bool result = mEventHandler->handleOrientationCheck(dat.toInt()); + replyPPS(msg, id, result ? "true": "false"); + } else if (msg == "orientation") { + mEventHandler->handleOrientationChange(dat.toInt()); + replyPPS(msg, id, ""); + } else if (msg == "SWIPE_DOWN") { + mEventHandler->handleSwipeDown(); + } else if (msg == "exit") { + mEventHandler->handleExit(); + } +} + +void QBBNavigatorEventNotifier::readData() +{ +#if defined(QBBNAVIGATOREVENTNOTIFIER_DEBUG) + qDebug() << "QBB: reading navigator data"; +#endif + + // allocate buffer for pps data + char buffer[PPS_BUFFER_SIZE]; + + // attempt to read pps data + errno = 0; + int bytes = qt_safe_read(mFd, buffer, PPS_BUFFER_SIZE - 1); + if (bytes == -1) + qFatal("QBB: failed to read navigator pps, errno=%d", errno); + + // check if pps data was received + if (bytes > 0) { + + // ensure data is null terminated + buffer[bytes] = '\0'; + + // process received message + QByteArray ppsData(buffer); + QByteArray msg; + QByteArray dat; + QByteArray id; + parsePPS(ppsData, msg, dat, id); + handleMessage(msg, dat, id); + } + +} diff --git a/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.h b/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.h new file mode 100644 index 0000000..2f9e607 --- /dev/null +++ b/src/plugins/platforms/blackberry/qbbnavigatoreventnotifier.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** +** Contact: Research In Motion <blackberry-qt@qnx.com> +** Contact: Klarälvdalens Datakonsult AB <info@kdab.com> +** +** This file is part of the QtCore module 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. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBBNAVIGATOREVENTNOTIFIER_H +#define QBBNAVIGATOREVENTNOTIFIER_H + +#include <QObject> + +QT_BEGIN_NAMESPACE + +class QBBNavigatorEventHandler; +class QSocketNotifier; + +class QBBNavigatorEventNotifier : public QObject +{ + Q_OBJECT +public: + explicit QBBNavigatorEventNotifier(QBBNavigatorEventHandler *eventHandler, QObject *parent = 0); + ~QBBNavigatorEventNotifier(); + +public Q_SLOTS: + void start(); + +private Q_SLOTS: + void readData(); + +private: + QBBNavigatorEventHandler *mEventHandler; + int mFd; + QSocketNotifier *mReadNotifier; + + void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id); + void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); + void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); +}; + +QT_END_NAMESPACE + +#endif // QBBNAVIGATOREVENTNOTIFIER_H |