From 3674718e3d7a030a774d53630888e424139df79b Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 15 Oct 2015 08:41:09 +0300 Subject: Dispatch all key and all generic motion events java objects to QtCore These events are needed to enable the usage of all input methods available on Android e.g. gamepads, stylus, etc. In orer to get GenericMotionEvents your application min API version must be at least 12, otherwise the application will receive only key events. Change-Id: I7564fccaf5423aa318ba4f62317eaf101ba6e97e Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjnihelpers.cpp | 63 +++++++++++++++++++++++++++++++++++++- src/corelib/kernel/qjnihelpers_p.h | 20 ++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index f77fc4220c..0a5a5dffb9 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -34,6 +34,7 @@ #include "qjnihelpers_p.h" #include "qmutex.h" #include "qlist.h" +#include "qvector.h" #include QT_BEGIN_NAMESPACE @@ -56,6 +57,40 @@ static void onAndroidUiThread(JNIEnv *, jclass, jlong thiz) delete runnable; } +namespace { + struct GenericMotionEventListeners { + QMutex mutex; + QVector listeners; + }; +} +Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners) + +static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) +{ + jboolean ret = JNI_FALSE; + QMutexLocker locker(&g_genericMotionEventListeners()->mutex); + foreach (auto listener, g_genericMotionEventListeners()->listeners) + ret |= listener->handleGenericMotionEvent(event); + return ret; +} + +namespace { + struct KeyEventListeners { + QMutex mutex; + QVector listeners; + }; +} +Q_GLOBAL_STATIC(KeyEventListeners, g_keyEventListeners) + +static jboolean dispatchKeyEvent(JNIEnv *, jclass, jobject event) +{ + jboolean ret = JNI_FALSE; + QMutexLocker locker(&g_keyEventListeners()->mutex); + foreach (auto listener, g_keyEventListeners()->listeners) + ret |= listener->handleKeyEvent(event); + return ret; +} + namespace { class ActivityResultListeners { @@ -227,7 +262,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) g_javaVM = vm; static const JNINativeMethod methods[] = { - {"onAndroidUiThread", "(J)V", reinterpret_cast(onAndroidUiThread)} + {"onAndroidUiThread", "(J)V", reinterpret_cast(onAndroidUiThread)}, + {"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast(dispatchGenericMotionEvent)}, + {"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast(dispatchKeyEvent)}, }; const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK); @@ -274,4 +311,28 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env) delete runnable; } +void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener) +{ + QMutexLocker locker(&g_genericMotionEventListeners()->mutex); + g_genericMotionEventListeners()->listeners.push_back(listener); +} + +void QtAndroidPrivate::unregisterGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener) +{ + QMutexLocker locker(&g_genericMotionEventListeners()->mutex); + g_genericMotionEventListeners()->listeners.removeOne(listener); +} + +void QtAndroidPrivate::registerKeyEventListener(QtAndroidPrivate::KeyEventListener *listener) +{ + QMutexLocker locker(&g_keyEventListeners()->mutex); + g_keyEventListeners()->listeners.push_back(listener); +} + +void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventListener *listener) +{ + QMutexLocker locker(&g_keyEventListeners()->mutex); + g_keyEventListeners()->listeners.removeOne(listener); +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 883b08ef60..536989b4fc 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -76,6 +76,20 @@ namespace QtAndroidPrivate virtual void handleResume() {}; }; + class Q_CORE_EXPORT GenericMotionEventListener + { + public: + virtual ~GenericMotionEventListener() {} + virtual bool handleGenericMotionEvent(jobject event) = 0; + }; + + class Q_CORE_EXPORT KeyEventListener + { + public: + virtual ~KeyEventListener() {} + virtual bool handleKeyEvent(jobject event) = 0; + }; + Q_CORE_EXPORT jobject activity(); Q_CORE_EXPORT JavaVM *javaVM(); Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env); @@ -95,6 +109,12 @@ namespace QtAndroidPrivate Q_CORE_EXPORT void handleResume(); Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener); Q_CORE_EXPORT void unregisterResumePauseListener(ResumePauseListener *listener); + + Q_CORE_EXPORT void registerGenericMotionEventListener(GenericMotionEventListener *listener); + Q_CORE_EXPORT void unregisterGenericMotionEventListener(GenericMotionEventListener *listener); + + Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener); + Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener); } QT_END_NAMESPACE -- cgit v1.2.3