mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-07-09 10:49:41 +00:00
Android: decouple JNI setup from unused subsystems
Query the natively compiled-in subsystems at runtime so the Java side only registers and initializes the managers that exist, fixing UnsatisfiedLinkError when SDL is built with a subsystem disabled (e.g. -DSDL_AUDIO_DISABLED). - Add SDL.setupJNI(int subsystems) plus SDL_INIT_* Java constants; SDLActivity passes an overridable getInitSubsystems() mask so custom activities can skip Java-side setup for unused subsystems. - Distinguish compiled from requested subsystems: JNI registration follows nativeGetCompiledSubsystems(), while manager initialization and surface/layout creation follow the requested-and-compiled mask. - Gate HIDDeviceManager.acquire() (USB/BLE device scanning) on a new nativeIsHIDAPIEnabled() query so HIDAPI-less builds never touch it. - Gate SDLControllerManager.initializeDeviceListener() and the joystick key-event path on the controller subsystem; gate the clipboard handler on video, mirroring the native guards. - Guard the SDLControllerManager JNI bindings with SDL_ANDROID_NEED_CONTROLLER_MANAGER (joystick or haptic enabled). - Skip layout updates in ShowTextInputTask when no layout exists (video disabled). - Reorganize SDL_android.h/.c into guarded per-subsystem groups with matching ordering.
This commit is contained in:
committed by
Sam Lantinga
parent
9961fb80a7
commit
2919e1899f
@@ -22,23 +22,29 @@ public class SDL {
|
||||
public static final int SDL_INIT_EVERYTHING = SDL_INIT_AUDIO | SDL_INIT_VIDEO |
|
||||
SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_SENSOR | SDL_INIT_CAMERA;
|
||||
|
||||
// SDLControllerManager backs all three of these, so it is set up when any are present.
|
||||
private static final int SDL_INIT_CONTROLLER = SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC;
|
||||
|
||||
private static int mInitializedSubsystems = SDL_INIT_EVERYTHING;
|
||||
private static int mCompiledSubsystems = SDL_INIT_EVERYTHING;
|
||||
|
||||
static public void setupJNI() {
|
||||
setupJNI(SDL_INIT_EVERYTHING);
|
||||
}
|
||||
|
||||
// Mask must match the native build's SDL_*_DISABLED flags: dropping SDL_INIT_AUDIO when the lib was built with audio stalls checkJNIReady() and SDL_SetMainReady() never fires.
|
||||
static public void setupJNI(int subsystems) {
|
||||
mInitializedSubsystems = subsystems;
|
||||
|
||||
SDLActivity.nativeSetupJNI();
|
||||
|
||||
if ((subsystems & SDL_INIT_AUDIO) != 0) {
|
||||
mCompiledSubsystems = SDLActivity.nativeGetCompiledSubsystems();
|
||||
mInitializedSubsystems = (subsystems & mCompiledSubsystems);
|
||||
|
||||
if (isSubsystemCompiled(SDL_INIT_AUDIO)) {
|
||||
SDLAudioManager.nativeSetupJNI();
|
||||
}
|
||||
|
||||
SDLControllerManager.nativeSetupJNI();
|
||||
if (isSubsystemCompiled(SDL_INIT_CONTROLLER)) {
|
||||
SDLControllerManager.nativeSetupJNI();
|
||||
}
|
||||
}
|
||||
|
||||
static public void initialize() {
|
||||
@@ -50,16 +56,30 @@ public class SDL {
|
||||
|
||||
SDLActivity.initialize();
|
||||
|
||||
if ((subsystems & SDL_INIT_AUDIO) != 0) {
|
||||
if (isSubsystemCompiled(SDL_INIT_AUDIO)) {
|
||||
SDLAudioManager.initialize();
|
||||
}
|
||||
|
||||
SDLControllerManager.initialize();
|
||||
if (isSubsystemCompiled(SDL_INIT_CONTROLLER)) {
|
||||
SDLControllerManager.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isSubsystemInitialized(int subsystem) {
|
||||
return (mInitializedSubsystems & subsystem) != 0;
|
||||
}
|
||||
|
||||
static boolean isSubsystemCompiled(int subsystem) {
|
||||
return (mCompiledSubsystems & subsystem) != 0;
|
||||
}
|
||||
|
||||
static boolean isControllerManagerReady() {
|
||||
return isSubsystemInitialized(SDL_INIT_CONTROLLER);
|
||||
}
|
||||
|
||||
// This function stores the current activity (SDL or not)
|
||||
static public void setContext(Activity context) {
|
||||
if ((mInitializedSubsystems & SDL_INIT_AUDIO) != 0) {
|
||||
if (isSubsystemCompiled(SDL_INIT_AUDIO)) {
|
||||
SDLAudioManager.setContext(context);
|
||||
}
|
||||
mContext = context;
|
||||
|
||||
@@ -337,6 +337,20 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the SDL_INIT_* subsystems this activity should set up on the Java side.
|
||||
* It can be overridden to skip the surface/layout creation, device listener and input event
|
||||
* routing for unused subsystems. Manager JNI setup always follows the subsystems compiled
|
||||
* into the native library, regardless of this mask. The native app must not SDL_Init() a
|
||||
* subsystem excluded here: it would initialize without Java-side events (no window surface,
|
||||
* no controller hotplug or input). Called from onCreate(); overrides must not depend on
|
||||
* state the subclass assigns after super.onCreate().
|
||||
* @return mask of SDL.SDL_INIT_* values.
|
||||
*/
|
||||
protected int getInitSubsystems() {
|
||||
return SDL.SDL_INIT_EVERYTHING;
|
||||
}
|
||||
|
||||
public static void initialize() {
|
||||
// The static nature of the singleton and Android quirkyness force us to initialize everything here
|
||||
// Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
|
||||
@@ -458,7 +472,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
|
||||
// Set up JNI
|
||||
SDL.setupJNI();
|
||||
SDL.setupJNI(getInitSubsystems());
|
||||
|
||||
// Initialize state
|
||||
SDL.initialize();
|
||||
@@ -467,22 +481,30 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mSingleton = this;
|
||||
SDL.setContext(this);
|
||||
|
||||
SDLControllerManager.initializeDeviceListener();
|
||||
if (SDL.isControllerManagerReady()) {
|
||||
SDLControllerManager.initializeDeviceListener();
|
||||
}
|
||||
|
||||
mClipboardHandler = new SDLClipboardHandler();
|
||||
if (SDL.isSubsystemCompiled(SDL.SDL_INIT_VIDEO)) {
|
||||
mClipboardHandler = new SDLClipboardHandler();
|
||||
}
|
||||
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
if (nativeIsHIDAPIEnabled()) {
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
}
|
||||
|
||||
// Set up the surface
|
||||
mSurface = createSDLSurface(this);
|
||||
if (SDL.isSubsystemInitialized(SDL.SDL_INIT_VIDEO)) {
|
||||
mSurface = createSDLSurface(this);
|
||||
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mSurface);
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mSurface);
|
||||
|
||||
// Get our current screen orientation and pass it down.
|
||||
SDLActivity.nativeSetNaturalOrientation(SDLActivity.getNaturalOrientation());
|
||||
mCurrentRotation = SDLActivity.getCurrentRotation();
|
||||
SDLActivity.onNativeRotationChanged(mCurrentRotation);
|
||||
// Get our current screen orientation and pass it down.
|
||||
SDLActivity.nativeSetNaturalOrientation(SDLActivity.getNaturalOrientation());
|
||||
mCurrentRotation = SDLActivity.getCurrentRotation();
|
||||
SDLActivity.onNativeRotationChanged(mCurrentRotation);
|
||||
}
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
@@ -502,19 +524,22 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
break;
|
||||
}
|
||||
|
||||
setContentView(mLayout);
|
||||
|
||||
setWindowStyle(false);
|
||||
if (mLayout != null) {
|
||||
setContentView(mLayout);
|
||||
setWindowStyle(false);
|
||||
}
|
||||
|
||||
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this);
|
||||
|
||||
// Get filename from "Open with" of another application
|
||||
Intent intent = getIntent();
|
||||
if (intent != null && intent.getData() != null) {
|
||||
String filename = intent.getData().getPath();
|
||||
if (filename != null) {
|
||||
Log.v(TAG, "Got filename: " + filename);
|
||||
SDLActivity.onNativeDropFile(filename);
|
||||
if (SDL.isSubsystemInitialized(SDL.SDL_INIT_VIDEO)) {
|
||||
Intent intent = getIntent();
|
||||
if (intent != null && intent.getData() != null) {
|
||||
String filename = intent.getData().getPath();
|
||||
if (filename != null) {
|
||||
Log.v(TAG, "Got filename: " + filename);
|
||||
SDLActivity.onNativeDropFile(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -886,21 +911,27 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
// Try a transition to resumed state
|
||||
if (mNextNativeState == NativeState.RESUMED) {
|
||||
if (mSurface.mIsSurfaceReady && (mHasFocus || mHasMultiWindow) && mIsResumedCalled) {
|
||||
boolean readyToRun = (mSurface == null) ? mIsResumedCalled
|
||||
: (mSurface.mIsSurfaceReady && (mHasFocus || mHasMultiWindow) && mIsResumedCalled);
|
||||
if (readyToRun) {
|
||||
if (mSDLThread == null) {
|
||||
// This is the entry point to the C app.
|
||||
// Start up the C app thread and enable sensor input for the first time
|
||||
// FIXME: Why aren't we enabling sensor input at start?
|
||||
|
||||
mSDLThread = new Thread(new SDLMain(), "SDLThread");
|
||||
mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||
if (mSurface != null) {
|
||||
mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||
}
|
||||
mSDLThread.start();
|
||||
|
||||
// No nativeResume(), don't signal Android_ResumeSem
|
||||
} else {
|
||||
nativeResume();
|
||||
}
|
||||
mSurface.handleResume();
|
||||
if (mSurface != null) {
|
||||
mSurface.handleResume();
|
||||
}
|
||||
|
||||
mCurrentNativeState = mNextNativeState;
|
||||
}
|
||||
@@ -1058,7 +1089,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
display.getRealMetrics(realMetrics);
|
||||
|
||||
boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) &&
|
||||
boolean bFullscreenLayout = (mSurface != null) &&
|
||||
((realMetrics.widthPixels == mSurface.getWidth()) &&
|
||||
(realMetrics.heightPixels == mSurface.getHeight()));
|
||||
|
||||
if ((Integer) data == 1) {
|
||||
@@ -1102,6 +1134,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// C functions we call
|
||||
public static native String nativeGetVersion();
|
||||
public static native void nativeSetupJNI();
|
||||
public static native int nativeGetCompiledSubsystems();
|
||||
public static native boolean nativeIsHIDAPIEnabled();
|
||||
public static native void nativeInitMainThread();
|
||||
public static native void nativeCleanupMainThread();
|
||||
public static native int nativeRunMain(String library, String function, Object arguments);
|
||||
@@ -1486,6 +1520,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLayout == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING);
|
||||
params.leftMargin = x;
|
||||
params.topMargin = y;
|
||||
@@ -1515,6 +1553,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean showTextInput(int input_type, int x, int y, int w, int h) {
|
||||
if (mLayout == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer the task to the main thread as a Runnable
|
||||
return mSingleton.commandHandler.post(new ShowTextInputTask(input_type, x, y, w, h));
|
||||
}
|
||||
@@ -1553,7 +1595,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
|
||||
// SOURCE_JOYSTICK, while its key events arrive from the keyboard source
|
||||
// So, retrieve the device itself and check all of its sources
|
||||
if (SDLControllerManager.isDeviceSDLJoystick(device)) {
|
||||
if (SDL.isControllerManagerReady() && SDLControllerManager.isDeviceSDLJoystick(device)) {
|
||||
// Note that we process events with specific key codes here
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (SDLControllerManager.onNativePadDown(deviceId, keyCode, event.getScanCode())) {
|
||||
|
||||
@@ -60,7 +60,7 @@ public class SDLControllerManager
|
||||
mJoystickHandler = new SDLJoystickHandler();
|
||||
}
|
||||
|
||||
if (mHapticHandler == null) {
|
||||
if (mHapticHandler == null && SDL.isSubsystemCompiled(SDL.SDL_INIT_HAPTIC)) {
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
|
||||
mHapticHandler = new SDLHapticHandler_API31();
|
||||
} else if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
@@ -90,7 +90,7 @@ public class SDLControllerManager
|
||||
|
||||
// Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
|
||||
static public boolean handleJoystickMotionEvent(MotionEvent event) {
|
||||
return mJoystickHandler.handleMotionEvent(event);
|
||||
return mJoystickHandler != null && mJoystickHandler.handleMotionEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,21 +118,27 @@ public class SDLControllerManager
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
static void detectHapticDevices() {
|
||||
mHapticHandler.detectHapticDevices();
|
||||
if (mHapticHandler != null) {
|
||||
mHapticHandler.detectHapticDevices();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
static void hapticRun(int device_id, float intensity, int length) {
|
||||
mHapticHandler.run(device_id, intensity, length);
|
||||
if (mHapticHandler != null) {
|
||||
mHapticHandler.run(device_id, intensity, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
static void hapticRumble(int device_id, float low_frequency_intensity, float high_frequency_intensity, int length) {
|
||||
mHapticHandler.rumble(device_id, low_frequency_intensity, high_frequency_intensity, length);
|
||||
if (mHapticHandler != null) {
|
||||
mHapticHandler.rumble(device_id, low_frequency_intensity, high_frequency_intensity, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +146,9 @@ public class SDLControllerManager
|
||||
*/
|
||||
static void hapticStop(int device_id)
|
||||
{
|
||||
mHapticHandler.stop(device_id);
|
||||
if (mHapticHandler != null) {
|
||||
mHapticHandler.stop(device_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a given device is considered a possible SDL joystick
|
||||
@@ -977,10 +985,13 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
}
|
||||
|
||||
if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
|
||||
if (enabled) {
|
||||
SDLActivity.getContentView().requestPointerCapture();
|
||||
} else {
|
||||
SDLActivity.getContentView().releasePointerCapture();
|
||||
View contentView = SDLActivity.getContentView();
|
||||
if (contentView != null) {
|
||||
if (enabled) {
|
||||
contentView.requestPointerCapture();
|
||||
} else {
|
||||
contentView.releasePointerCapture();
|
||||
}
|
||||
}
|
||||
mRelativeModeEnabled = enabled;
|
||||
return true;
|
||||
@@ -998,7 +1009,10 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
}
|
||||
|
||||
if (mRelativeModeEnabled && !SDLActivity.isDeXMode()) {
|
||||
SDLActivity.getContentView().requestPointerCapture();
|
||||
View contentView = SDLActivity.getContentView();
|
||||
if (contentView != null) {
|
||||
contentView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,17 +30,17 @@ extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#endif
|
||||
|
||||
#ifndef SDL_AUDIO_DISABLED
|
||||
// Audio support
|
||||
#include "../../audio/SDL_sysaudio.h"
|
||||
|
||||
// this appears to be broken right now (on Android, not SDL, I think...?).
|
||||
#define ALLOW_MULTIPLE_ANDROID_AUDIO_DEVICES 0
|
||||
#endif
|
||||
|
||||
void Android_StartAudioHotplug(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording);
|
||||
void Android_StopAudioHotplug(void);
|
||||
extern void Android_AudioThreadInit(SDL_AudioDevice *device);
|
||||
#endif // !SDL_AUDIO_DISABLED
|
||||
|
||||
// Life cycle
|
||||
typedef enum
|
||||
@@ -62,6 +62,9 @@ void Android_UnlockActivityMutex(void);
|
||||
void Android_SetAllowRecreateActivity(bool enabled);
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
// Interface from the SDL library into the Android Java activity
|
||||
extern void Android_JNI_SetActivityTitle(const char *title);
|
||||
extern void Android_JNI_SetWindowStyle(bool fullscreen);
|
||||
@@ -71,24 +74,34 @@ extern bool Android_JNI_ShouldMinimizeOnFocusLoss(void);
|
||||
|
||||
extern void Android_JNI_ShowScreenKeyboard(int input_type, SDL_Rect *inputRect);
|
||||
extern void Android_JNI_HideScreenKeyboard(void);
|
||||
bool Android_JNI_SuspendScreenSaver(bool suspend);
|
||||
extern ANativeWindow *Android_JNI_GetNativeWindow(void);
|
||||
|
||||
#endif // !SDL_VIDEO_DISABLED
|
||||
|
||||
// Kept outside the video guard for the camera driver; stays SDL_ORIENTATION_UNKNOWN when video is disabled (only the video Java layer updates it).
|
||||
extern SDL_DisplayOrientation Android_JNI_GetDisplayNaturalOrientation(void);
|
||||
// Also used by the camera subsystem, which is safe because camera requires video.
|
||||
extern SDL_DisplayOrientation Android_JNI_GetDisplayCurrentOrientation(void);
|
||||
|
||||
#ifndef SDL_AUDIO_DISABLED
|
||||
// Audio support
|
||||
void Android_StartAudioHotplug(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording);
|
||||
void Android_StopAudioHotplug(void);
|
||||
extern void Android_AudioThreadInit(SDL_AudioDevice *device);
|
||||
#endif // !SDL_AUDIO_DISABLED
|
||||
// Clipboard support
|
||||
bool Android_JNI_SetClipboardText(const char *text);
|
||||
char *Android_JNI_GetClipboardText(void);
|
||||
bool Android_JNI_HasClipboardText(void);
|
||||
|
||||
// Detecting device type
|
||||
extern bool Android_IsDeXMode(void);
|
||||
extern bool Android_IsChromebook(void);
|
||||
// Touch support
|
||||
void Android_JNI_InitTouch(void);
|
||||
|
||||
// Cursor support
|
||||
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y);
|
||||
void Android_JNI_DestroyCustomCursor(int cursorID);
|
||||
bool Android_JNI_SetCustomCursor(int cursorID);
|
||||
bool Android_JNI_SetSystemCursor(int cursorID);
|
||||
|
||||
// Relative mouse support
|
||||
bool Android_JNI_SupportsRelativeMouse(void);
|
||||
bool Android_JNI_SetRelativeMouseEnabled(bool enabled);
|
||||
|
||||
// MessageBox
|
||||
bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
|
||||
#endif // !SDL_VIDEO_DISABLED
|
||||
|
||||
bool Android_JNI_FileOpen(void **puserdata, const char *fileName, const char *mode);
|
||||
Sint64 Android_JNI_FileSize(void *userdata);
|
||||
@@ -103,34 +116,25 @@ bool Android_JNI_GetAssetPathInfo(const char *path, SDL_PathInfo *info);
|
||||
void Android_JNI_GetManifestEnvironmentVariables(void);
|
||||
int Android_JNI_OpenFileDescriptor(const char *uri, const char *mode);
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
// Clipboard support
|
||||
bool Android_JNI_SetClipboardText(const char *text);
|
||||
char *Android_JNI_GetClipboardText(void);
|
||||
bool Android_JNI_HasClipboardText(void);
|
||||
#endif // !SDL_VIDEO_DISABLED
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
// Power support
|
||||
int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent);
|
||||
#endif // !SDL_POWER_DISABLED
|
||||
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
// Joystick support
|
||||
void Android_JNI_DetectDevices(void);
|
||||
void Android_JNI_JoystickSetLED(int device_id, int red, int green, int blue);
|
||||
void Android_JNI_JoystickSetSensorsEnabled(int device_id, bool enabled);
|
||||
#endif // !SDL_JOYSTICK_DISABLED
|
||||
|
||||
#ifndef SDL_HAPTIC_DISABLED
|
||||
// Haptic support
|
||||
void Android_JNI_DetectHapticDevices(void);
|
||||
void Android_JNI_HapticRun(int device_id, float intensity, int length);
|
||||
void Android_JNI_HapticRumble(int device_id, float low_frequency_intensity, float high_frequency_intensity, int length);
|
||||
void Android_JNI_HapticStop(int device_id);
|
||||
|
||||
// Video
|
||||
bool Android_JNI_SuspendScreenSaver(bool suspend);
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
// Touch support
|
||||
void Android_JNI_InitTouch(void);
|
||||
#endif // !SDL_VIDEO_DISABLED
|
||||
#endif // !SDL_HAPTIC_DISABLED
|
||||
|
||||
// Threads
|
||||
#include <jni.h>
|
||||
@@ -143,21 +147,6 @@ bool Android_JNI_GetLocale(char *buf, size_t buflen);
|
||||
// Generic messages
|
||||
bool Android_JNI_SendMessage(int command, int param);
|
||||
|
||||
// MessageBox
|
||||
bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
// Cursor support
|
||||
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y);
|
||||
void Android_JNI_DestroyCustomCursor(int cursorID);
|
||||
bool Android_JNI_SetCustomCursor(int cursorID);
|
||||
bool Android_JNI_SetSystemCursor(int cursorID);
|
||||
|
||||
// Relative mouse support
|
||||
bool Android_JNI_SupportsRelativeMouse(void);
|
||||
bool Android_JNI_SetRelativeMouseEnabled(bool enabled);
|
||||
#endif // !SDL_VIDEO_DISABLED
|
||||
|
||||
// Show toast notification
|
||||
bool Android_JNI_ShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset);
|
||||
|
||||
@@ -171,10 +160,11 @@ SDL_FormFactor SDL_GetAndroidDeviceFormFactor(void);
|
||||
|
||||
char *SDL_GetAndroidPackageName(void); // this is a SDL_malloc'd string the caller will own.
|
||||
|
||||
#ifndef SDL_DIALOG_DISABLED
|
||||
// File Dialogs
|
||||
bool Android_JNI_ShowFileDialog(SDL_DialogFileCallback callback, void *userdata,
|
||||
const SDL_DialogFileFilter *filters, int nfilters, SDL_FileDialogType type,
|
||||
bool multiple, const char *initialPath);
|
||||
bool Android_JNI_ShowFileDialog(SDL_DialogFileCallback callback, void *userdata, const SDL_DialogFileFilter *filters,
|
||||
int nfilters, SDL_FileDialogType type, bool multiple, const char *initialPath);
|
||||
#endif // !SDL_DIALOG_DISABLED
|
||||
|
||||
// Ends C function definitions when using C++
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -675,6 +675,7 @@ static bool ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
|
||||
static bool ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
#ifndef SDL_HAPTIC_DISABLED
|
||||
SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
|
||||
if (!item) {
|
||||
return SDL_SetError("Rumble failed, device disconnected");
|
||||
@@ -687,6 +688,9 @@ static bool ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_
|
||||
float high_frequency_intensity = (float)high_frequency_rumble / SDL_MAX_UINT16;
|
||||
Android_JNI_HapticRumble(item->device_id, low_frequency_intensity, high_frequency_intensity, 5000);
|
||||
return true;
|
||||
#else
|
||||
return SDL_Unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
|
||||
Reference in New Issue
Block a user