diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version index 14cf79778..b26355318 100644 --- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version +++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version @@ -1 +1 @@ -1677864883723 \ No newline at end of file +1677906502154 \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/egl_bridge.c b/app_pojavlauncher/src/main/jni/egl_bridge.c index 262643c83..e8eeb5773 100644 --- a/app_pojavlauncher/src/main/jni/egl_bridge.c +++ b/app_pojavlauncher/src/main/jni/egl_bridge.c @@ -728,9 +728,9 @@ bool loadSymbolsVirGL() { int pojavInit() { ANativeWindow_acquire(pojav_environ->pojavWindow); - savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow); - savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow); - ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow,savedWidth,savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM); + pojav_environ->savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow); + pojav_environ->savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow); + ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow,pojav_environ->savedWidth,pojav_environ->savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM); // Only affects GL4ES as of now const char *forceVsync = getenv("FORCE_VSYNC"); @@ -857,9 +857,9 @@ int pojavInit() { return 0; } - printf("OSMDroid: width=%i;height=%i, reserving %i bytes for frame buffer\n", savedWidth, savedHeight, - savedWidth * 4 * savedHeight); - gbuffer = malloc(savedWidth * 4 * savedHeight+1); + printf("OSMDroid: width=%i;height=%i, reserving %i bytes for frame buffer\n", pojav_environ->savedWidth, pojav_environ->savedHeight, + pojav_environ->savedWidth * 4 * pojav_environ->savedHeight); + gbuffer = malloc(pojav_environ->savedWidth * 4 * pojav_environ->savedHeight+1); if (gbuffer) { printf("OSMDroid: created frame buffer\n"); return 1; @@ -894,7 +894,7 @@ void pojavSwapBuffers() { printf("Zink: attempted to swap buffers without context!"); break; } - OSMesaMakeCurrent_p(ctx,buf.bits,GL_UNSIGNED_BYTE,savedWidth,savedHeight); + OSMesaMakeCurrent_p(ctx,buf.bits,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); glFinish_p(); ANativeWindow_unlockAndPost(pojav_environ->pojavWindow); //OSMesaMakeCurrent_p(ctx,gbuffer,GL_UNSIGNED_BYTE,savedWidth,savedHeight); @@ -935,7 +935,7 @@ void pojavMakeCurrent(void* window) { } if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) { printf("OSMDroid: making current\n"); - OSMesaMakeCurrent_p((OSMesaContext)window,gbuffer,GL_UNSIGNED_BYTE,savedWidth,savedHeight); + OSMesaMakeCurrent_p((OSMesaContext)window,gbuffer,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL); OSMesaPixelStore_p(OSMESA_ROW_LENGTH,buf.stride); @@ -1014,7 +1014,7 @@ Java_org_lwjgl_opengl_GL_getGraphicsBufferAddr(JNIEnv *env, jobject thiz) { JNIEXPORT jintArray JNICALL Java_org_lwjgl_opengl_GL_getNativeWidthHeight(JNIEnv *env, jobject thiz) { jintArray ret = (*env)->NewIntArray(env,2); - jint arr[] = {savedWidth, savedHeight}; + jint arr[] = {pojav_environ->savedWidth, pojav_environ->savedHeight}; (*env)->SetIntArrayRegion(env,ret,0,2,arr); return ret; } diff --git a/app_pojavlauncher/src/main/jni/environ/environ.h b/app_pojavlauncher/src/main/jni/environ/environ.h index 3abee0b21..73f18a23e 100644 --- a/app_pojavlauncher/src/main/jni/environ/environ.h +++ b/app_pojavlauncher/src/main/jni/environ/environ.h @@ -6,12 +6,64 @@ #define POJAVLAUNCHER_ENVIRON_H #include +#include +#include + +typedef struct { + int type; + int i1; + int i2; + int i3; + int i4; +} GLFWInputEvent; + +typedef void GLFW_invoke_Char_func(void* window, unsigned int codepoint); +typedef void GLFW_invoke_CharMods_func(void* window, unsigned int codepoint, int mods); +typedef void GLFW_invoke_CursorEnter_func(void* window, int entered); +typedef void GLFW_invoke_CursorPos_func(void* window, double xpos, double ypos); +typedef void GLFW_invoke_FramebufferSize_func(void* window, int width, int height); +typedef void GLFW_invoke_Key_func(void* window, int key, int scancode, int action, int mods); +typedef void GLFW_invoke_MouseButton_func(void* window, int button, int action, int mods); +typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset); +typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height); struct pojav_environ_s { struct ANativeWindow* pojavWindow; render_window_t* mainWindowBundle; int config_renderer; bool force_vsync; + atomic_size_t eventCounter; + GLFWInputEvent events[8000]; + float grabCursorX, grabCursorY, lastCursorX, lastCursorY; + double cursorX, cursorY, cLastX, cLastY; + jmethodID method_accessAndroidClipboard; + jmethodID method_onGrabStateChanged; + jmethodID method_glftSetWindowAttrib; + jmethodID method_internalWindowSizeChanged; + jclass bridgeClazz; + jclass vmGlfwClass; + jboolean isGrabbing; + jbyte* keyDownBuffer; + JavaVM* runtimeJavaVMPtr; + JNIEnv* runtimeJNIEnvPtr_JRE; + JavaVM* dalvikJavaVMPtr; + JNIEnv* dalvikJNIEnvPtr_ANDROID; + long showingWindow; + bool isInputReady, isCursorEntered, isPrepareGrabPos, isUseStackQueueCall; + int savedWidth, savedHeight; +#define ADD_CALLBACK_WWIN(NAME) \ + GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME; + ADD_CALLBACK_WWIN(Char); + ADD_CALLBACK_WWIN(CharMods); + ADD_CALLBACK_WWIN(CursorEnter); + ADD_CALLBACK_WWIN(CursorPos); + ADD_CALLBACK_WWIN(FramebufferSize); + ADD_CALLBACK_WWIN(Key); + ADD_CALLBACK_WWIN(MouseButton); + ADD_CALLBACK_WWIN(Scroll); + ADD_CALLBACK_WWIN(WindowSize); + +#undef ADD_CALLBACK_WWIN }; extern struct pojav_environ_s *pojav_environ; diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index 5dc8304d4..8aac4cb8c 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -20,6 +20,7 @@ #include "log.h" #include "utils.h" +#include "environ/environ.h" #define EVENT_TYPE_CHAR 1000 #define EVENT_TYPE_CHAR_MODS 1001 @@ -33,50 +34,31 @@ jint (*orig_ProcessImpl_forkAndExec)(JNIEnv *env, jobject process, jint mode, jbyteArray helperpath, jbyteArray prog, jbyteArray argBlock, jint argc, jbyteArray envBlock, jint envc, jbyteArray dir, jintArray std_fds, jboolean redirectErrorStream); -typedef void GLFW_invoke_Char_func(void* window, unsigned int codepoint); -typedef void GLFW_invoke_CharMods_func(void* window, unsigned int codepoint, int mods); -typedef void GLFW_invoke_CursorEnter_func(void* window, int entered); -typedef void GLFW_invoke_CursorPos_func(void* window, double xpos, double ypos); -typedef void GLFW_invoke_FramebufferSize_func(void* window, int width, int height); -typedef void GLFW_invoke_Key_func(void* window, int key, int scancode, int action, int mods); -typedef void GLFW_invoke_MouseButton_func(void* window, int button, int action, int mods); -typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset); -typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height); - -static float grabCursorX, grabCursorY, lastCursorX, lastCursorY; -static double cursorX, cursorY, cLastX, cLastY; - -jmethodID method_accessAndroidClipboard; -jmethodID method_onGrabStateChanged; -jmethodID method_glftSetWindowAttrib; -jmethodID method_internalWindowSizeChanged; -jclass bridgeClazz; -jclass vmGlfwClass; -jboolean isGrabbing; -jbyte* keyDownBuffer; jint JNI_OnLoad(JavaVM* vm, void* reserved) { - if (dalvikJavaVMPtr == NULL) { + if (pojav_environ->dalvikJavaVMPtr == NULL) { + __android_log_print(ANDROID_LOG_INFO, "Native", "Saving DVM environ..."); //Save dalvik global JavaVM pointer - dalvikJavaVMPtr = vm; - (*vm)->GetEnv(vm, (void**) &dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4); - bridgeClazz = (*dalvikJNIEnvPtr_ANDROID)->NewGlobalRef(dalvikJNIEnvPtr_ANDROID,(*dalvikJNIEnvPtr_ANDROID) ->FindClass(dalvikJNIEnvPtr_ANDROID,"org/lwjgl/glfw/CallbackBridge")); - method_accessAndroidClipboard = (*dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(dalvikJNIEnvPtr_ANDROID, bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;"); - method_onGrabStateChanged = (*dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(dalvikJNIEnvPtr_ANDROID, bridgeClazz, "onGrabStateChanged", "(Z)V"); - isUseStackQueueCall = JNI_FALSE; - } else if (dalvikJavaVMPtr != vm) { - runtimeJavaVMPtr = vm; - (*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4); - vmGlfwClass = (*runtimeJNIEnvPtr_JRE)->NewGlobalRef(runtimeJNIEnvPtr_JRE, (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW")); - method_glftSetWindowAttrib = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "glfwSetWindowAttrib", "(JII)V"); - method_internalWindowSizeChanged = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "internalWindowSizeChanged", "(JII)V"); - jfieldID field_keyDownBuffer = (*runtimeJNIEnvPtr_JRE)->GetStaticFieldID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;"); - jobject keyDownBufferJ = (*runtimeJNIEnvPtr_JRE)->GetStaticObjectField(runtimeJNIEnvPtr_JRE, vmGlfwClass, field_keyDownBuffer); - keyDownBuffer = (*runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(runtimeJNIEnvPtr_JRE, keyDownBufferJ); + pojav_environ->dalvikJavaVMPtr = vm; + (*vm)->GetEnv(vm, (void**) &pojav_environ->dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4); + pojav_environ->bridgeClazz = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->NewGlobalRef(pojav_environ->dalvikJNIEnvPtr_ANDROID,(*pojav_environ->dalvikJNIEnvPtr_ANDROID) ->FindClass(pojav_environ->dalvikJNIEnvPtr_ANDROID,"org/lwjgl/glfw/CallbackBridge")); + pojav_environ->method_accessAndroidClipboard = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;"); + pojav_environ->method_onGrabStateChanged = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V"); + pojav_environ->isUseStackQueueCall = JNI_FALSE; + } else if (pojav_environ->dalvikJavaVMPtr != vm) { + __android_log_print(ANDROID_LOG_INFO, "Native", "Saving JVM environ..."); + pojav_environ->runtimeJavaVMPtr = vm; + (*vm)->GetEnv(vm, (void**) &pojav_environ->runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4); + pojav_environ->vmGlfwClass = (*pojav_environ->runtimeJNIEnvPtr_JRE)->NewGlobalRef(pojav_environ->runtimeJNIEnvPtr_JRE, (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW")); + pojav_environ->method_glftSetWindowAttrib = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "glfwSetWindowAttrib", "(JII)V"); + pojav_environ->method_internalWindowSizeChanged = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "internalWindowSizeChanged", "(JII)V"); + jfieldID field_keyDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticFieldID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;"); + jobject keyDownBufferJ = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticObjectField(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, field_keyDownBuffer); + pojav_environ->keyDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(pojav_environ->runtimeJNIEnvPtr_JRE, keyDownBufferJ); hookExec(); } - isGrabbing = JNI_FALSE; + pojav_environ->isGrabbing = JNI_FALSE; return JNI_VERSION_1_4; } @@ -84,7 +66,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { // Should be? void JNI_OnUnload(JavaVM* vm, void* reserved) { /* - if (dalvikJavaVMPtr == vm) { + if (pojav_environ->dalvikJavaVMPtr == vm) { } else { } @@ -96,10 +78,10 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { } #define ADD_CALLBACK_WWIN(NAME) \ -GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME; \ JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSet##NAME##Callback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) { \ - void** oldCallback = (void**) &GLFW_invoke_##NAME; \ - GLFW_invoke_##NAME = (GLFW_invoke_##NAME##_func*) (uintptr_t) callbackptr; \ + __android_log_print(ANDROID_LOG_INFO, "NativeInput", "%p Set callback for #NAME to %p", &JNI_OnLoad, callbackptr); \ + void** oldCallback = (void**) &pojav_environ->GLFW_invoke_##NAME; \ + pojav_environ->GLFW_invoke_##NAME = (GLFW_invoke_##NAME##_func*) (uintptr_t) callbackptr; \ return (jlong) (uintptr_t) *oldCallback; \ } @@ -117,99 +99,91 @@ ADD_CALLBACK_WWIN(WindowSize); jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr) { #ifdef DEBUG - LOGD("Debug: Attaching %s thread to %s, javavm.isNull=%d\n", isAndroid ? "Android" : "JRE", isAndroid ? "JRE" : "Android", (isAndroid ? runtimeJavaVMPtr : dalvikJavaVMPtr) == NULL); + LOGD("Debug: Attaching %s thread to %s, javavm.isNull=%d\n", isAndroid ? "Android" : "JRE", isAndroid ? "JRE" : "Android", (isAndroid ? pojav_environ->runtimeJavaVMPtr : pojav_environ->dalvikJavaVMPtr) == NULL); #endif - if (*secondJNIEnvPtr != NULL || (!isUseStackQueueCall)) return JNI_TRUE; + if (*secondJNIEnvPtr != NULL || (!pojav_environ->isUseStackQueueCall)) return JNI_TRUE; - if (isAndroid && runtimeJavaVMPtr) { - (*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, secondJNIEnvPtr, NULL); + if (isAndroid && pojav_environ->runtimeJavaVMPtr) { + (*pojav_environ->runtimeJavaVMPtr)->AttachCurrentThread(pojav_environ->runtimeJavaVMPtr, secondJNIEnvPtr, NULL); return JNI_TRUE; - } else if (!isAndroid && dalvikJavaVMPtr) { - (*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, secondJNIEnvPtr, NULL); + } else if (!isAndroid && pojav_environ->dalvikJavaVMPtr) { + (*pojav_environ->dalvikJavaVMPtr)->AttachCurrentThread(pojav_environ->dalvikJavaVMPtr, secondJNIEnvPtr, NULL); return JNI_TRUE; } return JNI_FALSE; } -typedef struct { - int type; - int i1; - int i2; - int i3; - int i4; -} GLFWInputEvent; -static atomic_size_t eventCounter = 0; -static GLFWInputEvent events[8000]; + void handleFramebufferSizeJava(long window, int w, int h) { - (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(runtimeJNIEnvPtr_JRE, vmGlfwClass, method_internalWindowSizeChanged, (long)window, w, h); + (*pojav_environ->runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, pojav_environ->method_internalWindowSizeChanged, (long)window, w, h); } void pojavPumpEvents(void* window) { - //__android_log_print(ANDROID_LOG_INFO, "input_bridge_v3", "pojavPumpEvents %d", eventCounter); - size_t counter = atomic_load_explicit(&eventCounter, memory_order_acquire); + //__android_log_print(ANDROID_LOG_INFO, "input_bridge_v3", "pojavPumppojav_environ->events %d", pojav_environ->eventCounter); + size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire); for(size_t i = 0; i < counter; i++) { - GLFWInputEvent event = events[i]; + GLFWInputEvent event = pojav_environ->events[i]; switch(event.type) { case EVENT_TYPE_CHAR: - if(GLFW_invoke_Char) GLFW_invoke_Char(window, event.i1); + if(pojav_environ->GLFW_invoke_Char) pojav_environ->GLFW_invoke_Char(window, event.i1); break; case EVENT_TYPE_CHAR_MODS: - if(GLFW_invoke_CharMods) GLFW_invoke_CharMods(window, event.i1, event.i2); + if(pojav_environ->GLFW_invoke_CharMods) pojav_environ->GLFW_invoke_CharMods(window, event.i1, event.i2); break; case EVENT_TYPE_KEY: - if(GLFW_invoke_Key) GLFW_invoke_Key(window, event.i1, event.i2, event.i3, event.i4); + if(pojav_environ->GLFW_invoke_Key) pojav_environ->GLFW_invoke_Key(window, event.i1, event.i2, event.i3, event.i4); break; case EVENT_TYPE_MOUSE_BUTTON: - if(GLFW_invoke_MouseButton) GLFW_invoke_MouseButton(window, event.i1, event.i2, event.i3); + if(pojav_environ->GLFW_invoke_MouseButton) pojav_environ->GLFW_invoke_MouseButton(window, event.i1, event.i2, event.i3); break; case EVENT_TYPE_SCROLL: - if(GLFW_invoke_Scroll) GLFW_invoke_Scroll(window, event.i1, event.i2); + if(pojav_environ->GLFW_invoke_Scroll) pojav_environ->GLFW_invoke_Scroll(window, event.i1, event.i2); break; case EVENT_TYPE_FRAMEBUFFER_SIZE: - handleFramebufferSizeJava(showingWindow, event.i1, event.i2); - if(GLFW_invoke_FramebufferSize) GLFW_invoke_FramebufferSize(window, event.i1, event.i2); + handleFramebufferSizeJava(pojav_environ->showingWindow, event.i1, event.i2); + if(pojav_environ->GLFW_invoke_FramebufferSize) pojav_environ->GLFW_invoke_FramebufferSize(window, event.i1, event.i2); break; case EVENT_TYPE_WINDOW_SIZE: - handleFramebufferSizeJava(showingWindow, event.i1, event.i2); - if(GLFW_invoke_WindowSize) GLFW_invoke_WindowSize(window, event.i1, event.i2); + handleFramebufferSizeJava(pojav_environ->showingWindow, event.i1, event.i2); + if(pojav_environ->GLFW_invoke_WindowSize) pojav_environ->GLFW_invoke_WindowSize(window, event.i1, event.i2); break; } } - if((cLastX != cursorX || cLastY != cursorY) && GLFW_invoke_CursorPos) { - cLastX = cursorX; - cLastY = cursorY; - GLFW_invoke_CursorPos(window, cursorX, cursorY); + if((pojav_environ->cLastX != pojav_environ->cursorX || pojav_environ->cLastY != pojav_environ->cursorY) && pojav_environ->GLFW_invoke_CursorPos) { + pojav_environ->cLastX = pojav_environ->cursorX; + pojav_environ->cLastY = pojav_environ->cursorY; + pojav_environ->GLFW_invoke_CursorPos(window, pojav_environ->cursorX, pojav_environ->cursorY); } - atomic_store_explicit(&eventCounter, counter, memory_order_release); + atomic_store_explicit(&pojav_environ->eventCounter, counter, memory_order_release); } void pojavRewindEvents() { - atomic_store_explicit(&eventCounter, 0, memory_order_release); + atomic_store_explicit(&pojav_environ->eventCounter, 0, memory_order_release); } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwGetCursorPos(JNIEnv *env, jclass clazz, jlong window, jobject xpos, jobject ypos) { - *(double*)(*env)->GetDirectBufferAddress(env, xpos) = cursorX; - *(double*)(*env)->GetDirectBufferAddress(env, ypos) = cursorY; + *(double*)(*env)->GetDirectBufferAddress(env, xpos) = pojav_environ->cursorX; + *(double*)(*env)->GetDirectBufferAddress(env, ypos) = pojav_environ->cursorY; // TODO: implement glfwGetCursorPos() } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwGetCursorPosA(JNIEnv *env, jclass clazz, jlong window, jdoubleArray xpos, jdoubleArray ypos) { - (*env)->SetDoubleArrayRegion(env, xpos, 0,1, &cursorX); - (*env)->SetDoubleArrayRegion(env, ypos, 0,1, &cursorY); + (*env)->SetDoubleArrayRegion(env, xpos, 0,1, &pojav_environ->cursorX); + (*env)->SetDoubleArrayRegion(env, ypos, 0,1, &pojav_environ->cursorY); // TODO: implement nglfwGetCursorPosA() } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_glfwSetCursorPos(JNIEnv *env, jclass clazz, jlong window, jdouble xpos, jdouble ypos) { - cLastX = cursorX = xpos; - cLastY = cursorY = ypos; + pojav_environ->cLastX = pojav_environ->cursorX = xpos; + pojav_environ->cLastY = pojav_environ->cursorY = ypos; // TODO: implement glfwSetCursorPos() } @@ -217,33 +191,33 @@ Java_org_lwjgl_glfw_GLFW_glfwSetCursorPos(JNIEnv *env, jclass clazz, jlong windo void sendData(int type, int i1, int i2, int i3, int i4) { if(type == EVENT_TYPE_CURSOR_POS) { - cursorX = i1; - cursorY = i2; + pojav_environ->cursorX = i1; + pojav_environ->cursorY = i2; }else { - size_t counter = atomic_load_explicit(&eventCounter, memory_order_acquire); + size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire); if (counter < 7999) { - GLFWInputEvent *event = &events[counter++]; + GLFWInputEvent *event = &pojav_environ->events[counter++]; event->type = type; event->i1 = i1; event->i2 = i2; event->i3 = i3; event->i4 = i4; } - atomic_store_explicit(&eventCounter, counter, memory_order_release); + atomic_store_explicit(&pojav_environ->eventCounter, counter, memory_order_release); } } void closeGLFWWindow() { /* - jclass glfwClazz = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW"); + jclass glfwClazz = (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW"); assert(glfwClazz != NULL); - jmethodID glfwMethod = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, glfwMethod, "glfwSetWindowShouldClose", "(JZ)V"); + jmethodID glfwMethod = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, glfwMethod, "glfwSetWindowShouldClose", "(JZ)V"); assert(glfwMethod != NULL); - (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( - runtimeJNIEnvPtr_JRE, + (*pojav_environ->runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( + pojav_environ->runtimeJNIEnvPtr_JRE, glfwClazz, glfwMethod, - (jlong) showingWindow, JNI_TRUE + (jlong) pojav_environ->showingWindow, JNI_TRUE ); */ exit(-1); @@ -273,42 +247,42 @@ void hookExec() { orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_UNIXProcess_forkAndExec"); if (!orig_ProcessImpl_forkAndExec) { orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_ProcessImpl_forkAndExec"); - cls = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "java/lang/ProcessImpl"); + cls = (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "java/lang/ProcessImpl"); } else { - cls = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "java/lang/UNIXProcess"); + cls = (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "java/lang/UNIXProcess"); } JNINativeMethod methods[] = { {"forkAndExec", "(I[B[B[BI[BI[B[IZ)I", (void *)&hooked_ProcessImpl_forkAndExec} }; - (*runtimeJNIEnvPtr_JRE)->RegisterNatives(runtimeJNIEnvPtr_JRE, cls, methods, 1); + (*pojav_environ->runtimeJNIEnvPtr_JRE)->RegisterNatives(pojav_environ->runtimeJNIEnvPtr_JRE, cls, methods, 1); printf("Registered forkAndExec\n"); } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetUseInputStackQueue(JNIEnv *env, jclass clazz, jboolean use_input_stack_queue) { - isUseStackQueueCall = (int) use_input_stack_queue; + pojav_environ->isUseStackQueueCall = (int) use_input_stack_queue; } JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThreadToOther(JNIEnv* env, jclass clazz, jboolean isAndroid, jboolean isUseStackQueueBool) { #ifdef DEBUG LOGD("Debug: JNI attaching thread, isUseStackQueue=%d\n", isUseStackQueueBool); #endif - if (isUseStackQueueCall && isAndroid) { - isPrepareGrabPos = true; + if (pojav_environ->isUseStackQueueCall && isAndroid) { + pojav_environ->isPrepareGrabPos = true; } return true; } JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jbyteArray copySrc) { #ifdef DEBUG - LOGD("Debug: Clipboard access is going on\n", isUseStackQueueCall); + LOGD("Debug: Clipboard access is going on\n", pojav_environ->isUseStackQueueCall); #endif JNIEnv *dalvikEnv; - (*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, &dalvikEnv, NULL); + (*pojav_environ->dalvikJavaVMPtr)->AttachCurrentThread(pojav_environ->dalvikJavaVMPtr, &dalvikEnv, NULL); assert(dalvikEnv != NULL); - assert(bridgeClazz != NULL); + assert(pojav_environ->bridgeClazz != NULL); LOGD("Clipboard: Converting string\n"); char *copySrcC = NULL; @@ -319,52 +293,52 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNI } LOGD("Clipboard: Calling 2nd\n"); - jstring pasteDst = convertStringJVM(dalvikEnv, env, (jstring) (*dalvikEnv)->CallStaticObjectMethod(dalvikEnv, bridgeClazz, method_accessAndroidClipboard, action, copyDst)); + jstring pasteDst = convertStringJVM(dalvikEnv, env, (jstring) (*dalvikEnv)->CallStaticObjectMethod(dalvikEnv, pojav_environ->bridgeClazz, pojav_environ->method_accessAndroidClipboard, action, copyDst)); if (copySrc) { (*dalvikEnv)->DeleteLocalRef(dalvikEnv, copyDst); (*env)->ReleaseByteArrayElements(env, copySrc, (jbyte *)copySrcC, 0); } - (*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr); + (*pojav_environ->dalvikJavaVMPtr)->DetachCurrentThread(pojav_environ->dalvikJavaVMPtr); return pasteDst; } JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetInputReady(JNIEnv* env, jclass clazz, jboolean inputReady) { #ifdef DEBUG - LOGD("Debug: Changing input state, isReady=%d, isUseStackQueueCall=%d\n", inputReady, isUseStackQueueCall); + LOGD("Debug: Changing input state, isReady=%d, pojav_environ->isUseStackQueueCall=%d\n", inputReady, pojav_environ->isUseStackQueueCall); #endif __android_log_print(ANDROID_LOG_INFO, "NativeInput", "Input ready: %i", inputReady); - isInputReady = inputReady; - return isUseStackQueueCall; + pojav_environ->isInputReady = inputReady; + return pojav_environ->isUseStackQueueCall; } static void updateGrabCursor(jint xset, jint yset) { - if (isGrabbing == JNI_TRUE) { - grabCursorX = xset; // savedWidth / 2; - grabCursorY = yset; // savedHeight / 2; - isPrepareGrabPos = true; + if (pojav_environ->isGrabbing == JNI_TRUE) { + pojav_environ->grabCursorX = xset; // pojav_environ->savedWidth / 2; + pojav_environ->grabCursorY = yset; // pojav_environ->savedHeight / 2; + pojav_environ->isPrepareGrabPos = true; } } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetGrabbing(JNIEnv* env, jclass clazz, jboolean grabbing) { JNIEnv *dalvikEnv; - (*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, &dalvikEnv, NULL); - (*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, bridgeClazz, method_onGrabStateChanged, grabbing); - (*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr); - isGrabbing = grabbing; - updateGrabCursor((jint)cursorX, (jint)cursorY); + (*pojav_environ->dalvikJavaVMPtr)->AttachCurrentThread(pojav_environ->dalvikJavaVMPtr, &dalvikEnv, NULL); + (*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, pojav_environ->bridgeClazz, pojav_environ->method_onGrabStateChanged, grabbing); + (*pojav_environ->dalvikJavaVMPtr)->DetachCurrentThread(pojav_environ->dalvikJavaVMPtr); + pojav_environ->isGrabbing = grabbing; + updateGrabCursor((jint)pojav_environ->cursorX, (jint)pojav_environ->cursorY); } -JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeIsGrabbing(JNIEnv* env, jclass clazz) { - return isGrabbing; +JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeisGrabbing(JNIEnv* env, jclass clazz) { + return pojav_environ->isGrabbing; } JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNIEnv* env, jclass clazz, jchar codepoint /* jint codepoint */) { - if (GLFW_invoke_Char && isInputReady) { - if (isUseStackQueueCall) { + if (pojav_environ->GLFW_invoke_Char && pojav_environ->isInputReady) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_CHAR, codepoint, 0, 0, 0); } else { - GLFW_invoke_Char((void*) showingWindow, (unsigned int) codepoint); + pojav_environ->GLFW_invoke_Char((void*) pojav_environ->showingWindow, (unsigned int) codepoint); // return lwjgl2_triggerCharEvent(codepoint); } return JNI_TRUE; @@ -373,11 +347,11 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNI } JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(JNIEnv* env, jclass clazz, jchar codepoint, jint mods) { - if (GLFW_invoke_CharMods && isInputReady) { - if (isUseStackQueueCall) { + if (pojav_environ->GLFW_invoke_CharMods && pojav_environ->isInputReady) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_CHAR_MODS, (unsigned int) codepoint, mods, 0, 0); } else { - GLFW_invoke_CharMods((void*) showingWindow, codepoint, mods); + pojav_environ->GLFW_invoke_CharMods((void*) pojav_environ->showingWindow, codepoint, mods); } return JNI_TRUE; } @@ -385,8 +359,8 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods } /* JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter(JNIEnv* env, jclass clazz, jint entered) { - if (GLFW_invoke_CursorEnter && isInputReady) { - GLFW_invoke_CursorEnter(showingWindow, entered); + if (pojav_environ->GLFW_invoke_CursorEnter && pojav_environ->isInputReady) { + pojav_environ->GLFW_invoke_CursorEnter(pojav_environ->showingWindow, entered); } } */ @@ -394,48 +368,48 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JN #ifdef DEBUG LOGD("Sending cursor position \n"); #endif - if (GLFW_invoke_CursorPos && isInputReady) { + if (pojav_environ->GLFW_invoke_CursorPos && pojav_environ->isInputReady) { #ifdef DEBUG - LOGD("GLFW_invoke_CursorPos && isInputReady \n"); + LOGD("pojav_environ->GLFW_invoke_CursorPos && pojav_environ->isInputReady \n"); #endif - if (!isCursorEntered) { - if (GLFW_invoke_CursorEnter) { - isCursorEntered = true; - if (isUseStackQueueCall) { + if (!pojav_environ->isCursorEntered) { + if (pojav_environ->GLFW_invoke_CursorEnter) { + pojav_environ->isCursorEntered = true; + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_CURSOR_ENTER, 1, 0, 0, 0); } else { - GLFW_invoke_CursorEnter((void*) showingWindow, 1); + pojav_environ->GLFW_invoke_CursorEnter((void*) pojav_environ->showingWindow, 1); } - } else if (isGrabbing) { + } else if (pojav_environ->isGrabbing) { // Some Minecraft versions does not use GLFWCursorEnterCallback // This is a smart check, as Minecraft will not in grab mode if already not. - isCursorEntered = true; + pojav_environ->isCursorEntered = true; } } - if (isGrabbing) { - if (!isPrepareGrabPos) { - grabCursorX += x - lastCursorX; - grabCursorY += y - lastCursorY; + if (pojav_environ->isGrabbing) { + if (!pojav_environ->isPrepareGrabPos) { + pojav_environ->grabCursorX += x - pojav_environ->lastCursorX; + pojav_environ->grabCursorY += y - pojav_environ->lastCursorY; } - lastCursorX = x; - lastCursorY = y; + pojav_environ->lastCursorX = x; + pojav_environ->lastCursorY = y; - if (isPrepareGrabPos) { - isPrepareGrabPos = false; + if (pojav_environ->isPrepareGrabPos) { + pojav_environ->isPrepareGrabPos = false; return; } } - if (!isUseStackQueueCall) { - GLFW_invoke_CursorPos((void*) showingWindow, (double) (x), (double) (y)); + if (!pojav_environ->isUseStackQueueCall) { + pojav_environ->GLFW_invoke_CursorPos((void*) pojav_environ->showingWindow, (double) (x), (double) (y)); } else { - sendData(EVENT_TYPE_CURSOR_POS, (isGrabbing ? grabCursorX : x), (isGrabbing ? grabCursorY : y), 0, 0); + sendData(EVENT_TYPE_CURSOR_POS, (pojav_environ->isGrabbing ? pojav_environ->grabCursorX : x), (pojav_environ->isGrabbing ? pojav_environ->grabCursorY : y), 0, 0); } - lastCursorX = x; - lastCursorY = y; + pojav_environ->lastCursorX = x; + pojav_environ->lastCursorY = y; } } #define max(a,b) \ @@ -443,12 +417,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JN __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* env, jclass clazz, jint key, jint scancode, jint action, jint mods) { - if (GLFW_invoke_Key && isInputReady) { - keyDownBuffer[max(0, key-31)]=(jbyte)action; - if (isUseStackQueueCall) { + if (pojav_environ->GLFW_invoke_Key && pojav_environ->isInputReady) { + pojav_environ->keyDownBuffer[max(0, key-31)]=(jbyte)action; + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_KEY, key, scancode, action, mods); } else { - GLFW_invoke_Key((void*) showingWindow, key, scancode, action, mods); + pojav_environ->GLFW_invoke_Key((void*) pojav_environ->showingWindow, key, scancode, action, mods); } } } @@ -456,68 +430,68 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(JNIEnv* env, jclass clazz, jint button, jint action, jint mods) { - if (isInputReady) { + if (pojav_environ->isInputReady) { if (button == -1) { // Notify to prepare set new grab pos - isPrepareGrabPos = true; - } else if (GLFW_invoke_MouseButton) { - if (isUseStackQueueCall) { + pojav_environ->isPrepareGrabPos = true; + } else if (pojav_environ->GLFW_invoke_MouseButton) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_MOUSE_BUTTON, button, action, mods, 0); } else { - GLFW_invoke_MouseButton((void*) showingWindow, button, action, mods); + pojav_environ->GLFW_invoke_MouseButton((void*) pojav_environ->showingWindow, button, action, mods); } } } } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScreenSize(JNIEnv* env, jclass clazz, jint width, jint height) { - savedWidth = width; - savedHeight = height; - if (isInputReady) { - if (GLFW_invoke_FramebufferSize) { - if (isUseStackQueueCall) { + pojav_environ->savedWidth = width; + pojav_environ->savedHeight = height; + if (pojav_environ->isInputReady) { + if (pojav_environ->GLFW_invoke_FramebufferSize) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_FRAMEBUFFER_SIZE, width, height, 0, 0); } else { - GLFW_invoke_FramebufferSize((void*) showingWindow, width, height); + pojav_environ->GLFW_invoke_FramebufferSize((void*) pojav_environ->showingWindow, width, height); } } - if (GLFW_invoke_WindowSize) { - if (isUseStackQueueCall) { + if (pojav_environ->GLFW_invoke_WindowSize) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_WINDOW_SIZE, width, height, 0, 0); } else { - GLFW_invoke_WindowSize((void*) showingWindow, width, height); + pojav_environ->GLFW_invoke_WindowSize((void*) pojav_environ->showingWindow, width, height); } } } - // return (isInputReady && (GLFW_invoke_FramebufferSize || GLFW_invoke_WindowSize)); + // return (pojav_environ->isInputReady && (pojav_environ->GLFW_invoke_FramebufferSize || pojav_environ->GLFW_invoke_WindowSize)); } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEnv* env, jclass clazz, jdouble xoffset, jdouble yoffset) { - if (GLFW_invoke_Scroll && isInputReady) { - if (isUseStackQueueCall) { + if (pojav_environ->GLFW_invoke_Scroll && pojav_environ->isInputReady) { + if (pojav_environ->isUseStackQueueCall) { sendData(EVENT_TYPE_SCROLL, xoffset, yoffset, 0, 0); } else { - GLFW_invoke_Scroll((void*) showingWindow, (double) xoffset, (double) yoffset); + pojav_environ->GLFW_invoke_Scroll((void*) pojav_environ->showingWindow, (double) xoffset, (double) yoffset); } } } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetShowingWindow(JNIEnv* env, jclass clazz, jlong window) { - showingWindow = (long) window; + pojav_environ->showingWindow = (long) window; } JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib(JNIEnv* env, jclass clazz, jint attrib, jint value) { - if (!showingWindow || !isUseStackQueueCall) { + if (!pojav_environ->showingWindow || !pojav_environ->isUseStackQueueCall) { // If the window is not shown, there is nothing to do yet. // For Minecraft < 1.13, calling to JNI functions here crashes the JVM for some reason, therefore it is skipped for now. return; } - (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( - runtimeJNIEnvPtr_JRE, - vmGlfwClass, method_glftSetWindowAttrib, - (jlong) showingWindow, attrib, value + (*pojav_environ->runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( + pojav_environ->runtimeJNIEnvPtr_JRE, + pojav_environ->vmGlfwClass, pojav_environ->method_glftSetWindowAttrib, + (jlong) pojav_environ->showingWindow, attrib, value ); } diff --git a/app_pojavlauncher/src/main/jni/jre_launcher.c b/app_pojavlauncher/src/main/jni/jre_launcher.c index 5c58f315a..6662ba383 100644 --- a/app_pojavlauncher/src/main/jni/jre_launcher.c +++ b/app_pojavlauncher/src/main/jni/jre_launcher.c @@ -35,6 +35,7 @@ #include "log.h" #include "utils.h" +#include "environ/environ.h" // Uncomment to try redirect signal handling to JVM // #define TRY_SIG2JVM @@ -160,7 +161,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env, //Signal trapper ready // Save dalvik JNIEnv pointer for JVM launch thread - dalvikJNIEnvPtr_ANDROID = env; + pojav_environ->dalvikJNIEnvPtr_ANDROID = env; if (argsArray == NULL) { LOGE("Args array null, returning"); diff --git a/app_pojavlauncher/src/main/jni/utils.h b/app_pojavlauncher/src/main/jni/utils.h index 7c7b148d7..04fc3a027 100644 --- a/app_pojavlauncher/src/main/jni/utils.h +++ b/app_pojavlauncher/src/main/jni/utils.h @@ -2,18 +2,7 @@ #include -static JavaVM* runtimeJavaVMPtr; -static JNIEnv* runtimeJNIEnvPtr_JRE; -static JavaVM* dalvikJavaVMPtr; -static JNIEnv* dalvikJNIEnvPtr_ANDROID; -//static JNIEnv* dalvikJNIEnvPtr_JRE; - -static long showingWindow; - -static bool isInputReady, isCursorEntered, isPrepareGrabPos, isUseStackQueueCall; - -static int savedWidth, savedHeight; jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr); char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray);