From 2dedbc72626453587606f096f886d76f09775378 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 5 Jun 2018 12:46:11 -0700 Subject: [PATCH] Add Android support for relative mouse mode to SDL. --- src/core/android/SDL_android.c | 26 ++++++++++++++++++++++---- src/core/android/SDL_android.h | 4 ++++ src/events/SDL_mouse.c | 1 + src/video/android/SDL_androidmouse.c | 23 +++++++++++++++++++---- src/video/android/SDL_androidmouse.h | 2 +- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index c5bec9059f6d3..c4b342385a362 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -102,7 +102,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y); + jint button, jint action, jfloat x, jfloat y, jboolean relative); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( JNIEnv* env, jclass jcls, @@ -226,6 +226,8 @@ static jmethodID midGetDisplayDPI; static jmethodID midCreateCustomCursor; static jmethodID midSetCustomCursor; static jmethodID midSetSystemCursor; +static jmethodID midSupportsRelativeMouse; +static jmethodID midSetRelativeMouseEnabled; /* audio manager */ static jclass mAudioManagerClass; @@ -339,12 +341,15 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c midSetCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setCustomCursor", "(I)Z"); midSetSystemCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setSystemCursor", "(I)Z"); + midSupportsRelativeMouse = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "supportsRelativeMouse", "()Z"); + midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); + if (!midGetNativeSurface || !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsAndroidTV || !midInputGetInputDeviceIds || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI || - !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor) { + !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -682,9 +687,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( /* Mouse */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y) + jint button, jint action, jfloat x, jfloat y, jboolean relative) { - Android_OnMouse(button, action, x, y); + Android_OnMouse(button, action, x, y, relative); } /* Accelerometer */ @@ -2202,6 +2207,19 @@ SDL_bool Android_JNI_SetSystemCursor(int cursorID) return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetSystemCursor, cursorID); } +SDL_bool Android_JNI_SupportsRelativeMouse() +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSupportsRelativeMouse); +} + +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1)); +} + + #endif /* __ANDROID__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 5eb727d19ecc1..6b3dfcb9edb05 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -107,6 +107,10 @@ int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y); SDL_bool Android_JNI_SetCustomCursor(int cursorID); SDL_bool Android_JNI_SetSystemCursor(int cursorID); +/* Relative mouse support */ +SDL_bool Android_JNI_SupportsRelativeMouse(); +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 4f4e62f873b55..135292eee51dd 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -688,6 +688,7 @@ static SDL_bool ShouldUseRelativeModeWarp(SDL_Mouse *mouse) { if (!mouse->SetRelativeMouseMode) { + SDL_assert(mouse->WarpMouse); /* Need this functionality for relative mode warp implementation */ return SDL_TRUE; } diff --git a/src/video/android/SDL_androidmouse.c b/src/video/android/SDL_androidmouse.c index 13c62718a2c3e..c79792d3963cf 100644 --- a/src/video/android/SDL_androidmouse.c +++ b/src/video/android/SDL_androidmouse.c @@ -137,6 +137,20 @@ Android_ShowCursor(SDL_Cursor * cursor) return 0; } +static int +Android_SetRelativeMouseMode(SDL_bool enabled) +{ + if (!Android_JNI_SupportsRelativeMouse()) { + return SDL_Unsupported(); + } + + if (!Android_JNI_SetRelativeMouseEnabled(enabled)) { + return SDL_Unsupported(); + } + + return 0; +} + void Android_InitMouse(void) { @@ -146,6 +160,7 @@ Android_InitMouse(void) mouse->CreateSystemCursor = Android_CreateSystemCursor; mouse->ShowCursor = Android_ShowCursor; mouse->FreeCursor = Android_FreeCursor; + mouse->SetRelativeMouseMode = Android_SetRelativeMouseMode; SDL_SetDefaultCursor(Android_CreateDefaultCursor()); @@ -172,7 +187,7 @@ TranslateButton(int state) } void -Android_OnMouse(int state, int action, float x, float y) +Android_OnMouse(int state, int action, float x, float y, SDL_bool relative) { int changes; Uint8 button; @@ -186,7 +201,7 @@ Android_OnMouse(int state, int action, float x, float y) changes = state & ~last_state; button = TranslateButton(changes); last_state = state; - SDL_SendMouseMotion(Android_Window, 0, 0, x, y); + SDL_SendMouseMotion(Android_Window, 0, relative, x, y); SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, button); break; @@ -194,13 +209,13 @@ Android_OnMouse(int state, int action, float x, float y) changes = last_state & ~state; button = TranslateButton(changes); last_state = state; - SDL_SendMouseMotion(Android_Window, 0, 0, x, y); + SDL_SendMouseMotion(Android_Window, 0, relative, x, y); SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, button); break; case ACTION_MOVE: case ACTION_HOVER_MOVE: - SDL_SendMouseMotion(Android_Window, 0, 0, x, y); + SDL_SendMouseMotion(Android_Window, 0, relative, x, y); break; case ACTION_SCROLL: diff --git a/src/video/android/SDL_androidmouse.h b/src/video/android/SDL_androidmouse.h index f201fad973f14..9aa71f5139f6b 100644 --- a/src/video/android/SDL_androidmouse.h +++ b/src/video/android/SDL_androidmouse.h @@ -25,7 +25,7 @@ #include "SDL_androidvideo.h" extern void Android_InitMouse(void); -extern void Android_OnMouse( int button, int action, float x, float y); +extern void Android_OnMouse(int button, int action, float x, float y, SDL_bool relative); #endif /* SDL_androidmouse_h_ */