diff --git a/src/Audio_SLES.c b/src/Audio_SLES.c index 0ca883aa2..0827d1230 100644 --- a/src/Audio_SLES.c +++ b/src/Audio_SLES.c @@ -30,6 +30,7 @@ static SLInterfaceID* _SL_IID_ENGINE; static SLInterfaceID* _SL_IID_BUFFERQUEUE; static SLInterfaceID* _SL_IID_PLAYBACKRATE; static SLInterfaceID* _SL_IID_VOLUME; + static const cc_string slLib = String_FromConst("libOpenSLES.so"); static cc_bool LoadSLFuncs(void) { diff --git a/src/Certs.c b/src/Certs.c index 5127921cf..85a5f8dfa 100644 --- a/src/Certs.c +++ b/src/Certs.c @@ -264,31 +264,31 @@ static int created_trust; void CertsBackend_Init(void) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); - JAVA_sslCreateTrust = JavaGetSMethod(env, "sslCreateTrust", "()I"); - JAVA_sslAddCert = JavaGetSMethod(env, "sslAddCert", "([B)V"); - JAVA_sslVerifyChain = JavaGetSMethod(env, "sslVerifyChain", "()I"); + JAVA_sslCreateTrust = Java_GetSMethod(env, "sslCreateTrust", "()I"); + JAVA_sslAddCert = Java_GetSMethod(env, "sslAddCert", "([B)V"); + JAVA_sslVerifyChain = Java_GetSMethod(env, "sslVerifyChain", "()I"); } int Certs_VerifyChain(struct X509CertContext* x509) { JNIEnv* env; jvalue args[1]; int i; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); - if (!created_trust) created_trust = JavaSCall_Int(env, JAVA_sslCreateTrust, NULL); + if (!created_trust) created_trust = Java_SCall_Int(env, JAVA_sslCreateTrust, NULL); if (!created_trust) return ERR_NOT_SUPPORTED; for (i = 0; i < x509->numCerts; i++) { struct X509Cert* cert = &x509->certs[i]; - args[0].l = JavaMakeBytes(env, cert->data, cert->offset); - JavaSCall_Void(env, JAVA_sslAddCert, args); - (*env)->DeleteLocalRef(env, args[0].l); + args[0].l = Java_AllocBytes(env, cert->data, cert->offset); + Java_SCall_Void(env, JAVA_sslAddCert, args); + Java_DeleteLocalRef(env, args[0].l); } - return JavaSCall_Int(env, JAVA_sslVerifyChain, NULL); + return Java_SCall_Int(env, JAVA_sslVerifyChain, NULL); } #elif CC_CRT_BACKEND == CC_CRT_BACKEND_WINCRYPTO #define CC_CRYPT32_FUNC extern diff --git a/src/LBackend_Android.c b/src/LBackend_Android.c index 2049bb4ba..8752987b0 100644 --- a/src/LBackend_Android.c +++ b/src/LBackend_Android.c @@ -111,8 +111,10 @@ static void JNICALL java_drawBackground(JNIEnv* env, jobject o, jobject bmp) { void LBackend_Redraw(void) { JNIEnv* env; - JavaGetCurrentEnv(env); - JavaCallVoid(env, "redrawBackground", "()V", NULL); + Java_GetCurrentEnv(env); + + jmethodID method = Java_GetIMethod(env, "redrawBackground", "()V"); + Java_ICall_Void(env, method, NULL); } static void LBackend_ButtonUpdateBackground(struct LButton* btn); @@ -154,7 +156,8 @@ static int ToAndroidColor(BitmapCol color) { static jstring JNICALL java_nextTextPart(JNIEnv* env, jobject o, jstring total, jintArray state) { char buffer[NATIVE_STR_LEN]; - cc_string text = JavaGetString(env, total, buffer); + // TODO should it really be raw? + cc_string text = Java_DecodeRaw(env, total, buffer); jint* state_ = (*env)->GetIntArrayElements(env, state, NULL); text.buffer += state_[0]; @@ -170,7 +173,7 @@ static jstring JNICALL java_nextTextPart(JNIEnv* env, jobject o, jstring total, state_[1] = ToAndroidColor(color); (*env)->ReleaseIntArrayElements(env, state, state_, 0); - return JavaMakeString(env, &part); + return Java_AllocString(env, &part); } @@ -205,29 +208,30 @@ void LBackend_ButtonInit(struct LButton* w, int width, int height) { } static void LBackend_ButtonShow(struct LButton* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[6]; LBackend_GetLayoutArgs(w, args); args[4].i = w->_textWidth; args[5].i = w->_textHeight; - jmethodID method = JavaGetIMethod(env, "buttonAdd", "(IIIIII)I"); - w->meta = (void*)JavaICall_Int(env, method, args); + jmethodID method = Java_GetIMethod(env, "buttonAdd", "(IIIIII)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); } void LBackend_ButtonUpdate(struct LButton* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[2]; if (!w->meta) return; args[0].i = (int)w->meta; - args[1].l = JavaMakeString(env, &w->text); + args[1].l = Java_AllocString(env, &w->text); // TODO share logic with LabelUpdate/ButtonUpdate - jmethodID method = JavaGetIMethod(env, "buttonUpdate", "(ILjava/lang/String;)V"); - JavaICall_Void(env, method, args); - (*env)->DeleteLocalRef(env, args[1].l); + jmethodID method = Java_GetIMethod(env, "buttonUpdate", "(ILjava/lang/String;)V"); + Java_ICall_Void(env, method, args); + + Java_DeleteLocalRef(env, args[1].l); } void LBackend_ButtonDraw(struct LButton* w) { } @@ -274,13 +278,13 @@ static void JNICALL java_makeButtonDefault(JNIEnv* env, jobject o, jobject bmp) } static void LBackend_ButtonUpdateBackground(struct LButton* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[1]; if (!w->meta) return; args[0].i = (int)w->meta; - jmethodID method = JavaGetIMethod(env, "buttonUpdateBackground", "(I)V"); - JavaICall_Void(env, method, args); + jmethodID method = Java_GetIMethod(env, "buttonUpdateBackground", "(I)V"); + Java_ICall_Void(env, method, args); } @@ -290,21 +294,21 @@ static void LBackend_ButtonUpdateBackground(struct LButton* w) { void LBackend_CheckboxInit(struct LCheckbox* w) { } static void LBackend_CheckboxShow(struct LCheckbox* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[6]; LBackend_GetLayoutArgs(w, args); - args[4].l = JavaMakeString(env, &w->text); + args[4].l = Java_AllocString(env, &w->text); args[5].z = w->value; - jmethodID method = JavaGetIMethod(env, "checkboxAdd", "(IIIILjava/lang/String;Z)I"); - w->meta = (void*)JavaICall_Int(env, method, args); - (*env)->DeleteLocalRef(env, args[4].l); + jmethodID method = Java_GetIMethod(env, "checkboxAdd", "(IIIILjava/lang/String;Z)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); + Java_DeleteLocalRef(env, args[4].l); } void LBackend_CheckboxDraw(struct LCheckbox* w) { } void LBackend_CheckboxUpdate(struct LCheckbox* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[2]; if (!w->meta) return; @@ -312,8 +316,8 @@ void LBackend_CheckboxUpdate(struct LCheckbox* w) { args[1].z = w->value; // TODO share logic with LabelUpdate/ButtonUpdate - jmethodID method = JavaGetIMethod(env, "checkboxUpdate", "(IZ)V"); - JavaICall_Void(env, method, args); + jmethodID method = Java_GetIMethod(env, "checkboxUpdate", "(IZ)V"); + Java_ICall_Void(env, method, args); } @@ -325,32 +329,32 @@ void LBackend_InputInit(struct LInput* w, int width) { } static void LBackend_InputShow(struct LInput* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[8]; LBackend_GetLayoutArgs(w, args); args[4].i = w->_textHeight; args[5].i = Display_ScaleY(LINPUT_HEIGHT); args[6].i = w->inputType; - args[7].l = JavaMakeConst(env, w->hintText); + args[7].l = Java_AllocConst(env, w->hintText); - jmethodID method = JavaGetIMethod(env, "inputAdd", "(IIIIIIILjava/lang/String;)I"); - w->meta = (void*)JavaICall_Int(env, method, args); - (*env)->DeleteLocalRef(env, args[7].l); + jmethodID method = Java_GetIMethod(env, "inputAdd", "(IIIIIIILjava/lang/String;)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); + Java_DeleteLocalRef(env, args[7].l); } void LBackend_InputUpdate(struct LInput* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[2]; if (!w->meta) return; args[0].i = (int)w->meta; - args[1].l = JavaMakeString(env, &w->text); + args[1].l = Java_AllocString(env, &w->text); // TODO share logic with LabelUpdate/ButtonUpdate - jmethodID method = JavaGetIMethod(env, "inputUpdate", "(ILjava/lang/String;)V"); - JavaICall_Void(env, method, args); - (*env)->DeleteLocalRef(env, args[1].l); + jmethodID method = Java_GetIMethod(env, "inputUpdate", "(ILjava/lang/String;)V"); + Java_ICall_Void(env, method, args); + Java_DeleteLocalRef(env, args[1].l); } void LBackend_InputTick(struct LInput* w) { } @@ -365,26 +369,26 @@ void LBackend_InputDraw(struct LInput* w) { } void LBackend_LabelInit(struct LLabel* w) { } static void LBackend_LabelShow(struct LLabel* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[4]; LBackend_GetLayoutArgs(w, args); - jmethodID method = JavaGetIMethod(env, "labelAdd", "(IIII)I"); - w->meta = (void*)JavaICall_Int(env, method, args); + jmethodID method = Java_GetIMethod(env, "labelAdd", "(IIII)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); } void LBackend_LabelUpdate(struct LLabel* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[2]; if (!w->meta) return; args[0].i = (int)w->meta; - args[1].l = JavaMakeString(env, &w->text); + args[1].l = Java_AllocString(env, &w->text); // TODO share logic with LabelUpdate/ButtonUpdate - jmethodID method = JavaGetIMethod(env, "labelUpdate", "(ILjava/lang/String;)V"); - JavaICall_Void(env, method, args); - (*env)->DeleteLocalRef(env, args[1].l); + jmethodID method = Java_GetIMethod(env, "labelUpdate", "(ILjava/lang/String;)V"); + Java_ICall_Void(env, method, args); + Java_DeleteLocalRef(env, args[1].l); } void LBackend_LabelDraw(struct LLabel* w) { } @@ -397,7 +401,7 @@ void LBackend_LineInit(struct LLine* w, int width) { } static void LBackend_LineShow(struct LLine* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[7]; LBackend_GetLayoutArgs(w, args); @@ -405,8 +409,8 @@ static void LBackend_LineShow(struct LLine* w) { args[5].i = Display_ScaleY(LLINE_HEIGHT); args[6].i = ToAndroidColor(LLine_GetColor()); - jmethodID method = JavaGetIMethod(env, "lineAdd", "(IIIIIII)I"); - w->meta = (void*)JavaICall_Int(env, method, args); + jmethodID method = Java_GetIMethod(env, "lineAdd", "(IIIIIII)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); } void LBackend_LineDraw(struct LLine* w) { } @@ -420,7 +424,7 @@ void LBackend_SliderInit(struct LSlider* w, int width, int height) { } static void LBackend_SliderShow(struct LSlider* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[7]; LBackend_GetLayoutArgs(w, args); @@ -428,20 +432,20 @@ static void LBackend_SliderShow(struct LSlider* w) { args[5].i = w->_height; args[6].i = ToAndroidColor(w->color); - jmethodID method = JavaGetIMethod(env, "sliderAdd", "(IIIIIII)I"); - w->meta = (void*)JavaICall_Int(env, method, args); + jmethodID method = Java_GetIMethod(env, "sliderAdd", "(IIIIIII)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); } void LBackend_SliderUpdate(struct LSlider* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[2]; if (!w->meta) return; args[0].i = (int)w->meta; args[1].i = w->value; - jmethodID method = JavaGetIMethod(env, "sliderUpdate", "(II)V"); - JavaICall_Void(env, method, args); + jmethodID method = Java_GetIMethod(env, "sliderUpdate", "(II)V"); + Java_ICall_Void(env, method, args); } void LBackend_SliderDraw(struct LSlider* w) {} @@ -454,14 +458,14 @@ void LBackend_TableInit(struct LTable* w) { } static void LBackend_TableShow(struct LTable* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[5]; LBackend_GetLayoutArgs(w, args); args[4].i = ToAndroidColor(LTable_RowColor(1, false, false)); - jmethodID method = JavaGetIMethod(env, "tableAdd", "(IIIII)I"); - w->meta = (void*)JavaICall_Int(env, method, args); + jmethodID method = Java_GetIMethod(env, "tableAdd", "(IIIII)I"); + w->meta = (void*)Java_ICall_Int(env, method, args); LBackend_TableUpdate(w); } @@ -473,33 +477,33 @@ static jstring GetTableDetails(JNIEnv* env, struct ServerInfo* server) { LTable_FormatUptime(&text, server->uptime); if (server->software.length) String_Format1(&text, " | %s", &server->software); - return JavaMakeString(env, &text); + return Java_AllocString(env, &text); } void LBackend_TableUpdate(struct LTable* w) { - JNIEnv* env; JavaGetCurrentEnv(env); + JNIEnv* env; Java_GetCurrentEnv(env); jvalue args[3]; jmethodID method; - method = JavaGetIMethod(env, "tableStartUpdate", "()V"); - JavaICall_Void(env, method, args); - method = JavaGetIMethod(env, "tableAddEntry", "(Ljava/lang/String;Ljava/lang/String;Z)V"); + method = Java_GetIMethod(env, "tableStartUpdate", "()V"); + Java_ICall_Void(env, method, args); + method = Java_GetIMethod(env, "tableAddEntry", "(Ljava/lang/String;Ljava/lang/String;Z)V"); for (int i = 0; i < w->rowsCount; i++) { struct ServerInfo* info = LTable_Get(i); - args[0].l = JavaMakeString(env, &info->name); + args[0].l = Java_AllocString(env, &info->name); args[1].l = GetTableDetails(env, info); args[2].z = info->featured; - JavaICall_Void(env, method, args); + Java_ICall_Void(env, method, args); - (*env)->DeleteLocalRef(env, args[0].l); - (*env)->DeleteLocalRef(env, args[1].l); + Java_DeleteLocalRef(env, args[0].l); + Java_DeleteLocalRef(env, args[1].l); } - method = JavaGetIMethod(env, "tableFinishUpdate", "(I)V"); + method = Java_GetIMethod(env, "tableFinishUpdate", "(I)V"); args[0].i = (int)w->meta; - JavaICall_Void(env, method, args); + Java_ICall_Void(env, method, args); } void LBackend_TableReposition(struct LTable* w) { @@ -545,7 +549,7 @@ static void JNICALL java_UIString(JNIEnv* env, jobject o, jint id, jstring str) if (!ipt) return; char buffer[NATIVE_STR_LEN]; - cc_string text = JavaGetString(env, str, buffer); + cc_string text = Java_GetString(env, str, buffer); String_Copy(&ipt->text, &text); if (ipt->TextChanged) ipt->TextChanged(ipt); } @@ -593,9 +597,9 @@ void LBackend_CloseScreen(struct LScreen* s) { s->widgets[i]->meta = NULL; } - JNIEnv* env; JavaGetCurrentEnv(env); - jmethodID method = JavaGetIMethod(env, "clearWidgetsAsync", "()V"); - JavaICall_Void(env, method, NULL); + JNIEnv* env; Java_GetCurrentEnv(env); + jmethodID method = Java_GetIMethod(env, "clearWidgetsAsync", "()V"); + Java_ICall_Void(env, method, NULL); } static const JNINativeMethod methods[] = { @@ -611,7 +615,7 @@ static const JNINativeMethod methods[] = { static void LBackend_InitHooks(void) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); JavaRegisterNatives(env, methods); } #endif diff --git a/src/android/Platform_Android.c b/src/android/Platform_Android.c index cf7e08f7b..c96b5e609 100644 --- a/src/android/Platform_Android.c +++ b/src/android/Platform_Android.c @@ -59,7 +59,7 @@ cc_bool Updater_Clean(void) { return true; } cc_result Updater_GetBuildTime(cc_uint64* t) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); *t = JavaCallLong(env, "getApkUpdateTime", "()J", NULL); return 0; } @@ -75,7 +75,7 @@ cc_result Updater_SetNewBuildTime(cc_uint64 t) { return ERR_NOT_SUPPORTED; } void Platform_TryLogJavaError(void) { JNIEnv* env; jthrowable err; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); err = (*env)->ExceptionOccurred(env); if (!err) return; @@ -106,7 +106,7 @@ void Directory_GetCachePath(cc_string* path) { /* (see https://developer.android.com/training/articles/perf-jni#threads */ void* ExecThread(void* param) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); ((Thread_StartFunc)param)(); (*VM_Ptr)->DetachCurrentThread(VM_Ptr); @@ -162,7 +162,17 @@ cc_string JavaGetString(JNIEnv* env, jstring str, char* buffer) { return dst; } -jobject JavaMakeString(JNIEnv* env, const cc_string* str) { +void Java_DecodeString(JNIEnv* env, jstring str, cc_string* dst) { + const jchar* src; + jsize len; + + src = (*env)->GetStringChars(env, str, NULL); + len = (*env)->GetStringLength(env, str); + String_AppendUtf16(dst, src, len * 2); + (*env)->ReleaseStringChars(env, str, src); +} + +jobject Java_AllocString(JNIEnv* env, const cc_string* str) { cc_uint8 tmp[2048 + 4]; cc_uint8* cur; int i, len = 0; @@ -175,8 +185,9 @@ jobject JavaMakeString(JNIEnv* env, const cc_string* str) { return (*env)->NewStringUTF(env, (const char*)tmp); } -jbyteArray JavaMakeBytes(JNIEnv* env, const void* src, cc_uint32 len) { +jbyteArray Java_AllocBytes(JNIEnv* env, const void* src, cc_uint32 len) { if (!len) return NULL; + jbyteArray arr = (*env)->NewByteArray(env, len); (*env)->SetByteArrayRegion(env, arr, 0, len, src); return arr; @@ -200,44 +211,37 @@ jobject JavaCallObject(JNIEnv* env, const char* name, const char* sig, jvalue* a void JavaCall_String_Void(const char* name, const cc_string* value) { JNIEnv* env; jvalue args[1]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); - args[0].l = JavaMakeString(env, value); + args[0].l = Java_AllocString(env, value); JavaCallVoid(env, name, "(Ljava/lang/String;)V", args); - (*env)->DeleteLocalRef(env, args[0].l); -} - -static void ReturnString(JNIEnv* env, jobject obj, cc_string* dst) { - const jchar* src; - jsize len; - if (!obj) return; - - src = (*env)->GetStringChars(env, obj, NULL); - len = (*env)->GetStringLength(env, obj); - String_AppendUtf16(dst, src, len * 2); - (*env)->ReleaseStringChars(env, obj, src); - (*env)->DeleteLocalRef(env, obj); + + Java_DeleteLocalRef(env, args[0].l); } void JavaCall_Void_String(const char* name, cc_string* dst) { JNIEnv* env; jobject obj; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); obj = JavaCallObject(env, name, "()Ljava/lang/String;", NULL); - ReturnString(env, obj, dst); + if (obj) Java_DecodeString(env, obj, dst); + + Java_DeleteLocalRef(env, obj); } void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* dst) { JNIEnv* env; jobject obj; jvalue args[1]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); - args[0].l = JavaMakeString(env, arg); + args[0].l = Java_AllocString(env, arg); obj = JavaCallObject(env, name, "(Ljava/lang/String;)Ljava/lang/String;", args); - ReturnString(env, obj, dst); - (*env)->DeleteLocalRef(env, args[0].l); + if (obj) Java_DecodeString(env, obj, dst); + + Java_DeleteLocalRef(env, args[0].l); + Java_DeleteLocalRef(env, obj); } @@ -261,6 +265,7 @@ static void JNICALL java_runGameAsync(JNIEnv* env, jobject instance) { Thread_Run(&thread, android_main, 1024 * 1024, "Game"); // TODO check stack size needed Thread_Detach(thread); } + static const JNINativeMethod methods[] = { { "updateInstance", "()V", java_updateInstance }, { "runGameAsync", "()V", java_runGameAsync } @@ -272,10 +277,11 @@ CC_API jint JNI_OnLoad(JavaVM* vm, void* reserved) { jclass klass; JNIEnv* env; VM_Ptr = vm; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); klass = (*env)->FindClass(env, "com/classicube/MainActivity"); App_Class = (*env)->NewGlobalRef(env, klass); - JavaRegisterNatives(env, methods); + + Java_RegisterNatives(env, methods); return JNI_VERSION_1_4; } diff --git a/src/android/Window_Android.c b/src/android/Window_Android.c index ee121a1c5..61e8a0f1c 100644 --- a/src/android/Window_Android.c +++ b/src/android/Window_Android.c @@ -20,6 +20,7 @@ static jmethodID JAVA_showAlert, JAVA_setRequestedOrientation; static jmethodID JAVA_openFileDialog, JAVA_saveFileDialog; static jmethodID JAVA_processedSurfaceDestroyed, JAVA_processEvents; static jmethodID JAVA_getDpiX, JAVA_getDpiY, JAVA_setupForGame; +static jmethodID JAVA_getClipboardText, JAVA_setClipboardText; static void RefreshWindowBounds(void) { Window_Main.Width = ANativeWindow_getWidth(win_handle); @@ -140,8 +141,10 @@ static void JNICALL java_processKeyChar(JNIEnv* env, jobject o, jint code) { } static void JNICALL java_processKeyText(JNIEnv* env, jobject o, jstring str) { - char buffer[NATIVE_STR_LEN]; - cc_string text = JavaGetString(env, str, buffer); + char buffer[NATIVE_STR_LEN]; cc_string text; + String_InitArray(text, buffer); + + Java_DecodeString(env, str, &text); Platform_Log1("KEY - TEXT %s", &text); Event_RaiseString(&InputEvents.TextChanged, &text); } @@ -192,7 +195,7 @@ static void JNICALL java_processSurfaceDestroyed(JNIEnv* env, jobject o) { /* eglSwapBuffers might return EGL_BAD_SURFACE, EGL_BAD_ALLOC, or some other error */ /* Instead the context is lost here in a consistent manner */ if (Gfx.Created) Gfx_LoseContext("surface lost"); - JavaICall_Void(env, JAVA_processedSurfaceDestroyed, NULL); + Java_ICall_Void(env, JAVA_processedSurfaceDestroyed, NULL); } static void JNICALL java_processSurfaceResized(JNIEnv* env, jobject o, jobject surface) { @@ -228,7 +231,7 @@ static void JNICALL java_onDestroy(JNIEnv* env, jobject o) { if (Window_Main.Exists) Window_RequestClose(); /* TODO: signal to java code we're done */ - /* JavaICall_Void(env, JAVA_processedDestroyed", NULL); */ + /* Java_ICall_Void(env, JAVA_processedDestroyed", NULL); */ } static void JNICALL java_onGotFocus(JNIEnv* env, jobject o) { @@ -281,26 +284,30 @@ static const JNINativeMethod methods[] = { { "processOFDResult", "(Ljava/lang/String;)V", java_processOFDResult }, }; -static void CacheMethodRefs(JNIEnv* env) { - JAVA_openKeyboard = JavaGetIMethod(env, "openKeyboard", "(Ljava/lang/String;I)V"); - JAVA_setKeyboardText = JavaGetIMethod(env, "setKeyboardText", "(Ljava/lang/String;)V"); - JAVA_closeKeyboard = JavaGetIMethod(env, "closeKeyboard", "()V"); - JAVA_getWindowState = JavaGetIMethod(env, "getWindowState", "()I"); - JAVA_enterFullscreen = JavaGetIMethod(env, "enterFullscreen", "()V"); - JAVA_exitFullscreen = JavaGetIMethod(env, "exitFullscreen", "()V"); +static void CacheJavaMethodRefs(JNIEnv* env) { + JAVA_openKeyboard = Java_GetIMethod(env, "openKeyboard", "(Ljava/lang/String;I)V"); + JAVA_setKeyboardText = Java_GetIMethod(env, "setKeyboardText", "(Ljava/lang/String;)V"); + JAVA_closeKeyboard = Java_GetIMethod(env, "closeKeyboard", "()V"); - JAVA_getDpiX = JavaGetIMethod(env, "getDpiX", "()F"); - JAVA_getDpiY = JavaGetIMethod(env, "getDpiY", "()F"); - JAVA_setupForGame = JavaGetIMethod(env, "setupForGame", "()V"); + JAVA_getWindowState = Java_GetIMethod(env, "getWindowState", "()I"); + JAVA_enterFullscreen = Java_GetIMethod(env, "enterFullscreen", "()V"); + JAVA_exitFullscreen = Java_GetIMethod(env, "exitFullscreen", "()V"); - JAVA_processedSurfaceDestroyed = JavaGetIMethod(env, "processedSurfaceDestroyed", "()V"); - JAVA_processEvents = JavaGetIMethod(env, "processEvents", "()V"); + JAVA_getDpiX = Java_GetIMethod(env, "getDpiX", "()F"); + JAVA_getDpiY = Java_GetIMethod(env, "getDpiY", "()F"); + JAVA_setupForGame = Java_GetIMethod(env, "setupForGame", "()V"); - JAVA_showAlert = JavaGetIMethod(env, "showAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); - JAVA_setRequestedOrientation = JavaGetIMethod(env, "setRequestedOrientation", "(I)V"); - JAVA_openFileDialog = JavaGetIMethod(env, "openFileDialog", "(Ljava/lang/String;)I"); - JAVA_saveFileDialog = JavaGetIMethod(env, "saveFileDialog", "(Ljava/lang/String;Ljava/lang/String;)I"); + JAVA_processedSurfaceDestroyed = Java_GetIMethod(env, "processedSurfaceDestroyed", "()V"); + JAVA_processEvents = Java_GetIMethod(env, "processEvents", "()V"); + + JAVA_showAlert = Java_GetIMethod(env, "showAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); + JAVA_setRequestedOrientation = Java_GetIMethod(env, "setRequestedOrientation", "(I)V"); + JAVA_openFileDialog = Java_GetIMethod(env, "openFileDialog", "(Ljava/lang/String;)I"); + JAVA_saveFileDialog = Java_GetIMethod(env, "saveFileDialog", "(Ljava/lang/String;Ljava/lang/String;)I"); + + JAVA_getClipboardText = Java_GetIMethod(env, "getClipboardText", "()Ljava/lang/String;"); + JAVA_setClipboardText = Java_GetIMethod(env, "setClipboardText", "(Ljava/lang/String;)V"); } void Window_PreInit(void) { @@ -311,9 +318,9 @@ void Window_PreInit(void) { void Window_Init(void) { JNIEnv* env; /* TODO: ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); */ - JavaGetCurrentEnv(env); - JavaRegisterNatives(env, methods); - CacheMethodRefs(env); + Java_GetCurrentEnv(env); + Java_RegisterNatives(env, methods); + CacheJavaMethodRefs(env); Window_Main.SoftKeyboard = SOFT_KEYBOARD_RESIZE; Input_SetTouchMode(true); @@ -321,20 +328,20 @@ void Window_Init(void) { Input.Sources = INPUT_SOURCE_NORMAL; DisplayInfo.Depth = 32; - DisplayInfo.ScaleX = JavaICall_Float(env, JAVA_getDpiX, NULL); - DisplayInfo.ScaleY = JavaICall_Float(env, JAVA_getDpiY, NULL); + DisplayInfo.ScaleX = Java_ICall_Float(env, JAVA_getDpiX, NULL); + DisplayInfo.ScaleY = Java_ICall_Float(env, JAVA_getDpiY, NULL); } void Window_Free(void) { } static void RemakeWindowSurface(void) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); winCreated = false; /* Force window to be destroyed and re-created */ /* (see comments in setupForGame for why this has to be done) */ - JavaICall_Void(env, JAVA_setupForGame, NULL); + Java_ICall_Void(env, JAVA_setupForGame, NULL); Platform_LogConst("Entering wait for window exist loop.."); /* Loop until window gets created by main UI thread */ @@ -368,29 +375,43 @@ void Window_SetTitle(const cc_string* title) { } void Clipboard_GetText(cc_string* value) { - JavaCall_Void_String("getClipboardText", value); + JNIEnv* env; + jobject obj; + Java_GetCurrentEnv(env); + + obj = Java_ICall_Obj(env, JAVA_getClipboardText, NULL); + if (obj) Java_DecodeString(env, obj, value); + + Java_DeleteLocalRef(env, obj); } + void Clipboard_SetText(const cc_string* value) { - JavaCall_String_Void("setClipboardText", value); + JNIEnv* env; + jvalue args[1]; + Java_GetCurrentEnv(env); + + args[0].l = Java_AllocString(env, value); + Java_ICall_Void(env, JAVA_setClipboardText, args); + Java_DeleteLocalRef(env, args[0].l); } int Window_GetWindowState(void) { JNIEnv* env; - JavaGetCurrentEnv(env); - return JavaICall_Int(env, JAVA_getWindowState, NULL); + Java_GetCurrentEnv(env); + return Java_ICall_Int(env, JAVA_getWindowState, NULL); } cc_result Window_EnterFullscreen(void) { JNIEnv* env; - JavaGetCurrentEnv(env); - JavaICall_Void(env, JAVA_enterFullscreen, NULL); + Java_GetCurrentEnv(env); + Java_ICall_Void(env, JAVA_enterFullscreen, NULL); return 0; } cc_result Window_ExitFullscreen(void) { JNIEnv* env; - JavaGetCurrentEnv(env); - JavaICall_Void(env, JAVA_exitFullscreen, NULL); + Java_GetCurrentEnv(env); + Java_ICall_Void(env, JAVA_exitFullscreen, NULL); return 0; } @@ -408,9 +429,9 @@ void Window_RequestClose(void) { void Window_ProcessEvents(float delta) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); /* TODO: Cache the java env */ - JavaICall_Void(env, JAVA_processEvents, NULL); + Java_ICall_Void(env, JAVA_processEvents, NULL); } void Gamepads_Init(void) { @@ -427,27 +448,29 @@ static void Cursor_DoSetVisible(cc_bool visible) { } static void ShowDialogCore(const char* title, const char* msg) { JNIEnv* env; jvalue args[2]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); Platform_LogConst(title); Platform_LogConst(msg); /* in case surface destroyed message has arrived */ Window_ProcessEvents(0.0); - args[0].l = JavaMakeConst(env, title); - args[1].l = JavaMakeConst(env, msg); - JavaICall_Void(env, JAVA_showAlert, args); - (*env)->DeleteLocalRef(env, args[0].l); - (*env)->DeleteLocalRef(env, args[1].l); + args[0].l = Java_AllocConst(env, title); + args[1].l = Java_AllocConst(env, msg); + Java_ICall_Void(env, JAVA_showAlert, args); + Java_DeleteLocalRef(env, args[0].l); + Java_DeleteLocalRef(env, args[1].l); } static FileDialogCallback ofd_callback; static int ofd_action; static void JNICALL java_processOFDResult(JNIEnv* env, jobject o, jstring str) { const char* raw; - - char buffer[NATIVE_STR_LEN]; - cc_string path = JavaGetString(env, str, buffer); + char buffer[NATIVE_STR_LEN]; cc_string path; + String_InitArray(path, buffer); + + // TODO should be raw + Java_DecodeString(env, str, &path); ofd_callback(&path); if (ofd_action == OFD_UPLOAD_DELETE) { @@ -462,15 +485,16 @@ static void JNICALL java_processOFDResult(JNIEnv* env, jobject o, jstring str) { cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* open_args) { JNIEnv* env; jvalue args[1]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); ofd_callback = open_args->Callback; ofd_action = open_args->uploadAction; // TODO use filters - args[0].l = JavaMakeConst(env, open_args->uploadFolder); - int OK = JavaICall_Int(env, JAVA_openFileDialog, args); - (*env)->DeleteLocalRef(env, args[0].l); + args[0].l = Java_AllocConst(env, open_args->uploadFolder); + int OK = Java_ICall_Int(env, JAVA_openFileDialog, args); + Java_DeleteLocalRef(env, args[0].l); + // TODO: Better error handling return OK ? 0 : ERR_INVALID_ARGUMENT; } @@ -478,7 +502,7 @@ cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* open_args) { cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* save_args) { JNIEnv* env; jvalue args[2]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); if (!save_args->defaultName.length) return SFD_ERR_NEED_DEFAULT_NAME; // save the item to a temp file, which is then (usually) later deleted by intent callback @@ -491,11 +515,12 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* save_args) { // TODO kinda ugly, maybe a better way? cc_string file = String_UNSAFE_SubstringAt(&path, String_IndexOf(&path, '/') + 1); - args[0].l = JavaMakeString(env, &path); - args[1].l = JavaMakeString(env, &file); - int OK = JavaICall_Int(env, JAVA_saveFileDialog, args); - (*env)->DeleteLocalRef(env, args[0].l); - (*env)->DeleteLocalRef(env, args[1].l); + args[0].l = Java_AllocString(env, &path); + args[1].l = Java_AllocString(env, &file); + int OK = Java_ICall_Int(env, JAVA_saveFileDialog, args); + Java_DeleteLocalRef(env, args[0].l); + Java_DeleteLocalRef(env, args[1].l); + // TODO: Better error handling return OK ? 0 : ERR_INVALID_ARGUMENT; } @@ -548,42 +573,42 @@ void Window_FreeFramebuffer(struct Bitmap* bmp) { void OnscreenKeyboard_Open(struct OpenKeyboardArgs* kArgs) { JNIEnv* env; jvalue args[2]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); DisplayInfo.ShowingSoftKeyboard = true; - args[0].l = JavaMakeString(env, kArgs->text); + args[0].l = Java_AllocString(env, kArgs->text); args[1].i = kArgs->type; - JavaICall_Void(env, JAVA_openKeyboard, args); - (*env)->DeleteLocalRef(env, args[0].l); + Java_ICall_Void(env, JAVA_openKeyboard, args); + Java_DeleteLocalRef(env, args[0].l); } void OnscreenKeyboard_SetText(const cc_string* text) { JNIEnv* env; jvalue args[1]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); - args[0].l = JavaMakeString(env, text); - JavaICall_Void(env, JAVA_setKeyboardText, args); - (*env)->DeleteLocalRef(env, args[0].l); + args[0].l = Java_AllocString(env, text); + Java_ICall_Void(env, JAVA_setKeyboardText, args); + Java_DeleteLocalRef(env, args[0].l); } void OnscreenKeyboard_Close(void) { JNIEnv* env; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); DisplayInfo.ShowingSoftKeyboard = false; - JavaICall_Void(env, JAVA_closeKeyboard, NULL); + Java_ICall_Void(env, JAVA_closeKeyboard, NULL); } void Window_LockLandscapeOrientation(cc_bool lock) { JNIEnv* env; jvalue args[1]; - JavaGetCurrentEnv(env); + Java_GetCurrentEnv(env); /* SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 0x00000006 */ /* SCREEN_ORIENTATION_UNSPECIFIED = 0xffffffff */ args[0].i = lock ? 0x00000006 : 0xffffffff; - JavaICall_Void(env, JAVA_setRequestedOrientation, args); + Java_ICall_Void(env, JAVA_setRequestedOrientation, args); } void Window_EnableRawMouse(void) { DefaultEnableRawMouse(); } diff --git a/src/android/interop_android.h b/src/android/interop_android.h index a3d72fcc8..34fd12d5f 100644 --- a/src/android/interop_android.h +++ b/src/android/interop_android.h @@ -3,20 +3,25 @@ extern jclass App_Class; extern jobject App_Instance; extern JavaVM* VM_Ptr; -#define JavaGetCurrentEnv(env) (*VM_Ptr)->AttachCurrentThread(VM_Ptr, &env, NULL) -#define JavaMakeConst(env, str) (*env)->NewStringUTF(env, str) +#define Java_GetCurrentEnv(env) (*VM_Ptr)->AttachCurrentThread(VM_Ptr, &env, NULL) -#define JavaRegisterNatives(env, methods) (*env)->RegisterNatives(env, App_Class, methods, Array_Elems(methods)); -#define JavaGetIMethod(env, name, sig) (*env)->GetMethodID(env, App_Class, name, sig) -#define JavaGetSMethod(env, name, sig) (*env)->GetStaticMethodID(env, App_Class, name, sig) +#define Java_DeleteLocalRef(env, arg) (*env)->DeleteLocalRef(env, arg); -/* Creates a string from the given java string. buffer must be at least NATIVE_STR_LEN long. */ -/* NOTE: Don't forget to call env->ReleaseStringUTFChars. Only works with ASCII strings. */ -cc_string JavaGetString(JNIEnv* env, jstring str, char* buffer); +#define Java_RegisterNatives(env, methods) (*env)->RegisterNatives(env, App_Class, methods, Array_Elems(methods)); +#define Java_GetIMethod(env, name, sig) (*env)->GetMethodID(env, App_Class, name, sig) +#define Java_GetSMethod(env, name, sig) (*env)->GetStaticMethodID(env, App_Class, name, sig) + +#define Java_AllocConst(env, str) (*env)->NewStringUTF(env, str) /* Allocates a java string from the given string. */ -jobject JavaMakeString(JNIEnv* env, const cc_string* str); +jobject Java_AllocString(JNIEnv* env, const cc_string* str); /* Allocates a java byte array from the given block of memory. */ -jbyteArray JavaMakeBytes(JNIEnv* env, const void* src, cc_uint32 len); +jbyteArray Java_AllocBytes(JNIEnv* env, const void* src, cc_uint32 len); + +/* Decodes the given java string into a string. */ +void Java_DecodeString(JNIEnv* env, jstring str, cc_string* dst); +/* Creates a string from the given java string. buffer must be at least NATIVE_STR_LEN long. */ +//cc_string Java_DecodeRaw(JNIEnv* env, jstring str, char* buffer); + /* Calls a method in the activity class that returns nothing. */ void JavaCallVoid(JNIEnv* env, const char* name, const char* sig, jvalue* args); /* Calls a method in the activity class that returns a jint. */ @@ -31,23 +36,23 @@ void JavaCall_Void_String(const char* name, cc_string* dst); void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* dst); /* Calls an instance method in the activity class that returns nothing */ -#define JavaICall_Void(env, method, args) (*env)->CallVoidMethodA(env, App_Instance, method, args) +#define Java_ICall_Void(env, method, args) (*env)->CallVoidMethodA(env, App_Instance, method, args) /* Calls an instance method in the activity class that returns a jint */ -#define JavaICall_Int(env, method, args) (*env)->CallIntMethodA(env, App_Instance, method, args) +#define Java_ICall_Int(env, method, args) (*env)->CallIntMethodA(env, App_Instance, method, args) /* Calls an instance method in the activity class that returns a jlong */ -#define JavaICall_Long(env, method, args) (*env)->CallLongMethodA(env, App_Instance, method, args) +#define Java_ICall_Long(env, method, args) (*env)->CallLongMethodA(env, App_Instance, method, args) /* Calls an instance method in the activity class that returns a jfloat */ -#define JavaICall_Float(env,method, args) (*env)->CallFloatMethodA(env, App_Instance, method, args) +#define Java_ICall_Float(env,method, args) (*env)->CallFloatMethodA(env, App_Instance, method, args) /* Calls an instance method in the activity class that returns a jobject */ -#define JavaICall_Obj(env, method, args) (*env)->CallObjectMethodA(env,App_Instance, method, args) +#define Java_ICall_Obj(env, method, args) (*env)->CallObjectMethodA(env,App_Instance, method, args) /* Calls a static method in the activity class that returns nothing */ -#define JavaSCall_Void(env, method, args) (*env)->CallStaticVoidMethodA(env, App_Class, method, args) +#define Java_SCall_Void(env, method, args) (*env)->CallStaticVoidMethodA(env, App_Class, method, args) /* Calls a static method in the activity class that returns a jint */ -#define JavaSCall_Int(env, method, args) (*env)->CallStaticIntMethodA(env, App_Class, method, args) +#define Java_SCall_Int(env, method, args) (*env)->CallStaticIntMethodA(env, App_Class, method, args) /* Calls a static method in the activity class that returns a jlong */ -#define JavaSCall_Long(env, method, args) (*env)->CallStaticLongMethodA(env, App_Class, method, args) +#define Java_SCall_Long(env, method, args) (*env)->CallStaticLongMethodA(env, App_Class, method, args) /* Calls a static method in the activity class that returns a jfloat */ -#define JavaSCall_Float(env,method, args) (*env)->CallStaticFloatMethodA(env, App_Class, method, args) +#define Java_SCall_Float(env,method, args) (*env)->CallStaticFloatMethodA(env, App_Class, method, args) /* Calls a static method in the activity class that returns a jobject */ -#define JavaSCall_Obj(env, method, args) (*env)->CallStaticObjectMethodA(env,App_Class, method, args) \ No newline at end of file +#define Java_SCall_Obj(env, method, args) (*env)->CallStaticObjectMethodA(env,App_Class, method, args) \ No newline at end of file