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 <sys/system_properties.h>
52#define SDL_JAVA_PREFIX org_libsdl_app
53#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
54#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
55#define SDL_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function)
56#define SDL_JAVA_AUDIO_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function)
57#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)
58#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)
61#define ENCODING_PCM_8BIT 3
62#define ENCODING_PCM_16BIT 2
63#define ENCODING_PCM_FLOAT 4
66JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
67 JNIEnv *env, jclass cls);
69JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(
70 JNIEnv *env, jclass cls,
71 jstring library, jstring function, jobject
array);
73JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
74 JNIEnv *env, jclass jcls,
77JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
78 JNIEnv *env, jclass jcls,
79 jint surfaceWidth, jint surfaceHeight,
80 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate);
82JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
83 JNIEnv *env, jclass cls);
85JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(
86 JNIEnv *env, jclass jcls);
88JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
89 JNIEnv *env, jclass jcls);
91JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(
92 JNIEnv *env, jclass jcls);
94JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
95 JNIEnv *env, jclass jcls,
98JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
99 JNIEnv *env, jclass jcls,
102JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(
103 JNIEnv *env, jclass jcls);
105JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
106 JNIEnv *env, jclass jcls);
108JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
109 JNIEnv *env, jclass jcls,
110 jint touch_device_id_in, jint pointer_finger_id_in,
111 jint action, jfloat
x, jfloat
y, jfloat
p);
113JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
114 JNIEnv *env, jclass jcls,
115 jint
button, jint action, jfloat
x, jfloat
y, jboolean relative);
117JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
118 JNIEnv *env, jclass jcls,
119 jfloat
x, jfloat
y, jfloat
z);
121JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
122 JNIEnv *env, jclass jcls);
124JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
125 JNIEnv *env, jclass cls);
127JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
128 JNIEnv *env, jclass cls);
130JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
131 JNIEnv *env, jclass cls);
133JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
134 JNIEnv *env, jclass cls);
136JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
137 JNIEnv *env, jclass cls);
139JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
140 JNIEnv *env, jclass cls, jboolean hasFocus);
142JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
143 JNIEnv *env, jclass cls,
146JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
147 JNIEnv *env, jclass cls,
150JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)(
151 JNIEnv *env, jclass cls);
153JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
154 JNIEnv *env, jclass cls,
157JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
158 JNIEnv* env, jclass cls,
159 jint touchId, jstring
name);
162JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
163 JNIEnv *env, jclass cls,
164 jstring
text, jint newCursorPosition);
166JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
167 JNIEnv *env, jclass cls,
170JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
171 JNIEnv *env, jclass cls,
172 jstring
text, jint newCursorPosition);
175JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(
176 JNIEnv *env, jclass jcls);
179JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(
180 JNIEnv *env, jclass jcls);
182JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
183 JNIEnv *env, jclass jcls,
184 jint device_id, jint keycode);
186JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
187 JNIEnv *env, jclass jcls,
188 jint device_id, jint keycode);
190JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
191 JNIEnv *env, jclass jcls,
192 jint device_id, jint
axis, jfloat
value);
194JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
195 JNIEnv *env, jclass jcls,
196 jint device_id, jint hat_id, jint
x, jint
y);
198JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
199 JNIEnv *env, jclass jcls,
200 jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,
201 jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs);
203JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
204 JNIEnv *env, jclass jcls,
207JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
208 JNIEnv *env, jclass jcls,
209 jint device_id, jstring device_name);
211JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
212 JNIEnv *env, jclass jcls,
220static void checkJNIReady(
void);
231static pthread_key_t mThreadKey;
232static pthread_once_t key_once = PTHREAD_ONCE_INIT;
233static JavaVM *mJavaVM =
NULL;
236static jclass mActivityClass;
239static jmethodID midGetNativeSurface;
240static jmethodID midSetSurfaceViewFormat;
241static jmethodID midSetActivityTitle;
242static jmethodID midSetWindowStyle;
243static jmethodID midSetOrientation;
244static jmethodID midMinimizeWindow;
245static jmethodID midShouldMinimizeOnFocusLoss;
246static jmethodID midGetContext;
247static jmethodID midIsTablet;
248static jmethodID midIsAndroidTV;
249static jmethodID midIsChromebook;
250static jmethodID midIsDeXMode;
251static jmethodID midManualBackButton;
252static jmethodID midInitTouch;
253static jmethodID midSendMessage;
254static jmethodID midShowTextInput;
255static jmethodID midIsScreenKeyboardShown;
256static jmethodID midClipboardSetText;
257static jmethodID midClipboardGetText;
258static jmethodID midClipboardHasText;
259static jmethodID midOpenAPKExpansionInputStream;
260static jmethodID midGetManifestEnvironmentVariables;
261static jmethodID midGetDisplayDPI;
262static jmethodID midCreateCustomCursor;
263static jmethodID midSetCustomCursor;
264static jmethodID midSetSystemCursor;
265static jmethodID midSupportsRelativeMouse;
266static jmethodID midSetRelativeMouseEnabled;
269static jclass mAudioManagerClass;
272static jmethodID midAudioOpen;
273static jmethodID midAudioWriteByteBuffer;
274static jmethodID midAudioWriteShortBuffer;
275static jmethodID midAudioWriteFloatBuffer;
276static jmethodID midAudioClose;
277static jmethodID midCaptureOpen;
278static jmethodID midCaptureReadByteBuffer;
279static jmethodID midCaptureReadShortBuffer;
280static jmethodID midCaptureReadFloatBuffer;
281static jmethodID midCaptureClose;
282static jmethodID midAudioSetThreadPriority;
285static jclass mControllerManagerClass;
288static jmethodID midPollInputDevices;
289static jmethodID midPollHapticDevices;
290static jmethodID midHapticRun;
291static jmethodID midHapticStop;
295static float fLastAccelerometer[3];
328Android_JNI_SetEnv(JNIEnv *env) {
329 int status = pthread_setspecific(mThreadKey, env);
331 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed pthread_setspecific() in Android_JNI_SetEnv() (err=%d)", status);
340 JNIEnv *env = pthread_getspecific(mThreadKey);
346 if (mJavaVM ==
NULL) {
347 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed, there is no JavaVM");
353 status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env,
NULL);
355 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to attach current thread (err=%d)", status);
360 if (Android_JNI_SetEnv(env) < 0) {
375 if (mJavaVM ==
NULL) {
376 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed, there is no JavaVM");
382 status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env,
NULL);
384 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Failed to attach current thread (err=%d)", status);
389 if (Android_JNI_SetEnv(env) < 0) {
398Android_JNI_ThreadDestroyed(
void *
value)
401 JNIEnv *env = (JNIEnv *)
value;
403 (*mJavaVM)->DetachCurrentThread(mJavaVM);
404 Android_JNI_SetEnv(
NULL);
410Android_JNI_CreateKey(
void)
412 int status = pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed);
414 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Error initializing mThreadKey with pthread_key_create() (err=%d)", status);
419Android_JNI_CreateKey_once(
void)
421 int status = pthread_once(&key_once, Android_JNI_CreateKey);
423 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Error initializing mThreadKey with pthread_once() (err=%d)", status);
428JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void *reserved)
431 return JNI_VERSION_1_4;
434void checkJNIReady(
void)
436 if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) {
445JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
447 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeSetupJNI()");
453 Android_JNI_CreateKey_once();
456 Android_JNI_SetEnv(env);
458 if (mJavaVM ==
NULL) {
459 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to found a JavaVM");
470 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_ActivityMutex mutex");
476 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_PauseSem semaphore");
481 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"failed to create Android_ResumeSem semaphore");
484 mActivityClass = (jclass)((*env)->NewGlobalRef(env, cls));
486 midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass,
487 "getNativeSurface",
"()Landroid/view/Surface;");
488 midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass,
489 "setSurfaceViewFormat",
"(I)V");
490 midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass,
491 "setActivityTitle",
"(Ljava/lang/String;)Z");
492 midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass,
493 "setWindowStyle",
"(Z)V");
494 midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass,
495 "setOrientation",
"(IIZLjava/lang/String;)V");
496 midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass,
497 "minimizeWindow",
"()V");
498 midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass,
499 "shouldMinimizeOnFocusLoss",
"()Z");
500 midGetContext = (*env)->GetStaticMethodID(env, mActivityClass,
501 "getContext",
"()Landroid/content/Context;");
502 midIsTablet = (*env)->GetStaticMethodID(env, mActivityClass,
504 midIsAndroidTV = (*env)->GetStaticMethodID(env, mActivityClass,
505 "isAndroidTV",
"()Z");
506 midIsChromebook = (*env)->GetStaticMethodID(env, mActivityClass,
507 "isChromebook",
"()Z");
508 midIsDeXMode = (*env)->GetStaticMethodID(env, mActivityClass,
510 midManualBackButton = (*env)->GetStaticMethodID(env, mActivityClass,
511 "manualBackButton",
"()V");
512 midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass,
514 midSendMessage = (*env)->GetStaticMethodID(env, mActivityClass,
515 "sendMessage",
"(II)Z");
516 midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass,
517 "showTextInput",
"(IIII)Z");
518 midIsScreenKeyboardShown = (*env)->GetStaticMethodID(env, mActivityClass,
519 "isScreenKeyboardShown",
"()Z");
520 midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass,
521 "clipboardSetText",
"(Ljava/lang/String;)V");
522 midClipboardGetText = (*env)->GetStaticMethodID(env, mActivityClass,
523 "clipboardGetText",
"()Ljava/lang/String;");
524 midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass,
525 "clipboardHasText",
"()Z");
526 midOpenAPKExpansionInputStream = (*env)->GetStaticMethodID(env, mActivityClass,
527 "openAPKExpansionInputStream",
"(Ljava/lang/String;)Ljava/io/InputStream;");
529 midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass,
530 "getManifestEnvironmentVariables",
"()Z");
532 midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass,
"getDisplayDPI",
"()Landroid/util/DisplayMetrics;");
533 midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"createCustomCursor",
"([IIIII)I");
534 midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"setCustomCursor",
"(I)Z");
535 midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass,
"setSystemCursor",
"(I)Z");
537 midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass,
"supportsRelativeMouse",
"()Z");
538 midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass,
"setRelativeMouseEnabled",
"(Z)Z");
541 if (!midGetNativeSurface || !midSetSurfaceViewFormat ||
542 !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midMinimizeWindow || !midShouldMinimizeOnFocusLoss || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInitTouch ||
543 !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
544 !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
545 !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
546 !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
547 !midIsChromebook || !midIsDeXMode || !midManualBackButton) {
548 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
555JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
557 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"AUDIO nativeSetupJNI()");
559 mAudioManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));
561 midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
562 "audioOpen",
"(IIII)[I");
563 midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
564 "audioWriteByteBuffer",
"([B)V");
565 midAudioWriteShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
566 "audioWriteShortBuffer",
"([S)V");
567 midAudioWriteFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
568 "audioWriteFloatBuffer",
"([F)V");
569 midAudioClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,
570 "audioClose",
"()V");
571 midCaptureOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
572 "captureOpen",
"(IIII)[I");
573 midCaptureReadByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
574 "captureReadByteBuffer",
"([BZ)I");
575 midCaptureReadShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
576 "captureReadShortBuffer",
"([SZ)I");
577 midCaptureReadFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
578 "captureReadFloatBuffer",
"([FZ)I");
579 midCaptureClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,
580 "captureClose",
"()V");
581 midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass,
582 "audioSetThreadPriority",
"(ZI)V");
584 if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
585 !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {
586 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
593JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
595 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"CONTROLLER nativeSetupJNI()");
597 mControllerManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));
599 midPollInputDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,
600 "pollInputDevices",
"()V");
601 midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,
602 "pollHapticDevices",
"()V");
603 midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass,
604 "hapticRun",
"(IFI)V");
605 midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass,
606 "hapticStop",
"(I)V");
608 if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) {
609 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?");
619JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, jstring library, jstring function, jobject
array)
622 const char *library_file;
623 void *library_handle;
625 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeRunMain()");
628 Android_JNI_SetEnv(env);
630 library_file = (*env)->GetStringUTFChars(env, library,
NULL);
631 library_handle = dlopen(library_file, RTLD_GLOBAL);
632 if (library_handle) {
633 const char *function_name;
636 function_name = (*env)->GetStringUTFChars(env, function,
NULL);
646 len = (*env)->GetArrayLength(env,
array);
653 for (
i = 0;
i <
len; ++
i) {
656 jstring
string = (*env)->GetObjectArrayElement(env,
array,
i);
658 utf = (*env)->GetStringUTFChars(env,
string, 0);
661 (*env)->ReleaseStringUTFChars(env,
string, utf);
663 (*env)->DeleteLocalRef(env,
string);
677 for (
i = 0;
i < argc; ++
i) {
683 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
685 (*env)->ReleaseStringUTFChars(env, function, function_name);
687 dlclose(library_handle);
690 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't load library %s", library_file);
692 (*env)->ReleaseStringUTFChars(env, library, library_file);
696 Android_JNI_SetEnv(
NULL);
705JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
706 JNIEnv *env, jclass jcls,
726 int pauseSignaled = 0;
727 int resumeSignaled = 0;
736 if (pauseSignaled > resumeSignaled) {
744JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
745 JNIEnv *env, jclass jcls,
746 jint surfaceWidth, jint surfaceHeight,
747 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate)
757JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
758 JNIEnv *env, jclass jcls)
770JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
771 JNIEnv *env, jclass jcls,
787JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
788 JNIEnv* env, jclass cls,
789 jint touchId, jstring
name)
791 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
795 (*env)->ReleaseStringUTFChars(env,
name, utfname);
799JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
800 JNIEnv *env, jclass jcls,
801 jint device_id, jint keycode)
803 return Android_OnPadDown(device_id, keycode);
807JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
808 JNIEnv *env, jclass jcls,
809 jint device_id, jint keycode)
811 return Android_OnPadUp(device_id, keycode);
815JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
816 JNIEnv *env, jclass jcls,
823JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
824 JNIEnv *env, jclass jcls,
825 jint device_id, jint hat_id, jint
x, jint
y)
827 Android_OnHat(device_id, hat_id,
x,
y);
831JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
832 JNIEnv *env, jclass jcls,
833 jint device_id, jstring device_name, jstring device_desc,
834 jint vendor_id, jint product_id, jboolean is_accelerometer,
835 jint button_mask, jint naxes, jint nhats, jint nballs)
838 const char *
name = (*env)->GetStringUTFChars(env, device_name,
NULL);
839 const char *desc = (*env)->GetStringUTFChars(env, device_desc,
NULL);
841 retval = Android_AddJoystick(device_id,
name, desc, vendor_id, product_id, is_accelerometer ?
SDL_TRUE :
SDL_FALSE, button_mask, naxes, nhats, nballs);
843 (*env)->ReleaseStringUTFChars(env, device_name,
name);
844 (*env)->ReleaseStringUTFChars(env, device_desc, desc);
849JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
850 JNIEnv *env, jclass jcls,
853 return Android_RemoveJoystick(device_id);
856JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
857 JNIEnv *env, jclass jcls, jint device_id, jstring device_name)
860 const char *
name = (*env)->GetStringUTFChars(env, device_name,
NULL);
864 (*env)->ReleaseStringUTFChars(env, device_name,
name);
869JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
870 JNIEnv *env, jclass jcls, jint device_id)
872 return Android_RemoveHaptic(device_id);
876JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(JNIEnv *env, jclass jcls)
886 SDL_SetError(
"Could not fetch native window from UI thread");
894JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, jclass jcls)
915JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv *env, jclass jcls)
931 SDL_EGL_DestroySurface(
_this,
data->egl_surface);
935 if (
data->native_window) {
936 ANativeWindow_release(
data->native_window);
947JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
948 JNIEnv *env, jclass jcls,
955JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
956 JNIEnv *env, jclass jcls,
963JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(
964 JNIEnv *env, jclass jcls)
974JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
975 JNIEnv *env, jclass jcls)
983JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
984 JNIEnv *env, jclass jcls,
985 jint touch_device_id_in, jint pointer_finger_id_in,
986 jint action, jfloat
x, jfloat
y, jfloat
p)
996JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
997 JNIEnv *env, jclass jcls,
998 jint
button, jint action, jfloat
x, jfloat
y, jboolean relative)
1008JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
1009 JNIEnv *env, jclass jcls,
1010 jfloat
x, jfloat
y, jfloat
z)
1012 fLastAccelerometer[0] =
x;
1013 fLastAccelerometer[1] =
y;
1014 fLastAccelerometer[2] =
z;
1019JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
1020 JNIEnv *env, jclass jcls)
1026JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
1027 JNIEnv *env, jclass cls)
1033JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
1034 JNIEnv *env, jclass cls)
1053JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
1054 JNIEnv *env, jclass cls)
1074 if (str && str[0]) {
1075 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"SDLActivity thread ends (error=%s)", str);
1077 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDLActivity thread ends");
1082JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
1083 JNIEnv *env, jclass cls)
1087 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativePause()");
1105JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
1106 JNIEnv *env, jclass cls)
1110 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeResume()");
1127JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
1128 JNIEnv *env, jclass cls, jboolean hasFocus)
1133 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeFocusChanged()");
1140JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
1141 JNIEnv *env, jclass cls,
1142 jstring
text, jint newCursorPosition)
1144 const char *utftext = (*env)->GetStringUTFChars(env,
text,
NULL);
1148 (*env)->ReleaseStringUTFChars(env,
text, utftext);
1151JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
1152 JNIEnv *env, jclass cls,
1159 if (chUnicode < 127) {
1180JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
1181 JNIEnv *env, jclass cls,
1182 jstring
text, jint newCursorPosition)
1184 const char *utftext = (*env)->GetStringUTFChars(env,
text,
NULL);
1188 (*env)->ReleaseStringUTFChars(env,
text, utftext);
1191JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
1192 JNIEnv *env, jclass cls,
1195 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
1198 jstring
result = (*env)->NewStringUTF(env, hint);
1199 (*env)->ReleaseStringUTFChars(env,
name, utfname);
1204JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
1205 JNIEnv *env, jclass cls,
1208 const char *utfname = (*env)->GetStringUTFChars(env,
name,
NULL);
1209 const char *utfvalue = (*env)->GetStringUTFChars(env,
value,
NULL);
1213 (*env)->ReleaseStringUTFChars(env,
name, utfname);
1214 (*env)->ReleaseStringUTFChars(env,
value, utfvalue);
1223struct LocalReferenceHolder
1229static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *
func)
1231 struct LocalReferenceHolder refholder;
1232 refholder.m_env =
NULL;
1233 refholder.m_func =
func;
1240static SDL_bool LocalReferenceHolder_Init(
struct LocalReferenceHolder *refholder, JNIEnv *env)
1242 const int capacity = 16;
1243 if ((*env)->PushLocalFrame(env, capacity) < 0) {
1244 SDL_SetError(
"Failed to allocate enough JVM local references");
1248 refholder->m_env = env;
1252static void LocalReferenceHolder_Cleanup(
struct LocalReferenceHolder *refholder)
1255 SDL_Log(
"Leaving function %s", refholder->m_func);
1257 if (refholder->m_env) {
1258 JNIEnv *env = refholder->m_env;
1259 (*env)->PopLocalFrame(env,
NULL);
1266 ANativeWindow *anw =
NULL;
1270 s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface);
1272 anw = ANativeWindow_fromSurface(env,
s);
1273 (*env)->DeleteLocalRef(env,
s);
1287 if (
format == WINDOW_FORMAT_RGBA_8888) {
1289 }
else if (
format == WINDOW_FORMAT_RGBX_8888) {
1291 }
else if (
format == WINDOW_FORMAT_RGB_565) {
1296 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format);
1303 jstring jtitle = (jstring)((*env)->NewStringUTF(env, title));
1304 (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetActivityTitle, jtitle);
1305 (*env)->DeleteLocalRef(env, jtitle);
1311 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0);
1318 jstring jhint = (jstring)((*env)->NewStringUTF(env, (hint ? hint :
"")));
1319 (*env)->CallStaticVoidMethod(env, mActivityClass, midSetOrientation,
w,
h, (resizable? 1 : 0), jhint);
1320 (*env)->DeleteLocalRef(env, jhint);
1326 (*env)->CallStaticVoidMethod(env, mActivityClass, midMinimizeWindow);
1332 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midShouldMinimizeOnFocusLoss);
1341 for (
i = 0;
i < 3; ++
i) {
1354static int audioBufferFormat = 0;
1355static jobject audioBuffer =
NULL;
1356static void *audioBufferPinned =
NULL;
1357static int captureBufferFormat = 0;
1358static jobject captureBuffer =
NULL;
1363 int numBufferFrames;
1364 jobject jbufobj =
NULL;
1366 int *resultElements;
1373 audioformat = ENCODING_PCM_8BIT;
1376 audioformat = ENCODING_PCM_16BIT;
1379 audioformat = ENCODING_PCM_FLOAT;
1386 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for capture");
1389 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for output");
1394 return SDL_SetError(
"Java-side initialization failed");
1397 if ((*env)->GetArrayLength(env, (jintArray)
result) != 4) {
1398 return SDL_SetError(
"Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)
result));
1401 resultElements = (*env)->GetIntArrayElements(env, (jintArray)
result, &isCopy);
1403 audioformat = resultElements[1];
1404 switch (audioformat) {
1405 case ENCODING_PCM_8BIT:
1408 case ENCODING_PCM_16BIT:
1411 case ENCODING_PCM_FLOAT:
1415 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1419 (*env)->ReleaseIntArrayElements(env, (jintArray)
result, resultElements, JNI_ABORT);
1420 (*env)->DeleteLocalRef(env,
result);
1424 switch (audioformat) {
1425 case ENCODING_PCM_8BIT:
1428 if (audioBufferLocal) {
1429 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1430 (*env)->DeleteLocalRef(env, audioBufferLocal);
1434 case ENCODING_PCM_16BIT:
1437 if (audioBufferLocal) {
1438 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1439 (*env)->DeleteLocalRef(env, audioBufferLocal);
1443 case ENCODING_PCM_FLOAT:
1446 if (audioBufferLocal) {
1447 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1448 (*env)->DeleteLocalRef(env, audioBufferLocal);
1453 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1456 if (jbufobj ==
NULL) {
1457 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: could not allocate an audio buffer");
1462 captureBufferFormat = audioformat;
1463 captureBuffer = jbufobj;
1465 audioBufferFormat = audioformat;
1466 audioBuffer = jbufobj;
1468 numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj);
1473 switch (audioformat) {
1474 case ENCODING_PCM_8BIT:
1475 audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
1477 case ENCODING_PCM_16BIT:
1478 audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
1480 case ENCODING_PCM_FLOAT:
1481 audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
1484 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1492 return displayOrientation;
1499 jobject jDisplayObj = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDisplayDPI);
1500 jclass jDisplayClass = (*env)->GetObjectClass(env, jDisplayObj);
1502 jfieldID fidXdpi = (*env)->GetFieldID(env, jDisplayClass,
"xdpi",
"F");
1503 jfieldID fidYdpi = (*env)->GetFieldID(env, jDisplayClass,
"ydpi",
"F");
1504 jfieldID fidDdpi = (*env)->GetFieldID(env, jDisplayClass,
"densityDpi",
"I");
1506 float nativeXdpi = (*env)->GetFloatField(env, jDisplayObj, fidXdpi);
1507 float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi);
1508 int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi);
1511 (*env)->DeleteLocalRef(env, jDisplayObj);
1512 (*env)->DeleteLocalRef(env, jDisplayClass);
1515 *ddpi = (float)nativeDdpi;
1529 return audioBufferPinned;
1536 switch (audioBufferFormat) {
1537 case ENCODING_PCM_8BIT:
1538 (*env)->ReleaseByteArrayElements(env, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
1539 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
1541 case ENCODING_PCM_16BIT:
1542 (*env)->ReleaseShortArrayElements(env, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
1543 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
1545 case ENCODING_PCM_FLOAT:
1546 (*env)->ReleaseFloatArrayElements(env, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
1547 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
1550 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled audio buffer format");
1560 jboolean isCopy = JNI_FALSE;
1563 switch (captureBufferFormat) {
1564 case ENCODING_PCM_8BIT:
1565 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
1566 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
1568 jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy);
1570 (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
1573 case ENCODING_PCM_16BIT:
1574 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen /
sizeof(
Sint16)));
1575 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
1577 jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
1580 (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
1583 case ENCODING_PCM_FLOAT:
1584 SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen /
sizeof(
float)));
1585 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
1587 jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
1588 br *=
sizeof(float);
1590 (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT);
1594 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled capture buffer format");
1604 switch (captureBufferFormat) {
1605 case ENCODING_PCM_8BIT:
1607 const jint
len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
1608 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) ==
len) { }
1611 case ENCODING_PCM_16BIT:
1613 const jint
len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
1614 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) ==
len) { }
1617 case ENCODING_PCM_FLOAT:
1619 const jint
len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
1620 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) ==
len) { }
1624 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1628 switch (captureBufferFormat) {
1629 case ENCODING_PCM_8BIT:
1630 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
1632 case ENCODING_PCM_16BIT:
1633 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
1635 case ENCODING_PCM_FLOAT:
1636 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
1639 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1650 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose);
1651 if (captureBuffer) {
1652 (*env)->DeleteGlobalRef(env, captureBuffer);
1653 captureBuffer =
NULL;
1656 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose);
1658 (*env)->DeleteGlobalRef(env, audioBuffer);
1660 audioBufferPinned =
NULL;
1668 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id);
1676 jthrowable exception;
1681 exception = (*env)->ExceptionOccurred(env);
1682 if (exception !=
NULL) {
1686 (*env)->ExceptionClear(env);
1689 jclass exceptionClass = (*env)->GetObjectClass(env, exception);
1690 jclass classClass = (*env)->FindClass(env,
"java/lang/Class");
1691 jstring exceptionName;
1692 const char *exceptionNameUTF8;
1693 jstring exceptionMessage;
1695 mid = (*env)->GetMethodID(env, classClass,
"getName",
"()Ljava/lang/String;");
1696 exceptionName = (jstring)(*env)->CallObjectMethod(env, exceptionClass, mid);
1697 exceptionNameUTF8 = (*env)->GetStringUTFChars(env, exceptionName, 0);
1699 mid = (*env)->GetMethodID(env, exceptionClass,
"getMessage",
"()Ljava/lang/String;");
1700 exceptionMessage = (jstring)(*env)->CallObjectMethod(env, exception, mid);
1702 if (exceptionMessage !=
NULL) {
1703 const char *exceptionMessageUTF8 = (*env)->GetStringUTFChars(env, exceptionMessage, 0);
1704 SDL_SetError(
"%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
1705 (*env)->ReleaseStringUTFChars(env, exceptionMessage, exceptionMessageUTF8);
1710 (*env)->ReleaseStringUTFChars(env, exceptionName, exceptionNameUTF8);
1719static int Internal_Android_JNI_FileOpen(
SDL_RWops *
ctx)
1721 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1727 jobject assetManager;
1728 jobject inputStream;
1730 jobject readableByteChannel;
1731 jstring fileNameJString;
1734 jfieldID descriptor;
1737 if (!LocalReferenceHolder_Init(&refs, env)) {
1741 fileNameJString = (jstring)
ctx->hidden.androidio.fileNameRef;
1742 ctx->hidden.androidio.position = 0;
1745 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
1748 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
1749 "getAssets",
"()Landroid/content/res/AssetManager;");
1750 assetManager = (*env)->CallObjectMethod(env,
context, mid);
1755 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, assetManager),
"openFd",
"(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
1756 inputStream = (*env)->CallObjectMethod(env, assetManager, mid, fileNameJString);
1757 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1761 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
"getStartOffset",
"()J");
1762 ctx->hidden.androidio.offset = (long)(*env)->CallLongMethod(env, inputStream, mid);
1763 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1767 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
"getDeclaredLength",
"()J");
1768 ctx->hidden.androidio.size = (long)(*env)->CallLongMethod(env, inputStream, mid);
1769 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1773 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
"getFileDescriptor",
"()Ljava/io/FileDescriptor;");
1774 fd = (*env)->CallObjectMethod(env, inputStream, mid);
1775 fdCls = (*env)->GetObjectClass(env,
fd);
1776 descriptor = (*env)->GetFieldID(env, fdCls,
"descriptor",
"I");
1777 ctx->hidden.androidio.fd = (*env)->GetIntField(env,
fd, descriptor);
1778 ctx->hidden.androidio.assetFileDescriptorRef = (*env)->NewGlobalRef(env, inputStream);
1781 lseek(
ctx->hidden.androidio.fd, (off_t)
ctx->hidden.androidio.offset, SEEK_SET);
1789 ctx->hidden.androidio.assetFileDescriptorRef =
NULL;
1792 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, assetManager),
1793 "open",
"(Ljava/lang/String;I)Ljava/io/InputStream;");
1794 inputStream = (*env)->CallObjectMethod(env, assetManager, mid, fileNameJString, 1 );
1795 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1797 inputStream = (*env)->CallStaticObjectMethod(env, mActivityClass, midOpenAPKExpansionInputStream, fileNameJString);
1802 if (Android_JNI_ExceptionOccurred(
SDL_FALSE) || !inputStream) {
1807 ctx->hidden.androidio.inputStreamRef = (*env)->NewGlobalRef(env, inputStream);
1817 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
1818 "available",
"()I");
1819 ctx->hidden.androidio.size = (long)(*env)->CallIntMethod(env, inputStream, mid);
1820 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1825 channels = (*env)->FindClass(env,
"java/nio/channels/Channels");
1826 mid = (*env)->GetStaticMethodID(env, channels,
1828 "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
1829 readableByteChannel = (*env)->CallStaticObjectMethod(
1830 env, channels, mid, inputStream);
1831 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1835 ctx->hidden.androidio.readableByteChannelRef =
1836 (*env)->NewGlobalRef(env, readableByteChannel);
1839 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, readableByteChannel),
1840 "read",
"(Ljava/nio/ByteBuffer;)I");
1841 ctx->hidden.androidio.readMethod = mid;
1848 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.fileNameRef);
1850 if(
ctx->hidden.androidio.inputStreamRef !=
NULL) {
1851 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.inputStreamRef);
1854 if(
ctx->hidden.androidio.readableByteChannelRef !=
NULL) {
1855 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.readableByteChannelRef);
1858 if(
ctx->hidden.androidio.assetFileDescriptorRef !=
NULL) {
1859 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.assetFileDescriptorRef);
1864 LocalReferenceHolder_Cleanup(&refs);
1869 const char *fileName,
const char *
mode)
1871 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1874 jstring fileNameJString;
1876 if (!LocalReferenceHolder_Init(&refs, env)) {
1877 LocalReferenceHolder_Cleanup(&refs);
1882 LocalReferenceHolder_Cleanup(&refs);
1886 fileNameJString = (*env)->NewStringUTF(env, fileName);
1887 ctx->hidden.androidio.fileNameRef = (*env)->NewGlobalRef(env, fileNameJString);
1888 ctx->hidden.androidio.inputStreamRef =
NULL;
1889 ctx->hidden.androidio.readableByteChannelRef =
NULL;
1890 ctx->hidden.androidio.readMethod =
NULL;
1891 ctx->hidden.androidio.assetFileDescriptorRef =
NULL;
1893 retval = Internal_Android_JNI_FileOpen(
ctx);
1894 LocalReferenceHolder_Cleanup(&refs);
1899 size_t size,
size_t maxnum)
1901 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1903 if (
ctx->hidden.androidio.assetFileDescriptorRef) {
1904 size_t bytesMax =
size * maxnum;
1906 if (
ctx->hidden.androidio.size != -1 &&
ctx->hidden.androidio.position + bytesMax >
ctx->hidden.androidio.size) {
1907 bytesMax =
ctx->hidden.androidio.size -
ctx->hidden.androidio.position;
1911 ctx->hidden.androidio.position +=
result;
1912 LocalReferenceHolder_Cleanup(&refs);
1915 LocalReferenceHolder_Cleanup(&refs);
1918 jlong bytesRemaining = (jlong) (
size * maxnum);
1919 jlong bytesMax = (jlong) (
ctx->hidden.androidio.size -
ctx->hidden.androidio.position);
1922 jobject readableByteChannel;
1923 jmethodID readMethod;
1927 if (bytesRemaining > bytesMax) bytesRemaining = bytesMax;
1930 if (!LocalReferenceHolder_Init(&refs, env)) {
1931 LocalReferenceHolder_Cleanup(&refs);
1935 readableByteChannel = (jobject)
ctx->hidden.androidio.readableByteChannelRef;
1936 readMethod = (jmethodID)
ctx->hidden.androidio.readMethod;
1937 byteBuffer = (*env)->NewDirectByteBuffer(env,
buffer, bytesRemaining);
1939 while (bytesRemaining > 0) {
1941 int result = (*env)->CallIntMethod(env, readableByteChannel, readMethod, byteBuffer);
1943 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1944 LocalReferenceHolder_Cleanup(&refs);
1952 bytesRemaining -=
result;
1954 ctx->hidden.androidio.position +=
result;
1956 LocalReferenceHolder_Cleanup(&refs);
1957 return bytesRead /
size;
1964 SDL_SetError(
"Cannot write to Android package filesystem");
1970 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1975 if (!LocalReferenceHolder_Init(&refs, env)) {
1976 LocalReferenceHolder_Cleanup(&refs);
1977 return SDL_SetError(
"Failed to allocate enough JVM local references");
1982 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.fileNameRef);
1985 if (
ctx->hidden.androidio.assetFileDescriptorRef) {
1986 jobject inputStream = (jobject)
ctx->hidden.androidio.assetFileDescriptorRef;
1987 jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
1989 (*env)->CallVoidMethod(env, inputStream, mid);
1990 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.assetFileDescriptorRef);
1991 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1996 jobject inputStream = (jobject)
ctx->hidden.androidio.inputStreamRef;
1999 jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream),
2001 (*env)->CallVoidMethod(env, inputStream, mid);
2002 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.inputStreamRef);
2003 (*env)->DeleteGlobalRef(env, (jobject)
ctx->hidden.androidio.readableByteChannelRef);
2004 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
2014 LocalReferenceHolder_Cleanup(&refs);
2021 return ctx->hidden.androidio.size;
2026 if (
ctx->hidden.androidio.assetFileDescriptorRef) {
2030 if (
ctx->hidden.androidio.size != -1 &&
offset >
ctx->hidden.androidio.size)
offset =
ctx->hidden.androidio.size;
2034 offset +=
ctx->hidden.androidio.position;
2035 if (
ctx->hidden.androidio.size != -1 &&
offset >
ctx->hidden.androidio.size)
offset =
ctx->hidden.androidio.size;
2046 ret = lseek(
ctx->hidden.androidio.fd, (off_t)
offset, SEEK_SET);
2047 if (ret == -1)
return -1;
2048 ctx->hidden.androidio.position = ret -
ctx->hidden.androidio.offset;
2058 newPosition =
ctx->hidden.androidio.position +
offset;
2061 newPosition =
ctx->hidden.androidio.size +
offset;
2068 if (newPosition < 0) {
2071 if (newPosition >
ctx->hidden.androidio.size) {
2072 newPosition =
ctx->hidden.androidio.size;
2075 movement = newPosition -
ctx->hidden.androidio.position;
2077 unsigned char buffer[4096];
2080 while (movement > 0) {
2083 if (amount > movement) {
2095 }
else if (movement < 0) {
2099 Internal_Android_JNI_FileOpen(
ctx);
2104 return ctx->hidden.androidio.position;
2110 return Internal_Android_JNI_FileClose(
ctx,
SDL_TRUE);
2116 jstring
string = (*env)->NewStringUTF(env,
text);
2117 (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText,
string);
2118 (*env)->DeleteLocalRef(env,
string);
2128 string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText);
2130 const char *utf = (*env)->GetStringUTFChars(env,
string, 0);
2133 (*env)->ReleaseStringUTFChars(env,
string, utf);
2135 (*env)->DeleteLocalRef(env,
string);
2144 jboolean
retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText);
2154 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2166 if (!LocalReferenceHolder_Init(&refs, env)) {
2167 LocalReferenceHolder_Cleanup(&refs);
2173 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2175 action = (*env)->NewStringUTF(env,
"android.intent.action.BATTERY_CHANGED");
2177 cls = (*env)->FindClass(env,
"android/content/IntentFilter");
2179 mid = (*env)->GetMethodID(env, cls,
"<init>",
"(Ljava/lang/String;)V");
2180 filter = (*env)->NewObject(env, cls, mid, action);
2182 (*env)->DeleteLocalRef(env, action);
2184 mid = (*env)->GetMethodID(env, mActivityClass,
"registerReceiver",
"(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
2187 (*env)->DeleteLocalRef(env,
filter);
2189 cls = (*env)->GetObjectClass(env, intent);
2191 imid = (*env)->GetMethodID(env, cls,
"getIntExtra",
"(Ljava/lang/String;I)I");
2194#define GET_INT_EXTRA(var, key) \
2196 iname = (*env)->NewStringUTF(env, key); \
2197 var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
2198 (*env)->DeleteLocalRef(env, iname);
2200 bmid = (*env)->GetMethodID(env, cls,
"getBooleanExtra",
"(Ljava/lang/String;Z)Z");
2203#define GET_BOOL_EXTRA(var, key) \
2205 bname = (*env)->NewStringUTF(env, key); \
2206 var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
2207 (*env)->DeleteLocalRef(env, bname);
2211 GET_INT_EXTRA(plug,
"plugged")
2213 LocalReferenceHolder_Cleanup(&refs);
2218 *plugged = (0 < plug) ? 1 : 0;
2223 GET_INT_EXTRA(status,
"status")
2225 LocalReferenceHolder_Cleanup(&refs);
2229 *charged = (status == 5) ? 1 : 0;
2233 GET_BOOL_EXTRA(present,
"present")
2234 *battery = present ? 1 : 0;
2247 GET_INT_EXTRA(level_temp,
"level")
2252 GET_INT_EXTRA(scale_temp,
"scale")
2257 LocalReferenceHolder_Cleanup(&refs);
2263 (*env)->DeleteLocalRef(env, intent);
2265 LocalReferenceHolder_Cleanup(&refs);
2272 (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch);
2278 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices);
2284 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
2290 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity,
length);
2296 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id);
2300#define COMMAND_SET_KEEP_SCREEN_ON 5
2307 success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midSendMessage, command,
param);
2308 return success ? 0 : -1;
2319 (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput,
2329 const int COMMAND_TEXTEDIT_HIDE = 3;
2336 jboolean is_shown = 0;
2337 is_shown = (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsScreenKeyboardShown);
2350 jintArray button_flags;
2351 jintArray button_ids;
2352 jobjectArray button_texts;
2362 clazz = (*env)->FindClass(env,
"java/lang/String");
2364 title = (*env)->NewStringUTF(env, messageboxdata->
title);
2367 button_flags = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2368 button_ids = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2369 button_texts = (*env)->NewObjectArray(env, messageboxdata->
numbuttons,
2373 (*env)->SetIntArrayRegion(env, button_flags,
i, 1, &temp);
2375 (*env)->SetIntArrayRegion(env, button_ids,
i, 1, &temp);
2377 (*env)->SetObjectArrayElement(env, button_texts,
i,
text);
2378 (*env)->DeleteLocalRef(env,
text);
2384 temp = (0xFF << 24) |
2388 (*env)->SetIntArrayRegion(env,
colors,
i, 1, &temp);
2394 (*env)->DeleteLocalRef(env, clazz);
2397 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2399 clazz = (*env)->GetObjectClass(env,
context);
2401 mid = (*env)->GetMethodID(env, clazz,
2402 "messageboxShowMessageBox",
"(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
2403 *buttonid = (*env)->CallIntMethod(env,
context, mid,
2404 messageboxdata->
flags,
2412 (*env)->DeleteLocalRef(env,
context);
2413 (*env)->DeleteLocalRef(env, clazz);
2417 (*env)->DeleteLocalRef(env, title);
2418 (*env)->DeleteLocalRef(env,
message);
2419 (*env)->DeleteLocalRef(env, button_flags);
2420 (*env)->DeleteLocalRef(env, button_ids);
2421 (*env)->DeleteLocalRef(env, button_texts);
2422 (*env)->DeleteLocalRef(env,
colors);
2430// Functions exposed to SDL applications in SDL_system.h
2449 return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2454 static int sdk_version;
2456 char sdk[PROP_VALUE_MAX] = {0};
2457 if (__system_property_get(
"ro.build.version.sdk", sdk) != 0) {
2467 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet);
2473 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV);
2479 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);
2485 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
2491 return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
2496 static char *s_AndroidInternalFilesPath =
NULL;
2498 if (!s_AndroidInternalFilesPath) {
2499 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2507 if (!LocalReferenceHolder_Init(&refs, env)) {
2508 LocalReferenceHolder_Cleanup(&refs);
2513 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2516 LocalReferenceHolder_Cleanup(&refs);
2521 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
2522 "getFilesDir",
"()Ljava/io/File;");
2523 fileObject = (*env)->CallObjectMethod(env,
context, mid);
2526 LocalReferenceHolder_Cleanup(&refs);
2531 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2532 "getCanonicalPath",
"()Ljava/lang/String;");
2533 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2534 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
2535 LocalReferenceHolder_Cleanup(&refs);
2543 LocalReferenceHolder_Cleanup(&refs);
2545 return s_AndroidInternalFilesPath;
2550 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2553 jstring stateString;
2558 if (!LocalReferenceHolder_Init(&refs, env)) {
2559 LocalReferenceHolder_Cleanup(&refs);
2563 cls = (*env)->FindClass(env,
"android/os/Environment");
2564 mid = (*env)->GetStaticMethodID(env, cls,
2565 "getExternalStorageState",
"()Ljava/lang/String;");
2566 stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid);
2568 state = (*env)->GetStringUTFChars(env, stateString,
NULL);
2571 __android_log_print(ANDROID_LOG_INFO,
"SDL",
"external storage state: %s",
state);
2574 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
2575 SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
2577 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
2581 (*env)->ReleaseStringUTFChars(env, stateString,
state);
2583 LocalReferenceHolder_Cleanup(&refs);
2589 static char *s_AndroidExternalFilesPath =
NULL;
2591 if (!s_AndroidExternalFilesPath) {
2592 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2600 if (!LocalReferenceHolder_Init(&refs, env)) {
2601 LocalReferenceHolder_Cleanup(&refs);
2606 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2609 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
context),
2610 "getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;");
2611 fileObject = (*env)->CallObjectMethod(env,
context, mid,
NULL);
2614 LocalReferenceHolder_Cleanup(&refs);
2619 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2620 "getAbsolutePath",
"()Ljava/lang/String;");
2621 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2627 LocalReferenceHolder_Cleanup(&refs);
2629 return s_AndroidExternalFilesPath;
2634 if (!mActivityClass || !midGetManifestEnvironmentVariables) {
2635 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Request to get environment variables before JNI is ready");
2639 if (!bHasEnvironmentVariables) {
2641 SDL_bool ret = (*env)->CallStaticBooleanMethod(env, mActivityClass, midGetManifestEnvironmentVariables);
2643 bHasEnvironmentVariables =
SDL_TRUE;
2651 int custom_cursor = 0;
2656 custom_cursor = (*env)->CallStaticIntMethod(env, mActivityClass, midCreateCustomCursor,
pixels,
surface->w,
surface->h,
hot_x, hot_y);
2657 (*env)->DeleteLocalRef(env,
pixels);
2661 return custom_cursor;
2668 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetCustomCursor, cursorID);
2674 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetSystemCursor, cursorID);
2680 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSupportsRelativeMouse);
2686 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetRelativeMouseEnabled, (
enabled == 1));
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_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_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)
char * Android_JNI_GetClipboardText(void)
void Android_JNI_SetWindowStyle(SDL_bool fullscreen)
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
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)
JNIEnv * Android_JNI_GetEnv(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)
ANativeWindow * Android_JNI_GetNativeWindow(void)
void Android_JNI_HideTextInput(void)
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
void Android_JNI_GetManifestEnvironmentVariables(void)
int Android_JNI_FileClose(SDL_RWops *ctx)
int Android_JNI_SendMessage(int command, int param)
void * Android_JNI_GetAudioBuffer(void)
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_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)
@ SDL_APP_WILLENTERFOREGROUND
@ SDL_APP_DIDENTERFOREGROUND
@ SDL_APP_WILLENTERBACKGROUND
@ SDL_APP_DIDENTERBACKGROUND
#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
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
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.
SDL_VideoDisplay * SDL_GetDisplay(int displayIndex)
SDL_VideoDevice * SDL_GetVideoDevice(void)
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_WINDOWEVENT_MINIMIZED
@ SDL_WINDOWEVENT_RESTORED
@ 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[]
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