Added support for Android relative mouse mode on API 24 and above

This commit is contained in:
Sam Lantinga 2018-05-29 11:18:01 -07:00
parent ff6aebc4a1
commit 03ff7dcf6b
2 changed files with 148 additions and 5 deletions

View File

@ -79,11 +79,24 @@ public class SDLActivity extends Activity {
protected static SDLClipboardHandler mClipboardHandler;
protected static Hashtable<Integer, Object> mCursors;
protected static int mLastCursorID;
protected static SDLGenericMotionListener_API12 mMotionListener;
// This is what SDL runs in. It invokes SDL_main(), eventually
protected static Thread mSDLThread;
protected static SDLGenericMotionListener_API12 getMotionListener() {
if (mMotionListener == null) {
if (Build.VERSION.SDK_INT >= 24) {
mMotionListener = new SDLGenericMotionListener_API24();
} else {
mMotionListener = new SDLGenericMotionListener_API12();
}
}
return mMotionListener;
}
/**
* This method returns the name of the shared object with the application entry point
* It can be overridden by derived classes.
@ -543,7 +556,7 @@ public class SDLActivity extends Activity {
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
public static native void onNativeKeyboardFocusLost();
public static native void onNativeMouse(int button, int action, float x, float y);
public static native void onNativeMouse(int button, int action, float x, float y, boolean relative);
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
@ -641,6 +654,22 @@ public class SDLActivity extends Activity {
}
/**
* This method is called by SDL using JNI.
*/
public static boolean supportsRelativeMouse()
{
return SDLActivity.getMotionListener().supportsRelativeMouse();
}
/**
* This method is called by SDL using JNI.
*/
public static boolean setRelativeMouseEnabled(boolean enabled)
{
return SDLActivity.getMotionListener().setRelativeMouseEnabled(enabled);
}
/**
* This method is called by SDL using JNI.
*/
@ -1231,7 +1260,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
if (Build.VERSION.SDK_INT >= 12) {
setOnGenericMotionListener(new SDLGenericMotionListener_API12());
setOnGenericMotionListener(SDLActivity.getMotionListener());
}
// Some arbitrary defaults to avoid a potential division by zero
@ -1456,7 +1485,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
mouseButton = 1; // oh well.
}
}
SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
// We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values
// if we are. We'll leverage our existing mouse motion listener
SDLGenericMotionListener_API12 motionListener = SDLActivity.getMotionListener();
x = motionListener.getEventX(event);
y = motionListener.getEventY(event);
SDLActivity.onNativeMouse(mouseButton, action, x, y, motionListener.inRelativeMode());
} else {
switch(action) {
case MotionEvent.ACTION_MOVE:

View File

@ -534,14 +534,14 @@ class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;
case MotionEvent.ACTION_HOVER_MOVE:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;
default:
@ -556,5 +556,112 @@ class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
// Event was not managed
return false;
}
public boolean supportsRelativeMouse() {
return false;
}
public boolean inRelativeMode() {
return false;
}
public boolean setRelativeMouseEnabled(boolean enabled) {
return false;
}
public float getEventX(MotionEvent event) {
return event.getX(0);
}
public float getEventY(MotionEvent event) {
return event.getY(0);
}
}
class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
// Generic Motion (mouse hover, joystick...) events go here
private boolean mRelativeModeEnabled;
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
float x, y;
int action;
switch ( event.getSource() ) {
case InputDevice.SOURCE_JOYSTICK:
case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event);
case InputDevice.SOURCE_MOUSE:
if (!SDLActivity.mSeparateMouseAndTouch) {
break;
}
action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;
case MotionEvent.ACTION_HOVER_MOVE:
if (mRelativeModeEnabled) {
x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
y = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
}
else {
x = event.getX(0);
y = event.getY(0);
}
SDLActivity.onNativeMouse(0, action, x, y, mRelativeModeEnabled);
return true;
default:
break;
}
break;
default:
break;
}
// Event was not managed
return false;
}
public boolean supportsRelativeMouse() {
return true;
}
public boolean inRelativeMode() {
return mRelativeModeEnabled;
}
public boolean setRelativeMouseEnabled(boolean enabled) {
mRelativeModeEnabled = enabled;
return true;
}
public float getEventX(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
}
else {
return event.getX(0);
}
}
public float getEventY(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
}
else {
return event.getY(0);
}
}
}