7#include <QtGui/QGuiApplication>
8#include <qpa/qwindowsysteminterface.h>
10#include <QtCore/qhash.h>
11#include <QtCore/qbytearray.h>
12#include <QtCore/QDebug>
13#include <QtCore/QMetaEnum>
14#include <QtCore/QSocketNotifier>
15#include <QtCore/private/qcore_unix_p.h>
19Q_LOGGING_CATEGORY(lcQpaInputHwButton,
"qt.qpa.input.hwbutton");
31 int enumeratorIndex = QQnxButtonEventNotifier::staticMetaObject.indexOfEnumerator(QByteArrayLiteral(
"ButtonId"));
32 QMetaEnum enumerator = QQnxButtonEventNotifier::staticMetaObject.enumerator(enumeratorIndex);
33 m_buttonKeys.reserve(ButtonCount - bid_minus);
34 for (
int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
35 m_buttonKeys.append(enumerator.valueToKey(buttonId));
36 m_state[buttonId] = ButtonUp;
47 qCDebug(lcQpaInputHwButton) <<
"Starting hardware button event processing";
53 m_fd = qt_safe_open(ppsPath, O_RDONLY);
55#if defined (QQNXBUTTON_DEBUG)
56 qWarning(
"QQNX: failed to open buttons pps, errno=%d", errno);
61 m_readNotifier =
new QSocketNotifier(m_fd, QSocketNotifier::Read);
62 QObject::connect(m_readNotifier, SIGNAL(activated(QSocketDescriptor)),
this, SLOT(updateButtonStates()));
64 qCDebug(lcQpaInputHwButton,
"successfully connected to Navigator. fd = %d", m_fd);
70 char buffer[ppsBufferSize];
74 int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
75 qCDebug(lcQpaInputHwButton) <<
"Read" << bytes <<
"bytes of data";
78 qWarning(
"QQNX: failed to read hardware buttons pps object, errno=%d", errno);
89 qCDebug(lcQpaInputHwButton,
"Received PPS message:\n%s", buffer);
92 QByteArray ppsData = QByteArray::fromRawData(buffer, bytes);
93 QHash<QByteArray, QByteArray> fields;
94 if (!parsePPS(ppsData, &fields))
98 for (
int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
100 QByteArray key = m_buttonKeys.at(buttonId);
101 ButtonState newState = (fields.value(key) ==
"b_up" ? ButtonUp : ButtonDown);
104 if (m_state[buttonId] != newState) {
105 qCDebug(lcQpaInputHwButton) <<
"Hardware button event: button =" << key <<
"state =" << fields.value(key);
107 m_state[buttonId] = newState;
110 QEvent::Type type = (newState == ButtonDown) ? QEvent::KeyPress : QEvent::KeyRelease;
115 key = Qt::Key_VolumeDown;
123 key = Qt::Key_VolumeUp;
127 key = Qt::Key_PowerDown;
131 qCDebug(lcQpaInputHwButton) <<
"Unknown hardware button";
136 Qt::KeyboardModifiers modifier = Qt::NoModifier;
139 QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, modifier);
146 delete m_readNotifier;
155bool QQnxButtonEventNotifier::parsePPS(
const QByteArray &ppsData, QHash<QByteArray, QByteArray> *messageFields)
const
158 QList<QByteArray> lines = ppsData.split(
'\n');
161 if (lines.size() == 0 || !lines.at(0).contains(QByteArrayLiteral(
"@status"))) {
162 qWarning(
"QQNX: unrecognized pps object, data=%s", ppsData.constData());
167 for (
int i = 1; i < lines.size(); i++) {
170 const QByteArray &attr = lines.at(i);
172 qCDebug(lcQpaInputHwButton) << Q_FUNC_INFO <<
"attr =" << attr;
174 int doubleColon = attr.indexOf(QByteArrayLiteral(
"::"));
175 if (doubleColon == -1) {
180 QByteArray key = attr.left(doubleColon);
181 QByteArray value = attr.mid(doubleColon + 2);
182 messageFields->insert(key, value);
Combined button and popup list for selecting options.