aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@theqtcompany.com>2016-03-17 15:45:44 +0100
committerAndy Nichols <andy.nichols@theqtcompany.com>2016-03-17 15:46:51 +0100
commit57b578485a192b55765461adbd6a47a81fdf6eb3 (patch)
tree58767a3038402938663a2e913902f05341bc3ed7
parentbb53183d4089a9f764b69dfbc47d8b91433af4f4 (diff)
parentb3e8bd55289d54bd21b4f16c6b997d805bba816e (diff)
Merge remote-tracking branch 'origin/5.7' into dev
-rw-r--r--src/gamepad/doc/src/qtgamepad-overview.qdoc2
-rw-r--r--src/gamepad/gamepad.pro3
-rw-r--r--src/gamepad/qgamepad.h2
-rw-r--r--src/gamepad/qgamepadbackend.cpp6
-rw-r--r--src/gamepad/qgamepadbackendfactory.cpp4
-rw-r--r--src/gamepad/qgamepadkeynavigation.h2
-rw-r--r--src/imports/gamepad/qtgamepad.cpp2
-rw-r--r--src/plugins/gamepads/android/src/qandroidgamepadbackend.cpp176
-rw-r--r--src/plugins/gamepads/android/src/qandroidgamepadbackend_p.h7
9 files changed, 152 insertions, 52 deletions
diff --git a/src/gamepad/doc/src/qtgamepad-overview.qdoc b/src/gamepad/doc/src/qtgamepad-overview.qdoc
index 594796a..08c7c85 100644
--- a/src/gamepad/doc/src/qtgamepad-overview.qdoc
+++ b/src/gamepad/doc/src/qtgamepad-overview.qdoc
@@ -35,7 +35,7 @@
****************************************************************************/
/*!
- \page index.html
+ \page qtgamepad-index.html
\title Qt Gamepad
\brief A cross-platform library to facilitate the use of gamepad hardware in Qt and Qt Quick applications
diff --git a/src/gamepad/gamepad.pro b/src/gamepad/gamepad.pro
index b97a01d..92d68cc 100644
--- a/src/gamepad/gamepad.pro
+++ b/src/gamepad/gamepad.pro
@@ -34,3 +34,6 @@ ANDROID_JAR_DEPENDENCIES = \
ANDROID_LIB_DEPENDENCIES = \
plugins/gamepads/libandroidgamepad.so
+
+ANDROID_FEATURES = \
+ android.hardware.gamepad
diff --git a/src/gamepad/qgamepad.h b/src/gamepad/qgamepad.h
index 3ad3503..2c99e85 100644
--- a/src/gamepad/qgamepad.h
+++ b/src/gamepad/qgamepad.h
@@ -72,7 +72,7 @@ class Q_GAMEPAD_EXPORT QGamepad : public QObject
Q_PROPERTY(bool buttonCenter READ buttonCenter NOTIFY buttonCenterChanged)
Q_PROPERTY(bool buttonGuide READ buttonGuide NOTIFY buttonGuideChanged)
public:
- explicit QGamepad(int deviceId = 0, QObject *parent = 0);
+ explicit QGamepad(int deviceId = 0, QObject *parent = nullptr);
~QGamepad();
int deviceId() const;
diff --git a/src/gamepad/qgamepadbackend.cpp b/src/gamepad/qgamepadbackend.cpp
index 0f11800..2b74634 100644
--- a/src/gamepad/qgamepadbackend.cpp
+++ b/src/gamepad/qgamepadbackend.cpp
@@ -39,6 +39,8 @@
QT_BEGIN_NAMESPACE
+static const QLatin1String GAMEPAD_GROUP("___gamepad_saved_states_v2");
+
QGamepadBackend::QGamepadBackend(QObject *parent) :
QObject(parent)
{
@@ -80,7 +82,7 @@ void QGamepadBackend::saveSettings(int productId, const QVariant &value)
s.reset(new QSettings());
else
s.reset(new QSettings(m_settingsFilePath));
- s->beginGroup(QString::fromLatin1("___gamepad_saved_states"));
+ s->beginGroup(GAMEPAD_GROUP);
QString key = QString::fromLatin1("id_%1").arg(productId);
if (value.isNull())
s->remove(key);
@@ -95,7 +97,7 @@ QVariant QGamepadBackend::readSettings(int productId)
s.reset(new QSettings());
else
s.reset(new QSettings(m_settingsFilePath));
- s->beginGroup(QString::fromLatin1("___gamepad_saved_states"));
+ s->beginGroup(GAMEPAD_GROUP);
return s->value(QString::fromLatin1("id_%1").arg(productId));
}
diff --git a/src/gamepad/qgamepadbackendfactory.cpp b/src/gamepad/qgamepadbackendfactory.cpp
index 0434e4b..25a1064 100644
--- a/src/gamepad/qgamepadbackendfactory.cpp
+++ b/src/gamepad/qgamepadbackendfactory.cpp
@@ -77,10 +77,10 @@ QGamepadBackend *QGamepadBackendFactory::create(const QString &name, const QStri
#ifndef QT_NO_LIBRARY
if (!pluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(pluginPath);
- if (QGamepadBackend *ret = qLoadPlugin1<QGamepadBackend, QGamepadBackendPlugin>(directLoader(), name, args))
+ if (QGamepadBackend *ret = qLoadPlugin<QGamepadBackend, QGamepadBackendPlugin>(directLoader(), name, args))
return ret;
}
- if (QGamepadBackend *ret = qLoadPlugin1<QGamepadBackend, QGamepadBackendPlugin>(loader(), name, args))
+ if (QGamepadBackend *ret = qLoadPlugin<QGamepadBackend, QGamepadBackendPlugin>(loader(), name, args))
return ret;
#endif
return 0;
diff --git a/src/gamepad/qgamepadkeynavigation.h b/src/gamepad/qgamepadkeynavigation.h
index e9e7959..9bd599c 100644
--- a/src/gamepad/qgamepadkeynavigation.h
+++ b/src/gamepad/qgamepadkeynavigation.h
@@ -70,7 +70,7 @@ class Q_GAMEPAD_EXPORT QGamepadKeyNavigation : public QObject
Q_PROPERTY(Qt::Key buttonL3Key READ buttonL3Key WRITE setButtonL3Key NOTIFY buttonL3KeyChanged)
Q_PROPERTY(Qt::Key buttonR3Key READ buttonR3Key WRITE setButtonR3Key NOTIFY buttonR3KeyChanged)
public:
- explicit QGamepadKeyNavigation(QObject *parent = 0);
+ explicit QGamepadKeyNavigation(QObject *parent = nullptr);
bool active() const;
QGamepad *gamepad() const;
diff --git a/src/imports/gamepad/qtgamepad.cpp b/src/imports/gamepad/qtgamepad.cpp
index 1d550db..8196f47 100644
--- a/src/imports/gamepad/qtgamepad.cpp
+++ b/src/imports/gamepad/qtgamepad.cpp
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE
-static QObject *gamepadmanager_singletontype_provider(QQmlEngine */*engine*/, QJSEngine */*scriptEngine*/)
+static QObject *gamepadmanager_singletontype_provider(QQmlEngine * /* engine */, QJSEngine * /* scriptEngine */)
{
QGamepadManager *manager = QGamepadManager::instance();
QQmlEngine::setObjectOwnership(manager, QQmlEngine::CppOwnership);
diff --git a/src/plugins/gamepads/android/src/qandroidgamepadbackend.cpp b/src/plugins/gamepads/android/src/qandroidgamepadbackend.cpp
index 8ad5287..492e123 100644
--- a/src/plugins/gamepads/android/src/qandroidgamepadbackend.cpp
+++ b/src/plugins/gamepads/android/src/qandroidgamepadbackend.cpp
@@ -120,6 +120,18 @@ namespace {
axisMap[motionField("AXIS_HAT_Y")].gamepadAxis = QGamepadManager::AxisLeftY;
axisMap[motionField("AXIS_Z")].gamepadAxis = QGamepadManager::AxisRightX;
axisMap[motionField("AXIS_RZ")].gamepadAxis = QGamepadManager::AxisRightY;
+ {
+ auto &axis = axisMap[motionField("AXIS_LTRIGGER")];
+ axis.gamepadAxis = QGamepadManager::AxisInvalid;
+ axis.gamepadMinButton = QGamepadManager::ButtonL2;
+ axis.gamepadMaxButton = QGamepadManager::ButtonL2;
+ }
+ {
+ auto &axis = axisMap[motionField("AXIS_RTRIGGER")];
+ axis.gamepadAxis = QGamepadManager::AxisInvalid;
+ axis.gamepadMinButton = QGamepadManager::ButtonR2;
+ axis.gamepadMaxButton = QGamepadManager::ButtonR2;
+ }
allAndroidAxes.push_back(motionField("AXIS_X"));
allAndroidAxes.push_back(motionField("AXIS_Y"));
@@ -140,13 +152,14 @@ namespace {
allAndroidAxes.push_back(motionField("AXIS_WHEEL"));
}
- acceptedSources.push_back(inputDeviceField("SOURCE_DPAD"));
if (QtAndroidPrivate::androidSdkVersion() >= 12) {
acceptedSources.push_back(inputDeviceField("SOURCE_GAMEPAD"));
acceptedSources.push_back(inputDeviceField("SOURCE_CLASS_JOYSTICK"));
if (QtAndroidPrivate::androidSdkVersion() >= 21) {
acceptedSources.push_back(inputDeviceField("SOURCE_HDMI"));
}
+ } else {
+ acceptedSources.push_back(inputDeviceField("SOURCE_DPAD"));
}
ACTION_DOWN = keyField("ACTION_DOWN");
@@ -186,22 +199,43 @@ namespace {
const char qtGamePadClassName[] = "org/qtproject/qt5/android/gamepad/QtGamepad";
- inline void setAxisInfo(QJNIObjectPrivate &motionRange, QAndroidGamepadBackend::Mapping::AndroidAxisInfo &info)
+ inline void setAxisInfo(QJNIObjectPrivate &event, int axis, QAndroidGamepadBackend::Mapping::AndroidAxisInfo &info)
{
- if (motionRange.isValid()) {
- info.flatArea = motionRange.callMethod<jfloat>("getFlat", "()F");
- info.minValue = motionRange.callMethod<jfloat>("getMin", "()F");
- info.maxValue = motionRange.callMethod<jfloat>("getMax", "()F");
- info.fuzz = motionRange.callMethod<jfloat>("getFuzz", "()F");
- } else {
- info.flatArea = 0;
+ QJNIObjectPrivate device(event.callObjectMethod("getDevice", "()Landroid/view/InputDevice;"));
+ if (device.isValid()) {
+ const int source = event.callMethod<jint>("getSource", "()I");
+ QJNIObjectPrivate motionRange = device.callObjectMethod("getMotionRange","(II)Landroid/view/InputDevice$MotionRange;", axis, source);
+ if (motionRange.isValid()) {
+ info.flatArea = motionRange.callMethod<jfloat>("getFlat", "()F");
+ info.minValue = motionRange.callMethod<jfloat>("getMin", "()F");
+ info.maxValue = motionRange.callMethod<jfloat>("getMax", "()F");
+ info.fuzz = motionRange.callMethod<jfloat>("getFuzz", "()F");
+ return;
+ }
}
+ info.flatArea = 0;
}
} // namespace
Q_GLOBAL_STATIC(DefaultMapping, g_defaultMapping)
+void QAndroidGamepadBackend::Mapping::AndroidAxisInfo::restoreSavedData(const QVariantMap &value)
+{
+ gamepadAxis = QGamepadManager::GamepadAxis(value[QLatin1Literal("axis")].toInt());
+ gamepadMinButton = QGamepadManager::GamepadButton(value[QLatin1Literal("minButton")].toInt());
+ gamepadMaxButton = QGamepadManager::GamepadButton(value[QLatin1Literal("maxButton")].toInt());
+}
+
+QVariantMap QAndroidGamepadBackend::Mapping::AndroidAxisInfo::dataToSave() const
+{
+ QVariantMap data;
+ data[QLatin1Literal("axis")] = gamepadAxis;
+ data[QLatin1Literal("minButton")] = gamepadMinButton;
+ data[QLatin1Literal("maxButton")] = gamepadMaxButton;
+ return data;
+}
+
QAndroidGamepadBackend::QAndroidGamepadBackend(QObject *parent)
: QGamepadBackend(parent)
{
@@ -233,7 +267,7 @@ void QAndroidGamepadBackend::addDevice(int deviceId)
if (acceptable) {
m_devices.insert(deviceId, *g_defaultMapping());
- int productId = inputDevice.callMethod<jint>("getProductId", "()I");
+ int productId = qHash(inputDevice.callObjectMethod("getDescriptor", "()Ljava/lang/String;").toString());
m_devices[deviceId].productId = productId;
if (productId) {
QVariant settings = readSettings(productId);
@@ -243,7 +277,7 @@ void QAndroidGamepadBackend::addDevice(int deviceId)
QVariantMap data = settings.toMap()[AXES_KEY].toMap();
for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it)
- deviceInfo.axisMap[it.key().toInt()].gamepadAxis = QGamepadManager::GamepadAxis(it.value().toInt());
+ deviceInfo.axisMap[it.key().toInt()].restoreSavedData(it.value().toMap());
data = settings.toMap()[BUTTONS_KEY].toMap();
for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it)
@@ -330,9 +364,12 @@ void QAndroidGamepadBackend::resetConfiguration(int deviceId)
if (it == m_devices.end())
return;
- int productId = it.value().productId;
- it.value() = *g_defaultMapping();
- it.value().productId = productId;
+ it.value().axisMap.clear();
+ it.value().buttonsMap.clear();
+ it.value().calibrateButton = QGamepadManager::ButtonInvalid;
+ it.value().calibrateAxis = QGamepadManager::AxisInvalid;
+ it.value().cancelConfigurationButton = QGamepadManager::ButtonInvalid;
+ it.value().needsConfigure = false;
}
bool QAndroidGamepadBackend::handleKeyEvent(jobject event)
@@ -412,12 +449,13 @@ bool QAndroidGamepadBackend::handleGenericMotionEvent(jobject event)
return false;
auto &deviceMap = deviceIt.value();
- if (deviceMap.calibrateAxis != QGamepadManager::AxisInvalid) {
+ if (deviceMap.calibrateAxis != QGamepadManager::AxisInvalid ||
+ deviceMap.calibrateButton != QGamepadManager::ButtonInvalid) {
double lastValue = 0;
int lastAxis = -1;
for (int axis : g_defaultMapping()->allAndroidAxes) {
- double value = fabs(ev.callMethod<jfloat>("getAxisValue", "(I)F", axis));
- if (value > lastValue) {
+ double value = ev.callMethod<jfloat>("getAxisValue", "(I)F", axis);
+ if (fabs(value) > fabs(lastValue)) {
lastValue = value;
lastAxis = axis;
}
@@ -426,46 +464,98 @@ bool QAndroidGamepadBackend::handleGenericMotionEvent(jobject event)
if (!lastValue || lastAxis == -1)
return false;
- deviceMap.axisMap[lastAxis].gamepadAxis = deviceMap.calibrateAxis;
- auto axis = deviceMap.calibrateAxis;
- deviceMap.calibrateAxis = QGamepadManager::AxisInvalid;
- saveData(deviceMap);
- FunctionEvent::runOnQtThread(this, [this, deviceId, axis]{
- emit axisConfigured(deviceId, axis);
- });
+ if (deviceMap.calibrateAxis != QGamepadManager::AxisInvalid) {
+ deviceMap.axisMap[lastAxis].gamepadAxis = deviceMap.calibrateAxis;
+ auto axis = deviceMap.calibrateAxis;
+ deviceMap.calibrateAxis = QGamepadManager::AxisInvalid;
+ saveData(deviceMap);
+ FunctionEvent::runOnQtThread(this, [this, deviceId, axis]{
+ emit axisConfigured(deviceId, axis);
+ });
+ } else if (deviceMap.calibrateButton != QGamepadManager::ButtonInvalid &&
+ deviceMap.calibrateButton != QGamepadManager::ButtonUp &&
+ deviceMap.calibrateButton != QGamepadManager::ButtonDown &&
+ deviceMap.calibrateButton != QGamepadManager::ButtonLeft &&
+ deviceMap.calibrateButton != QGamepadManager::ButtonRight) {
+ auto &axis = deviceMap.axisMap[lastAxis];
+ axis.gamepadAxis = QGamepadManager::AxisInvalid;
+ setAxisInfo(ev, lastAxis, axis);
+ bool save = false;
+ if (lastValue == axis.minValue) {
+ axis.gamepadMinButton = deviceMap.calibrateButton;
+ if (axis.gamepadMaxButton == QGamepadManager::ButtonInvalid)
+ axis.gamepadMaxButton = deviceMap.calibrateButton;
+ save = true;
+ } else if (lastValue == axis.maxValue) {
+ axis.gamepadMaxButton = deviceMap.calibrateButton;
+ if (axis.gamepadMinButton == QGamepadManager::ButtonInvalid)
+ axis.gamepadMinButton = deviceMap.calibrateButton;
+ save = true;
+ }
+
+ if (save) {
+ auto but = deviceMap.calibrateButton;
+ deviceMap.calibrateButton = QGamepadManager::ButtonInvalid;
+ saveData(deviceMap);
+ FunctionEvent::runOnQtThread(this, [this, deviceId, but]{
+ emit buttonConfigured(deviceId, but);
+ });
+ }
+ }
}
typedef QPair<QGamepadManager::GamepadAxis, double> GamepadAxisValue;
- QVector<GamepadAxisValue> values;
- for (auto it = deviceMap.axisMap.begin(); it != deviceMap.axisMap.end(); ++it) {
- auto &axisInfo = it.value();
- if (axisInfo.flatArea == -1) {
- // compute the range & flat area
- QJNIObjectPrivate device(ev.callObjectMethod("getDevice", "()Landroid/view/InputDevice;"));
- if (device.isValid()) {
- const int source = ev.callMethod<jint>("getSource", "()I");
- QJNIObjectPrivate motionRange = device.callObjectMethod("getMotionRange","(II)Landroid/view/InputDevice$MotionRange;", it.key(), source);
- setAxisInfo(motionRange, axisInfo);
+ QVector<GamepadAxisValue> axisValues;
+ typedef QPair<QGamepadManager::GamepadButton, double> GamepadButtonValue;
+ QVector<GamepadButtonValue> buttonValues;
+ auto setValue = [&axisValues, &buttonValues](Mapping::AndroidAxisInfo &axisInfo, double value) {
+ if (axisInfo.setValue(value)) {
+ if (axisInfo.gamepadAxis != QGamepadManager::AxisInvalid) {
+ axisValues.push_back(GamepadAxisValue(axisInfo.gamepadAxis, axisInfo.lastValue));
+ } else {
+ if (axisInfo.lastValue < 0) {
+ buttonValues.push_back(GamepadButtonValue(axisInfo.gamepadMinButton, axisInfo.lastValue));
+ axisInfo.gamepadLastButton = axisInfo.gamepadMinButton;
+ } else if (axisInfo.lastValue > 0) {
+ buttonValues.push_back(GamepadButtonValue(axisInfo.gamepadMaxButton, axisInfo.lastValue));
+ axisInfo.gamepadLastButton = axisInfo.gamepadMaxButton;
+ } else {
+ buttonValues.push_back(GamepadButtonValue(axisInfo.gamepadLastButton, 0.0));
+ axisInfo.gamepadLastButton = QGamepadManager::ButtonInvalid;
+ }
}
}
-
+ };
+ for (auto it = deviceMap.axisMap.begin(); it != deviceMap.axisMap.end(); ++it) {
+ auto &axisInfo = it.value();
+ if (axisInfo.flatArea == -1)
+ setAxisInfo(ev, it.key(), axisInfo);
const int historicalValues = ev.callMethod<jint>("getHistorySize", "()I");
for (int i = 0; i < historicalValues; ++i) {
double value = ev.callMethod<jfloat>("getHistoricalAxisValue", "(II)F", it.key(), i);
- if (axisInfo.setValue(value))
- values.push_back(GamepadAxisValue(axisInfo.gamepadAxis, axisInfo.lastValue));
+ setValue(axisInfo, value);
}
double value = ev.callMethod<jfloat>("getAxisValue", "(I)F", it.key());
- if (axisInfo.setValue(value))
- values.push_back(GamepadAxisValue(axisInfo.gamepadAxis, axisInfo.lastValue));
+ setValue(axisInfo, value);
}
- if (!values.isEmpty()) {
- FunctionEvent::runOnQtThread(this, [this, deviceId, values]{
- foreach (const auto &axisValue, values)
+ if (!axisValues.isEmpty()) {
+ FunctionEvent::runOnQtThread(this, [this, deviceId, axisValues]{
+ foreach (const auto &axisValue, axisValues)
emit gamepadAxisMoved(deviceId, axisValue.first, axisValue.second);
});
}
+
+ if (!buttonValues.isEmpty()) {
+ FunctionEvent::runOnQtThread(this, [this, deviceId, buttonValues]{
+ foreach (const auto &buttonValue, buttonValues)
+ if (buttonValue.second)
+ emit gamepadButtonPressed(deviceId, buttonValue.first, fabs(buttonValue.second));
+ else
+ emit gamepadButtonReleased(deviceId, buttonValue.first);
+ });
+ }
+
return false;
}
@@ -505,7 +595,7 @@ void QAndroidGamepadBackend::saveData(const QAndroidGamepadBackend::Mapping &dev
QVariantMap settings, data;
for (auto it = deviceInfo.axisMap.begin(); it != deviceInfo.axisMap.end(); ++it)
- data[QString::number(it.key())] = it.value().gamepadAxis;
+ data[QString::number(it.key())] = it.value().dataToSave();
settings[AXES_KEY] = data;
data.clear();
diff --git a/src/plugins/gamepads/android/src/qandroidgamepadbackend_p.h b/src/plugins/gamepads/android/src/qandroidgamepadbackend_p.h
index 764a530..4ef6552 100644
--- a/src/plugins/gamepads/android/src/qandroidgamepadbackend_p.h
+++ b/src/plugins/gamepads/android/src/qandroidgamepadbackend_p.h
@@ -101,10 +101,15 @@ public:
lastValue = value;
return true;
}
+ void restoreSavedData(const QVariantMap &value);
+ QVariantMap dataToSave() const;
double flatArea = -1;
double fuzz = 0;
double lastValue = 0;
+ QGamepadManager::GamepadButton gamepadMinButton = QGamepadManager::ButtonInvalid;
+ QGamepadManager::GamepadButton gamepadMaxButton = QGamepadManager::ButtonInvalid;
+ QGamepadManager::GamepadButton gamepadLastButton = QGamepadManager::ButtonInvalid;
};
QHash<int, AndroidAxisInfo> axisMap;
QHash<int, QGamepadManager::GamepadButton> buttonsMap;
@@ -113,7 +118,7 @@ public:
QGamepadManager::GamepadAxis calibrateAxis = QGamepadManager::AxisInvalid;
QGamepadManager::GamepadButton cancelConfigurationButton = QGamepadManager::ButtonInvalid;
int productId = 0;
- bool needsConfigure = true;
+ bool needsConfigure = false;
};
private: