21 #include "../../SDL_internal.h" 33 #include "keyinfotable.h" 35 #include "../../events/SDL_events_c.h" 36 #include "../../video/android/SDL_androidkeyboard.h" 37 #include "../../video/android/SDL_androidmouse.h" 38 #include "../../video/android/SDL_androidtouch.h" 39 #include "../../video/android/SDL_androidvideo.h" 40 #include "../../video/android/SDL_androidwindow.h" 41 #include "../../joystick/android/SDL_sysjoystick_c.h" 42 #include "../../haptic/android/SDL_syshaptic_c.h" 44 #include <android/log.h> 46 #include <sys/types.h> 52 #define LOGI(...) do {} while (0) 53 #define LOGE(...) do {} while (0) 56 #define SDL_JAVA_PREFIX org_libsdl_app 57 #define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function) 58 #define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function 59 #define SDL_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function) 60 #define SDL_JAVA_AUDIO_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function) 61 #define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) 62 #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) 65 #define ENCODING_PCM_8BIT 3 66 #define ENCODING_PCM_16BIT 2 67 #define ENCODING_PCM_FLOAT 4 70 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
71 JNIEnv* mEnv, jclass cls);
73 JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(
74 JNIEnv* env, jclass cls,
75 jstring library, jstring
function, jobject
array);
77 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
78 JNIEnv* env, jclass jcls,
81 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
82 JNIEnv* env, jclass jcls,
83 jint surfaceWidth, jint surfaceHeight,
84 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate);
86 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
87 JNIEnv* env, jclass jcls);
89 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(
90 JNIEnv* env, jclass jcls);
92 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
93 JNIEnv* env, jclass jcls,
96 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
97 JNIEnv* env, jclass jcls,
100 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
101 JNIEnv* env, jclass jcls);
103 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
104 JNIEnv* env, jclass jcls,
105 jint touch_device_id_in, jint pointer_finger_id_in,
106 jint action, jfloat
x, jfloat
y, jfloat
p);
108 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
109 JNIEnv* env, jclass jcls,
110 jint
button, jint action, jfloat
x, jfloat
y, jboolean relative);
112 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
113 JNIEnv* env, jclass jcls,
114 jfloat
x, jfloat
y, jfloat
z);
116 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
117 JNIEnv* env, jclass jcls);
119 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
120 JNIEnv* env, jclass cls);
122 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
123 JNIEnv* env, jclass cls);
125 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
126 JNIEnv* env, jclass cls);
128 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
129 JNIEnv* env, jclass cls);
131 JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
132 JNIEnv* env, jclass cls,
135 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
136 JNIEnv* env, jclass cls,
139 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)(
140 JNIEnv* env, jclass cls);
142 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
143 JNIEnv* env, jclass cls,
147 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
148 JNIEnv* env, jclass cls,
149 jstring
text, jint newCursorPosition);
151 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
152 JNIEnv* env, jclass cls,
155 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
156 JNIEnv* env, jclass cls,
157 jstring
text, jint newCursorPosition);
160 JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(
161 JNIEnv *env, jclass jcls);
164 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(
165 JNIEnv *env, jclass jcls);
167 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
168 JNIEnv* env, jclass jcls,
169 jint device_id, jint keycode);
171 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
172 JNIEnv* env, jclass jcls,
173 jint device_id, jint keycode);
175 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
176 JNIEnv* env, jclass jcls,
177 jint device_id, jint
axis, jfloat
value);
179 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
180 JNIEnv* env, jclass jcls,
181 jint device_id, jint hat_id, jint
x, jint
y);
183 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
184 JNIEnv* env, jclass jcls,
185 jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,
186 jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs);
188 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
189 JNIEnv* env, jclass jcls,
192 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
193 JNIEnv* env, jclass jcls,
194 jint device_id, jstring device_name);
196 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
197 JNIEnv* env, jclass jcls,
205 static void Android_JNI_ThreadDestroyed(
void*);
206 static void checkJNIReady(
void);
217 static pthread_key_t mThreadKey;
218 static JavaVM* mJavaVM;
221 static jclass mActivityClass;
224 static jmethodID midGetNativeSurface;
225 static jmethodID midSetActivityTitle;
226 static jmethodID midSetWindowStyle;
227 static jmethodID midSetOrientation;
228 static jmethodID midGetContext;
229 static jmethodID midIsTablet;
230 static jmethodID midIsAndroidTV;
231 static jmethodID midIsChromebook;
232 static jmethodID midIsDeXMode;
233 static jmethodID midManualBackButton;
234 static jmethodID midInputGetInputDeviceIds;
235 static jmethodID midSendMessage;
236 static jmethodID midShowTextInput;
237 static jmethodID midIsScreenKeyboardShown;
238 static jmethodID midClipboardSetText;
239 static jmethodID midClipboardGetText;
240 static jmethodID midClipboardHasText;
241 static jmethodID midOpenAPKExpansionInputStream;
242 static jmethodID midGetManifestEnvironmentVariables;
243 static jmethodID midGetDisplayDPI;
244 static jmethodID midCreateCustomCursor;
245 static jmethodID midSetCustomCursor;
246 static jmethodID midSetSystemCursor;
247 static jmethodID midSupportsRelativeMouse;
248 static jmethodID midSetRelativeMouseEnabled;
251 static jclass mAudioManagerClass;
254 static jmethodID midAudioOpen;
255 static jmethodID midAudioWriteByteBuffer;
256 static jmethodID midAudioWriteShortBuffer;
257 static jmethodID midAudioWriteFloatBuffer;
258 static jmethodID midAudioClose;
259 static jmethodID midCaptureOpen;
260 static jmethodID midCaptureReadByteBuffer;
261 static jmethodID midCaptureReadShortBuffer;
262 static jmethodID midCaptureReadFloatBuffer;
263 static jmethodID midCaptureClose;
266 static jclass mControllerManagerClass;
269 static jmethodID midPollInputDevices;
270 static jmethodID midPollHapticDevices;
271 static jmethodID midHapticRun;
272 static jmethodID midHapticStop;
275 static jfieldID fidSeparateMouseAndTouch;
278 static float fLastAccelerometer[3];
288 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm,
void* reserved)
292 LOGI(
"JNI_OnLoad called");
293 if ((*mJavaVM)->GetEnv(mJavaVM, (
void**) &env, JNI_VERSION_1_4) != JNI_OK) {
294 LOGE(
"Failed to get the environment using GetEnv()");
301 if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) {
302 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"Error initializing pthread key");
306 return JNI_VERSION_1_4;
311 if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) {
320 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls)
322 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeSetupJNI()");
326 mActivityClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
328 midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
329 "getNativeSurface",
"()Landroid/view/Surface;");
330 midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
331 "setActivityTitle",
"(Ljava/lang/String;)Z");
332 midSetWindowStyle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
333 "setWindowStyle",
"(Z)V");
334 midSetOrientation = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
335 "setOrientation",
"(IIZLjava/lang/String;)V");
336 midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
337 "getContext",
"()Landroid/content/Context;");
338 midIsTablet = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
340 midIsAndroidTV = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
341 "isAndroidTV",
"()Z");
342 midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
343 "isChromebook",
"()Z");
344 midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
346 midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
347 "manualBackButton",
"()V");
348 midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
349 "inputGetInputDeviceIds",
"(I)[I");
350 midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
351 "sendMessage",
"(II)Z");
352 midShowTextInput = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
353 "showTextInput",
"(IIII)Z");
354 midIsScreenKeyboardShown = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
355 "isScreenKeyboardShown",
"()Z");
356 midClipboardSetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
357 "clipboardSetText",
"(Ljava/lang/String;)V");
358 midClipboardGetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
359 "clipboardGetText",
"()Ljava/lang/String;");
360 midClipboardHasText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
361 "clipboardHasText",
"()Z");
362 midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
363 "openAPKExpansionInputStream",
"(Ljava/lang/String;)Ljava/io/InputStream;");
365 midGetManifestEnvironmentVariables = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
366 "getManifestEnvironmentVariables",
"()Z");
368 midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"getDisplayDPI",
"()Landroid/util/DisplayMetrics;");
369 midCreateCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"createCustomCursor",
"([IIIII)I");
370 midSetCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"setCustomCursor",
"(I)Z");
371 midSetSystemCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"setSystemCursor",
"(I)Z");
373 midSupportsRelativeMouse = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"supportsRelativeMouse",
"()Z");
374 midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"setRelativeMouseEnabled",
"(Z)Z");
377 if (!midGetNativeSurface ||
378 !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds ||
379 !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
380 !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
381 !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
382 !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
383 !midIsChromebook || !midIsDeXMode || !midManualBackButton) {
384 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
387 fidSeparateMouseAndTouch = (*mEnv)->GetStaticFieldID(mEnv, mActivityClass,
"mSeparateMouseAndTouch",
"Z");
389 if (!fidSeparateMouseAndTouch) {
390 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java static fields, do you have the latest version of SDLActivity.java?");
397 JNIEXPORT
void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls)
399 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"AUDIO nativeSetupJNI()");
403 mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
405 midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
406 "audioOpen",
"(IIII)[I");
407 midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
408 "audioWriteByteBuffer",
"([B)V");
409 midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
410 "audioWriteShortBuffer",
"([S)V");
411 midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
412 "audioWriteFloatBuffer",
"([F)V");
413 midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
414 "audioClose",
"()V");
415 midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
416 "captureOpen",
"(IIII)[I");
417 midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
418 "captureReadByteBuffer",
"([BZ)I");
419 midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
420 "captureReadShortBuffer",
"([SZ)I");
421 midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
422 "captureReadFloatBuffer",
"([FZ)I");
423 midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
424 "captureClose",
"()V");
426 if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
427 !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) {
428 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
435 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls)
437 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"CONTROLLER nativeSetupJNI()");
441 mControllerManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
443 midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
444 "pollInputDevices",
"()V");
445 midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
446 "pollHapticDevices",
"()V");
447 midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
448 "hapticRun",
"(IFI)V");
449 midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
450 "hapticStop",
"(I)V");
452 if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) {
453 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?");
460 typedef int (*SDL_main_func)(
int argc,
char *argv[]);
463 JNIEXPORT
int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv* env, jclass cls, jstring library, jstring
function, jobject
array)
466 const char *library_file;
467 void *library_handle;
469 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeRunMain()");
471 library_file = (*env)->GetStringUTFChars(env, library,
NULL);
472 library_handle = dlopen(library_file, RTLD_GLOBAL);
473 if (library_handle) {
474 const char *function_name;
477 function_name = (*env)->GetStringUTFChars(env,
function,
NULL);
478 SDL_main = (SDL_main_func)dlsym(library_handle, function_name);
486 len = (*env)->GetArrayLength(env,
array);
493 for (i = 0; i <
len; ++
i) {
496 jstring
string = (*env)->GetObjectArrayElement(env,
array, i);
498 utf = (*env)->GetStringUTFChars(env,
string, 0);
501 (*env)->ReleaseStringUTFChars(env,
string, utf);
503 (*env)->DeleteLocalRef(env,
string);
517 for (i = 0; i < argc; ++
i) {
523 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
525 (*env)->ReleaseStringUTFChars(env,
function, function_name);
527 dlclose(library_handle);
530 __android_log_print(ANDROID_LOG_ERROR,
"SDL",
"nativeRunMain(): Couldn't load library %s", library_file);
532 (*env)->ReleaseStringUTFChars(env, library, library_file);
541 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
542 JNIEnv* env, jclass jcls,
547 (*env)->ReleaseStringUTFChars(env,
filename, path);
552 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
553 JNIEnv* env, jclass jcls,
554 jint surfaceWidth, jint surfaceHeight,
555 jint deviceWidth, jint deviceHeight, jint
format, jfloat rate)
560 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
561 JNIEnv *env, jclass jcls,
569 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
570 JNIEnv* env, jclass jcls,
571 jint device_id, jint keycode)
573 return Android_OnPadDown(device_id, keycode);
577 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(
578 JNIEnv* env, jclass jcls,
579 jint device_id, jint keycode)
581 return Android_OnPadUp(device_id, keycode);
585 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(
586 JNIEnv* env, jclass jcls,
589 Android_OnJoy(device_id, axis,
value);
593 JNIEXPORT
void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
594 JNIEnv* env, jclass jcls,
595 jint device_id, jint hat_id, jint
x, jint
y)
597 Android_OnHat(device_id, hat_id, x,
y);
601 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
602 JNIEnv* env, jclass jcls,
603 jint device_id, jstring device_name, jstring device_desc,
604 jint vendor_id, jint product_id, jboolean is_accelerometer,
605 jint button_mask, jint naxes, jint nhats, jint nballs)
608 const char *
name = (*env)->GetStringUTFChars(env, device_name,
NULL);
609 const char *desc = (*env)->GetStringUTFChars(env, device_desc,
NULL);
611 retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ?
SDL_TRUE :
SDL_FALSE, button_mask, naxes, nhats, nballs);
613 (*env)->ReleaseStringUTFChars(env, device_name, name);
614 (*env)->ReleaseStringUTFChars(env, device_desc, desc);
619 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
620 JNIEnv* env, jclass jcls,
623 return Android_RemoveJoystick(device_id);
626 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(
627 JNIEnv* env, jclass jcls, jint device_id, jstring device_name)
630 const char *name = (*env)->GetStringUTFChars(env, device_name,
NULL);
632 retval = Android_AddHaptic(device_id, name);
634 (*env)->ReleaseStringUTFChars(env, device_name, name);
639 JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
640 JNIEnv* env, jclass jcls, jint device_id)
642 return Android_RemoveHaptic(device_id);
647 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv* env, jclass jcls)
673 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv* env, jclass jcls)
690 SDL_EGL_MakeCurrent(_this,
NULL,
NULL);
700 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(
701 JNIEnv* env, jclass jcls,
708 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(
709 JNIEnv* env, jclass jcls,
716 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(
717 JNIEnv* env, jclass jcls)
725 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
726 JNIEnv* env, jclass jcls,
727 jint touch_device_id_in, jint pointer_finger_id_in,
728 jint action, jfloat
x, jfloat
y, jfloat
p)
734 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
735 JNIEnv* env, jclass jcls,
736 jint
button, jint action, jfloat
x, jfloat
y, jboolean relative)
742 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
743 JNIEnv* env, jclass jcls,
744 jfloat
x, jfloat
y, jfloat
z)
746 fLastAccelerometer[0] =
x;
747 fLastAccelerometer[1] =
y;
748 fLastAccelerometer[2] =
z;
753 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
754 JNIEnv* env, jclass jcls)
760 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
761 JNIEnv* env, jclass cls)
767 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
768 JNIEnv* env, jclass cls)
783 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativePause)(
784 JNIEnv* env, jclass cls)
786 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativePause()");
801 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
802 JNIEnv* env, jclass cls)
804 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"nativeResume()");
819 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
820 JNIEnv* env, jclass cls,
821 jstring
text, jint newCursorPosition)
823 const char *utftext = (*env)->GetStringUTFChars(env, text,
NULL);
827 (*env)->ReleaseStringUTFChars(env, text, utftext);
830 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
831 JNIEnv* env, jclass cls,
838 if (chUnicode < 127) {
853 if (mod & KMOD_SHIFT) {
860 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
861 JNIEnv* env, jclass cls,
862 jstring
text, jint newCursorPosition)
864 const char *utftext = (*env)->GetStringUTFChars(env, text,
NULL);
868 (*env)->ReleaseStringUTFChars(env, text, utftext);
871 JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
872 JNIEnv* env, jclass cls,
875 const char *utfname = (*env)->GetStringUTFChars(env, name,
NULL);
878 jstring
result = (*env)->NewStringUTF(env, hint);
879 (*env)->ReleaseStringUTFChars(env, name, utfname);
884 JNIEXPORT
void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
885 JNIEnv* env, jclass cls,
888 const char *utfname = (*env)->GetStringUTFChars(env, name,
NULL);
889 const char *utfvalue = (*env)->GetStringUTFChars(env,
value,
NULL);
893 (*env)->ReleaseStringUTFChars(env, name, utfname);
894 (*env)->ReleaseStringUTFChars(env,
value, utfvalue);
902 static int s_active = 0;
903 struct LocalReferenceHolder
909 static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *
func)
911 struct LocalReferenceHolder refholder;
912 refholder.m_env =
NULL;
913 refholder.m_func =
func;
920 static SDL_bool LocalReferenceHolder_Init(
struct LocalReferenceHolder *refholder, JNIEnv *env)
922 const int capacity = 16;
923 if ((*env)->PushLocalFrame(env, capacity) < 0) {
924 SDL_SetError(
"Failed to allocate enough JVM local references");
928 refholder->m_env = env;
932 static void LocalReferenceHolder_Cleanup(
struct LocalReferenceHolder *refholder)
935 SDL_Log(
"Leaving function %s", refholder->m_func);
937 if (refholder->m_env) {
938 JNIEnv* env = refholder->m_env;
939 (*env)->PopLocalFrame(env,
NULL);
944 static SDL_bool LocalReferenceHolder_IsActive(
void)
955 s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface);
956 anw = ANativeWindow_fromSurface(env, s);
957 (*env)->DeleteLocalRef(env, s);
966 jstring jtitle = (jstring)((*mEnv)->NewStringUTF(mEnv, title));
967 (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetActivityTitle, jtitle);
968 (*mEnv)->DeleteLocalRef(mEnv, jtitle);
974 (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0);
981 jstring jhint = (jstring)((*mEnv)->NewStringUTF(mEnv, (hint ? hint :
"")));
982 (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetOrientation, w, h, (resizable? 1 : 0), jhint);
983 (*mEnv)->DeleteLocalRef(mEnv, jhint);
992 for (i = 0; i < 3; ++
i) {
993 values[
i] = fLastAccelerometer[
i];
1002 static void Android_JNI_ThreadDestroyed(
void*
value)
1005 JNIEnv *env = (JNIEnv*) value;
1007 (*mJavaVM)->DetachCurrentThread(mJavaVM);
1008 pthread_setspecific(mThreadKey,
NULL);
1027 int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env,
NULL);
1029 LOGE(
"failed to attach current thread");
1042 pthread_setspecific(mThreadKey, (
void*) env);
1056 static int audioBufferFormat = 0;
1057 static jobject audioBuffer =
NULL;
1058 static void* audioBufferPinned =
NULL;
1059 static int captureBufferFormat = 0;
1060 static jobject captureBuffer =
NULL;
1065 int numBufferFrames;
1066 jobject jbufobj =
NULL;
1068 int *resultElements;
1074 LOGE(
"callback_handler: failed to attach current thread");
1080 audioformat = ENCODING_PCM_8BIT;
1083 audioformat = ENCODING_PCM_16BIT;
1086 audioformat = ENCODING_PCM_FLOAT;
1093 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for capture");
1094 result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->
freq, audioformat, spec->
channels, spec->
samples);
1096 __android_log_print(ANDROID_LOG_VERBOSE,
"SDL",
"SDL audio: opening device for output");
1097 result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->
freq, audioformat, spec->
channels, spec->
samples);
1099 if (result ==
NULL) {
1101 return SDL_SetError(
"Java-side initialization failed");
1104 if ((*env)->GetArrayLength(env, (jintArray)result) != 4) {
1105 return SDL_SetError(
"Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result));
1108 resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy);
1109 spec->
freq = resultElements[0];
1110 audioformat = resultElements[1];
1111 switch (audioformat) {
1112 case ENCODING_PCM_8BIT:
1115 case ENCODING_PCM_16BIT:
1118 case ENCODING_PCM_FLOAT:
1122 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1124 spec->
channels = resultElements[2];
1125 spec->
samples = resultElements[3];
1126 (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT);
1127 (*env)->DeleteLocalRef(env, result);
1131 switch (audioformat) {
1132 case ENCODING_PCM_8BIT:
1134 jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->
samples * spec->
channels);
1135 if (audioBufferLocal) {
1136 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1137 (*env)->DeleteLocalRef(env, audioBufferLocal);
1141 case ENCODING_PCM_16BIT:
1143 jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->
samples * spec->
channels);
1144 if (audioBufferLocal) {
1145 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1146 (*env)->DeleteLocalRef(env, audioBufferLocal);
1150 case ENCODING_PCM_FLOAT:
1152 jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->
samples * spec->
channels);
1153 if (audioBufferLocal) {
1154 jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
1155 (*env)->DeleteLocalRef(env, audioBufferLocal);
1160 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1163 if (jbufobj ==
NULL) {
1164 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: could not allocate an audio buffer");
1169 captureBufferFormat = audioformat;
1170 captureBuffer = jbufobj;
1172 audioBufferFormat = audioformat;
1173 audioBuffer = jbufobj;
1175 numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj);
1180 switch (audioformat) {
1181 case ENCODING_PCM_8BIT:
1182 audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
1184 case ENCODING_PCM_16BIT:
1185 audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
1187 case ENCODING_PCM_FLOAT:
1188 audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
1191 return SDL_SetError(
"Unexpected audio format from Java: %d\n", audioformat);
1201 jobject jDisplayObj = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDisplayDPI);
1202 jclass jDisplayClass = (*env)->GetObjectClass(env, jDisplayObj);
1204 jfieldID fidXdpi = (*env)->GetFieldID(env, jDisplayClass,
"xdpi",
"F");
1205 jfieldID fidYdpi = (*env)->GetFieldID(env, jDisplayClass,
"ydpi",
"F");
1206 jfieldID fidDdpi = (*env)->GetFieldID(env, jDisplayClass,
"densityDpi",
"I");
1208 float nativeXdpi = (*env)->GetFloatField(env, jDisplayObj, fidXdpi);
1209 float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi);
1210 int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi);
1213 (*env)->DeleteLocalRef(env, jDisplayObj);
1214 (*env)->DeleteLocalRef(env, jDisplayClass);
1217 *ddpi = (float)nativeDdpi;
1231 return audioBufferPinned;
1238 switch (audioBufferFormat) {
1239 case ENCODING_PCM_8BIT:
1240 (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
1241 (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
1243 case ENCODING_PCM_16BIT:
1244 (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
1245 (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
1247 case ENCODING_PCM_FLOAT:
1248 (*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
1249 (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
1252 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled audio buffer format");
1262 jboolean isCopy = JNI_FALSE;
1265 switch (captureBufferFormat) {
1266 case ENCODING_PCM_8BIT:
1267 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
1268 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
1270 jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy);
1272 (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
1275 case ENCODING_PCM_16BIT:
1276 SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen /
sizeof(
Sint16)));
1277 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
1279 jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
1282 (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
1285 case ENCODING_PCM_FLOAT:
1286 SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen /
sizeof(float)));
1287 br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
1289 jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
1290 br *=
sizeof(float);
1292 (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT);
1296 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: unhandled capture buffer format");
1306 switch (captureBufferFormat) {
1307 case ENCODING_PCM_8BIT:
1309 const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
1310 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) ==
len) { }
1313 case ENCODING_PCM_16BIT:
1315 const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
1316 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) ==
len) { }
1319 case ENCODING_PCM_FLOAT:
1321 const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
1322 while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) ==
len) { }
1326 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1330 switch (captureBufferFormat) {
1331 case ENCODING_PCM_8BIT:
1332 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
1334 case ENCODING_PCM_16BIT:
1335 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
1337 case ENCODING_PCM_FLOAT:
1338 (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
1341 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"SDL audio: flushing unhandled capture buffer format");
1352 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose);
1353 if (captureBuffer) {
1354 (*env)->DeleteGlobalRef(env, captureBuffer);
1355 captureBuffer =
NULL;
1358 (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose);
1360 (*env)->DeleteGlobalRef(env, audioBuffer);
1362 audioBufferPinned =
NULL;
1372 jthrowable exception;
1376 exception = (*mEnv)->ExceptionOccurred(mEnv);
1377 if (exception !=
NULL) {
1381 (*mEnv)->ExceptionClear(mEnv);
1384 jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception);
1385 jclass classClass = (*mEnv)->FindClass(mEnv,
"java/lang/Class");
1386 jstring exceptionName;
1387 const char* exceptionNameUTF8;
1388 jstring exceptionMessage;
1390 mid = (*mEnv)->GetMethodID(mEnv, classClass,
"getName",
"()Ljava/lang/String;");
1391 exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
1392 exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
1394 mid = (*mEnv)->GetMethodID(mEnv, exceptionClass,
"getMessage",
"()Ljava/lang/String;");
1395 exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
1397 if (exceptionMessage !=
NULL) {
1398 const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0);
1399 SDL_SetError(
"%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
1400 (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionMessage, exceptionMessageUTF8);
1405 (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionName, exceptionNameUTF8);
1414 static int Internal_Android_JNI_FileOpen(
SDL_RWops*
ctx)
1416 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1422 jobject assetManager;
1423 jobject inputStream;
1425 jobject readableByteChannel;
1426 jstring fileNameJString;
1429 jfieldID descriptor;
1432 if (!LocalReferenceHolder_Init(&refs, mEnv)) {
1436 fileNameJString = (jstring)ctx->
hidden.androidio.fileNameRef;
1437 ctx->
hidden.androidio.position = 0;
1440 context = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, midGetContext);
1443 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context),
1444 "getAssets",
"()Landroid/content/res/AssetManager;");
1445 assetManager = (*mEnv)->CallObjectMethod(mEnv, context, mid);
1450 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
"openFd",
"(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
1451 inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString);
1452 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1456 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
"getStartOffset",
"()J");
1457 ctx->
hidden.androidio.offset = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
1458 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1462 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
"getDeclaredLength",
"()J");
1463 ctx->
hidden.androidio.
size = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
1464 if (Android_JNI_ExceptionOccurred(
SDL_TRUE)) {
1468 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
"getFileDescriptor",
"()Ljava/io/FileDescriptor;");
1469 fd = (*mEnv)->CallObjectMethod(mEnv, inputStream, mid);
1470 fdCls = (*mEnv)->GetObjectClass(mEnv, fd);
1471 descriptor = (*mEnv)->GetFieldID(mEnv, fdCls,
"descriptor",
"I");
1472 ctx->
hidden.androidio.fd = (*mEnv)->GetIntField(mEnv, fd, descriptor);
1473 ctx->
hidden.androidio.assetFileDescriptorRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);
1476 lseek(ctx->
hidden.androidio.fd, (off_t)ctx->
hidden.androidio.offset, SEEK_SET);
1484 ctx->
hidden.androidio.assetFileDescriptorRef =
NULL;
1487 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
1488 "open",
"(Ljava/lang/String;I)Ljava/io/InputStream;");
1489 inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 );
1490 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1492 inputStream = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, midOpenAPKExpansionInputStream, fileNameJString);
1497 if (Android_JNI_ExceptionOccurred(
SDL_FALSE) || !inputStream) {
1502 ctx->
hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);
1512 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
1513 "available",
"()I");
1514 ctx->
hidden.androidio.
size = (long)(*mEnv)->CallIntMethod(mEnv, inputStream, mid);
1515 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1520 channels = (*mEnv)->FindClass(mEnv,
"java/nio/channels/Channels");
1521 mid = (*mEnv)->GetStaticMethodID(mEnv, channels,
1523 "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
1524 readableByteChannel = (*mEnv)->CallStaticObjectMethod(
1525 mEnv, channels, mid, inputStream);
1526 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1530 ctx->
hidden.androidio.readableByteChannelRef =
1531 (*mEnv)->NewGlobalRef(mEnv, readableByteChannel);
1534 mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, readableByteChannel),
1535 "read",
"(Ljava/nio/ByteBuffer;)I");
1536 ctx->
hidden.androidio.readMethod = mid;
1543 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.fileNameRef);
1545 if(ctx->
hidden.androidio.inputStreamRef !=
NULL) {
1546 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.inputStreamRef);
1549 if(ctx->
hidden.androidio.readableByteChannelRef !=
NULL) {
1550 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.readableByteChannelRef);
1553 if(ctx->
hidden.androidio.assetFileDescriptorRef !=
NULL) {
1554 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.assetFileDescriptorRef);
1559 LocalReferenceHolder_Cleanup(&refs);
1564 const char* fileName,
const char*
mode)
1566 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1569 jstring fileNameJString;
1571 if (!LocalReferenceHolder_Init(&refs, mEnv)) {
1572 LocalReferenceHolder_Cleanup(&refs);
1577 LocalReferenceHolder_Cleanup(&refs);
1581 fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
1582 ctx->
hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString);
1584 ctx->
hidden.androidio.readableByteChannelRef =
NULL;
1586 ctx->
hidden.androidio.assetFileDescriptorRef =
NULL;
1588 retval = Internal_Android_JNI_FileOpen(ctx);
1589 LocalReferenceHolder_Cleanup(&refs);
1594 size_t size,
size_t maxnum)
1596 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1598 if (ctx->
hidden.androidio.assetFileDescriptorRef) {
1599 size_t bytesMax = size * maxnum;
1604 result = read(ctx->
hidden.androidio.fd, buffer, bytesMax );
1607 LocalReferenceHolder_Cleanup(&refs);
1608 return result /
size;
1610 LocalReferenceHolder_Cleanup(&refs);
1613 jlong bytesRemaining = (jlong) (size * maxnum);
1614 jlong bytesMax = (jlong) (ctx->
hidden.androidio.
size - ctx->
hidden.androidio.position);
1617 jobject readableByteChannel;
1618 jmethodID readMethod;
1622 if (bytesRemaining > bytesMax) bytesRemaining = bytesMax;
1625 if (!LocalReferenceHolder_Init(&refs, mEnv)) {
1626 LocalReferenceHolder_Cleanup(&refs);
1630 readableByteChannel = (jobject)ctx->
hidden.androidio.readableByteChannelRef;
1631 readMethod = (jmethodID)ctx->
hidden.androidio.readMethod;
1632 byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
1634 while (bytesRemaining > 0) {
1636 int result = (*mEnv)->CallIntMethod(mEnv, readableByteChannel, readMethod, byteBuffer);
1638 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1639 LocalReferenceHolder_Cleanup(&refs);
1647 bytesRemaining -=
result;
1651 LocalReferenceHolder_Cleanup(&refs);
1652 return bytesRead /
size;
1657 size_t size,
size_t num)
1659 SDL_SetError(
"Cannot write to Android package filesystem");
1665 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1670 if (!LocalReferenceHolder_Init(&refs, mEnv)) {
1671 LocalReferenceHolder_Cleanup(&refs);
1672 return SDL_SetError(
"Failed to allocate enough JVM local references");
1677 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.fileNameRef);
1680 if (ctx->
hidden.androidio.assetFileDescriptorRef) {
1681 jobject inputStream = (jobject)ctx->
hidden.androidio.assetFileDescriptorRef;
1682 jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
1684 (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
1685 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.assetFileDescriptorRef);
1686 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1691 jobject inputStream = (jobject)ctx->
hidden.androidio.inputStreamRef;
1694 jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
1696 (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
1697 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.inputStreamRef);
1698 (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->
hidden.androidio.readableByteChannelRef);
1699 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
1709 LocalReferenceHolder_Cleanup(&refs);
1721 if (ctx->
hidden.androidio.assetFileDescriptorRef) {
1726 offset += ctx->
hidden.androidio.offset;
1729 offset += ctx->
hidden.androidio.position;
1731 offset += ctx->
hidden.androidio.offset;
1741 ret = lseek(ctx->
hidden.androidio.fd, (off_t)offset, SEEK_SET);
1742 if (ret == -1)
return -1;
1743 ctx->
hidden.androidio.position = ret - ctx->
hidden.androidio.offset;
1763 if (newPosition < 0) {
1766 if (newPosition > ctx->
hidden.androidio.
size) {
1770 movement = newPosition - ctx->
hidden.androidio.position;
1772 unsigned char buffer[4096];
1775 while (movement > 0) {
1778 if (amount > movement) {
1790 }
else if (movement < 0) {
1793 Internal_Android_JNI_FileClose(ctx,
SDL_FALSE);
1794 Internal_Android_JNI_FileOpen(ctx);
1799 return ctx->
hidden.androidio.position;
1805 return Internal_Android_JNI_FileClose(ctx,
SDL_TRUE);
1811 jstring
string = (*env)->NewStringUTF(env, text);
1812 (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText,
string);
1813 (*env)->DeleteLocalRef(env,
string);
1823 string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText);
1825 const char* utf = (*env)->GetStringUTFChars(env,
string, 0);
1828 (*env)->ReleaseStringUTFChars(env,
string, utf);
1830 (*env)->DeleteLocalRef(env,
string);
1839 jboolean retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText);
1849 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
1861 if (!LocalReferenceHolder_Init(&refs, env)) {
1862 LocalReferenceHolder_Cleanup(&refs);
1868 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
1870 action = (*env)->NewStringUTF(env,
"android.intent.action.BATTERY_CHANGED");
1872 cls = (*env)->FindClass(env,
"android/content/IntentFilter");
1874 mid = (*env)->GetMethodID(env, cls,
"<init>",
"(Ljava/lang/String;)V");
1875 filter = (*env)->NewObject(env, cls, mid, action);
1877 (*env)->DeleteLocalRef(env, action);
1879 mid = (*env)->GetMethodID(env, mActivityClass,
"registerReceiver",
"(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
1880 intent = (*env)->CallObjectMethod(env, context, mid,
NULL, filter);
1882 (*env)->DeleteLocalRef(env, filter);
1884 cls = (*env)->GetObjectClass(env, intent);
1886 imid = (*env)->GetMethodID(env, cls,
"getIntExtra",
"(Ljava/lang/String;I)I");
1889 #define GET_INT_EXTRA(var, key) \ 1891 iname = (*env)->NewStringUTF(env, key); \ 1892 var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ 1893 (*env)->DeleteLocalRef(env, iname); 1895 bmid = (*env)->GetMethodID(env, cls,
"getBooleanExtra",
"(Ljava/lang/String;Z)Z");
1898 #define GET_BOOL_EXTRA(var, key) \ 1900 bname = (*env)->NewStringUTF(env, key); \ 1901 var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ 1902 (*env)->DeleteLocalRef(env, bname); 1906 GET_INT_EXTRA(plug,
"plugged")
1908 LocalReferenceHolder_Cleanup(&refs);
1913 *plugged = (0 < plug) ? 1 : 0;
1918 GET_INT_EXTRA(status,
"status")
1920 LocalReferenceHolder_Cleanup(&refs);
1924 *charged = (status == 5) ? 1 : 0;
1928 GET_BOOL_EXTRA(present,
"present")
1929 *battery = present ? 1 : 0;
1942 GET_INT_EXTRA(level_temp,
"level")
1947 GET_INT_EXTRA(scale_temp,
"scale")
1951 if ((level == -1) || (scale == -1)) {
1952 LocalReferenceHolder_Cleanup(&refs);
1955 *percent = level * 100 /
scale;
1958 (*env)->DeleteLocalRef(env, intent);
1960 LocalReferenceHolder_Cleanup(&refs);
1968 jintArray
array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, midInputGetInputDeviceIds, sources);
1972 number = (int) (*env)->GetArrayLength(env, array);
1974 jint* elements = (*env)->GetIntArrayElements(env, array,
NULL);
1978 for (i = 0; i < number; ++
i) {
1979 (*ids)[
i] = elements[
i];
1981 (*env)->ReleaseIntArrayElements(env, array, elements, JNI_ABORT);
1984 (*env)->DeleteLocalRef(env, array);
1993 (*env)->SetStaticBooleanField(env, mActivityClass, fidSeparateMouseAndTouch, new_value ? JNI_TRUE : JNI_FALSE);
1999 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices);
2005 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
2011 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length);
2017 (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id);
2021 #define COMMAND_SET_KEEP_SCREEN_ON 5 2028 success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midSendMessage, command, param);
2029 return success ? 0 : -1;
2040 (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput,
2050 const int COMMAND_TEXTEDIT_HIDE = 3;
2057 jboolean is_shown = 0;
2058 is_shown = (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midIsScreenKeyboardShown);
2071 jintArray button_flags;
2072 jintArray button_ids;
2073 jobjectArray button_texts;
2083 clazz = (*env)->FindClass(env,
"java/lang/String");
2085 title = (*env)->NewStringUTF(env, messageboxdata->
title);
2086 message = (*env)->NewStringUTF(env, messageboxdata->
message);
2088 button_flags = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2089 button_ids = (*env)->NewIntArray(env, messageboxdata->
numbuttons);
2090 button_texts = (*env)->NewObjectArray(env, messageboxdata->
numbuttons,
2092 for (i = 0; i < messageboxdata->
numbuttons; ++
i) {
2094 (*env)->SetIntArrayRegion(env, button_flags, i, 1, &temp);
2096 (*env)->SetIntArrayRegion(env, button_ids, i, 1, &temp);
2097 text = (*env)->NewStringUTF(env, messageboxdata->
buttons[i].
text);
2098 (*env)->SetObjectArrayElement(env, button_texts, i, text);
2099 (*env)->DeleteLocalRef(env, text);
2105 temp = (0xFF << 24) |
2109 (*env)->SetIntArrayRegion(env, colors, i, 1, &temp);
2115 (*env)->DeleteLocalRef(env, clazz);
2118 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2120 clazz = (*env)->GetObjectClass(env, context);
2122 mid = (*env)->GetMethodID(env, clazz,
2123 "messageboxShowMessageBox",
"(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
2124 *buttonid = (*env)->CallIntMethod(env, context, mid,
2125 messageboxdata->
flags,
2133 (*env)->DeleteLocalRef(env, context);
2134 (*env)->DeleteLocalRef(env, clazz);
2138 (*env)->DeleteLocalRef(env, title);
2139 (*env)->DeleteLocalRef(env, message);
2140 (*env)->DeleteLocalRef(env, button_flags);
2141 (*env)->DeleteLocalRef(env, button_ids);
2142 (*env)->DeleteLocalRef(env, button_texts);
2143 (*env)->DeleteLocalRef(env, colors);
2151 // Functions exposed to SDL applications in SDL_system.h
2170 return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2176 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet);
2182 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV);
2188 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);
2194 return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
2200 return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
2205 static char *s_AndroidInternalFilesPath =
NULL;
2207 if (!s_AndroidInternalFilesPath) {
2208 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2216 if (!LocalReferenceHolder_Init(&refs, env)) {
2217 LocalReferenceHolder_Cleanup(&refs);
2222 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2225 LocalReferenceHolder_Cleanup(&refs);
2230 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
2231 "getFilesDir",
"()Ljava/io/File;");
2232 fileObject = (*env)->CallObjectMethod(env, context, mid);
2235 LocalReferenceHolder_Cleanup(&refs);
2240 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2241 "getCanonicalPath",
"()Ljava/lang/String;");
2242 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2243 if (Android_JNI_ExceptionOccurred(
SDL_FALSE)) {
2244 LocalReferenceHolder_Cleanup(&refs);
2248 path = (*env)->GetStringUTFChars(env, pathString,
NULL);
2249 s_AndroidInternalFilesPath =
SDL_strdup(path);
2250 (*env)->ReleaseStringUTFChars(env, pathString, path);
2252 LocalReferenceHolder_Cleanup(&refs);
2254 return s_AndroidInternalFilesPath;
2259 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2262 jstring stateString;
2267 if (!LocalReferenceHolder_Init(&refs, env)) {
2268 LocalReferenceHolder_Cleanup(&refs);
2272 cls = (*env)->FindClass(env,
"android/os/Environment");
2273 mid = (*env)->GetStaticMethodID(env, cls,
2274 "getExternalStorageState",
"()Ljava/lang/String;");
2275 stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid);
2277 state = (*env)->GetStringUTFChars(env, stateString,
NULL);
2280 __android_log_print(ANDROID_LOG_INFO,
"SDL",
"external storage state: %s", state);
2283 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
2284 SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
2285 }
else if (
SDL_strcmp(state,
"mounted_ro") == 0) {
2286 stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
2290 (*env)->ReleaseStringUTFChars(env, stateString, state);
2292 LocalReferenceHolder_Cleanup(&refs);
2298 static char *s_AndroidExternalFilesPath =
NULL;
2300 if (!s_AndroidExternalFilesPath) {
2301 struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
2309 if (!LocalReferenceHolder_Init(&refs, env)) {
2310 LocalReferenceHolder_Cleanup(&refs);
2315 context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
2318 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
2319 "getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;");
2320 fileObject = (*env)->CallObjectMethod(env, context, mid,
NULL);
2323 LocalReferenceHolder_Cleanup(&refs);
2328 mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
2329 "getAbsolutePath",
"()Ljava/lang/String;");
2330 pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
2332 path = (*env)->GetStringUTFChars(env, pathString,
NULL);
2333 s_AndroidExternalFilesPath =
SDL_strdup(path);
2334 (*env)->ReleaseStringUTFChars(env, pathString, path);
2336 LocalReferenceHolder_Cleanup(&refs);
2338 return s_AndroidExternalFilesPath;
2343 if (!mActivityClass || !midGetManifestEnvironmentVariables) {
2344 __android_log_print(ANDROID_LOG_WARN,
"SDL",
"Request to get environment variables before JNI is ready");
2348 if (!bHasEnvironmentVariables) {
2350 SDL_bool ret = (*env)->CallStaticBooleanMethod(env, mActivityClass, midGetManifestEnvironmentVariables);
2352 bHasEnvironmentVariables =
SDL_TRUE;
2360 int custom_cursor = 0;
2362 pixels = (*mEnv)->NewIntArray(mEnv, surface->
w * surface->
h);
2364 (*mEnv)->SetIntArrayRegion(mEnv, pixels, 0, surface->
w * surface->
h, (
int *)surface->
pixels);
2365 custom_cursor = (*mEnv)->CallStaticIntMethod(mEnv, mActivityClass, midCreateCustomCursor, pixels, surface->
w, surface->
h, hot_x, hot_y);
2366 (*mEnv)->DeleteLocalRef(mEnv, pixels);
2370 return custom_cursor;
2377 return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetCustomCursor, cursorID);
2383 return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetSystemCursor, cursorID);
2389 return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSupportsRelativeMouse);
2395 return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1));
int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
GLenum GLenum GLenum GLenum GLenum scale
SDL_bool SDL_IsAndroidTablet(void)
int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)
int Android_JNI_FileClose(SDL_RWops *ctx)
void Android_OnMouse(int button, int action, float x, float y, SDL_bool relative)
void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint)
int Android_OnKeyUp(int keycode)
int Android_JNI_SendMessage(int command, int param)
void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
void Android_JNI_WriteAudioBuffer(void)
GLsizei const GLchar *const * string
#define SDL_AndroidBackButton
GLint GLint GLint GLint GLint x
GLuint GLsizei const GLchar * message
SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
int SDL_SendDropFile(SDL_Window *window, const char *file)
GLfloat GLfloat GLfloat GLfloat h
#define SDL_AndroidGetExternalStoragePath
A collection of pixels used in software blitting.
void Android_JNI_SetActivityTitle(const char *title)
static screen_context_t context
char * Android_JNI_GetClipboardText(void)
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
int Android_OnKeyDown(int keycode)
void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
static AndroidKeyInfo unicharToAndroidKeyInfoTable[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value)
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode)
int SDL_SendDropComplete(SDL_Window *window)
GLuint const GLchar * name
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
SDL_bool SDL_IsDeXMode(void)
SDL_sem * Android_PauseSem
static SDL_VideoDevice * _this
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int Android_JNI_SetupThread(void)
GLenum GLsizei GLsizei GLint * values
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y)
void Android_JNI_FlushCapturedAudio(void)
SDL_VideoDisplay * SDL_GetDisplay(int displayIndex)
#define SDL_StopTextInput
GLenum GLsizei const void * pathString
int SDL_SendClipboardUpdate(void)
int SDL_SendKeyboardText(const char *text)
#define SDL_stack_alloc(type, count)
void Android_JNI_CloseAudioDevice(const int iscapture)
SDL_bool Android_JNI_SupportsRelativeMouse(void)
SDL_bool Android_JNI_HasClipboardText(void)
SDL_bool SDL_IsChromebook(void)
int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent)
size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size, size_t num)
SDL_Window * Android_Window
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
SDL_bool Android_JNI_SetSystemCursor(int cursorID)
void * Android_JNI_GetAudioBuffer(void)
GLint GLint GLint GLint GLint GLint y
SDL_bool SDL_IsAndroidTV(void)
void Android_JNI_SuspendScreenSaver(SDL_bool suspend)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
void Android_JNI_PollHapticDevices(void)
const SDL_MessageBoxButtonData * buttons
MessageBox structure containing title, text, window, etc.
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1)
GLenum GLenum GLsizei const GLuint GLboolean enabled
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)
Sint64(* size)(struct SDL_RWops *context)
#define SDL_assert(condition)
#define SDL_OutOfMemory()
void Android_JNI_HapticStop(int device_id)
ANativeWindow * Android_JNI_GetNativeWindow(void)
void Android_JNI_GetManifestEnvironmentVariables(void)
union SDL_RWops::@10 hidden
static char text[MAX_TEXT_LENGTH]
void Android_JNI_HideTextInput(void)
SDL_bool Android_JNI_SetCustomCursor(int cursorID)
#define SDL_AndroidGetActivity
void Android_JNI_HapticRun(int device_id, float intensity, int length)
int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
SDL_sem * Android_ResumeSem
size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size, size_t maxnum)
C_LINKAGE SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[])
int Android_JNI_SetClipboardText(const char *text)
#define SDL_AndroidGetExternalStorageState
SDL_VideoDevice * SDL_GetVideoDevice(void)
SDL_bool Android_JNI_IsScreenKeyboardShown(void)
void Android_JNI_SetWindowStyle(SDL_bool fullscreen)
GLsizei const GLchar *const * path
int SDL_SendAppEvent(SDL_EventType eventType)
void Android_JNI_PollInputDevices(void)
void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate)
#define SDL_stack_free(data)
#define SDL_AndroidGetJNIEnv
ANativeWindow * native_window
int Android_JNI_GetTouchDeviceIds(int **ids)
GLuint GLsizei GLsizei * length
const SDL_MessageBoxColorScheme * colorScheme
SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]
#define SDL_AndroidGetInternalStoragePath
JNIEnv * Android_JNI_GetEnv(void)
SDL_Scancode
The SDL keyboard scancode representation.
int SDL_SendEditingText(const char *text, int start, int length)
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence)
A rectangle, with the origin at the upper left.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
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
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
struct @64::@65 channels[NUM_CHANNELS]