Skip to content

Commit

Permalink
Added support for Android relative mouse mode on API 24 and above
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed May 29, 2018
1 parent ff6aebc commit 03ff7dc
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 5 deletions.
42 changes: 39 additions & 3 deletions android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
Expand Up @@ -79,11 +79,24 @@ public enum NativeState {
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.
Expand Down Expand Up @@ -543,7 +556,7 @@ boolean sendCommand(int command, Object data) {
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);
Expand Down Expand Up @@ -641,6 +654,22 @@ public static boolean isScreenKeyboardShown()

}

/**
* 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.
*/
Expand Down Expand Up @@ -1231,7 +1260,7 @@ public SDLSurface(Context context) {
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
Expand Down Expand Up @@ -1456,7 +1485,14 @@ public boolean onTouch(View v, MotionEvent event) {
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:
Expand Down
Expand Up @@ -534,14 +534,14 @@ public boolean onGenericMotion(View v, MotionEvent event) {
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:
Expand All @@ -556,5 +556,112 @@ public boolean onGenericMotion(View v, MotionEvent event) {
// 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);
}
}
}

0 comments on commit 03ff7dc

Please sign in to comment.