Added support for Android relative mouse mode on API 24 and above
authorSam Lantinga <slouken@libsdl.org>
Tue, 29 May 2018 11:18:01 -0700
changeset 12004757d81897470
parent 12003 c606531db77b
child 12005 94f3f018d3eb
Added support for Android relative mouse mode on API 24 and above
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Tue May 29 08:03:44 2018 -0700
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Tue May 29 11:18:01 2018 -0700
     1.3 @@ -79,11 +79,24 @@
     1.4      protected static SDLClipboardHandler mClipboardHandler;
     1.5      protected static Hashtable<Integer, Object> mCursors;
     1.6      protected static int mLastCursorID;
     1.7 +    protected static SDLGenericMotionListener_API12 mMotionListener;
     1.8  
     1.9  
    1.10      // This is what SDL runs in. It invokes SDL_main(), eventually
    1.11      protected static Thread mSDLThread;
    1.12  
    1.13 +    protected static SDLGenericMotionListener_API12 getMotionListener() {
    1.14 +        if (mMotionListener == null) {
    1.15 +            if (Build.VERSION.SDK_INT >= 24) {
    1.16 +                mMotionListener = new SDLGenericMotionListener_API24();
    1.17 +            } else {
    1.18 +                mMotionListener = new SDLGenericMotionListener_API12();
    1.19 +            }
    1.20 +        }
    1.21 +
    1.22 +        return mMotionListener;
    1.23 +    }
    1.24 +
    1.25      /**
    1.26       * This method returns the name of the shared object with the application entry point
    1.27       * It can be overridden by derived classes.
    1.28 @@ -543,7 +556,7 @@
    1.29      public static native void onNativeKeyDown(int keycode);
    1.30      public static native void onNativeKeyUp(int keycode);
    1.31      public static native void onNativeKeyboardFocusLost();
    1.32 -    public static native void onNativeMouse(int button, int action, float x, float y);
    1.33 +    public static native void onNativeMouse(int button, int action, float x, float y, boolean relative);
    1.34      public static native void onNativeTouch(int touchDevId, int pointerFingerId,
    1.35                                              int action, float x,
    1.36                                              float y, float p);
    1.37 @@ -644,6 +657,22 @@
    1.38      /**
    1.39       * This method is called by SDL using JNI.
    1.40       */
    1.41 +    public static boolean supportsRelativeMouse()
    1.42 +    {
    1.43 +        return SDLActivity.getMotionListener().supportsRelativeMouse();
    1.44 +    }
    1.45 +
    1.46 +    /**
    1.47 +     * This method is called by SDL using JNI.
    1.48 +     */
    1.49 +    public static boolean setRelativeMouseEnabled(boolean enabled)
    1.50 +    {
    1.51 +        return SDLActivity.getMotionListener().setRelativeMouseEnabled(enabled);
    1.52 +    }
    1.53 +
    1.54 +    /**
    1.55 +     * This method is called by SDL using JNI.
    1.56 +     */
    1.57      public static boolean sendMessage(int command, int param) {
    1.58          if (mSingleton == null) {
    1.59              return false;
    1.60 @@ -1231,7 +1260,7 @@
    1.61          mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
    1.62  
    1.63          if (Build.VERSION.SDK_INT >= 12) {
    1.64 -            setOnGenericMotionListener(new SDLGenericMotionListener_API12());
    1.65 +            setOnGenericMotionListener(SDLActivity.getMotionListener());
    1.66          }
    1.67  
    1.68          // Some arbitrary defaults to avoid a potential division by zero
    1.69 @@ -1456,7 +1485,14 @@
    1.70                      mouseButton = 1;    // oh well.
    1.71                  }
    1.72              }
    1.73 -            SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
    1.74 +
    1.75 +            // We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values
    1.76 +            // if we are.  We'll leverage our existing mouse motion listener
    1.77 +            SDLGenericMotionListener_API12 motionListener = SDLActivity.getMotionListener();
    1.78 +            x = motionListener.getEventX(event);
    1.79 +            y = motionListener.getEventY(event);
    1.80 +
    1.81 +            SDLActivity.onNativeMouse(mouseButton, action, x, y, motionListener.inRelativeMode());
    1.82          } else {
    1.83              switch(action) {
    1.84                  case MotionEvent.ACTION_MOVE:
     2.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Tue May 29 08:03:44 2018 -0700
     2.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Tue May 29 11:18:01 2018 -0700
     2.3 @@ -534,14 +534,14 @@
     2.4                      case MotionEvent.ACTION_SCROLL:
     2.5                          x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
     2.6                          y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
     2.7 -                        SDLActivity.onNativeMouse(0, action, x, y);
     2.8 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
     2.9                          return true;
    2.10  
    2.11                      case MotionEvent.ACTION_HOVER_MOVE:
    2.12                          x = event.getX(0);
    2.13                          y = event.getY(0);
    2.14  
    2.15 -                        SDLActivity.onNativeMouse(0, action, x, y);
    2.16 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
    2.17                          return true;
    2.18  
    2.19                      default:
    2.20 @@ -556,5 +556,112 @@
    2.21          // Event was not managed
    2.22          return false;
    2.23      }
    2.24 +
    2.25 +    public boolean supportsRelativeMouse() {
    2.26 +        return false;
    2.27 +    }
    2.28 +
    2.29 +    public boolean inRelativeMode() {
    2.30 +        return false;
    2.31 +    }
    2.32 +
    2.33 +    public boolean setRelativeMouseEnabled(boolean enabled) {
    2.34 +        return false;
    2.35 +    }
    2.36 +
    2.37 +    public float getEventX(MotionEvent event) {
    2.38 +        return event.getX(0);
    2.39 +    }
    2.40 +
    2.41 +    public float getEventY(MotionEvent event) {
    2.42 +        return event.getY(0);
    2.43 +    }
    2.44 +
    2.45  }
    2.46  
    2.47 +class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
    2.48 +    // Generic Motion (mouse hover, joystick...) events go here
    2.49 +
    2.50 +    private boolean mRelativeModeEnabled;
    2.51 +
    2.52 +    @Override
    2.53 +    public boolean onGenericMotion(View v, MotionEvent event) {
    2.54 +        float x, y;
    2.55 +        int action;
    2.56 +
    2.57 +        switch ( event.getSource() ) {
    2.58 +            case InputDevice.SOURCE_JOYSTICK:
    2.59 +            case InputDevice.SOURCE_GAMEPAD:
    2.60 +            case InputDevice.SOURCE_DPAD:
    2.61 +                return SDLControllerManager.handleJoystickMotionEvent(event);
    2.62 +                
    2.63 +            case InputDevice.SOURCE_MOUSE:
    2.64 +                if (!SDLActivity.mSeparateMouseAndTouch) {
    2.65 +                    break;
    2.66 +                }
    2.67 +                action = event.getActionMasked();
    2.68 +                switch (action) {
    2.69 +                    case MotionEvent.ACTION_SCROLL:
    2.70 +                        x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
    2.71 +                        y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
    2.72 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
    2.73 +                        return true;
    2.74 +
    2.75 +                    case MotionEvent.ACTION_HOVER_MOVE:
    2.76 +                        if (mRelativeModeEnabled) {
    2.77 +                            x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
    2.78 +                            y = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
    2.79 +                        }
    2.80 +                        else {
    2.81 +                            x = event.getX(0);
    2.82 +                            y = event.getY(0);
    2.83 +                        }
    2.84 +
    2.85 +                        SDLActivity.onNativeMouse(0, action, x, y, mRelativeModeEnabled);
    2.86 +                        return true;
    2.87 +
    2.88 +                    default:
    2.89 +                        break;
    2.90 +                }
    2.91 +                break;
    2.92 +
    2.93 +            default:
    2.94 +                break;
    2.95 +        }
    2.96 +
    2.97 +        // Event was not managed
    2.98 +        return false;
    2.99 +    }
   2.100 +
   2.101 +    public boolean supportsRelativeMouse() {
   2.102 +        return true;
   2.103 +    }
   2.104 +
   2.105 +    public boolean inRelativeMode() {
   2.106 +        return mRelativeModeEnabled;
   2.107 +    }
   2.108 +
   2.109 +    public boolean setRelativeMouseEnabled(boolean enabled) {
   2.110 +        mRelativeModeEnabled = enabled;
   2.111 +        return true;
   2.112 +    }
   2.113 +
   2.114 +    public float getEventX(MotionEvent event) {
   2.115 +        if (mRelativeModeEnabled) {
   2.116 +            return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
   2.117 +        }
   2.118 +        else {
   2.119 +            return event.getX(0);
   2.120 +        }
   2.121 +    }
   2.122 +
   2.123 +    public float getEventY(MotionEvent event) {
   2.124 +        if (mRelativeModeEnabled) {
   2.125 +            return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
   2.126 +        }
   2.127 +        else {
   2.128 +            return event.getY(0);
   2.129 +        }
   2.130 +    }
   2.131 +}
   2.132 +