Qt 6.x
The Qt SDK
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
16#if defined(QQNXBUTTON_DEBUG)
17#define qButtonDebug qDebug
18#else
19#define qButtonDebug QT_NO_QDEBUG_MACRO
20#endif
21
23
24const char *QQnxButtonEventNotifier::ppsPath = "/pps/system/buttons/status";
25const size_t QQnxButtonEventNotifier::ppsBufferSize = 256;
26
28 : QObject(parent),
29 m_fd(-1),
30 m_readNotifier(0)
31{
32 // Set initial state of buttons to ButtonUp and
33 // fetch the new button ids
34 int enumeratorIndex = QQnxButtonEventNotifier::staticMetaObject.indexOfEnumerator(QByteArrayLiteral("ButtonId"));
35 QMetaEnum enumerator = QQnxButtonEventNotifier::staticMetaObject.enumerator(enumeratorIndex);
36 m_buttonKeys.reserve(ButtonCount - bid_minus);
37 for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
38 m_buttonKeys.append(enumerator.valueToKey(buttonId));
39 m_state[buttonId] = ButtonUp;
40 }
41}
42
44{
45 close();
46}
47
49{
50 qButtonDebug("starting hardware button event processing");
51 if (m_fd != -1)
52 return;
53
54 // Open the pps interface
55 errno = 0;
56 m_fd = qt_safe_open(ppsPath, O_RDONLY);
57 if (m_fd == -1) {
58#if defined (QQNXBUTTON_DEBUG)
59 qWarning("QQNX: failed to open buttons pps, errno=%d", errno);
60#endif
61 return;
62 }
63
64 m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
65 QObject::connect(m_readNotifier, SIGNAL(activated(QSocketDescriptor)), this, SLOT(updateButtonStates()));
66
67 qButtonDebug("successfully connected to Navigator. fd = %d", m_fd);
68}
69
70void QQnxButtonEventNotifier::updateButtonStates()
71{
72 // Allocate buffer for pps data
73 char buffer[ppsBufferSize];
74
75 // Attempt to read pps data
76 errno = 0;
77 int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
78 qButtonDebug() << "Read" << bytes << "bytes of data";
79 if (bytes == -1) {
80 qWarning("QQNX: failed to read hardware buttons pps object, errno=%d", errno);
81 return;
82 }
83
84 // We seem to get a spurious read notification after the real one. Ignore it
85 if (bytes == 0)
86 return;
87
88 // Ensure data is null terminated
89 buffer[bytes] = '\0';
90
91 qButtonDebug("received PPS message:\n%s", buffer);
92
93 // Process received message
96 if (!parsePPS(ppsData, &fields))
97 return;
98
99 // Update our state and inject key events as needed
100 for (int buttonId = bid_minus; buttonId < ButtonCount; ++buttonId) {
101 // Extract the new button state
102 QByteArray key = m_buttonKeys.at(buttonId);
103 ButtonState newState = (fields.value(key) == "b_up" ? ButtonUp : ButtonDown);
104
105 // If state has changed, update our state and inject a keypress event
106 if (m_state[buttonId] != newState) {
107 qButtonDebug() << "Hardware button event: button =" << key << "state =" << fields.value(key);
108 m_state[buttonId] = newState;
109
110 // Is it a key press or key release event?
112
113 Qt::Key key;
114 switch (buttonId) {
115 case bid_minus:
117 break;
118
119 case bid_playpause:
121 break;
122
123 case bid_plus:
125 break;
126
127 case bid_power:
129 break;
130
131 default:
132 qButtonDebug("Unknown hardware button");
133 continue;
134 }
135
136 // No modifiers
137 Qt::KeyboardModifiers modifier = Qt::NoModifier;
138
139 // Post the event
141 }
142 }
143}
144
145void QQnxButtonEventNotifier::close()
146{
147 delete m_readNotifier;
148 m_readNotifier = 0;
149
150 if (m_fd != -1) {
151 qt_safe_close(m_fd);
152 m_fd = -1;
153 }
154}
155
156bool QQnxButtonEventNotifier::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QByteArray> *messageFields) const
157{
158 // tokenize pps data into lines
159 QList<QByteArray> lines = ppsData.split('\n');
160
161 // validate pps object
162 if (lines.size() == 0 || !lines.at(0).contains(QByteArrayLiteral("@status"))) {
163 qWarning("QQNX: unrecognized pps object, data=%s", ppsData.constData());
164 return false;
165 }
166
167 // parse pps object attributes and extract values
168 for (int i = 1; i < lines.size(); i++) {
169
170 // tokenize current attribute
171 const QByteArray &attr = lines.at(i);
172
173 qButtonDebug() << "attr=" << attr;
174
175 int doubleColon = attr.indexOf(QByteArrayLiteral("::"));
176 if (doubleColon == -1) {
177 // abort - malformed attribute
178 continue;
179 }
180
181 QByteArray key = attr.left(doubleColon);
182 QByteArray value = attr.mid(doubleColon + 2);
183 messageFields->insert(key, value);
184 }
185 return true;
186}
187
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
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 left(qsizetype len) const
Returns a byte array that contains the first len bytes of this byte array.
QByteArray mid(qsizetype index, qsizetype len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:394
\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.
\inmodule QtCore
Definition qhash.h:818
T value(const Key &key) const noexcept
Definition qhash.h:1044
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void reserve(qsizetype size)
Definition qlist.h:746
void append(parameter_type t)
Definition qlist.h:441
\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:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
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:972
@ Key_VolumeUp
Definition qnamespace.h:847
@ Key_VolumeDown
Definition qnamespace.h:845
@ Key_Play
@ NoModifier
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
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:162
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLuint64 key
GLenum GLuint buffer
GLenum type
#define qButtonDebug
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent