2021-04-18 07:35:25 +04:00
package org.libsdl.app ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.List ;
import android.content.Context ;
2021-04-20 23:40:33 +04:00
import android.os.Build ;
import android.os.VibrationEffect ;
import android.os.Vibrator ;
2021-04-18 07:35:25 +04:00
import android.util.Log ;
2021-04-20 23:40:33 +04:00
import android.view.InputDevice ;
import android.view.KeyEvent ;
import android.view.MotionEvent ;
import android.view.View ;
2021-04-18 07:35:25 +04:00
public class SDLControllerManager
{
public static native int nativeSetupJNI ( ) ;
public static native int nativeAddJoystick ( int device_id , String name , String desc ,
int vendor_id , int product_id ,
boolean is_accelerometer , int button_mask ,
int naxes , int nhats , int nballs ) ;
public static native int nativeRemoveJoystick ( int device_id ) ;
public static native int nativeAddHaptic ( int device_id , String name ) ;
public static native int nativeRemoveHaptic ( int device_id ) ;
public static native int onNativePadDown ( int device_id , int keycode ) ;
public static native int onNativePadUp ( int device_id , int keycode ) ;
public static native void onNativeJoy ( int device_id , int axis ,
float value ) ;
public static native void onNativeHat ( int device_id , int hat_id ,
int x , int y ) ;
protected static SDLJoystickHandler mJoystickHandler ;
protected static SDLHapticHandler mHapticHandler ;
private static final String TAG = " SDLControllerManager " ;
public static void initialize ( ) {
if ( mJoystickHandler = = null ) {
if ( Build . VERSION . SDK_INT > = 19 ) {
mJoystickHandler = new SDLJoystickHandler_API19 ( ) ;
} else {
mJoystickHandler = new SDLJoystickHandler_API16 ( ) ;
}
}
if ( mHapticHandler = = null ) {
if ( Build . VERSION . SDK_INT > = 26 ) {
mHapticHandler = new SDLHapticHandler_API26 ( ) ;
} else {
mHapticHandler = new SDLHapticHandler ( ) ;
}
}
}
// Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
public static boolean handleJoystickMotionEvent ( MotionEvent event ) {
return mJoystickHandler . handleMotionEvent ( event ) ;
}
/ * *
* This method is called by SDL using JNI .
* /
public static void pollInputDevices ( ) {
mJoystickHandler . pollInputDevices ( ) ;
}
/ * *
* This method is called by SDL using JNI .
* /
public static void pollHapticDevices ( ) {
mHapticHandler . pollHapticDevices ( ) ;
}
/ * *
* This method is called by SDL using JNI .
* /
public static void hapticRun ( int device_id , float intensity , int length ) {
mHapticHandler . run ( device_id , intensity , length ) ;
}
/ * *
* This method is called by SDL using JNI .
* /
public static void hapticStop ( int device_id )
{
mHapticHandler . stop ( device_id ) ;
}
// Check if a given device is considered a possible SDL joystick
public static boolean isDeviceSDLJoystick ( int deviceId ) {
InputDevice device = InputDevice . getDevice ( deviceId ) ;
// We cannot use InputDevice.isVirtual before API 16, so let's accept
// only nonnegative device ids (VIRTUAL_KEYBOARD equals -1)
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 */
2021-04-20 23:40:33 +04:00
/ *
2021-04-18 07:35:25 +04:00
if ( ( sources & InputDevice . SOURCE_CLASS_JOYSTICK ) ! = 0 ) {
Log . v ( TAG , " Input device " + device . getName ( ) + " has class joystick. " ) ;
}
if ( ( sources & InputDevice . SOURCE_DPAD ) = = InputDevice . SOURCE_DPAD ) {
Log . v ( TAG , " Input device " + device . getName ( ) + " is a dpad. " ) ;
}
if ( ( sources & InputDevice . SOURCE_GAMEPAD ) = = InputDevice . SOURCE_GAMEPAD ) {
Log . v ( TAG , " Input device " + device . getName ( ) + " is a gamepad. " ) ;
}
2021-04-20 23:40:33 +04:00
* /
2021-04-18 07:35:25 +04:00
return ( ( sources & InputDevice . SOURCE_CLASS_JOYSTICK ) ! = 0 | |
( ( sources & InputDevice . SOURCE_DPAD ) = = InputDevice . SOURCE_DPAD ) | |
( ( sources & InputDevice . SOURCE_GAMEPAD ) = = InputDevice . SOURCE_GAMEPAD )
) ;
}
}
class SDLJoystickHandler {
/ * *
* Handles given MotionEvent .
* @param event the event to be handled .
* @return if given event was processed .
* /
public boolean handleMotionEvent ( MotionEvent event ) {
return false ;
}
/ * *
* Handles adding and removing of input devices .
* /
public void pollInputDevices ( ) {
}
}
/* Actual joystick functionality available for API >= 12 devices */
class SDLJoystickHandler_API16 extends SDLJoystickHandler {
static class SDLJoystick {
public int device_id ;
public String name ;
public String desc ;
public ArrayList < InputDevice . MotionRange > axes ;
public ArrayList < InputDevice . MotionRange > hats ;
}
static class RangeComparator implements Comparator < InputDevice . MotionRange > {
@Override
public int compare ( InputDevice . MotionRange arg0 , InputDevice . MotionRange arg1 ) {
// Some controllers, like the Moga Pro 2, return AXIS_GAS (22) for right trigger and AXIS_BRAKE (23) for left trigger - swap them so they're sorted in the right order for SDL
int arg0Axis = arg0 . getAxis ( ) ;
int arg1Axis = arg1 . getAxis ( ) ;
if ( arg0Axis = = MotionEvent . AXIS_GAS ) {
arg0Axis = MotionEvent . AXIS_BRAKE ;
} else if ( arg0Axis = = MotionEvent . AXIS_BRAKE ) {
arg0Axis = MotionEvent . AXIS_GAS ;
}
if ( arg1Axis = = MotionEvent . AXIS_GAS ) {
arg1Axis = MotionEvent . AXIS_BRAKE ;
} else if ( arg1Axis = = MotionEvent . AXIS_BRAKE ) {
arg1Axis = MotionEvent . AXIS_GAS ;
}
return arg0Axis - arg1Axis ;
}
}
2021-04-20 23:40:33 +04:00
private final ArrayList < SDLJoystick > mJoysticks ;
2021-04-18 07:35:25 +04:00
public SDLJoystickHandler_API16 ( ) {
mJoysticks = new ArrayList < SDLJoystick > ( ) ;
}
@Override
public void pollInputDevices ( ) {
int [ ] deviceIds = InputDevice . getDeviceIds ( ) ;
2021-04-20 23:40:33 +04:00
for ( int device_id : deviceIds ) {
if ( SDLControllerManager . isDeviceSDLJoystick ( device_id ) ) {
SDLJoystick joystick = getJoystick ( device_id ) ;
if ( joystick = = null ) {
InputDevice joystickDevice = InputDevice . getDevice ( device_id ) ;
joystick = new SDLJoystick ( ) ;
joystick . device_id = device_id ;
2021-04-18 07:35:25 +04:00
joystick . name = joystickDevice . getName ( ) ;
joystick . desc = getJoystickDescriptor ( joystickDevice ) ;
joystick . axes = new ArrayList < InputDevice . MotionRange > ( ) ;
joystick . hats = new ArrayList < InputDevice . MotionRange > ( ) ;
List < InputDevice . MotionRange > ranges = joystickDevice . getMotionRanges ( ) ;
Collections . sort ( ranges , new RangeComparator ( ) ) ;
2021-04-20 23:40:33 +04:00
for ( InputDevice . MotionRange range : ranges ) {
2021-04-18 07:35:25 +04:00
if ( ( range . getSource ( ) & InputDevice . SOURCE_CLASS_JOYSTICK ) ! = 0 ) {
2021-04-20 23:40:33 +04:00
if ( range . getAxis ( ) = = MotionEvent . AXIS_HAT_X | | range . getAxis ( ) = = MotionEvent . AXIS_HAT_Y ) {
2021-04-18 07:35:25 +04:00
joystick . hats . add ( range ) ;
2021-04-20 23:40:33 +04:00
} else {
2021-04-18 07:35:25 +04:00
joystick . axes . add ( range ) ;
}
}
}
mJoysticks . add ( joystick ) ;
2021-04-20 23:40:33 +04:00
SDLControllerManager . nativeAddJoystick ( joystick . device_id , joystick . name , joystick . desc ,
getVendorId ( joystickDevice ) , getProductId ( joystickDevice ) , false ,
getButtonMask ( joystickDevice ) , joystick . axes . size ( ) , joystick . hats . size ( ) / 2 , 0 ) ;
2021-04-18 07:35:25 +04:00
}
}
}
/* Check removed devices */
2021-04-20 23:40:33 +04:00
ArrayList < Integer > removedDevices = null ;
for ( SDLJoystick joystick : mJoysticks ) {
int device_id = joystick . device_id ;
int i ;
for ( i = 0 ; i < deviceIds . length ; i + + ) {
if ( device_id = = deviceIds [ i ] ) break ;
2021-04-18 07:35:25 +04:00
}
2021-04-20 23:40:33 +04:00
if ( i = = deviceIds . length ) {
if ( removedDevices = = null ) {
removedDevices = new ArrayList < Integer > ( ) ;
}
removedDevices . add ( device_id ) ;
2021-04-18 07:35:25 +04:00
}
}
2021-04-20 23:40:33 +04:00
if ( removedDevices ! = null ) {
for ( int device_id : removedDevices ) {
SDLControllerManager . nativeRemoveJoystick ( device_id ) ;
for ( int i = 0 ; i < mJoysticks . size ( ) ; i + + ) {
if ( mJoysticks . get ( i ) . device_id = = device_id ) {
mJoysticks . remove ( i ) ;
break ;
}
2021-04-18 07:35:25 +04:00
}
}
}
}
protected SDLJoystick getJoystick ( int device_id ) {
2021-04-20 23:40:33 +04:00
for ( SDLJoystick joystick : mJoysticks ) {
if ( joystick . device_id = = device_id ) {
return joystick ;
2021-04-18 07:35:25 +04:00
}
}
return null ;
}
@Override
public boolean handleMotionEvent ( MotionEvent event ) {
2022-07-19 07:48:31 +04:00
if ( ( event . getSource ( ) & InputDevice . SOURCE_JOYSTICK ) ! = 0 ) {
int actionPointerIndex = event . getActionIndex ( ) ;
int action = event . getActionMasked ( ) ;
if ( action = = MotionEvent . ACTION_MOVE ) {
SDLJoystick joystick = getJoystick ( event . getDeviceId ( ) ) ;
if ( joystick ! = null ) {
for ( int i = 0 ; i < joystick . axes . size ( ) ; i + + ) {
InputDevice . MotionRange range = joystick . axes . get ( i ) ;
/* Normalize the value to -1...1 */
float value = ( event . getAxisValue ( range . getAxis ( ) , actionPointerIndex ) - range . getMin ( ) ) / range . getRange ( ) * 2 . 0f - 1 . 0f ;
SDLControllerManager . onNativeJoy ( joystick . device_id , i , value ) ;
}
for ( int i = 0 ; i < joystick . hats . size ( ) / 2 ; i + + ) {
int hatX = Math . round ( event . getAxisValue ( joystick . hats . get ( 2 * i ) . getAxis ( ) , actionPointerIndex ) ) ;
int hatY = Math . round ( event . getAxisValue ( joystick . hats . get ( 2 * i + 1 ) . getAxis ( ) , actionPointerIndex ) ) ;
SDLControllerManager . onNativeHat ( joystick . device_id , i , hatX , hatY ) ;
}
2021-04-20 23:40:33 +04:00
}
2021-04-18 07:35:25 +04:00
}
}
return true ;
}
public String getJoystickDescriptor ( InputDevice joystickDevice ) {
String desc = joystickDevice . getDescriptor ( ) ;
if ( desc ! = null & & ! desc . isEmpty ( ) ) {
return desc ;
}
return joystickDevice . getName ( ) ;
}
public int getProductId ( InputDevice joystickDevice ) {
return 0 ;
}
public int getVendorId ( InputDevice joystickDevice ) {
return 0 ;
}
public int getButtonMask ( InputDevice joystickDevice ) {
return - 1 ;
}
}
class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
@Override
public int getProductId ( InputDevice joystickDevice ) {
return joystickDevice . getProductId ( ) ;
}
@Override
public int getVendorId ( InputDevice joystickDevice ) {
return joystickDevice . getVendorId ( ) ;
}
@Override
public int getButtonMask ( InputDevice joystickDevice ) {
int button_mask = 0 ;
int [ ] keys = new int [ ] {
KeyEvent . KEYCODE_BUTTON_A ,
KeyEvent . KEYCODE_BUTTON_B ,
KeyEvent . KEYCODE_BUTTON_X ,
KeyEvent . KEYCODE_BUTTON_Y ,
KeyEvent . KEYCODE_BACK ,
KeyEvent . KEYCODE_BUTTON_MODE ,
KeyEvent . KEYCODE_BUTTON_START ,
KeyEvent . KEYCODE_BUTTON_THUMBL ,
KeyEvent . KEYCODE_BUTTON_THUMBR ,
KeyEvent . KEYCODE_BUTTON_L1 ,
KeyEvent . KEYCODE_BUTTON_R1 ,
KeyEvent . KEYCODE_DPAD_UP ,
KeyEvent . KEYCODE_DPAD_DOWN ,
KeyEvent . KEYCODE_DPAD_LEFT ,
KeyEvent . KEYCODE_DPAD_RIGHT ,
KeyEvent . KEYCODE_BUTTON_SELECT ,
KeyEvent . KEYCODE_DPAD_CENTER ,
// These don't map into any SDL controller buttons directly
KeyEvent . KEYCODE_BUTTON_L2 ,
KeyEvent . KEYCODE_BUTTON_R2 ,
KeyEvent . KEYCODE_BUTTON_C ,
KeyEvent . KEYCODE_BUTTON_Z ,
KeyEvent . KEYCODE_BUTTON_1 ,
KeyEvent . KEYCODE_BUTTON_2 ,
KeyEvent . KEYCODE_BUTTON_3 ,
KeyEvent . KEYCODE_BUTTON_4 ,
KeyEvent . KEYCODE_BUTTON_5 ,
KeyEvent . KEYCODE_BUTTON_6 ,
KeyEvent . KEYCODE_BUTTON_7 ,
KeyEvent . KEYCODE_BUTTON_8 ,
KeyEvent . KEYCODE_BUTTON_9 ,
KeyEvent . KEYCODE_BUTTON_10 ,
KeyEvent . KEYCODE_BUTTON_11 ,
KeyEvent . KEYCODE_BUTTON_12 ,
KeyEvent . KEYCODE_BUTTON_13 ,
KeyEvent . KEYCODE_BUTTON_14 ,
KeyEvent . KEYCODE_BUTTON_15 ,
KeyEvent . KEYCODE_BUTTON_16 ,
} ;
int [ ] masks = new int [ ] {
( 1 < < 0 ) , // A -> A
( 1 < < 1 ) , // B -> B
( 1 < < 2 ) , // X -> X
( 1 < < 3 ) , // Y -> Y
( 1 < < 4 ) , // BACK -> BACK
( 1 < < 5 ) , // MODE -> GUIDE
( 1 < < 6 ) , // START -> START
( 1 < < 7 ) , // THUMBL -> LEFTSTICK
( 1 < < 8 ) , // THUMBR -> RIGHTSTICK
( 1 < < 9 ) , // L1 -> LEFTSHOULDER
( 1 < < 10 ) , // R1 -> RIGHTSHOULDER
( 1 < < 11 ) , // DPAD_UP -> DPAD_UP
( 1 < < 12 ) , // DPAD_DOWN -> DPAD_DOWN
( 1 < < 13 ) , // DPAD_LEFT -> DPAD_LEFT
( 1 < < 14 ) , // DPAD_RIGHT -> DPAD_RIGHT
( 1 < < 4 ) , // SELECT -> BACK
( 1 < < 0 ) , // DPAD_CENTER -> A
( 1 < < 15 ) , // L2 -> ??
( 1 < < 16 ) , // R2 -> ??
( 1 < < 17 ) , // C -> ??
( 1 < < 18 ) , // Z -> ??
( 1 < < 20 ) , // 1 -> ??
( 1 < < 21 ) , // 2 -> ??
( 1 < < 22 ) , // 3 -> ??
( 1 < < 23 ) , // 4 -> ??
( 1 < < 24 ) , // 5 -> ??
( 1 < < 25 ) , // 6 -> ??
( 1 < < 26 ) , // 7 -> ??
( 1 < < 27 ) , // 8 -> ??
( 1 < < 28 ) , // 9 -> ??
( 1 < < 29 ) , // 10 -> ??
( 1 < < 30 ) , // 11 -> ??
( 1 < < 31 ) , // 12 -> ??
// We're out of room...
0xFFFFFFFF , // 13 -> ??
0xFFFFFFFF , // 14 -> ??
0xFFFFFFFF , // 15 -> ??
0xFFFFFFFF , // 16 -> ??
} ;
boolean [ ] has_keys = joystickDevice . hasKeys ( keys ) ;
for ( int i = 0 ; i < keys . length ; + + i ) {
if ( has_keys [ i ] ) {
button_mask | = masks [ i ] ;
}
}
return button_mask ;
}
}
class SDLHapticHandler_API26 extends SDLHapticHandler {
@Override
public void run ( int device_id , float intensity , int length ) {
SDLHaptic haptic = getHaptic ( device_id ) ;
if ( haptic ! = null ) {
Log . d ( " SDL " , " Rtest: Vibe with intensity " + intensity + " for " + length ) ;
if ( intensity = = 0 . 0f ) {
stop ( device_id ) ;
return ;
}
int vibeValue = Math . round ( intensity * 255 ) ;
if ( vibeValue > 255 ) {
vibeValue = 255 ;
}
if ( vibeValue < 1 ) {
stop ( device_id ) ;
return ;
}
try {
haptic . vib . vibrate ( VibrationEffect . createOneShot ( length , vibeValue ) ) ;
}
catch ( Exception e ) {
// Fall back to the generic method, which uses DEFAULT_AMPLITUDE, but works even if
// something went horribly wrong with the Android 8.0 APIs.
haptic . vib . vibrate ( length ) ;
}
}
}
}
class SDLHapticHandler {
2021-04-20 23:40:33 +04:00
static class SDLHaptic {
2021-04-18 07:35:25 +04:00
public int device_id ;
public String name ;
public Vibrator vib ;
}
2021-04-20 23:40:33 +04:00
private final ArrayList < SDLHaptic > mHaptics ;
2021-04-18 07:35:25 +04:00
public SDLHapticHandler ( ) {
mHaptics = new ArrayList < SDLHaptic > ( ) ;
}
public void run ( int device_id , float intensity , int length ) {
SDLHaptic haptic = getHaptic ( device_id ) ;
if ( haptic ! = null ) {
haptic . vib . vibrate ( length ) ;
}
}
public void stop ( int device_id ) {
SDLHaptic haptic = getHaptic ( device_id ) ;
if ( haptic ! = null ) {
haptic . vib . cancel ( ) ;
}
}
public void pollHapticDevices ( ) {
final int deviceId_VIBRATOR_SERVICE = 999999 ;
boolean hasVibratorService = false ;
int [ ] deviceIds = InputDevice . getDeviceIds ( ) ;
// It helps processing the device ids in reverse order
// For example, in the case of the XBox 360 wireless dongle,
// so the first controller seen by SDL matches what the receiver
// considers to be the first controller
for ( int i = deviceIds . length - 1 ; i > - 1 ; i - - ) {
SDLHaptic haptic = getHaptic ( deviceIds [ i ] ) ;
if ( haptic = = null ) {
InputDevice device = InputDevice . getDevice ( deviceIds [ i ] ) ;
Vibrator vib = device . getVibrator ( ) ;
if ( vib . hasVibrator ( ) ) {
haptic = new SDLHaptic ( ) ;
haptic . device_id = deviceIds [ i ] ;
haptic . name = device . getName ( ) ;
haptic . vib = vib ;
mHaptics . add ( haptic ) ;
SDLControllerManager . nativeAddHaptic ( haptic . device_id , haptic . name ) ;
}
}
}
/* Check VIBRATOR_SERVICE */
Vibrator vib = ( Vibrator ) SDL . getContext ( ) . getSystemService ( Context . VIBRATOR_SERVICE ) ;
if ( vib ! = null ) {
hasVibratorService = vib . hasVibrator ( ) ;
if ( hasVibratorService ) {
SDLHaptic haptic = getHaptic ( deviceId_VIBRATOR_SERVICE ) ;
if ( haptic = = null ) {
haptic = new SDLHaptic ( ) ;
haptic . device_id = deviceId_VIBRATOR_SERVICE ;
haptic . name = " VIBRATOR_SERVICE " ;
haptic . vib = vib ;
mHaptics . add ( haptic ) ;
SDLControllerManager . nativeAddHaptic ( haptic . device_id , haptic . name ) ;
}
}
}
/* Check removed devices */
2021-04-20 23:40:33 +04:00
ArrayList < Integer > removedDevices = null ;
for ( SDLHaptic haptic : mHaptics ) {
int device_id = haptic . device_id ;
int i ;
for ( i = 0 ; i < deviceIds . length ; i + + ) {
if ( device_id = = deviceIds [ i ] ) break ;
2021-04-18 07:35:25 +04:00
}
2021-04-20 23:40:33 +04:00
if ( device_id ! = deviceId_VIBRATOR_SERVICE | | ! hasVibratorService ) {
if ( i = = deviceIds . length ) {
if ( removedDevices = = null ) {
removedDevices = new ArrayList < Integer > ( ) ;
}
removedDevices . add ( device_id ) ;
}
} // else: don't remove the vibrator if it is still present
2021-04-18 07:35:25 +04:00
}
2021-04-20 23:40:33 +04:00
if ( removedDevices ! = null ) {
for ( int device_id : removedDevices ) {
SDLControllerManager . nativeRemoveHaptic ( device_id ) ;
for ( int i = 0 ; i < mHaptics . size ( ) ; i + + ) {
if ( mHaptics . get ( i ) . device_id = = device_id ) {
mHaptics . remove ( i ) ;
break ;
}
2021-04-18 07:35:25 +04:00
}
}
}
}
protected SDLHaptic getHaptic ( int device_id ) {
2021-04-20 23:40:33 +04:00
for ( SDLHaptic haptic : mHaptics ) {
if ( haptic . device_id = = device_id ) {
return haptic ;
2021-04-18 07:35:25 +04:00
}
}
return null ;
}
}
class SDLGenericMotionListener_API12 implements View . OnGenericMotionListener {
// Generic Motion (mouse hover, joystick...) events go here
@Override
public boolean onGenericMotion ( View v , MotionEvent event ) {
float x , y ;
int action ;
switch ( event . getSource ( ) ) {
case InputDevice . SOURCE_JOYSTICK :
2022-07-19 07:48:31 +04:00
case InputDevice . SOURCE_GAMEPAD :
case InputDevice . SOURCE_DPAD :
2021-04-18 07:35:25 +04:00
return SDLControllerManager . handleJoystickMotionEvent ( event ) ;
case InputDevice . SOURCE_MOUSE :
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 ;
default :
break ;
}
// Event was not managed
return false ;
}
public boolean supportsRelativeMouse ( ) {
return false ;
}
public boolean inRelativeMode ( ) {
return false ;
}
public boolean setRelativeMouseEnabled ( boolean enabled ) {
return false ;
}
public void reclaimRelativeMouseModeIfNeeded ( )
{
}
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 ) {
// 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 ;
}
@Override
public boolean inRelativeMode ( ) {
return mRelativeModeEnabled ;
}
@Override
public boolean setRelativeMouseEnabled ( boolean enabled ) {
mRelativeModeEnabled = enabled ;
return true ;
}
@Override
public float getEventX ( MotionEvent event ) {
if ( mRelativeModeEnabled ) {
return event . getAxisValue ( MotionEvent . AXIS_RELATIVE_X ) ;
2021-04-20 23:40:33 +04:00
} else {
2021-04-18 07:35:25 +04:00
return event . getX ( 0 ) ;
}
}
@Override
public float getEventY ( MotionEvent event ) {
if ( mRelativeModeEnabled ) {
return event . getAxisValue ( MotionEvent . AXIS_RELATIVE_Y ) ;
2021-04-20 23:40:33 +04:00
} else {
2021-04-18 07:35:25 +04:00
return event . getY ( 0 ) ;
}
}
}
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 :
2022-07-19 07:48:31 +04:00
case InputDevice . SOURCE_GAMEPAD :
case InputDevice . SOURCE_DPAD :
2021-04-18 07:35:25 +04:00
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 ) ) ;
}
@Override
public boolean inRelativeMode ( ) {
return mRelativeModeEnabled ;
}
@Override
public boolean setRelativeMouseEnabled ( boolean enabled ) {
if ( ! SDLActivity . isDeXMode ( ) | | ( Build . VERSION . SDK_INT > = 27 ) ) {
if ( enabled ) {
SDLActivity . getContentView ( ) . requestPointerCapture ( ) ;
2021-04-20 23:40:33 +04:00
} else {
2021-04-18 07:35:25 +04:00
SDLActivity . getContentView ( ) . releasePointerCapture ( ) ;
}
mRelativeModeEnabled = enabled ;
return true ;
2021-04-20 23:40:33 +04:00
} else {
2021-04-18 07:35:25 +04:00
return false ;
}
}
@Override
public void reclaimRelativeMouseModeIfNeeded ( )
{
if ( mRelativeModeEnabled & & ! SDLActivity . isDeXMode ( ) ) {
SDLActivity . getContentView ( ) . requestPointerCapture ( ) ;
}
}
@Override
public float getEventX ( MotionEvent event ) {
// Relative mouse in capture mode will only have relative for X/Y
return event . getX ( 0 ) ;
}
@Override
public float getEventY ( MotionEvent event ) {
// Relative mouse in capture mode will only have relative for X/Y
return event . getY ( 0 ) ;
}
}