| | |
| | | import android.util.Log; |
| | | |
| | | |
| | | public class SDLControllerManager |
| | | public class SDLControllerManager |
| | | { |
| | | |
| | | public static native int nativeSetupJNI(); |
| | | |
| | | public static native int nativeAddJoystick(int device_id, String name, String desc, |
| | | int is_accelerometer, int nbuttons, |
| | | 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); |
| | |
| | | private static final String TAG = "SDLControllerManager"; |
| | | |
| | | public static void initialize() { |
| | | mJoystickHandler = null; |
| | | mHapticHandler = null; |
| | | |
| | | SDLControllerManager.setup(); |
| | | } |
| | | |
| | | public static void setup() { |
| | | if (Build.VERSION.SDK_INT >= 16) { |
| | | mJoystickHandler = new SDLJoystickHandler_API16(); |
| | | } else if (Build.VERSION.SDK_INT >= 12) { |
| | | mJoystickHandler = new SDLJoystickHandler_API12(); |
| | | } else { |
| | | mJoystickHandler = new SDLJoystickHandler(); |
| | | if (mJoystickHandler == null) { |
| | | if (Build.VERSION.SDK_INT >= 19) { |
| | | mJoystickHandler = new SDLJoystickHandler_API19(); |
| | | } else { |
| | | mJoystickHandler = new SDLJoystickHandler_API16(); |
| | | } |
| | | } |
| | | mHapticHandler = new SDLHapticHandler(); |
| | | |
| | | 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 |
| | |
| | | /** |
| | | * This method is called by SDL using JNI. |
| | | */ |
| | | public static void hapticRun(int device_id, int length) { |
| | | mHapticHandler.run(device_id, length); |
| | | 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 |
| | |
| | | |
| | | /* This is called for every button press, so let's not spam the logs */ |
| | | /** |
| | | if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { |
| | | Log.v(TAG, "Input device " + device.getName() + " is a joystick."); |
| | | 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."); |
| | |
| | | } |
| | | **/ |
| | | |
| | | return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || |
| | | return ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 || |
| | | ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || |
| | | ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) |
| | | ); |
| | |
| | | |
| | | } |
| | | |
| | | /* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */ |
| | | class SDLJoystickHandler { |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /* Actual joystick functionality available for API >= 12 devices */ |
| | | class SDLJoystickHandler_API12 extends SDLJoystickHandler { |
| | | class SDLJoystickHandler_API16 extends SDLJoystickHandler { |
| | | |
| | | static class SDLJoystick { |
| | | public int device_id; |
| | |
| | | static class RangeComparator implements Comparator<InputDevice.MotionRange> { |
| | | @Override |
| | | public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) { |
| | | return arg0.getAxis() - arg1.getAxis(); |
| | | // 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; |
| | | } |
| | | } |
| | | |
| | | private ArrayList<SDLJoystick> mJoysticks; |
| | | |
| | | public SDLJoystickHandler_API12() { |
| | | public SDLJoystickHandler_API16() { |
| | | |
| | | mJoysticks = new ArrayList<SDLJoystick>(); |
| | | } |
| | |
| | | @Override |
| | | public void pollInputDevices() { |
| | | 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--) { |
| | | for(int i=0; i < deviceIds.length; ++i) { |
| | | SDLJoystick joystick = getJoystick(deviceIds[i]); |
| | | if (joystick == null) { |
| | | joystick = new SDLJoystick(); |
| | |
| | | } |
| | | |
| | | mJoysticks.add(joystick); |
| | | SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, 0, -1, |
| | | joystick.axes.size(), joystick.hats.size()/2, 0); |
| | | SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | public String getJoystickDescriptor(InputDevice joystickDevice) { |
| | | return joystickDevice.getName(); |
| | | } |
| | | } |
| | | |
| | | |
| | | class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 { |
| | | |
| | | @Override |
| | | public String getJoystickDescriptor(InputDevice joystickDevice) { |
| | | String desc = joystickDevice.getDescriptor(); |
| | | |
| | | if (desc != null && !desc.isEmpty()) { |
| | | return desc; |
| | | } |
| | | |
| | | return super.getJoystickDescriptor(joystickDevice); |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | private ArrayList<SDLHaptic> mHaptics; |
| | | |
| | | |
| | | public SDLHapticHandler() { |
| | | mHaptics = new ArrayList<SDLHaptic>(); |
| | | } |
| | | |
| | | public void run(int device_id, int length) { |
| | | public void run(int device_id, float intensity, int length) { |
| | | SDLHaptic haptic = getHaptic(device_id); |
| | | if (haptic != null) { |
| | | haptic.vib.vibrate (length); |
| | | 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; |
| | | |
| | |
| | | // so the first controller seen by SDL matches what the receiver |
| | | // considers to be the first controller |
| | | |
| | | if (Build.VERSION.SDK_INT >= 16) |
| | | { |
| | | 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); |
| | | } |
| | | 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) { |
| | | if (Build.VERSION.SDK_INT >= 11) { |
| | | hasVibratorService = vib.hasVibrator(); |
| | | } else { |
| | | hasVibratorService = true; |
| | | } |
| | | hasVibratorService = vib.hasVibrator(); |
| | | |
| | | if (hasVibratorService) { |
| | | SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); |
| | |
| | | haptic = new SDLHaptic(); |
| | | haptic.device_id = deviceId_VIBRATOR_SERVICE; |
| | | haptic.name = "VIBRATOR_SERVICE"; |
| | | haptic.vib = vib; |
| | | haptic.vib = vib; |
| | | mHaptics.add(haptic); |
| | | SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); |
| | | } |
| | |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { |
| | |
| | | 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); |
| | | 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: |
| | |
| | | // 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); |
| | | } |
| | | else { |
| | | return event.getX(0); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public float getEventY(MotionEvent event) { |
| | | if (mRelativeModeEnabled) { |
| | | return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y); |
| | | } |
| | | else { |
| | | 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: |
| | | case InputDevice.SOURCE_GAMEPAD: |
| | | case InputDevice.SOURCE_DPAD: |
| | | 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(); |
| | | } |
| | | else { |
| | | SDLActivity.getContentView().releasePointerCapture(); |
| | | } |
| | | mRelativeModeEnabled = enabled; |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | 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); |
| | | } |
| | | } |