Skip to content

Commit

Permalink
Added support for external mouse in Samsung DeX mode
Browse files Browse the repository at this point in the history
relative mode doesn't work, but absolute coordinates are functional
  • Loading branch information
slouken committed Jun 18, 2018
1 parent f1d8f5f commit a515853
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 3 deletions.
37 changes: 35 additions & 2 deletions android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
Expand Up @@ -670,6 +670,17 @@ public static boolean isScreenKeyboardShown()
*/
public static boolean supportsRelativeMouse()
{
// ChromeOS doesn't provide relative mouse motion via the Android 7 APIs
if (isChromebook()) {
return false;
}

// Samsung DeX mode doesn't support relative mice properly under Android 7 APIs,
// and simply returns no data under Android 8 APIs.
if (isDeXMode()) {
return false;
}

return SDLActivity.getMotionListener().supportsRelativeMouse();
}

Expand All @@ -678,6 +689,10 @@ public static boolean supportsRelativeMouse()
*/
public static boolean setRelativeMouseEnabled(boolean enabled)
{
if (enabled && !supportsRelativeMouse()) {
return false;
}

return SDLActivity.getMotionListener().setRelativeMouseEnabled(enabled);
}

Expand Down Expand Up @@ -713,6 +728,23 @@ public static boolean isChromebook() {
return getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management");
}

/**
* This method is called by SDL using JNI.
*/
public static boolean isDeXMode() {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
try {
final Configuration config = getContext().getResources().getConfiguration();
final Class configClass = config.getClass();
return configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
== configClass.getField("semDesktopModeEnabled").getInt(config);
} catch(Exception ignored) {
return false;
}
}

/**
* This method is called by SDL using JNI.
*/
Expand Down Expand Up @@ -1313,7 +1345,7 @@ public SDLSurface(Context context) {
setOnGenericMotionListener(SDLActivity.getMotionListener());
}

if (Build.VERSION.SDK_INT >= 26) {
if ((Build.VERSION.SDK_INT >= 26) && !SDLActivity.isDeXMode()) {
setOnCapturedPointerListener(new SDLCapturedPointerListener_API26());
}

Expand Down Expand Up @@ -1544,7 +1576,8 @@ public boolean onTouch(View v, MotionEvent event) {
float x,y,p;

// !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
// 12290 = Samsung DeX mode desktop mouse
if ((event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == 12290) && SDLActivity.mSeparateMouseAndTouch) {
if (Build.VERSION.SDK_INT < 14) {
mouseButton = 1; // all mouse buttons are the left button
} else {
Expand Down
Expand Up @@ -692,6 +692,7 @@ public boolean onGenericMotion(View v, MotionEvent event) {
return SDLControllerManager.handleJoystickMotionEvent(event);

case InputDevice.SOURCE_MOUSE:
case 12290: // DeX desktop mouse cursor is a separate non-standard input type.
if (!SDLActivity.mSeparateMouseAndTouch) {
break;
}
Expand Down
5 changes: 5 additions & 0 deletions include/SDL_system.h
Expand Up @@ -130,6 +130,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void);
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);

/**
\brief Return true is the application is running on a Samsung DeX docking station
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);

/**
See the official Android developer guide for more information:
http://developer.android.com/guide/topics/data/data-storage.html
Expand Down
11 changes: 10 additions & 1 deletion src/core/android/SDL_android.c
Expand Up @@ -215,6 +215,7 @@ static jmethodID midSetOrientation;
static jmethodID midGetContext;
static jmethodID midIsAndroidTV;
static jmethodID midIsChromebook;
static jmethodID midIsDeXMode;
static jmethodID midInputGetInputDeviceIds;
static jmethodID midSendMessage;
static jmethodID midShowTextInput;
Expand Down Expand Up @@ -320,6 +321,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
"isAndroidTV","()Z");
midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"isChromebook", "()Z");
midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"isDeXMode", "()Z");
midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"inputGetInputDeviceIds", "(I)[I");
midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
Expand Down Expand Up @@ -354,7 +357,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
!midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
!midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
!midIsChromebook) {
!midIsChromebook || !midIsDeXMode) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
}

Expand Down Expand Up @@ -2036,6 +2039,12 @@ SDL_bool SDL_IsChromebook(void)
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);
}

SDL_bool SDL_IsDeXMode(void)
{
JNIEnv *env = Android_JNI_GetEnv();
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
}

const char * SDL_AndroidGetInternalStoragePath(void)
{
static char *s_AndroidInternalFilesPath = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -673,3 +673,4 @@
#define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL
#define SDL_HasAVX512F SDL_HasAVX512F_REAL
#define SDL_IsChromebook SDL_IsChromebook_REAL
#define SDL_IsDeXMode SDL_IsDeXMode_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -714,4 +714,5 @@ SDL_DYNAPI_PROC(int,SDL_LinuxSetThreadPriority,(Sint64 a, int b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX512F,(void),(),return)
#ifdef __ANDROID__
SDL_DYNAPI_PROC(SDL_bool,SDL_IsChromebook,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return)
#endif
3 changes: 3 additions & 0 deletions src/events/SDL_mouse.c
Expand Up @@ -721,6 +721,9 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
} else if (mouse->SetRelativeMouseMode(enabled) < 0) {
if (enabled) {
/* Fall back to warp mode if native relative mode failed */
if (!mouse->WarpMouse) {
return SDL_SetError("No relative mode implementation available");
}
mouse->relative_mode_warp = SDL_TRUE;
}
}
Expand Down

0 comments on commit a515853

Please sign in to comment.