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,
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,
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
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
A collection of pixels used in software blitting.
void Android_JNI_SetActivityTitle(const char *title)
static screen_context_t context
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
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]
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF PF else PF lsl PF lsl PF lsl PF endif SIZE macro preload_middle scratch_holds_offset if bpp if else PF PF endif endif endif endm macro preload_trailing base if bpp if bpp *pix_per_block PF PF lsl PF PF PF PF PF else PF lsl PF lsl PF PF PF PF PF base if bpp if narrow_case &&bpp<=dst_w_bpp) PF bic, WK0, base, #31 PF pld, [WK0] PF add, WK1, base, X, LSL #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 90f PF pld, [WK1]90:.else PF bic, WK0, base, #31 PF pld, [WK0] PF add, WK1, base, X, lsl #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 92f91:PF add, WK0, WK0, #32 PF cmp, WK0, WK1 PF pld, [WK0] PF bne, 91b92:.endif .endif.endm.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond X, X, #8 *numbytes/dst_w_bpp .endif process_tail cond, numbytes, firstreg .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst cond, numbytes, firstreg, DST .endif.endm.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_BRANCH_OVER .ifc cond, mi bpl 100f .endif .ifc cond, cs bcc 100f .endif .ifc cond, ne beq 100f .endif conditional_process1_helper, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx100:.else conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .endif.endm.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx .if(flags) &(FLAG_DST_READWRITE|FLAG_BRANCH_OVER|FLAG_PROCESS_CORRUPTS_PSR|FLAG_PROCESS_DOES_STORE) test conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_PROCESS_CORRUPTS_PSR test .endif conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx .else test process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0 process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond1 X, X, #8 *numbytes1/dst_w_bpp sub &cond2 X, X, #8 *numbytes2/dst_w_bpp .endif process_tail cond1, numbytes1, firstreg1 process_tail cond2, numbytes2, firstreg2 pixst cond1, numbytes1, firstreg1, DST pixst cond2, numbytes2, firstreg2, DST .endif.endm.macro test_bits_1_0_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-1 .else movs SCRATCH, WK0, lsl #32-1 .endif.endm.macro test_bits_3_2_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-3 .else movs SCRATCH, WK0, lsl #32-3 .endif.endm.macro leading_15bytes process_head, process_tail .set DECREMENT_X, 1 .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 .set DECREMENT_X, 0 sub X, X, WK0, lsr #dst_bpp_shift str X, [sp, #LINE_SAVED_REG_COUNT *4] mov X, WK0 .endif .if dst_w_bpp==8 conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X .elseif dst_w_bpp==16 test_bits_1_0_ptr conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X .endif conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 ldr X, [sp, #LINE_SAVED_REG_COUNT *4] .endif.endm.macro test_bits_3_2_pix movs SCRATCH, X, lsl #dst_bpp_shift+32-3.endm.macro test_bits_1_0_pix .if dst_w_bpp==8 movs SCRATCH, X, lsl #dst_bpp_shift+32-1 .else movs SCRATCH, X, lsr #1 .endif.endm.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0 .if dst_w_bpp==16 test_bits_1_0_pix conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0 .elseif dst_w_bpp==8 conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0 .endif.endm.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment110:.set SUBBLOCK, 0 .rept pix_per_block *dst_w_bpp/128 process_head, 16, 0, unaligned_src, unaligned_mask, 1 .if(src_bpp > 0) &&(mask_bpp==0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle src_bpp, SRC, 1 .elseif(src_bpp==0) &&(mask_bpp > 0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle mask_bpp, MASK, 1 .else preload_middle src_bpp, SRC, 0 preload_middle mask_bpp, MASK, 0 .endif .if(dst_r_bpp > 0) &&((SUBBLOCK % 2)==0) &&(((flags) &FLAG_NO_PRELOAD_DST)==0) PF pld, [DST, #32 *prefetch_distance - dst_alignment] .endif process_tail, 16, 0 .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst, 16, 0, DST .endif .set SUBBLOCK, SUBBLOCK+1 .endr subs X, X, #pix_per_block bhs 110b.endm.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask .if dst_r_bpp > tst bne process_inner_loop DST_PRELOAD_BIAS endif preload_trailing SRC preload_trailing MASK DST endif add medium_case_inner_loop_and_trailing_pixels unaligned_mask endm macro medium_case_inner_loop_and_trailing_pixels DST endif subs bhs tst beq exit_label trailing_15bytes unaligned_mask endm macro narrow_case_inner_loop_and_trailing_pixels unaligned_mask tst conditional_process1 trailing_15bytes unaligned_mask endm macro switch_on_alignment action
#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)