Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic Android pen backend #11455

Merged
merged 4 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public enum NativeState {
protected static SDLClipboardHandler mClipboardHandler;
protected static Hashtable<Integer, PointerIcon> mCursors;
protected static int mLastCursorID;
protected static SDLGenericMotionListener_API12 mMotionListener;
protected static SDLGenericMotionListener_API14 mMotionListener;
protected static HIDDeviceManager mHIDDeviceManager;

// This is what SDL runs in. It invokes SDL_main(), eventually
Expand All @@ -232,14 +232,14 @@ public enum NativeState {
protected static boolean mActivityCreated = false;
private static SDLFileDialogState mFileDialogState = null;

protected static SDLGenericMotionListener_API12 getMotionListener() {
protected static SDLGenericMotionListener_API14 getMotionListener() {
if (mMotionListener == null) {
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
mMotionListener = new SDLGenericMotionListener_API26();
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
mMotionListener = new SDLGenericMotionListener_API24();
} else {
mMotionListener = new SDLGenericMotionListener_API12();
mMotionListener = new SDLGenericMotionListener_API14();
}
}

Expand Down Expand Up @@ -1059,6 +1059,7 @@ protected boolean sendCommand(int command, Object data) {
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
public static native void onNativePen(int penId, int button, int action, float x, float y, float p);
public static native void onNativeAccel(float x, float y, float z);
public static native void onNativeClipboardChanged();
public static native void onNativeSurfaceCreated();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -662,44 +662,61 @@ protected SDLHaptic getHaptic(int device_id) {
}
}

class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
class SDLGenericMotionListener_API14 implements View.OnGenericMotionListener {
// Generic Motion (mouse hover, joystick...) events go here
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
if (event.getSource() == InputDevice.SOURCE_JOYSTICK)
return SDLControllerManager.handleJoystickMotionEvent(event);

float x, y;
int action;
int action = event.getActionMasked();
int pointerCount = event.getPointerCount();
boolean consumed = false;

switch ( event.getSource() ) {
case InputDevice.SOURCE_JOYSTICK:
return SDLControllerManager.handleJoystickMotionEvent(event);
for (int i = 0; i < pointerCount; i++) {
int toolType = event.getToolType(i);

case InputDevice.SOURCE_MOUSE:
action = event.getActionMasked();
if (toolType == MotionEvent.TOOL_TYPE_MOUSE) {
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, i);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, i);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;
consumed = true;
break;

case MotionEvent.ACTION_HOVER_MOVE:
x = event.getX(0);
y = event.getY(0);
x = getEventX(event, i);
y = getEventY(event, i);

SDLActivity.onNativeMouse(0, action, x, y, false);
return true;
SDLActivity.onNativeMouse(0, action, x, y, checkRelativeEvent(event));
consumed = true;
break;

default:
break;
}
break;
} else if (toolType == MotionEvent.TOOL_TYPE_STYLUS || toolType == MotionEvent.TOOL_TYPE_ERASER) {
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
case MotionEvent.ACTION_HOVER_MOVE:
case MotionEvent.ACTION_HOVER_EXIT:
x = event.getX(i);
y = event.getY(i);
float p = event.getPressure(i);

// BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4
int buttons = event.getButtonState() >> 4;

default:
break;
SDLActivity.onNativePen(event.getPointerId(i), buttons, action, x, y, p);
consumed = true;
break;
}
}
}

// Event was not managed
return false;
return consumed;
}

public boolean supportsRelativeMouse() {
Expand All @@ -714,46 +731,29 @@ public boolean setRelativeMouseEnabled(boolean enabled) {
return false;
}

public void reclaimRelativeMouseModeIfNeeded()
{
public void reclaimRelativeMouseModeIfNeeded() {

}

public boolean checkRelativeEvent(MotionEvent event) {
return inRelativeMode();
}

public float getEventX(MotionEvent event) {
return event.getX(0);
public float getEventX(MotionEvent event, int pointerIndex) {
return event.getX(pointerIndex);
}

public float getEventY(MotionEvent event) {
return event.getY(0);
public float getEventY(MotionEvent event, int pointerIndex) {
return event.getY(pointerIndex);
}

}

class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
// Generic Motion (mouse hover, joystick...) events go here

private boolean mRelativeModeEnabled;

@Override
public boolean onGenericMotion(View v, MotionEvent event) {

// Handle relative mouse mode
if (mRelativeModeEnabled) {
if (event.getSource() == InputDevice.SOURCE_MOUSE) {
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_HOVER_MOVE) {
float x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
float y = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
SDLActivity.onNativeMouse(0, action, x, y, true);
return true;
}
}
}

// Event was not managed, call SDLGenericMotionListener_API12 method
return super.onGenericMotion(v, event);
}

@Override
public boolean supportsRelativeMouse() {
return true;
Expand All @@ -771,20 +771,20 @@ public boolean setRelativeMouseEnabled(boolean enabled) {
}

@Override
public float getEventX(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
public float getEventX(MotionEvent event, int pointerIndex) {
if (mRelativeModeEnabled && event.getToolType(pointerIndex) == MotionEvent.TOOL_TYPE_MOUSE) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X, pointerIndex);
} else {
return event.getX(0);
return event.getX(pointerIndex);
}
}

@Override
public float getEventY(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
public float getEventY(MotionEvent event, int pointerIndex) {
if (mRelativeModeEnabled && event.getToolType(pointerIndex) == MotionEvent.TOOL_TYPE_MOUSE) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y, pointerIndex);
} else {
return event.getY(0);
return event.getY(pointerIndex);
}
}
}
Expand All @@ -793,65 +793,6 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
// 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:
return SDLControllerManager.handleJoystickMotionEvent(event);

case InputDevice.SOURCE_MOUSE:
// DeX desktop mouse cursor is a separate non-standard input type.
case InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN:
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:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;

default:
break;
}
break;

case InputDevice.SOURCE_MOUSE_RELATIVE:
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:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y, true);
return true;

default:
break;
}
break;

default:
break;
}

// Event was not managed
return false;
}

@Override
public boolean supportsRelativeMouse() {
return (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */);
Expand All @@ -878,22 +819,26 @@ public boolean setRelativeMouseEnabled(boolean enabled) {
}

@Override
public void reclaimRelativeMouseModeIfNeeded()
{
public void reclaimRelativeMouseModeIfNeeded() {
if (mRelativeModeEnabled && !SDLActivity.isDeXMode()) {
SDLActivity.getContentView().requestPointerCapture();
}
}

@Override
public float getEventX(MotionEvent event) {
public boolean checkRelativeEvent(MotionEvent event) {
return event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE;
}

@Override
public float getEventX(MotionEvent event, int pointerIndex) {
// Relative mouse in capture mode will only have relative for X/Y
return event.getX(0);
return event.getX(pointerIndex);
}

@Override
public float getEventY(MotionEvent event) {
public float getEventY(MotionEvent event, int pointerIndex) {
// Relative mouse in capture mode will only have relative for X/Y
return event.getY(0);
return event.getY(pointerIndex);
}
}
Loading
Loading