diff -r 2ce56475ad57 android-project/app/src/main/java/org/libsdl/app/SDLActivity.java --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java Tue Nov 07 09:10:32 2017 -0800 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java Mon Nov 13 21:18:15 2017 +0100 @@ -33,6 +33,108 @@ */ public class SDLActivity extends Activity { private static final String TAG = "SDL"; + + public static void debugSource(int s, String prefix) { + int s_copy = s; + String cls = ""; + String src = ""; + int tst = 0; + int FLAG_TAINTED = 0x80000000; + + if ((s & InputDevice.SOURCE_CLASS_BUTTON) != 0) cls += " BUTTON"; + if ((s & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) cls += " JOYSTICK"; + if ((s & InputDevice.SOURCE_CLASS_POINTER) != 0) cls += " POINTER"; + if ((s & InputDevice.SOURCE_CLASS_POSITION) != 0) cls += " POSITION"; + if ((s & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) cls += " TRACKBALL"; + + + int s2 = s_copy & ~InputDevice.SOURCE_ANY; // keep class bits + s2 &= ~( InputDevice.SOURCE_CLASS_BUTTON + | InputDevice.SOURCE_CLASS_JOYSTICK + | InputDevice.SOURCE_CLASS_POINTER + | InputDevice.SOURCE_CLASS_POSITION + | InputDevice.SOURCE_CLASS_TRACKBALL); + + // Everything has been processed + if (s2 != 0) cls += "Some_Unkown"; + + s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class; + + tst = InputDevice.SOURCE_BLUETOOTH_STYLUS; + if ((s & tst) == tst) src += " BLUETOOTH_STYLUS"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_DPAD; + if ((s & tst) == tst) src += " DPAD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_GAMEPAD; + if ((s & tst) == tst) src += " GAMEPAD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_HDMI; + if ((s & tst) == tst) src += " HDMI"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_JOYSTICK; + if ((s & tst) == tst) src += " JOYSTICK"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_KEYBOARD; + if ((s & tst) == tst) src += " KEYBOARD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_MOUSE; + if ((s & tst) == tst) src += " MOUSE"; + s2 &= ~tst; + + if (Build.VERSION.SDK_INT >= 26) { + tst = InputDevice.SOURCE_MOUSE_RELATIVE; + if ((s & tst) == tst) src += " MOUSE_RELATIVE"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_ROTARY_ENCODER; + if ((s & tst) == tst) src += " ROTARY_ENCODER"; + s2 &= ~tst; + } + tst = InputDevice.SOURCE_STYLUS; + if ((s & tst) == tst) src += " STYLUS"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TOUCHPAD; + if ((s & tst) == tst) src += " TOUCHPAD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TOUCHSCREEN; + if ((s & tst) == tst) src += " TOUCHSCREEN"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TOUCH_NAVIGATION; + if ((s & tst) == tst) src += " TOUCH_NAVIGATION"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TRACKBALL; + if ((s & tst) == tst) src += " TRACKBALL"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_ANY; + if ((s & tst) == tst) src += " ANY"; + s2 &= ~tst; + + + /* Private flag that indicates when the system has detected that + * this key event may be inconsistent with respect to the sequence of + * previously delivered key events, such as when a key up event is sent but the key + * was not down.*/ + if (s == FLAG_TAINTED) src += " FLAG_TAINTED"; + s2 &= ~FLAG_TAINTED; + + // Everything has been processed + if (s2 != 0) src += " Some_Unkown"; + + Log.v(TAG, prefix + " value=" + s_copy + " CLASS={" + cls + " } source(s):" + src); + } + public static boolean mIsResumedCalled, mIsSurfaceReady, mHasFocus; @@ -513,6 +615,7 @@ public static native void onNativeSurfaceDestroyed(); public static native String nativeGetHint(String name); public static native void nativeSetenv(String name, String value); + public static native void nativeAddTouch(String name, int value); /** * This method is called by SDL using JNI. @@ -716,19 +819,17 @@ /** * This method is called by SDL using JNI. - * @return an array which may be empty but is never null. */ - public static int[] inputGetInputDeviceIds(int sources) { + public static void initTouch() { int[] ids = InputDevice.getDeviceIds(); - int[] filtered = new int[ids.length]; - int used = 0; + int touch = InputDevice.SOURCE_TOUCHSCREEN; + for (int i = 0; i < ids.length; ++i) { InputDevice device = InputDevice.getDevice(ids[i]); - if ((device != null) && ((device.getSources() & sources) != 0)) { - filtered[used++] = device.getId(); + if (device != null && (device.getSources() & touch) == touch) { + nativeAddTouch(device.getName(), device.getId()); } } - return Arrays.copyOf(filtered, used); } // APK expansion files support @@ -1253,7 +1354,7 @@ } } - if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) { + if ((event.getSource() & InputDevice.SOURCE_CLASS_BUTTON) != 0) { if (event.getAction() == KeyEvent.ACTION_DOWN) { //Log.v("SDL", "key down: " + keyCode); if (SDLActivity.isTextInputEvent(event)) { @@ -1268,8 +1369,8 @@ return true; } } - - if ((event.getSource() & InputDevice.SOURCE_MOUSE) != 0) { + + if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { // on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses // they are ignored here because sending them as mouse input to SDL is messy if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) { diff -r 2ce56475ad57 android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java Tue Nov 07 09:10:32 2017 -0800 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java Mon Nov 13 21:18:15 2017 +0100 @@ -86,11 +86,12 @@ if ((device == null) || (deviceId < 0)) { return false; } + int sources = device.getSources(); /* This is called for every button press, so let's not spam the logs */ /** - if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { + if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { Log.v(TAG, "Input device " + device.getName() + " is a joystick."); } if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) { @@ -101,7 +102,7 @@ } **/ - return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || + return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) || ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ); @@ -229,7 +230,7 @@ @Override public boolean handleMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) { + if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { int actionPointerIndex = event.getActionIndex(); int action = event.getActionMasked(); switch(action) { diff -r 2ce56475ad57 src/core/android/SDL_android.c --- a/src/core/android/SDL_android.c Tue Nov 07 09:10:32 2017 -0800 +++ b/src/core/android/SDL_android.c Mon Nov 13 21:18:15 2017 +0100 @@ -132,14 +132,19 @@ JNIEnv* env, jclass cls, jstring name, jstring value); -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)( - JNIEnv* env, jclass cls); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)( + JNIEnv* env, jclass cls, + jstring name, jint value); /* Java class SDLInputConnection */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( + JNIEnv* env, jclass cls, + jchar chUnicode); + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); @@ -212,7 +217,7 @@ static jmethodID midSetActivityTitle; static jmethodID midSetOrientation; static jmethodID midGetContext; -static jmethodID midInputGetInputDeviceIds; +static jmethodID midInitTouch; static jmethodID midSendMessage; static jmethodID midShowTextInput; static jmethodID midIsScreenKeyboardShown; @@ -279,7 +284,7 @@ return JNI_VERSION_1_4; } -void checkJNIReady() +static void checkJNIReady() { if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) { // We aren't fully initialized, let's just return. @@ -306,8 +311,8 @@ "setOrientation","(IIZLjava/lang/String;)V"); midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getContext","()Landroid/content/Context;"); - midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "inputGetInputDeviceIds", "(I)[I"); + midInitTouch = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "initTouch", "()V"); midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "sendMessage", "(II)Z"); midShowTextInput = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -329,7 +334,7 @@ midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); if (!midGetNativeSurface || - !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds || + !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInitTouch || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables|| !midGetDisplayDPI) { @@ -831,6 +836,18 @@ } +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)( + JNIEnv* env, jclass cls, + jstring name, jint value) +{ + + const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); + + SDL_AddTouch((SDL_TouchID) value, utfname); + + (*env)->ReleaseStringUTFChars(env, name, utfname); +} + /******************************************************************************* Functions called by SDL into Java *******************************************************************************/ @@ -1790,29 +1822,10 @@ return 0; } -/* returns number of found touch devices as return value and ids in parameter ids */ -int Android_JNI_GetTouchDeviceIds(int **ids) { +/* requests adding touch devices, then callbacks to nativeAddTouch() */ +int Android_JNI_InitTouch() { JNIEnv *env = Android_JNI_GetEnv(); - jint sources = 4098; /* == InputDevice.SOURCE_TOUCHSCREEN */ - jintArray array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, midInputGetInputDeviceIds, sources); - int number = 0; - *ids = NULL; - if (array) { - number = (int) (*env)->GetArrayLength(env, array); - if (0 < number) { - jint* elements = (*env)->GetIntArrayElements(env, array, NULL); - if (elements) { - int i; - *ids = SDL_malloc(number * sizeof (**ids)); - for (i = 0; i < number; ++i) { /* not assuming sizeof (jint) == sizeof (int) */ - (*ids)[i] = elements[i]; - } - (*env)->ReleaseIntArrayElements(env, array, elements, JNI_ABORT); - } - } - (*env)->DeleteLocalRef(env, array); - } - return number; + (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch); } /* sets the mSeparateMouseAndTouch field */ diff -r 2ce56475ad57 src/core/android/SDL_android.h --- a/src/core/android/SDL_android.h Tue Nov 07 09:10:32 2017 -0800 +++ b/src/core/android/SDL_android.h Mon Nov 13 21:18:15 2017 +0100 @@ -83,7 +84,7 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend); /* Touch support */ -int Android_JNI_GetTouchDeviceIds(int **ids); +int Android_JNI_InitTouch(void); void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value); /* Threads */ diff -r 2ce56475ad57 src/video/android/SDL_androidtouch.c --- a/src/video/android/SDL_androidtouch.c Tue Nov 07 09:10:32 2017 -0800 +++ b/src/video/android/SDL_androidtouch.c Mon Nov 13 21:18:15 2017 +0100 @@ -63,19 +63,10 @@ void Android_InitTouch(void) { - int i; - int* ids; - const int number = Android_JNI_GetTouchDeviceIds(&ids); - SDL_AddHintCallback(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, SeparateEventsHintWatcher, NULL); - if (0 < number) { - for (i = 0; i < number; ++i) { - SDL_AddTouch((SDL_TouchID) ids[i], ""); /* no error handling */ - } - SDL_free(ids); - } + Android_JNI_InitTouch(); } void Android_QuitTouch(void)