Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqnxbuttoneventnotifier.cpp
Go to the documentation of this file.
1// Copyright (C) 2012 Research In Motion
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtGui/QGuiApplication>
7#include <qpa/qwindowsysteminterface.h>
8
9#include <QtCore/qhash.h>
10#include <QtCore/qbytearray.h>
11#include <QtCore/QDebug>
12#include <QtCore/QMetaEnum>
13#include <QtCore/QSocketNotifier>
14#include <QtCore/private/qcore_unix_p.h>
15
17
18Q_LOGGING_CATEGORY(lcQpaInputHwButton, "qt.qpa.input.hwbutton");
19
20const char *QQnxButtonEventNotifier::ppsPath = "/pps/system/buttons/status";
21const size_t QQnxButtonEventNotifier::ppsBufferSize = 256;
22
24 : QObject(parent),
25 m_fd(-1),
26 m_readNotifier(0)
27{
28 // Set initial state of buttons to ButtonUp and
29 // fetch the new button ids
30 int enumeratorIndex = QQnxButtonEventNotifier::staticMetaObject.indexOfEnumerator(QByteArrayLiteral("ButtonId"));
31 QMetaEnum enumerator = QQnxButtonEventNotifier::staticMetaObject.enumerator(enumeratorIndex);
32 m_buttonKeys.reserve(ButtonCount - bid_minus);
33 for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
34 m_buttonKeys.append(enumerator.valueToKey(buttonId));
35 m_state[buttonId] = ButtonUp;
36 }
37}
38
43
45{
46 qCDebug(lcQpaInputHwButton) << "Starting hardware button event processing";
47 if (m_fd != -1)
48 return;
49
50 // Open the pps interface
51 errno = 0;
52 m_fd = qt_safe_open(ppsPath, O_RDONLY);
53 if (m_fd == -1) {
54#if defined (QQNXBUTTON_DEBUG)
55 qWarning("QQNX: failed to open buttons pps, errno=%d", errno);
56#endif
57 return;
58 }
59
60 m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
61 QObject::connect(m_readNotifier, SIGNAL(activated(QSocketDescriptor)), this, SLOT(updateButtonStates()));
62
63 qCDebug(lcQpaInputHwButton, "successfully connected to Navigator. fd = %d", m_fd);
64}
65
66void QQnxButtonEventNotifier::updateButtonStates()
67{
68 // Allocate buffer for pps data
69 char buffer[ppsBufferSize];
70
71 // Attempt to read pps data
72 errno = 0;
73 int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
74 qCDebug(lcQpaInputHwButton) << "Read" << bytes << "bytes of data";
75
76 if (bytes == -1) {
77 qWarning("QQNX: failed to read hardware buttons pps object, errno=%d", errno);
78 return;
79 }
80
81 // We seem to get a spurious read notification after the real one. Ignore it
82 if (bytes == 0)
83 return;
84
85 // Ensure data is null terminated
86 buffer[bytes] = '\0';
87
88 qCDebug(lcQpaInputHwButton, "Received PPS message:\n%s", buffer);
89
90 // Process received message
92 QHash<QByteArray, QByteArray> fields;
93 if (!parsePPS(ppsData, &fields))
94 return;
95
96 // Update our state and inject key events as needed
97 for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
98 // Extract the new button state
99 QByteArray key = m_buttonKeys.at(buttonId);
100 ButtonState newState = (fields.value(key) == "b_up" ? ButtonUp : ButtonDown);
101
102 // If state has changed, update our state and inject a keypress event
103 if (m_state[buttonId] != newState) {
104 qCDebug(lcQpaInputHwButton) << "Hardware button event: button =" << key << "state =" << fields.value(key);
105
106 m_state[buttonId] = newState;
107
108 // Is it a key press or key release event?
110
111 Qt::Key key;
112 switch (buttonId) {
113 case bid_minus:
115 break;
116
117 case bid_playpause:
119 break;
120
121 case bid_plus:
123 break;
124
125 case bid_power:
127 break;
128
129 default:
130 qCDebug(lcQpaInputHwButton) << "Unknown hardware button";
131 continue;
132 }
133
134 // No modifiers
135 Qt::KeyboardModifiers modifier = Qt::NoModifier;
136
137 // Post the event
139 }
140 }
141}
142
143void QQnxButtonEventNotifier::close()
144{
145 delete m_readNotifier;
146 m_readNotifier = 0;
147
148 if (m_fd != -1) {
149 qt_safe_close(m_fd);
150 m_fd = -1;
151 }
152}
153
154bool QQnxButtonEventNotifier::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QByteArray> *messageFields) const
155{
156 // tokenize pps data into lines
157 QList<QByteArray> lines = ppsData.split('\n');
158
159 // validate pps object
160 if (lines.size() == 0 || !lines.at(0).contains(QByteArrayLiteral("@status"))) {
161 qWarning("QQNX: unrecognized pps object, data=%s", ppsData.constData());
162 return false;
163 }
164
165 // parse pps object attributes and extract values
166 for (int i = 1; i < lines.size(); i++) {
167
168 // tokenize current attribute
169 const QByteArray &attr = lines.at(i);
170
171 qCDebug(lcQpaInputHwButton) << Q_FUNC_INFO << "attr =" << attr;
172
173 int doubleColon = attr.indexOf(QByteArrayLiteral("::"));
174 if (doubleColon == -1) {
175 // abort - malformed attribute
176 continue;
177 }
178
179 QByteArray key = attr.left(doubleColon);
180 QByteArray value = attr.mid(doubleColon + 2);
181 messageFields->insert(key, value);
182 }
183 return true;
184}
185
\inmodule QtCore
Definition qbytearray.h:57
QByteArray left(qsizetype n) const &
Definition qbytearray.h:169
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray & insert(qsizetype i, QByteArrayView data)
QByteArray mid(qsizetype index, qsizetype len=-1) const &
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
@ KeyPress
Definition qcoreevent.h:64
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void reserve(qsizetype size)
Definition qlist.h:753
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtCore
const char * valueToKey(int value) const
Returns the string that is used as the name of the given enumeration value, or \nullptr if value is n...
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QQnxButtonEventNotifier(QObject *parent=nullptr)
\inmodule QtCore
\inmodule QtCore
static bool handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
@ Key_PowerDown
Definition qnamespace.h:977
@ Key_VolumeUp
Definition qnamespace.h:852
@ Key_VolumeDown
Definition qnamespace.h:850
@ Key_Play
@ NoModifier
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_FUNC_INFO
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static int qt_safe_close(int fd)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLuint64 key
GLenum GLuint buffer
GLenum type