QNX: Enable support for hardware buttons in QPA plugin
Change-Id: I3de18c3fdcfdacddc375b70800b34b6a8d16ac41 Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com> Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com>
This commit is contained in:
parent
e54f6ed87b
commit
834e9823fc
@ -23,6 +23,7 @@ CONFIG(blackberry) {
|
||||
# Uncomment these to enable debugging output for various aspects of the plugin
|
||||
#DEFINES += QQNXBPSEVENTFILTER_DEBUG
|
||||
#DEFINES += QQNXBUFFER_DEBUG
|
||||
#DEFINES += QQNXBUTTON_DEBUG
|
||||
#DEFINES += QQNXCLIPBOARD_DEBUG
|
||||
#DEFINES += QQNXFILEDIALOGHELPER_DEBUG
|
||||
#DEFINES += QQNXGLBACKINGSTORE_DEBUG
|
||||
@ -109,12 +110,14 @@ CONFIG(qqnx_pps) {
|
||||
SOURCES += qqnxnavigatorpps.cpp \
|
||||
qqnxnavigatoreventnotifier.cpp \
|
||||
qqnxvirtualkeyboardpps.cpp \
|
||||
qqnxclipboard.cpp
|
||||
qqnxclipboard.cpp \
|
||||
qqnxbuttoneventnotifier.cpp
|
||||
|
||||
HEADERS += qqnxnavigatorpps.h \
|
||||
qqnxnavigatoreventnotifier.h \
|
||||
qqnxvirtualkeyboardpps.h \
|
||||
qqnxclipboard.h
|
||||
qqnxclipboard.h \
|
||||
qqnxbuttoneventnotifier.h
|
||||
|
||||
LIBS += -lpps -lclipboard
|
||||
|
||||
|
221
src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
Normal file
221
src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 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 "qqnxbuttoneventnotifier.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaEnum>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
#include <QtCore/private/qcore_unix_p.h>
|
||||
|
||||
#ifdef QQNXBUTTON_DEBUG
|
||||
#define qButtonDebug qDebug
|
||||
#else
|
||||
#define qButtonDebug QT_NO_QDEBUG_MACRO
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char *ppsPath = "/pps/system/buttons/status";
|
||||
static const int ppsBufferSize = 256;
|
||||
|
||||
QQnxButtonEventNotifier::QQnxButtonEventNotifier(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_fd(-1),
|
||||
m_readNotifier(0)
|
||||
{
|
||||
// Set initial state of buttons to ButtonUp and
|
||||
// fetch the new button ids
|
||||
int enumeratorIndex = QQnxButtonEventNotifier::staticMetaObject.indexOfEnumerator(QByteArrayLiteral("ButtonId"));
|
||||
QMetaEnum enumerator = QQnxButtonEventNotifier::staticMetaObject.enumerator(enumeratorIndex);
|
||||
for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
|
||||
m_buttonKeys.append(enumerator.valueToKey(buttonId));
|
||||
m_state[buttonId] = ButtonUp;
|
||||
}
|
||||
}
|
||||
|
||||
QQnxButtonEventNotifier::~QQnxButtonEventNotifier()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void QQnxButtonEventNotifier::start()
|
||||
{
|
||||
qButtonDebug() << Q_FUNC_INFO << "starting hardware button event processing";
|
||||
if (m_fd != -1)
|
||||
return;
|
||||
|
||||
// Open the pps interface
|
||||
errno = 0;
|
||||
m_fd = qt_safe_open(ppsPath, O_RDONLY);
|
||||
if (m_fd == -1) {
|
||||
qWarning("QQNX: failed to open buttons pps, errno=%d", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
|
||||
QObject::connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(updateButtonStates()));
|
||||
|
||||
qButtonDebug() << Q_FUNC_INFO << "successfully connected to Navigator. fd =" << m_fd;
|
||||
}
|
||||
|
||||
void QQnxButtonEventNotifier::updateButtonStates()
|
||||
{
|
||||
// Allocate buffer for pps data
|
||||
char buffer[ppsBufferSize];
|
||||
|
||||
// Attempt to read pps data
|
||||
errno = 0;
|
||||
int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
|
||||
qButtonDebug() << "Read" << bytes << "bytes of data";
|
||||
if (bytes == -1) {
|
||||
qWarning("QQNX: failed to read hardware buttons pps object, errno=%d", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
// We seem to get a spurious read notification after the real one. Ignore it
|
||||
if (bytes == 0)
|
||||
return;
|
||||
|
||||
// Ensure data is null terminated
|
||||
buffer[bytes] = '\0';
|
||||
|
||||
qButtonDebug() << Q_FUNC_INFO << "received PPS message:\n" << buffer;
|
||||
|
||||
// Process received message
|
||||
QByteArray ppsData = QByteArray::fromRawData(buffer, bytes);
|
||||
QHash<QByteArray, QByteArray> fields;
|
||||
if (!parsePPS(ppsData, &fields))
|
||||
return;
|
||||
|
||||
// Update our state and inject key events as needed
|
||||
for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
|
||||
// Extract the new button state
|
||||
QByteArray key = m_buttonKeys.at(buttonId);
|
||||
ButtonState newState = (fields.value(key) == QByteArrayLiteral("b_up") ? ButtonUp : ButtonDown);
|
||||
|
||||
// If state has changed, update our state and inject a keypress event
|
||||
if (m_state[buttonId] != newState) {
|
||||
qButtonDebug() << "Hardware button event: button =" << key << "state =" << fields.value(key);
|
||||
m_state[buttonId] = newState;
|
||||
|
||||
// Is it a key press or key release event?
|
||||
QEvent::Type type = (newState == ButtonDown) ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
|
||||
Qt::Key key;
|
||||
switch (buttonId) {
|
||||
case bid_minus:
|
||||
key = Qt::Key_VolumeDown;
|
||||
break;
|
||||
|
||||
case bid_playpause:
|
||||
key = Qt::Key_Play;
|
||||
break;
|
||||
|
||||
case bid_plus:
|
||||
key = Qt::Key_VolumeUp;
|
||||
break;
|
||||
|
||||
case bid_power:
|
||||
key = Qt::Key_PowerDown;
|
||||
break;
|
||||
|
||||
default:
|
||||
qButtonDebug() << "Unknown hardware button";
|
||||
continue;
|
||||
}
|
||||
|
||||
// No modifiers
|
||||
Qt::KeyboardModifiers modifier = Qt::NoModifier;
|
||||
|
||||
// Post the event
|
||||
QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QQnxButtonEventNotifier::close()
|
||||
{
|
||||
delete m_readNotifier;
|
||||
m_readNotifier = 0;
|
||||
|
||||
if (m_fd != -1) {
|
||||
qt_safe_close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool QQnxButtonEventNotifier::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QByteArray> *messageFields) const
|
||||
{
|
||||
// tokenize pps data into lines
|
||||
QList<QByteArray> lines = ppsData.split('\n');
|
||||
|
||||
// validate pps object
|
||||
if (lines.size() == 0 || lines.at(0) != QByteArrayLiteral("@status")) {
|
||||
qWarning("QQNX: unrecognized pps object, data=%s", ppsData.constData());
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse pps object attributes and extract values
|
||||
for (int i = 1; i < lines.size(); i++) {
|
||||
|
||||
// tokenize current attribute
|
||||
const QByteArray &attr = lines.at(i);
|
||||
|
||||
qButtonDebug() << Q_FUNC_INFO << "attr=" << attr;
|
||||
|
||||
int doubleColon = attr.indexOf(QByteArrayLiteral("::"));
|
||||
if (doubleColon == -1) {
|
||||
// abort - malformed attribute
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray key = attr.left(doubleColon);
|
||||
QByteArray value = attr.mid(doubleColon + 2);
|
||||
messageFields->insert(key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
90
src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h
Normal file
90
src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h
Normal file
@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 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 QQNXBUTTONSEVENTNOTIFIER_H
|
||||
#define QQNXBUTTONSEVENTNOTIFIER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
class QQnxButtonEventNotifier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(ButtonId)
|
||||
public:
|
||||
enum ButtonId {
|
||||
bid_minus = 0,
|
||||
bid_playpause,
|
||||
bid_plus,
|
||||
bid_power,
|
||||
ButtonCount
|
||||
};
|
||||
|
||||
enum ButtonState {
|
||||
ButtonUp,
|
||||
ButtonDown
|
||||
};
|
||||
|
||||
explicit QQnxButtonEventNotifier(QObject *parent = 0);
|
||||
~QQnxButtonEventNotifier();
|
||||
|
||||
public Q_SLOTS:
|
||||
void start();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateButtonStates();
|
||||
|
||||
private:
|
||||
void close();
|
||||
bool parsePPS(const QByteArray &ppsData, QHash<QByteArray, QByteArray> *messageFields) const;
|
||||
|
||||
int m_fd;
|
||||
QSocketNotifier *m_readNotifier;
|
||||
ButtonState m_state[ButtonCount];
|
||||
QList<QByteArray> m_buttonKeys;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQNXBUTTONSEVENTNOTIFIER_H
|
@ -62,6 +62,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(QQNX_PPS)
|
||||
# include "qqnxbuttoneventnotifier.h"
|
||||
# include "qqnxnavigatoreventnotifier.h"
|
||||
# include "qqnxclipboard.h"
|
||||
|
||||
@ -112,6 +113,7 @@ QQnxIntegration::QQnxIntegration()
|
||||
#if defined(QQNX_PPS)
|
||||
, m_navigatorEventNotifier(0)
|
||||
, m_inputContext(0)
|
||||
, m_buttonsNotifier(new QQnxButtonEventNotifier())
|
||||
#endif
|
||||
, m_services(0)
|
||||
, m_fontDatabase(new QGenericUnixFontDatabase())
|
||||
@ -210,6 +212,11 @@ QQnxIntegration::QQnxIntegration()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(QQNX_PPS)
|
||||
// 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(m_buttonsNotifier, "start", Qt::QueuedConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
QQnxIntegration::~QQnxIntegration()
|
||||
@ -218,6 +225,9 @@ QQnxIntegration::~QQnxIntegration()
|
||||
delete m_nativeInterface;
|
||||
|
||||
#if defined(QQNX_PPS)
|
||||
// Destroy the hardware button notifier
|
||||
delete m_buttonsNotifier;
|
||||
|
||||
// Destroy input context
|
||||
delete m_inputContext;
|
||||
#endif
|
||||
|
@ -65,6 +65,7 @@ class QQnxServices;
|
||||
#if defined(QQNX_PPS)
|
||||
class QQnxInputContext;
|
||||
class QQnxNavigatorEventNotifier;
|
||||
class QQnxButtonEventNotifier;
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_CLIPBOARD)
|
||||
@ -132,6 +133,7 @@ private:
|
||||
#if defined(QQNX_PPS)
|
||||
QQnxNavigatorEventNotifier *m_navigatorEventNotifier;
|
||||
QQnxInputContext *m_inputContext;
|
||||
QQnxButtonEventNotifier *m_buttonsNotifier;
|
||||
#endif
|
||||
QQnxServices *m_services;
|
||||
QPlatformFontDatabase *m_fontDatabase;
|
||||
|
Loading…
Reference in New Issue
Block a user