21 #include "../../SDL_internal.h"
34 #include "keyinfotable.h"
36 #include "../../events/SDL_events_c.h"
37 #include "../../video/android/SDL_androidkeyboard.h"
38 #include "../../video/android/SDL_androidmouse.h"
39 #include "../../video/android/SDL_androidtouch.h"
40 #include "../../video/android/SDL_androidvideo.h"
41 #include "../../video/android/SDL_androidwindow.h"
42 #include "../../joystick/android/SDL_sysjoystick_c.h"
43 #include "../../haptic/android/SDL_syshaptic_c.h"
45 #include <android/log.h>
46 #include <android/configuration.h>
47 #include <android/asset_manager_jni.h>
48 #include <sys/system_properties.h>
50 #include <sys/types.h>
54 #define SDL_JAVA_PREFIX org_libsdl_app
55 #define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
56 #define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
57 #define SDL_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function)
58 #define SDL_JAVA_AUDIO_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function)
59 #define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)
60 #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)
63 #define ENCODING_PCM_8BIT 3
64 #define ENCODING_PCM_16BIT 2
65 #define ENCODING_PCM_FLOAT 4
68 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
69 JNIEnv *env, jclass cls);
71 JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(
72 JNIEnv *env, jclass cls,
73 jstring library, jstring
function, jobject
array);
75 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
76 JNIEnv *env, jclass jcls,
79 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
80 JNIEnv *env, jclass jcls,
81 jint surfaceWidth, jint surfaceHeight,
82 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate);
84 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
85 JNIEnv *env, jclass cls);
87 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(
88 JNIEnv *env, jclass jcls);
90 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
91 JNIEnv *env, jclass jcls);
93 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(
94 JNIEnv *env, jclass jcls);
96 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
97 JNIEnv *env, jclass jcls,
100 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
101 JNIEnv *env, jclass jcls,
104 JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(
105 JNIEnv *env, jclass jcls);
107 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
108 JNIEnv *env, jclass jcls);
110 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
111 JNIEnv *env, jclass jcls,
112 jint touch_device_id_in, jint pointer_finger_id_in,
113 jint
action, jfloat
x, jfloat
y, jfloat
p);
115 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
116 JNIEnv *env, jclass jcls,
119 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
120 JNIEnv *env, jclass jcls,
121 jfloat
x, jfloat
y, jfloat
z);
123 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
124 JNIEnv *env, jclass jcls);
126 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
127 JNIEnv *env, jclass cls);
129 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
130 JNIEnv *env, jclass cls);
132 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
133 JNIEnv *env, jclass cls);
135 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
136 JNIEnv *env, jclass cls);
138 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
139 JNIEnv *env, jclass cls);
141 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
142 JNIEnv *env, jclass cls);
144 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
145 JNIEnv *env, jclass cls, jboolean hasFocus);
147 JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
148 JNIEnv *env, jclass cls,
151 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
152 JNIEnv *env, jclass cls,
155 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
156 JNIEnv *env, jclass cls,
159 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
160 JNIEnv* env, jclass cls,
161 jint touchId, jstring
name);
163 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
164 JNIEnv* env, jclass cls,
165 jint requestCode, jboolean
result);
167 static JNINativeMethod SDLActivity_tab[] = {
168 {
"nativeSetupJNI",
"()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
169 {
"nativeRunMain",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
170 {
"onNativeDropFile",
"(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) },
171 {
"nativeSetScreenResolution",
"(IIIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },
172 {
"onNativeResize",
"()V", SDL_JAVA_INTERFACE(onNativeResize) },
173 {
"onNativeSurfaceCreated",
"()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) },
174 {
"onNativeSurfaceChanged",
"()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) },
175 {
"onNativeSurfaceDestroyed",
"()V", SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed) },
176 {
"onNativeKeyDown",
"(I)V", SDL_JAVA_INTERFACE(onNativeKeyDown) },
177 {
"onNativeKeyUp",
"(I)V", SDL_JAVA_INTERFACE(onNativeKeyUp) },
178 {
"onNativeSoftReturnKey",
"()Z", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) },
179 {
"onNativeKeyboardFocusLost",
"()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) },
180 {
"onNativeTouch",
"(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) },
181 {
"onNativeMouse",
"(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) },
182 {
"onNativeAccel",
"(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) },
183 {
"onNativeClipboardChanged",
"()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
184 {
"nativeLowMemory",
"()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
185 {
"onNativeLocaleChanged",
"()V", SDL_JAVA_INTERFACE(onNativeLocaleChanged) },
186 {
"nativeSendQuit",
"()V", SDL_JAVA_INTERFACE(nativeSendQuit) },
187 {
"nativeQuit",
"()V", SDL_JAVA_INTERFACE(nativeQuit) },
188 {
"nativePause",
"()V", SDL_JAVA_INTERFACE(nativePause) },
189 {
"nativeResume",
"()V", SDL_JAVA_INTERFACE(nativeResume) },
190 {
"nativeFocusChanged",
"(Z)V", SDL_JAVA_INTERFACE(nativeFocusChanged) },
191 {
"nativeGetHint",
"(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) },
192 {
"nativeSetenv",
"(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
193 {
"onNativeOrientationChanged",
"(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
194 {
"nativeAddTouch",
"(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) },
195 {
"nativePermissionResult",
"(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) }
199 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
200 JNIEnv *env, jclass cls,
201 jstring
text, jint newCursorPosition);
203 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
204 JNIEnv *env, jclass cls,
207 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
208 JNIEnv *env, jclass cls,
209 jstring
text, jint newCursorPosition);
211 static JNINativeMethod SDLInputConnection_tab[] = {
212 {
"nativeCommitText",
"(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText) },
213 {
"nativeGenerateScancodeForUnichar",
"(C)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar) },
214 {
"nativeSetComposingText",
"(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText) }
218 JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(
219 JNIEnv *env, jclass jcls);
221 static JNINativeMethod SDLAudioManager_tab[] = {
222 {
"nativeSetupJNI",
"()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }
226 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(
227 JNIEnv *env, jclass jcls);
229 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
230 JNIEnv *env, jclass jcls,
231 jint device_id, jint keycode);
233 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
234 JNIEnv *env, jclass jcls,
235 jint device_id, jint keycode);
237 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
238 JNIEnv *env, jclass jcls,
239 jint device_id, jint
axis, jfloat
value);
241 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
242 JNIEnv *env, jclass jcls,
243 jint device_id, jint hat_id, jint
x, jint
y);
245 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
246 JNIEnv *env, jclass jcls,
247 jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,
248 jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs);
250 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
251 JNIEnv *env, jclass jcls,
254 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
255 JNIEnv *env, jclass jcls,
256 jint device_id, jstring device_name);
258 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
259 JNIEnv *env, jclass jcls,
262 static JNINativeMethod SDLControllerManager_tab[] = {
263 {
"nativeSetupJNI",
"()I", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) },
264 {
"onNativePadDown",
"(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) },
265 {
"onNativePadUp",
"(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },
266 {
"onNativeJoy",
"(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },
267 {
"onNativeHat",
"(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) },
268 {
"nativeAddJoystick",
"(ILjava/lang/String;Ljava/lang/String;IIZIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
269 {
"nativeRemoveJoystick",
"(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) },
270 {
"nativeAddHaptic",
"(ILjava/lang/String;)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) },
271 {
"nativeRemoveHaptic",
"(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) }
278 static void checkJNIReady(
void);
289 static pthread_key_t mThreadKey;
290 static pthread_once_t key_once = PTHREAD_ONCE_INIT;
291 static JavaVM *mJavaVM =
NULL;
294 static jclass mActivityClass;
297 static jmethodID midClipboardGetText;
298 static jmethodID midClipboardHasText;
299 static jmethodID midClipboardSetText;
300 static jmethodID midCreateCustomCursor;
301 static jmethodID midGetContext;
302 static jmethodID midGetDisplayDPI;
303 static jmethodID midGetManifestEnvironmentVariables;
304 static jmethodID midGetNativeSurface;
305 static jmethodID midInitTouch;
306 static jmethodID midIsAndroidTV;
307 static jmethodID midIsChromebook;
308 static jmethodID midIsDeXMode;
309 static jmethodID midIsScreenKeyboardShown;
310 static jmethodID midIsTablet;
311 static jmethodID midManualBackButton;
312 static jmethodID midMinimizeWindow;
313 static jmethodID midOpenURL;
314 static jmethodID midRequestPermission;
315 static jmethodID midSendMessage;
316 static jmethodID midSetActivityTitle;
317 static jmethodID midSetCustomCursor;
318 static jmethodID midSetOrientation;
319 static jmethodID midSetRelativeMouseEnabled;
320 static jmethodID midSetSurfaceViewFormat;
321 static jmethodID midSetSystemCursor;
322 static jmethodID midSetWindowStyle;
323 static jmethodID midShouldMinimizeOnFocusLoss;
324 static jmethodID midShowTextInput;
325 static jmethodID midSupportsRelativeMouse;
328 static jclass mAudioManagerClass;
331 static jmethodID midAudioOpen;
332 static jmethodID midAudioWriteByteBuffer;
333 static jmethodID midAudioWriteShortBuffer;
334 static jmethodID midAudioWriteFloatBuffer;
335 static jmethodID midAudioClose;
336 static jmethodID midCaptureOpen;
337 static jmethodID midCaptureReadByteBuffer;
338 static jmethodID midCaptureReadShortBuffer;
339 static jmethodID midCaptureReadFloatBuffer;
340 static jmethodID midCaptureClose;
341 static jmethodID midAudioSetThreadPriority;
344 static jclass mControllerManagerClass;
347 static jmethodID midPollInputDevices;
348 static jmethodID midPollHapticDevices;
349 static jmethodID midHapticRun;
350 static jmethodID midHapticStop;
354 static float fLastAccelerometer[3];
357 static SDL_bool bHasEnvironmentVariables;
360 static SDL_bool bPermissionRequestResult;
363 static void Internal_Android_Create_AssetManager(
void);
364 static void Internal_Android_Destroy_AssetManager(
void);
365 static AAssetManager *asset_manager =
NULL;
366 static jobject javaAssetManagerRef = 0;
396 Android_JNI_SetEnv(JNIEnv *env) {
397 int status = pthread_setspecific(mThreadKey, env);
399 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed pthread_setspecific() in Android_JNI_SetEnv() (err=%d)", status);
408 JNIEnv *env = pthread_getspecific(mThreadKey);
414 if (mJavaVM ==
NULL) {
415 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed, there is no JavaVM");
421 status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env,
NULL);
423 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to attach current thread (err=%d)", status);
428 if (Android_JNI_SetEnv(env) < 0) {
443 if (mJavaVM ==
NULL) {
444 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed, there is no JavaVM");
450 status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env,
NULL);
452 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to attach current thread (err=%d)", status);
457 if (Android_JNI_SetEnv(env) < 0) {
466 Android_JNI_ThreadDestroyed(
void *
value)
469 JNIEnv *env = (JNIEnv *)
value;
471 (*mJavaVM)->DetachCurrentThread(mJavaVM);
472 Android_JNI_SetEnv(
NULL);
478 Android_JNI_CreateKey(
void)
480 int status = pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed);
482 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Error initializing mThreadKey with pthread_key_create() (err=%d)", status);
487 Android_JNI_CreateKey_once(
void)
489 int status = pthread_once(&key_once, Android_JNI_CreateKey);
491 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Error initializing mThreadKey with pthread_once() (err=%d)", status);
496 register_methods(JNIEnv *env,
const char *classname, JNINativeMethod *methods,
int nb)
498 jclass clazz = (*env)->FindClass(env, classname);
499 if (clazz ==
NULL || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) {
500 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to register methods of %s", classname);
506 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void *reserved)
511 if ((*mJavaVM)->GetEnv(mJavaVM, (
void **)&env, JNI_VERSION_1_4) != JNI_OK) {
512 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to get JNI Env");
513 return JNI_VERSION_1_4;
516 register_methods(env,
"org/libsdl/app/SDLActivity", SDLActivity_tab,
SDL_arraysize(SDLActivity_tab));
517 register_methods(env,
"org/libsdl/app/SDLInputConnection", SDLInputConnection_tab,
SDL_arraysize(SDLInputConnection_tab));
518 register_methods(env,
"org/libsdl/app/SDLAudioManager", SDLAudioManager_tab,
SDL_arraysize(SDLAudioManager_tab));
519 register_methods(env,
"org/libsdl/app/SDLControllerManager", SDLControllerManager_tab,
SDL_arraysize(SDLControllerManager_tab));
521 return JNI_VERSION_1_4;
524 void checkJNIReady(
void)
526 if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) {
535 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
537 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeSetupJNI()");
543 Android_JNI_CreateKey_once();
546 Android_JNI_SetEnv(env);
548 if (mJavaVM ==
NULL) {
549 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to found a JavaVM");
560 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_ActivityMutex mutex");
566 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_PauseSem semaphore");
571 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_ResumeSem semaphore");
574 mActivityClass = (jclass)((*env)->NewGlobalRef(env, cls));
576 midClipboardGetText = (*env)->GetStaticMethodID(env, mActivityClass,
"clipboardGetText",
"()Ljava/lang/String;");
577 midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass,
"clipboardHasText",
"()Z");
578 midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass,
"clipboardSetText",
"(Ljava/lang/String;)V");
579 midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"createCustomCursor",
"([IIIII)I");
580 midGetContext = (*env)->GetStaticMethodID(env, mActivityClass,
"getContext",
"()Landroid/content/Context;");
581 midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass,
"getDisplayDPI",
"()Landroid/util/DisplayMetrics;");
582 midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass,
"getManifestEnvironmentVariables",
"()Z");
583 midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass,
"getNativeSurface",
"()Landroid/view/Surface;");
584 midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass,
"initTouch",
"()V");
585 midIsAndroidTV = (*env)->GetStaticMethodID(env, mActivityClass,
"isAndroidTV",
"()Z");
586 midIsChromebook = (*env)->GetStaticMethodID(env, mActivityClass,
"isChromebook",
"()Z");
587 midIsDeXMode = (*env)->GetStaticMethodID(env, mActivityClass,
"isDeXMode",
"()Z");
588 midIsScreenKeyboardShown = (*env)->GetStaticMethodID(env, mActivityClass,
"isScreenKeyboardShown",
"()Z");
589 midIsTablet = (*env)->GetStaticMethodID(env, mActivityClass,
"isTablet",
"()Z");
590 midManualBackButton = (*env)->GetStaticMethodID(env, mActivityClass,
"manualBackButton",
"()V");
591 midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass,
"minimizeWindow",
"()V");
592 midOpenURL = (*env)->GetStaticMethodID(env, mActivityClass,
"openURL",
"(Ljava/lang/String;)I");
593 midRequestPermission = (*env)->GetStaticMethodID(env, mActivityClass,
"requestPermission",
"(Ljava/lang/String;I)V");
594 midSendMessage = (*env)->GetStaticMethodID(env, mActivityClass,
"sendMessage",
"(II)Z");
595 midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass,
"setActivityTitle",
"(Ljava/lang/String;)Z");
596 midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"setCustomCursor",
"(I)Z");
597 midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass,
"setOrientation",
"(IIZLjava/lang/String;)V");
598 midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass,
"setRelativeMouseEnabled",
"(Z)Z");
599 midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass,
"setSurfaceViewFormat",
"(I)V");
600 midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"setSystemCursor",
"(I)Z");
601 midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass,
"setWindowStyle",
"(Z)V");
602 midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass,
"shouldMinimizeOnFocusLoss",
"()Z");
603 midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass,
"showTextInput",
"(IIII)Z");
604 midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass,
"supportsRelativeMouse",
"()Z");
606 if (!midClipboardGetText ||
607 !midClipboardHasText ||
608 !midClipboardSetText ||
609 !midCreateCustomCursor ||
612 !midGetManifestEnvironmentVariables ||
613 !midGetNativeSurface ||
618 !midIsScreenKeyboardShown ||
620 !midManualBackButton ||
621 !midMinimizeWindow ||
623 !midRequestPermission ||
625 !midSetActivityTitle ||
626 !midSetCustomCursor ||
627 !midSetOrientation ||
628 !midSetRelativeMouseEnabled ||
629 !midSetSurfaceViewFormat ||
630 !midSetSystemCursor ||
631 !midSetWindowStyle ||
632 !midShouldMinimizeOnFocusLoss ||
634 !midSupportsRelativeMouse) {
635 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
642 JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
644 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"AUDIO nativeSetupJNI()");
646 mAudioManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));
648 midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
649 "audioOpen",
"(IIII)[I");
650 midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
651 "audioWriteByteBuffer",
"([B)V");
652 midAudioWriteShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
653 "audioWriteShortBuffer",
"([S)V");
654 midAudioWriteFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
655 "audioWriteFloatBuffer",
"([F)V");
656 midAudioClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,
657 "audioClose",
"()V");
658 midCaptureOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
659 "captureOpen",
"(IIII)[I");
660 midCaptureReadByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
661 "captureReadByteBuffer",
"([BZ)I");
662 midCaptureReadShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
663 "captureReadShortBuffer",
"([SZ)I");
664 midCaptureReadFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
665 "captureReadFloatBuffer",
"([FZ)I");
666 midCaptureClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,
667 "captureClose",
"()V");
668 midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass,
669 "audioSetThreadPriority",
"(ZI)V");
671 if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
672 !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {
673 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
680 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
682 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"CONTROLLER nativeSetupJNI()");
684 mControllerManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));
686 midPollInputDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,
687 "pollInputDevices",
"()V");
688 midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,
689 "pollHapticDevices",
"()V");
690 midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass,
691 "hapticRun",
"(IFI)V");
692 midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass,
693 "hapticStop",
"(I)V");
695 if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) {
696 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?");
706 JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, jstring library, jstring
function, jobject
array)
709 const char *library_file;
710 void *library_handle;
712 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeRunMain()");
715 Android_JNI_SetEnv(env);
717 library_file = (*env)->GetStringUTFChars(env, library,
NULL);
718 library_handle = dlopen(library_file, RTLD_GLOBAL);
720 if (!library_handle) {
723 const char *library_name =
SDL_strrchr(library_file,
'/');
724 if (library_name && *library_name) {
726 library_handle = dlopen(library_name, RTLD_GLOBAL);
730 if (library_handle) {
731 const char *function_name;
734 function_name = (*env)->GetStringUTFChars(env,
function,
NULL);
744 len = (*env)->GetArrayLength(env,
array);
751 for (
i = 0;
i <
len; ++
i) {
754 jstring
string = (*env)->GetObjectArrayElement(env,
array,
i);
756 utf = (*env)->GetStringUTFChars(env,
string, 0);
759 (*env)->ReleaseStringUTFChars(env,
string, utf);
761 (*env)->DeleteLocalRef(env,
string);
775 for (
i = 0;
i < argc; ++
i) {
781 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
783 (*env)->ReleaseStringUTFChars(env,
function, function_name);
785 dlclose(library_handle);
788 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't load library %s", library_file);
790 (*env)->ReleaseStringUTFChars(env, library, library_file);
794 Android_JNI_SetEnv(
NULL);
803 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
804 JNIEnv *env, jclass jcls,
824 int pauseSignaled = 0;
825 int resumeSignaled = 0;
834 if (pauseSignaled > resumeSignaled) {
842 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
843 JNIEnv *env, jclass jcls,
844 jint surfaceWidth, jint surfaceHeight,
845 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate)
855 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
856 JNIEnv *env, jclass jcls)
868 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
869 JNIEnv *env, jclass jcls,
885 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
886 JNIEnv* env, jclass cls,
887 jint touchId, jstring
name)
889 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
893 (*env)->ReleaseStringUTFChars(env,
name, utfname);
896 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
897 JNIEnv* env, jclass cls,
898 jint requestCode, jboolean
result)
900 bPermissionRequestResult =
result;
905 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
906 JNIEnv *env, jclass jcls,
907 jint device_id, jint keycode)
909 return Android_OnPadDown(device_id, keycode);
913 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
914 JNIEnv *env, jclass jcls,
915 jint device_id, jint keycode)
917 return Android_OnPadUp(device_id, keycode);
921 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
922 JNIEnv *env, jclass jcls,
929 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
930 JNIEnv *env, jclass jcls,
931 jint device_id, jint hat_id, jint
x, jint
y)
933 Android_OnHat(device_id, hat_id,
x,
y);
937 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
938 JNIEnv *env, jclass jcls,
939 jint device_id, jstring device_name, jstring device_desc,
940 jint vendor_id, jint product_id, jboolean is_accelerometer,
941 jint button_mask, jint naxes, jint nhats, jint nballs)
944 const char *
name = (*env)->GetStringUTFChars(env, device_name,
NULL);
945 const char *desc = (*env)->GetStringUTFChars(env, device_desc,
NULL);
947 retval = Android_AddJoystick(device_id,
name, desc, vendor_id, product_id, is_accelerometer ?
SDL_TRUE :
SDL_FALSE, button_mask, naxes, nhats, nballs);
949 (*env)->ReleaseStringUTFChars(env, device_name,
name);
950 (*env)->ReleaseStringUTFChars(env, device_desc, desc);
955 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
956 JNIEnv *env, jclass jcls,
959 return Android_RemoveJoystick(device_id);
962 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
963 JNIEnv *env, jclass jcls, jint device_id, jstring device_name)
966 const char *
name = (*env)->GetStringUTFChars(env, device_name,
NULL);
970 (*env)->ReleaseStringUTFChars(env, device_name,
name);
975 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
976 JNIEnv *env, jclass jcls, jint device_id)
978 return Android_RemoveHaptic(device_id);
982 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(JNIEnv *env, jclass jcls)
992 SDL_SetError(
"Could not fetch native window from UI thread");
1000 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, jclass jcls)
1021 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv *env, jclass jcls)
1023 int nb_attempt = 50;
1035 if (!
data->backup_done) {
1037 if (nb_attempt == 0) {
1038 SDL_SetError(
"Try to release egl_surface with context probably still active");
1047 SDL_EGL_DestroySurface(
_this,
data->egl_surface);
1051 if (
data->native_window) {
1052 ANativeWindow_release(
data->native_window);
1063 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
1064 JNIEnv *env, jclass jcls,
1071 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
1072 JNIEnv *env, jclass jcls,
1079 JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(
1080 JNIEnv *env, jclass jcls)
1090 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
1091 JNIEnv *env, jclass jcls)
1099 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
1100 JNIEnv *env, jclass jcls,
1101 jint touch_device_id_in, jint pointer_finger_id_in,
1102 jint
action, jfloat
x, jfloat
y, jfloat
p)
1112 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
1113 JNIEnv *env, jclass jcls,
1124 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
1125 JNIEnv *env, jclass jcls,
1126 jfloat
x, jfloat
y, jfloat
z)
1128 fLastAccelerometer[0] =
x;
1129 fLastAccelerometer[1] =
y;
1130 fLastAccelerometer[2] =
z;
1135 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
1136 JNIEnv *env, jclass jcls)
1142 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
1143 JNIEnv *env, jclass cls)
1150 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
1151 JNIEnv *env, jclass cls)
1158 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
1159 JNIEnv *env, jclass cls)
1178 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
1179 JNIEnv *env, jclass cls)
1198 Internal_Android_Destroy_AssetManager();
1201 if (str && str[0]) {
1202 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"SDLActivity thread ends (error=%s)", str);
1204 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDLActivity thread ends");
1209 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
1210 JNIEnv *env, jclass cls)
1212 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativePause()");
1220 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
1221 JNIEnv *env, jclass cls)
1223 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeResume()");
1232 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
1233 JNIEnv *env, jclass cls, jboolean hasFocus)
1238 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeFocusChanged()");
1245 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
1246 JNIEnv *env, jclass cls,
1247 jstring
text, jint newCursorPosition)
1249 const char *utftext = (*env)->GetStringUTFChars(env,
text,
NULL);
1253 (*env)->ReleaseStringUTFChars(env,
text, utftext);
1256 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
1257 JNIEnv *env, jclass cls,
1264 if (chUnicode < 127) {
1285 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
1286 JNIEnv *env, jclass cls,
1287 jstring
text, jint newCursorPosition)
1289 const char *utftext = (*env)->GetStringUTFChars(env,
text,
NULL);
1293 (*env)->ReleaseStringUTFChars(env,
text, utftext);
1296 JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
1297 JNIEnv *env, jclass cls,
1300 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
1303 jstring
result = (*env)->NewStringUTF(env, hint);
1304 (*env)->ReleaseStringUTFChars(env,
name, utfname);
1309 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
1310 JNIEnv *env, jclass cls,
1313 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
1314 const char *utfvalue = (*env)->GetStringUTFChars(env,
value,
NULL);
1318 (*env)->ReleaseStringUTFChars(env,
name, utfname);
1319 (*env)->ReleaseStringUTFChars(env,
value, utfvalue);
1328 struct LocalReferenceHolder
1334 static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *
func)
1336 struct LocalReferenceHolder refholder;
1337 refholder.m_env =
NULL;
1338 refholder.m_func =
func;
1345 static SDL_bool LocalReferenceHolder_Init(
struct LocalReferenceHolder *refholder, JNIEnv *env)
1347 const int capacity = 16;
1348 if ((*env)->PushLocalFrame(env, capacity) < 0) {
1349 SDL_SetError(
"Failed to allocate enough JVM local references");
1353 refholder->m_env = env;
1357 static void LocalReferenceHolder_Cleanup(
struct LocalReferenceHolder *refholder)
1360 SDL_Log(
"Leaving function %s", refholder->m_func);
1362 if (refholder->m_env) {
1363 JNIEnv *env = refholder->m_env;
1364 (*env)->PopLocalFrame(env,
NULL);
1371 ANativeWindow *anw =
NULL;
1375 s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface);
1377 anw = ANativeWindow_fromSurface(env,
s);
1378 (*env)->DeleteLocalRef(env,
s);
1392 if (
format == WINDOW_FORMAT_RGBA_8888) {
1394 }
else if (
format == WINDOW_FORMAT_RGBX_8888) {
1396 }
else if (
format == WINDOW_FORMAT_RGB_565) {
1401 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format);
1408 jstring jtitle = (*env)->NewStringUTF(env, title);
1409 (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetActivityTitle, jtitle);
1410 (*env)->DeleteLocalRef(env, jtitle);
1416 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0);
1423 jstring jhint = (*env)->NewStringUTF(env, (hint ? hint :
""));
1424 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetOrientation,
w,
h, (resizable? 1 : 0), jhint);
1425 (*env)->DeleteLocalRef(env, jhint);
1431 (*env)->CallStaticVoidMethod(env, mActivityClass, midMinimizeWindow);
1437 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midShouldMinimizeOnFocusLoss);
1446 for (
i = 0;
i < 3; ++
i) {
1459 static int audioBufferFormat = 0;
1460 static jobject audioBuffer =
NULL;
1461 static void *audioBufferPinned =
NULL;
1462 static int captureBufferFormat = 0;
1463 static jobject captureBuffer =
NULL;
1468 jobject jbufobj =
NULL;
1470 int *resultElements;
1477 audioformat = ENCODING_PCM_8BIT;
1480 audioformat = ENCODING_PCM_16BIT;
1483 audioformat = ENCODING_PCM_FLOAT;
1490 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for capture");
1493 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for output");
1498 return SDL_SetError(
"Java-side initialization failed");
1501 if ((*env)->GetArrayLength(env, (jintArray)
result) != 4) {
1502 return SDL_SetError(
"Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)
result));
1505 resultElements = (*env)->GetIntArrayElements(env, (jintArray)
result, &isCopy);
1507 audioformat = resultElements[1];
1508 switch (audioformat) {
1509 case ENCODING_PCM_8BIT:
1512 case ENCODING_PCM_16BIT:
1515 case ENCODING_PCM_FLOAT:
1519 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1523 (*env)->ReleaseIntArrayElements(env, (jintArray)
result, resultElements, JNI_ABORT);
1524 (*env)->DeleteLocalRef(env,
result);
1528 switch (audioformat) {
1529 case ENCODING_PCM_8BIT:
1532 if (audioBufferLocal) {
1533 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1534 (*env)->DeleteLocalRef(env, audioBufferLocal);
1538 case ENCODING_PCM_16BIT:
1541 if (audioBufferLocal) {
1542 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1543 (*env)->DeleteLocalRef(env, audioBufferLocal);
1547 case ENCODING_PCM_FLOAT:
1550 if (audioBufferLocal) {
1551 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1552 (*env)->DeleteLocalRef(env, audioBufferLocal);
1557 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1560 if (jbufobj ==
NULL) {
1561 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: could not allocate an audio buffer");
1566 captureBufferFormat = audioformat;
1567 captureBuffer = jbufobj;
1569 audioBufferFormat = audioformat;
1570 audioBuffer = jbufobj;
1576 switch (audioformat) {
1577 case ENCODING_PCM_8BIT:
1578 audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
1580 case ENCODING_PCM_16BIT:
1581 audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
1583 case ENCODING_PCM_FLOAT:
1584 audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
1587 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1595 return displayOrientation;
1602 jobject jDisplayObj = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDisplayDPI);
1603 jclass jDisplayClass = (*env)->GetObjectClass(env, jDisplayObj);
1605 jfieldID fidXdpi = (*env)->GetFieldID(env, jDisplayClass,
"xdpi",
"F");
1606 jfieldID fidYdpi = (*env)->GetFieldID(env, jDisplayClass,
"ydpi",
"F");
1607 jfieldID fidDdpi = (*env)->GetFieldID(env, jDisplayClass,
"densityDpi",
"I");
1609 float nativeXdpi = (*env)->GetFloatField(env, jDisplayObj, fidXdpi);
1610 float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi);
1611 int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi);
1614 (*env)->DeleteLocalRef(env, jDisplayObj);
1615 (*env)->DeleteLocalRef(env, jDisplayClass);
1618 *ddpi = (float)nativeDdpi;
1632 return audioBufferPinned;
1639 switch (audioBufferFormat) {
1640 case ENCODING_PCM_8BIT:
1641 (*env)->ReleaseByteArrayElements(env, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
1642 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
1644 case ENCODING_PCM_16BIT:
1645 (*env)->ReleaseShortArrayElements(env, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
1646 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
1648 case ENCODING_PCM_FLOAT:
1649 (*env)->ReleaseFloatArrayElements(env, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
1650 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
1653 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled audio buffer format");
1663 jboolean isCopy = JNI_FALSE;
1666 switch (captureBufferFormat) {
1667 case ENCODING_PCM_8BIT:
1668 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
1669 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
1671 jbyte *
ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy);
1673 (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer,
ptr, JNI_ABORT);
1676 case ENCODING_PCM_16BIT:
1677 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen /
sizeof(
Sint16)));
1678 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
1680 jshort *
ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
1683 (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer,
ptr, JNI_ABORT);
1686 case ENCODING_PCM_FLOAT:
1687 SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen /
sizeof(
float)));
1688 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
1690 jfloat *
ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
1691 br *=
sizeof(float);
1693 (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer,
ptr, JNI_ABORT);
1697 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled capture buffer format");
1707 switch (captureBufferFormat) {
1708 case ENCODING_PCM_8BIT:
1710 const jint
len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
1711 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) ==
len) { }
1714 case ENCODING_PCM_16BIT:
1716 const jint
len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
1717 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) ==
len) { }
1720 case ENCODING_PCM_FLOAT:
1722 const jint
len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
1723 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) ==
len) { }
1727 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1731 switch (captureBufferFormat) {
1732 case ENCODING_PCM_8BIT:
1733 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
1735 case ENCODING_PCM_16BIT:
1736 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
1738 case ENCODING_PCM_FLOAT:
1739 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
1742 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1753 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose);
1754 if (captureBuffer) {
1755 (*env)->DeleteGlobalRef(env, captureBuffer);
1756 captureBuffer =
NULL;
1759 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose);
1761 (*env)->DeleteGlobalRef(env, audioBuffer);
1763 audioBufferPinned =
NULL;
1771 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id);
1779 jthrowable exception;
1784 exception = (*env)->ExceptionOccurred(env);
1785 if (exception !=
NULL) {
1789 (*env)->ExceptionClear(env);
1792 jclass exceptionClass = (*env)->GetObjectClass(env, exception);
1793 jclass classClass = (*env)->FindClass(env,
"java/lang/Class");
1794 jstring exceptionName;
1795 const char *exceptionNameUTF8;
1796 jstring exceptionMessage;
1798 mid = (*env)->GetMethodID(env, classClass,
"getName",
"()Ljava/lang/String;");
1799 exceptionName = (jstring)(*env)->CallObjectMethod(env, exceptionClass, mid);
1800 exceptionNameUTF8 = (*env)->GetStringUTFChars(env, exceptionName, 0);
1802 mid = (*env)->GetMethodID(env, exceptionClass,
"getMessage",
"()Ljava/lang/String;");
1803 exceptionMessage = (jstring)(*env)->CallObjectMethod(env, exception, mid);
1805 if (exceptionMessage !=
NULL) {
1806 const char *exceptionMessageUTF8 = (*env)->GetStringUTFChars(env, exceptionMessage, 0);
1807 SDL_SetError(
"%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
1808 (*env)->ReleaseStringUTFChars(env, exceptionMessage, exceptionMessageUTF8);
1813 (*env)->ReleaseStringUTFChars(env, exceptionName, exceptionNameUTF8);
1822 static void Internal_Android_Create_AssetManager() {
1824 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1828 jobject javaAssetManager;
1830 if (!LocalReferenceHolder_Init(&refs, env)) {
1831 LocalReferenceHolder_Cleanup(&refs);
1836 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
1839 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
1840 "getAssets",
"()Landroid/content/res/AssetManager;");
1841 javaAssetManager = (*env)->CallObjectMethod(env,
context, mid);
1849 javaAssetManagerRef = (*env)->NewGlobalRef(env, javaAssetManager);
1850 asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef);
1852 if (asset_manager ==
NULL) {
1853 (*env)->DeleteGlobalRef(env, javaAssetManagerRef);
1854 Android_JNI_ExceptionOccurred(
SDL_TRUE);
1857 LocalReferenceHolder_Cleanup(&refs);
1860 static void Internal_Android_Destroy_AssetManager() {
1863 if (asset_manager) {
1864 (*env)->DeleteGlobalRef(env, javaAssetManagerRef);
1865 asset_manager =
NULL;
1870 const char *fileName,
const char *
mode)
1872 AAsset *asset =
NULL;
1873 ctx->hidden.androidio.asset =
NULL;
1875 if (asset_manager ==
NULL) {
1876 Internal_Android_Create_AssetManager();
1879 if (asset_manager ==
NULL) {
1883 asset = AAssetManager_open(asset_manager, fileName, AASSET_MODE_UNKNOWN);
1884 if (asset ==
NULL) {
1889 ctx->hidden.androidio.asset = (
void*) asset;
1894 size_t size,
size_t maxnum)
1897 AAsset *asset = (AAsset*)
ctx->hidden.androidio.asset;
1912 SDL_SetError(
"Cannot write to Android package filesystem");
1919 AAsset *asset = (AAsset*)
ctx->hidden.androidio.asset;
1920 result = AAsset_getLength64(asset);
1927 AAsset *asset = (AAsset*)
ctx->hidden.androidio.asset;
1934 AAsset *asset = (AAsset*)
ctx->hidden.androidio.asset;
1935 AAsset_close(asset);
1942 jstring
string = (*env)->NewStringUTF(env,
text);
1943 (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText,
string);
1944 (*env)->DeleteLocalRef(env,
string);
1954 string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText);
1956 const char *utf = (*env)->GetStringUTFChars(env,
string, 0);
1959 (*env)->ReleaseStringUTFChars(env,
string, utf);
1961 (*env)->DeleteLocalRef(env,
string);
1970 jboolean
retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText);
1980 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1992 if (!LocalReferenceHolder_Init(&refs, env)) {
1993 LocalReferenceHolder_Cleanup(&refs);
1999 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2001 action = (*env)->NewStringUTF(env,
"android.intent.action.BATTERY_CHANGED");
2003 cls = (*env)->FindClass(env,
"android/content/IntentFilter");
2005 mid = (*env)->GetMethodID(env, cls,
"<init>",
"(Ljava/lang/String;)V");
2008 (*env)->DeleteLocalRef(env,
action);
2010 mid = (*env)->GetMethodID(env, mActivityClass,
"registerReceiver",
"(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
2013 (*env)->DeleteLocalRef(env,
filter);
2015 cls = (*env)->GetObjectClass(env, intent);
2017 imid = (*env)->GetMethodID(env, cls,
"getIntExtra",
"(Ljava/lang/String;I)I");
2020 #define GET_INT_EXTRA(var, key) \
2022 iname = (*env)->NewStringUTF(env, key); \
2023 (var) = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
2024 (*env)->DeleteLocalRef(env, iname);
2026 bmid = (*env)->GetMethodID(env, cls,
"getBooleanExtra",
"(Ljava/lang/String;Z)Z");
2029 #define GET_BOOL_EXTRA(var, key) \
2031 bname = (*env)->NewStringUTF(env, key); \
2032 (var) = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
2033 (*env)->DeleteLocalRef(env, bname);
2037 GET_INT_EXTRA(plug,
"plugged")
2039 LocalReferenceHolder_Cleanup(&refs);
2044 *plugged = (0 < plug) ? 1 : 0;
2049 GET_INT_EXTRA(status,
"status")
2051 LocalReferenceHolder_Cleanup(&refs);
2055 *charged = (status == 5) ? 1 : 0;
2059 GET_BOOL_EXTRA(present,
"present")
2060 *battery = present ? 1 : 0;
2073 GET_INT_EXTRA(level_temp,
"level")
2078 GET_INT_EXTRA(scale_temp,
"scale")
2083 LocalReferenceHolder_Cleanup(&refs);
2089 (*env)->DeleteLocalRef(env, intent);
2091 LocalReferenceHolder_Cleanup(&refs);
2098 (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch);
2104 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices);
2110 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
2116 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity,
length);
2122 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id);
2126 #define COMMAND_SET_KEEP_SCREEN_ON 5
2133 success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midSendMessage, command,
param);
2134 return success ? 0 : -1;
2145 (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput,
2155 const int COMMAND_TEXTEDIT_HIDE = 3;
2162 jboolean is_shown = 0;
2163 is_shown = (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsScreenKeyboardShown);
2176 jintArray button_flags;
2177 jintArray button_ids;
2178 jobjectArray button_texts;
2188 clazz = (*env)->FindClass(env,
"java/lang/String");
2190 title = (*env)->NewStringUTF(env, messageboxdata->
title);
2193 button_flags = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2194 button_ids = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2195 button_texts = (*env)->NewObjectArray(env, messageboxdata->
numbuttons,
2203 sdlButton = &messageboxdata->
buttons[
i];
2206 temp = sdlButton->
flags;
2207 (*env)->SetIntArrayRegion(env, button_flags,
i, 1, &temp);
2209 (*env)->SetIntArrayRegion(env, button_ids,
i, 1, &temp);
2210 text = (*env)->NewStringUTF(env, sdlButton->
text);
2211 (*env)->SetObjectArrayElement(env, button_texts,
i,
text);
2212 (*env)->DeleteLocalRef(env,
text);
2218 temp = (0xFFU << 24) |
2222 (*env)->SetIntArrayRegion(env,
colors,
i, 1, &temp);
2228 (*env)->DeleteLocalRef(env, clazz);
2231 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2233 clazz = (*env)->GetObjectClass(env,
context);
2235 mid = (*env)->GetMethodID(env, clazz,
2236 "messageboxShowMessageBox",
"(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
2237 *buttonid = (*env)->CallIntMethod(env,
context, mid,
2238 messageboxdata->
flags,
2246 (*env)->DeleteLocalRef(env,
context);
2247 (*env)->DeleteLocalRef(env, clazz);
2251 (*env)->DeleteLocalRef(env, title);
2252 (*env)->DeleteLocalRef(env,
message);
2253 (*env)->DeleteLocalRef(env, button_flags);
2254 (*env)->DeleteLocalRef(env, button_ids);
2255 (*env)->DeleteLocalRef(env, button_texts);
2256 (*env)->DeleteLocalRef(env,
colors);
2264 // Functions exposed to SDL applications in SDL_system.h
2283 return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2288 static int sdk_version;
2290 char sdk[PROP_VALUE_MAX] = {0};
2291 if (__system_property_get(
"ro.build.version.sdk", sdk) != 0) {
2301 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet);
2307 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV);
2313 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);
2319 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
2325 (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
2330 static char *s_AndroidInternalFilesPath =
NULL;
2332 if (!s_AndroidInternalFilesPath) {
2333 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2341 if (!LocalReferenceHolder_Init(&refs, env)) {
2342 LocalReferenceHolder_Cleanup(&refs);
2347 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2350 LocalReferenceHolder_Cleanup(&refs);
2355 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
2356 "getFilesDir",
"()Ljava/io/File;");
2357 fileObject = (*env)->CallObjectMethod(env,
context, mid);
2360 LocalReferenceHolder_Cleanup(&refs);
2365 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2366 "getCanonicalPath",
"()Ljava/lang/String;");
2367 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2368 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
2369 LocalReferenceHolder_Cleanup(&refs);
2377 LocalReferenceHolder_Cleanup(&refs);
2379 return s_AndroidInternalFilesPath;
2384 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2387 jstring stateString;
2392 if (!LocalReferenceHolder_Init(&refs, env)) {
2393 LocalReferenceHolder_Cleanup(&refs);
2397 cls = (*env)->FindClass(env,
"android/os/Environment");
2398 mid = (*env)->GetStaticMethodID(env, cls,
2399 "getExternalStorageState",
"()Ljava/lang/String;");
2400 stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid);
2402 state = (*env)->GetStringUTFChars(env, stateString,
NULL);
2405 __android_log_print(ANDROID_LOG_INFO,
"SDL",
"external storage state: %s",
state);
2408 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
2409 SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
2411 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
2415 (*env)->ReleaseStringUTFChars(env, stateString,
state);
2417 LocalReferenceHolder_Cleanup(&refs);
2423 static char *s_AndroidExternalFilesPath =
NULL;
2425 if (!s_AndroidExternalFilesPath) {
2426 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2434 if (!LocalReferenceHolder_Init(&refs, env)) {
2435 LocalReferenceHolder_Cleanup(&refs);
2440 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2443 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
2444 "getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;");
2445 fileObject = (*env)->CallObjectMethod(env,
context, mid,
NULL);
2448 LocalReferenceHolder_Cleanup(&refs);
2453 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2454 "getAbsolutePath",
"()Ljava/lang/String;");
2455 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2461 LocalReferenceHolder_Cleanup(&refs);
2463 return s_AndroidExternalFilesPath;
2473 if (!mActivityClass || !midGetManifestEnvironmentVariables) {
2474 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Request to get environment variables before JNI is ready");
2478 if (!bHasEnvironmentVariables) {
2480 SDL_bool ret = (*env)->CallStaticBooleanMethod(env, mActivityClass, midGetManifestEnvironmentVariables);
2482 bHasEnvironmentVariables =
SDL_TRUE;
2490 int custom_cursor = 0;
2495 custom_cursor = (*env)->CallStaticIntMethod(env, mActivityClass, midCreateCustomCursor,
pixels,
surface->w,
surface->h,
hot_x, hot_y);
2496 (*env)->DeleteLocalRef(env,
pixels);
2500 return custom_cursor;
2507 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetCustomCursor, cursorID);
2513 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetSystemCursor, cursorID);
2519 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSupportsRelativeMouse);
2525 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetRelativeMouseEnabled, (
enabled == 1));
2531 const int requestCode = 1;
2539 jstring jpermission = (*env)->NewStringUTF(env, permission);
2540 (*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
2541 (*env)->DeleteLocalRef(env, jpermission);
2547 return bPermissionRequestResult;
2552 AConfiguration *cfg;
2557 Internal_Android_Destroy_AssetManager();
2559 if (asset_manager ==
NULL) {
2560 Internal_Android_Create_AssetManager();
2563 if (asset_manager ==
NULL) {
2567 cfg = AConfiguration_new();
2573 char language[2] = {};
2574 char country[2] = {};
2577 AConfiguration_fromAssetManager(cfg, asset_manager);
2578 AConfiguration_getLanguage(cfg, language);
2579 AConfiguration_getCountry(cfg, country);
2583 buf[
id++] = language[0];
2585 buf[
id++] = language[1];
2593 buf[
id++] = country[0];
2595 buf[
id++] = country[1];
2603 AConfiguration_delete(cfg);
2612 jstring jurl = (*env)->NewStringUTF(env, url);
2613 const int ret = (*env)->CallStaticIntMethod(env, mActivityClass, midOpenURL, jurl);
2614 (*env)->DeleteLocalRef(env, jurl);
SDL_bool Android_JNI_HasClipboardText(void)
SDL_bool SDL_IsAndroidTablet(void)
SDL_bool Android_JNI_SupportsRelativeMouse(void)
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
void * Android_JNI_GetAudioBuffer(void)
void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
void Android_JNI_FlushCapturedAudio(void)
void Android_ActivityMutex_Lock(void)
SDL_bool Android_JNI_IsScreenKeyboardShown(void)
int Android_JNI_SetupThread(void)
void Android_JNI_SetSurfaceViewFormat(int format)
size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size, size_t maxnum)
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode)
int Android_JNI_GetLocale(char *buf, size_t buflen)
int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
void Android_JNI_MinizeWindow(void)
int SDL_GetAndroidSDKVersion(void)
void Android_JNI_CloseAudioDevice(const int iscapture)
size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size, size_t num)
void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint)
SDL_bool Android_JNI_SetCustomCursor(int cursorID)
void Android_JNI_HapticRun(int device_id, float intensity, int length)
void Android_ActivityMutex_Unlock(void)
SDL_bool Android_JNI_SetSystemCursor(int cursorID)
int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent)
void Android_JNI_SetActivityTitle(const char *title)
void Android_JNI_SetWindowStyle(SDL_bool fullscreen)
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
ANativeWindow * Android_JNI_GetNativeWindow(void)
SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void)
SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void)
void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id)
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence)
void Android_JNI_SuspendScreenSaver(SDL_bool suspend)
void Android_JNI_PollHapticDevices(void)
void Android_JNI_InitTouch(void)
void Android_ActivityMutex_Lock_Running(void)
void Android_JNI_HapticStop(int device_id)
SDL_bool SDL_IsChromebook(void)
SDL_bool SDL_IsDeXMode(void)
SDL_bool SDL_IsAndroidTV(void)
void Android_JNI_WriteAudioBuffer(void)
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y)
void Android_JNI_PollInputDevices(void)
void Android_JNI_HideTextInput(void)
char * Android_JNI_GetClipboardText(void)
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
JNIEnv * Android_JNI_GetEnv(void)
void Android_JNI_GetManifestEnvironmentVariables(void)
int Android_JNI_FileClose(SDL_RWops *ctx)
SDL_bool Android_JNI_RequestPermission(const char *permission)
int Android_JNI_SendMessage(int command, int param)
int Android_JNI_OpenURL(const char *url)
int Android_JNI_SetClipboardText(const char *text)
int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)
int Android_OnKeyUp(int keycode)
int Android_OnKeyDown(int keycode)
void Android_OnMouse(SDL_Window *window, int button, int action, float x, float y, SDL_bool relative)
void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
SDL_sem * Android_ResumeSem
void Android_SendResize(SDL_Window *window)
SDL_mutex * Android_ActivityMutex
SDL_sem * Android_PauseSem
void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate)
SDL_Window * Android_Window
#define SDL_assert(condition)
#define SDL_AtomicDecRef(a)
Decrement an atomic variable used as a reference count.
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
int SDL_SendClipboardUpdate(void)
int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1)
int SDL_SendDropFile(SDL_Window *window, const char *file)
int SDL_SendDropComplete(SDL_Window *window)
#define SDL_AndroidGetActivity
#define SDL_AndroidGetJNIEnv
#define SDL_AndroidRequestPermission
#define SDL_AndroidGetExternalStoragePath
#define SDL_AndroidGetInternalStoragePath
#define SDL_StopTextInput
#define SDL_DestroySemaphore
#define SDL_AndroidGetExternalStorageState
#define SDL_AndroidBackButton
#define SDL_CreateSemaphore
#define SDL_GetHintBoolean
#define SDL_OutOfMemory()
int SDL_SendAppEvent(SDL_EventType eventType)
#define SDL_HINT_RETURN_KEY_HIDES_IME
A variable to control whether the return key on the soft keyboard should hide the soft keyboard on An...
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
int SDL_SendEditingText(const char *text, int start, int length)
int SDL_SendKeyboardText(const char *text)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
int uint32_t uint32_t uint32_t uint32_t uint32_t int drmModeModeInfoPtr mode int uint32_t uint32_t uint32_t uint32_t int32_t hot_x
SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[])
int(* SDL_main_func)(int argc, char *argv[])
@ SDL_MESSAGEBOX_COLOR_MAX
@ SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT
GLint GLint GLint GLint GLint GLint y
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLenum GLenum GLenum GLenum scale
GLenum GLsizei const void * pathString
GLuint GLsizei const GLchar * message
GLenum GLsizei GLsizei GLint * values
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei const GLchar *const * path
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
GLsizei const GLchar *const * string
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
SDL_Scancode
The SDL keyboard scancode representation.
#define SDL_arraysize(array)
SDL_VideoDevice * SDL_GetVideoDevice(void)
SDL_VideoDisplay * SDL_GetDisplay(int displayIndex)
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
@ SDL_TOUCH_DEVICE_DIRECT
static SDL_VideoDevice * _this
@ SDL_WINDOWEVENT_FOCUS_LOST
@ SDL_WINDOWEVENT_FOCUS_GAINED
@ SDL_DISPLAYEVENT_ORIENTATION
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
static AndroidKeyInfo unicharToAndroidKeyInfoTable[]
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF PF else PF lsl PF lsl PF lsl PF endif SIZE macro preload_middle scratch_holds_offset if bpp if else PF PF endif endif endif endm macro preload_trailing base if bpp if bpp *pix_per_block PF PF lsl PF PF PF PF PF else PF lsl PF lsl PF PF PF PF PF base if bpp if narrow_case &&bpp<=dst_w_bpp) PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, LSL #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 90f PF pld,[WK1]90:.else PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, lsl #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 92f91:PF add, WK0, WK0, #32 PF cmp, WK0, WK1 PF pld,[WK0] PF bne, 91b92:.endif .endif.endm.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond X, X, #8 *numbytes/dst_w_bpp .endif process_tail cond, numbytes, firstreg .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst cond, numbytes, firstreg, DST .endif.endm.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_BRANCH_OVER .ifc cond, mi bpl 100f .endif .ifc cond, cs bcc 100f .endif .ifc cond, ne beq 100f .endif conditional_process1_helper, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx100:.else conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .endif.endm.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx .if(flags) &(FLAG_DST_READWRITE|FLAG_BRANCH_OVER|FLAG_PROCESS_CORRUPTS_PSR|FLAG_PROCESS_DOES_STORE) test conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_PROCESS_CORRUPTS_PSR test .endif conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx .else test process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0 process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond1 X, X, #8 *numbytes1/dst_w_bpp sub &cond2 X, X, #8 *numbytes2/dst_w_bpp .endif process_tail cond1, numbytes1, firstreg1 process_tail cond2, numbytes2, firstreg2 pixst cond1, numbytes1, firstreg1, DST pixst cond2, numbytes2, firstreg2, DST .endif.endm.macro test_bits_1_0_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-1 .else movs SCRATCH, WK0, lsl #32-1 .endif.endm.macro test_bits_3_2_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-3 .else movs SCRATCH, WK0, lsl #32-3 .endif.endm.macro leading_15bytes process_head, process_tail .set DECREMENT_X, 1 .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 .set DECREMENT_X, 0 sub X, X, WK0, lsr #dst_bpp_shift str X,[sp, #LINE_SAVED_REG_COUNT *4] mov X, WK0 .endif .if dst_w_bpp==8 conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X .elseif dst_w_bpp==16 test_bits_1_0_ptr conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X .endif conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 ldr X,[sp, #LINE_SAVED_REG_COUNT *4] .endif.endm.macro test_bits_3_2_pix movs SCRATCH, X, lsl #dst_bpp_shift+32-3.endm.macro test_bits_1_0_pix .if dst_w_bpp==8 movs SCRATCH, X, lsl #dst_bpp_shift+32-1 .else movs SCRATCH, X, lsr #1 .endif.endm.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0 .if dst_w_bpp==16 test_bits_1_0_pix conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0 .elseif dst_w_bpp==8 conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0 .endif.endm.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment110:.set SUBBLOCK, 0 .rept pix_per_block *dst_w_bpp/128 process_head, 16, 0, unaligned_src, unaligned_mask, 1 .if(src_bpp > 0) &&(mask_bpp==0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle src_bpp, SRC, 1 .elseif(src_bpp==0) &&(mask_bpp > 0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle mask_bpp, MASK, 1 .else preload_middle src_bpp, SRC, 0 preload_middle mask_bpp, MASK, 0 .endif .if(dst_r_bpp > 0) &&((SUBBLOCK % 2)==0) &&(((flags) &FLAG_NO_PRELOAD_DST)==0) PF pld,[DST, #32 *prefetch_distance - dst_alignment] .endif process_tail, 16, 0 .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst, 16, 0, DST .endif .set SUBBLOCK, SUBBLOCK+1 .endr subs X, X, #pix_per_block bhs 110b.endm.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask .if dst_r_bpp > tst bne process_inner_loop DST_PRELOAD_BIAS endif preload_trailing SRC preload_trailing MASK DST endif add medium_case_inner_loop_and_trailing_pixels unaligned_mask endm macro medium_case_inner_loop_and_trailing_pixels DST endif subs bhs tst beq exit_label trailing_15bytes unaligned_mask endm macro narrow_case_inner_loop_and_trailing_pixels unaligned_mask tst conditional_process1 trailing_15bytes unaligned_mask endm macro switch_on_alignment action
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]
MessageBox structure containing title, text, window, etc.
const SDL_MessageBoxColorScheme * colorScheme
const SDL_MessageBoxButtonData * buttons
A rectangle, with the origin at the upper left (integer).
A collection of pixels used in software blitting.
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
static char text[MAX_TEXT_LENGTH]
static screen_context_t context
typedef int(__stdcall *FARPROC)()