Added support for external mouse in Samsung DeX mode
authorSam Lantinga <slouken@libsdl.org>
Mon, 18 Jun 2018 13:14:02 -0700
changeset 120243688283680b1
parent 12023 842dd960769e
child 12025 39a92b19f99e
Added support for external mouse in Samsung DeX mode
relative mode doesn't work, but absolute coordinates are functional
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
include/SDL_system.h
src/core/android/SDL_android.c
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
src/events/SDL_mouse.c
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Mon Jun 18 13:14:00 2018 -0700
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Mon Jun 18 13:14:02 2018 -0700
     1.3 @@ -670,6 +670,17 @@
     1.4       */
     1.5      public static boolean supportsRelativeMouse()
     1.6      {
     1.7 +        // ChromeOS doesn't provide relative mouse motion via the Android 7 APIs
     1.8 +        if (isChromebook()) {
     1.9 +            return false;
    1.10 +        }
    1.11 +
    1.12 +        // Samsung DeX mode doesn't support relative mice properly under Android 7 APIs,
    1.13 +        // and simply returns no data under Android 8 APIs.
    1.14 +        if (isDeXMode()) {
    1.15 +            return false;
    1.16 +        }
    1.17 +
    1.18          return SDLActivity.getMotionListener().supportsRelativeMouse();
    1.19      }
    1.20  
    1.21 @@ -678,6 +689,10 @@
    1.22       */
    1.23      public static boolean setRelativeMouseEnabled(boolean enabled)
    1.24      {
    1.25 +        if (enabled && !supportsRelativeMouse()) {
    1.26 +            return false;
    1.27 +        }
    1.28 +
    1.29          return SDLActivity.getMotionListener().setRelativeMouseEnabled(enabled);
    1.30      }
    1.31  
    1.32 @@ -716,6 +731,23 @@
    1.33      /**
    1.34       * This method is called by SDL using JNI.
    1.35       */
    1.36 +    public static boolean isDeXMode() {
    1.37 +        if (Build.VERSION.SDK_INT < 24) {
    1.38 +            return false;
    1.39 +        }
    1.40 +        try {
    1.41 +            final Configuration config = getContext().getResources().getConfiguration();
    1.42 +            final Class configClass = config.getClass();
    1.43 +            return configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
    1.44 +                    == configClass.getField("semDesktopModeEnabled").getInt(config);
    1.45 +        } catch(Exception ignored) {
    1.46 +            return false;
    1.47 +        }
    1.48 +    }
    1.49 +
    1.50 +    /**
    1.51 +     * This method is called by SDL using JNI.
    1.52 +     */
    1.53      public static DisplayMetrics getDisplayDPI() {
    1.54          return getContext().getResources().getDisplayMetrics();
    1.55      }
    1.56 @@ -1313,7 +1345,7 @@
    1.57              setOnGenericMotionListener(SDLActivity.getMotionListener());
    1.58          }
    1.59  
    1.60 -        if (Build.VERSION.SDK_INT >= 26) {
    1.61 +        if ((Build.VERSION.SDK_INT >= 26) && !SDLActivity.isDeXMode()) {
    1.62              setOnCapturedPointerListener(new SDLCapturedPointerListener_API26());
    1.63          }
    1.64  
    1.65 @@ -1544,7 +1576,8 @@
    1.66          float x,y,p;
    1.67  
    1.68          // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
    1.69 -        if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
    1.70 +        // 12290 = Samsung DeX mode desktop mouse
    1.71 +        if ((event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == 12290) && SDLActivity.mSeparateMouseAndTouch) {
    1.72              if (Build.VERSION.SDK_INT < 14) {
    1.73                  mouseButton = 1; // all mouse buttons are the left button
    1.74              } else {
     2.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Mon Jun 18 13:14:00 2018 -0700
     2.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Mon Jun 18 13:14:02 2018 -0700
     2.3 @@ -692,6 +692,7 @@
     2.4                  return SDLControllerManager.handleJoystickMotionEvent(event);
     2.5                  
     2.6              case InputDevice.SOURCE_MOUSE:
     2.7 +            case 12290: // DeX desktop mouse cursor is a separate non-standard input type.
     2.8                  if (!SDLActivity.mSeparateMouseAndTouch) {
     2.9                      break;
    2.10                  }
     3.1 --- a/include/SDL_system.h	Mon Jun 18 13:14:00 2018 -0700
     3.2 +++ b/include/SDL_system.h	Mon Jun 18 13:14:02 2018 -0700
     3.3 @@ -131,6 +131,11 @@
     3.4  extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);
     3.5  
     3.6  /**
     3.7 +  \brief Return true is the application is running on a Samsung DeX docking station
     3.8 + */
     3.9 +extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
    3.10 +
    3.11 +/**
    3.12     See the official Android developer guide for more information:
    3.13     http://developer.android.com/guide/topics/data/data-storage.html
    3.14  */
     4.1 --- a/src/core/android/SDL_android.c	Mon Jun 18 13:14:00 2018 -0700
     4.2 +++ b/src/core/android/SDL_android.c	Mon Jun 18 13:14:02 2018 -0700
     4.3 @@ -215,6 +215,7 @@
     4.4  static jmethodID midGetContext;
     4.5  static jmethodID midIsAndroidTV;
     4.6  static jmethodID midIsChromebook;
     4.7 +static jmethodID midIsDeXMode;
     4.8  static jmethodID midInputGetInputDeviceIds;
     4.9  static jmethodID midSendMessage;
    4.10  static jmethodID midShowTextInput;
    4.11 @@ -320,6 +321,8 @@
    4.12                                  "isAndroidTV","()Z");
    4.13      midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.14                                  "isChromebook", "()Z");
    4.15 +    midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.16 +                                "isDeXMode", "()Z");
    4.17      midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.18                                  "inputGetInputDeviceIds", "(I)[I");
    4.19      midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.20 @@ -354,7 +357,7 @@
    4.21         !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
    4.22         !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
    4.23         !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
    4.24 -       !midIsChromebook) {
    4.25 +       !midIsChromebook || !midIsDeXMode) {
    4.26          __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
    4.27      }
    4.28  
    4.29 @@ -2036,6 +2039,12 @@
    4.30      return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);
    4.31  }
    4.32  
    4.33 +SDL_bool SDL_IsDeXMode(void)
    4.34 +{
    4.35 +    JNIEnv *env = Android_JNI_GetEnv();
    4.36 +    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
    4.37 +}
    4.38 +
    4.39  const char * SDL_AndroidGetInternalStoragePath(void)
    4.40  {
    4.41      static char *s_AndroidInternalFilesPath = NULL;
     5.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Mon Jun 18 13:14:00 2018 -0700
     5.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Mon Jun 18 13:14:02 2018 -0700
     5.3 @@ -673,3 +673,4 @@
     5.4  #define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL
     5.5  #define SDL_HasAVX512F SDL_HasAVX512F_REAL
     5.6  #define SDL_IsChromebook SDL_IsChromebook_REAL
     5.7 +#define SDL_IsDeXMode SDL_IsDeXMode_REAL
     6.1 --- a/src/dynapi/SDL_dynapi_procs.h	Mon Jun 18 13:14:00 2018 -0700
     6.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Mon Jun 18 13:14:02 2018 -0700
     6.3 @@ -714,4 +714,5 @@
     6.4  SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX512F,(void),(),return)
     6.5  #ifdef __ANDROID__
     6.6  SDL_DYNAPI_PROC(SDL_bool,SDL_IsChromebook,(void),(),return)
     6.7 +SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return)
     6.8  #endif
     7.1 --- a/src/events/SDL_mouse.c	Mon Jun 18 13:14:00 2018 -0700
     7.2 +++ b/src/events/SDL_mouse.c	Mon Jun 18 13:14:02 2018 -0700
     7.3 @@ -721,6 +721,9 @@
     7.4      } else if (mouse->SetRelativeMouseMode(enabled) < 0) {
     7.5          if (enabled) {
     7.6              /* Fall back to warp mode if native relative mode failed */
     7.7 +            if (!mouse->WarpMouse) {
     7.8 +                return SDL_SetError("No relative mode implementation available");
     7.9 +            }
    7.10              mouse->relative_mode_warp = SDL_TRUE;
    7.11          }
    7.12      }