Re-write the input pipe to C code

This commit is contained in:
khanhduytran0 2020-10-14 15:09:32 +07:00
parent 11f1e1b5c9
commit 904a8286dc
4 changed files with 260 additions and 24 deletions

View File

@ -403,7 +403,7 @@ public class MainActivity extends LoggableActivity implements OnTouchListener, O
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: // 0
case MotionEvent.ACTION_POINTER_DOWN: // 5
CallbackBridge.sendGrabInitialPosUnset();
CallbackBridge.sendPrepareGrabInitialPos();
isTouchInHotbar = hudKeyHandled != -1;
if (isTouchInHotbar) {
@ -631,7 +631,7 @@ public class MainActivity extends LoggableActivity implements OnTouchListener, O
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: // 0
case MotionEvent.ACTION_POINTER_DOWN: // 5
CallbackBridge.sendGrabInitialPosUnset();
CallbackBridge.sendPrepareGrabInitialPos();
CallbackBridge.sendMouseKeycode(!CallbackBridge.mouseLeft ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, 0, true);
initialX = x;
@ -693,6 +693,18 @@ public class MainActivity extends LoggableActivity implements OnTouchListener, O
}
});
minecraftGLView.setOnTouchListener(glTouchListener);
minecraftGLView.setOnGenericMotionListener(new OnGenericMotionListener(){
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_SCROLL:
CallbackBridge.sendScroll((double) event.getAxisValue(MotionEvent.AXIS_VSCROLL), (double) event.getAxisValue(MotionEvent.AXIS_HSCROLL));
break;
}
return true;
}
});
minecraftGLView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){
private boolean isCalled = false;

View File

@ -2,6 +2,7 @@ package org.lwjgl.glfw;
import java.io.*;
import java.util.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
public class CallbackBridge {
public static final int JRE_TYPE_CURSOR_POS = 0;
@ -35,23 +36,28 @@ public class CallbackBridge {
DEBUG_STRING.append("CursorPos=" + x + ", " + y + "\n");
mouseX = x;
mouseY = y;
sendData(JRE_TYPE_CURSOR_POS, x, y);
nativeSendCursorPos(x, y);
}
public static void sendGrabInitialPosUnset() {
DEBUG_STRING.append("Grab initial posititon uset");
sendData(JRE_TYPE_GRAB_INITIAL_POS_UNSET);
public static void sendPrepareGrabInitialPos() {
DEBUG_STRING.append("Prepare set grab initial posititon");
sendMouseKeycode(-1, 0, false);
}
public static void sendKeycode(int keycode, char keychar, int modifiers, boolean isDown) {
DEBUG_STRING.append("KeyCode=" + keycode + ", Char=" + keychar);
sendData(JRE_TYPE_KEYCODE_CONTROL, keycode, Character.toString(keychar), Boolean.toString(isDown), modifiers);
// TODO CHECK: This may cause input issue, not receive input!
if (!nativeSendCharMods(keycode, modifiers) ||!nativeSendChar(keycode)) {
nativeSendKey(keycode, 0 /* scancode */, isDown ? 1 : 0, modifiers);
}
public static void sendMouseKeycode(int keycode, int modifiers, boolean isDown) {
DEBUG_STRING.append("MouseKey=" + keycode + ", down=" + isDown + "\n");
// sendData(JRE_TYPE_KEYCODE_CONTROL, keycode, Character.toString(keychar), Boolean.toString(isDown), modifiers);
}
public static void sendMouseKeycode(int button, int modifiers, boolean isDown) {
DEBUG_STRING.append("MouseKey=" + button + ", down=" + isDown + "\n");
// if (isGrabbing()) DEBUG_STRING.append("MouseGrabStrace: " + android.util.Log.getStackTraceString(new Throwable()) + "\n");
sendData(JRE_TYPE_MOUSE_KEYCODE_CONTROL, keycode, Boolean.toString(isDown), modifiers);
nativeSendMouseButton(button, isDown ? 1 : 0, modifiers);
}
public static void sendMouseKeycode(int keycode) {
@ -59,8 +65,14 @@ public class CallbackBridge {
sendMouseKeycode(keycode, 0, false);
}
public static void sendScroll(double xoffset, double yoffset) {
DEBUG_STRING.append("ScrollX=" + xoffset + ",ScrollY=" + yoffset);
nativeSendScroll(xoffset, yoffset);
}
public static void sendUpdateWindowSize(int w, int h) {
sendData(JRE_TYPE_WINDOW_SIZE, w, h);
nativeSendFramebufferSize(w, h);
nativeSendWindowSize(w, h);
}
public static boolean isGrabbing() {
@ -76,7 +88,7 @@ public class CallbackBridge {
break;
}
}
/*
private static String currData;
public static void sendData(int type, Object... dataArr) {
currData = "";
@ -92,12 +104,26 @@ public class CallbackBridge {
}
nativeSendData(true, type, currData);
}
private static native void nativeSendData(boolean isAndroid, int type, String data);
*/
private static native void nativeAttachThreadToJRE();
private static native boolean nativeSendChar(int codepoint);
// GLFW: GLFWCharModsCallback deprecated, but is Minecraft still use?
private static native boolean nativeSendCharMods(int codepoint, int mods);
private static native void nativeSendCursorEnter(int entered);
private static native void nativeSendCursorPos(int x, int y);
private static native void nativeSendFramebufferSize(int width, int height);
private static native void nativeSendKey(int key, int scancode, int action, int mods);
private static native void nativeSendMouseButton(int button, int action, int mods);
private static native void nativeSendScroll(double xoffset, double yoffset);
private static native void nativeSendWindowSize(int width, int height);
public static native boolean nativeIsGrabbing();
static {
System.loadLibrary("pojavexec");
nativeAttachThreadToJRE();
}
}

View File

@ -3,20 +3,24 @@
#include "utils.h"
jclass inputBridgeClass_ANDROID;
jmethodID inputBridgeMethod_ANDROID;
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);
jclass inputBridgeClass_JRE;
jmethodID inputBridgeMethod_JRE;
JavaVM* firstJavaVM, secondJavaVM;
JNIEnv* firstJNIEnv, secondJNIEnv;
jclass inputBridgeClass_ANDROID, inputBridgeClass_JRE;
jmethodID inputBridgeMethod_ANDROID, inputBridgeMethod_JRE;
jboolean isGrabbing;
JavaVM* firstJavaVM;
JNIEnv* firstJNIEnv;
JavaVM* secondJavaVM;
JNIEnv* secondJNIEnv;
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
if (dalvikJavaVMPtr == NULL) {
//Save dalvik global JavaVM pointer
@ -62,6 +66,27 @@ void getJavaInputBridge(jclass* clazz, jmethodID* method) {
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThreadToJRE(JNIEnv* env, jclass clazz, jboolean isAndroid) {
if (isAndroid == JNI_TRUE) {
firstJavaVM = dalvikJavaVMPtr;
firstJNIEnv = dalvikJNIEnvPtr_ANDROID;
secondJavaVM = runtimeJavaVMPtr;
attachThreadIfNeed(&isAndroidThreadAttached, &runtimeJNIEnvPtr_ANDROID);
getJavaInputBridge(&inputBridgeClass_ANDROID, &inputBridgeMethod_ANDROID);
isPrepareGrabPos = true;
} else {
firstJavaVM = runtimeJavaVMPtr;
firstJNIEnv = runtimeJNIEnvPtr_JRE;
secondJavaVM = dalvikJavaVMPtr;
attachThreadIfNeed(&isRuntimeThreadAttached, &dalvikJNIEnvPtr_JRE);
getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
}
}
// TODO deprecate if implement fully callback in native
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendData(JNIEnv* env, jclass clazz, jboolean isAndroid, jint type, jstring data) {
if (isAndroid == JNI_TRUE) {
firstJavaVM = dalvikJavaVMPtr;
@ -105,3 +130,172 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeIsGrabbing(J
return isGrabbing;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNIEnv* env, jclass clazz, jint codepoint) {
if (GLFW_invoke_Char && isInputReady) {
GLFW_invoke_Char(showingWindow, codepoint);
return JNI_TRUE;
}
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(JNIEnv* env, jclass clazz, jint codepoint, jint mods) {
if (GLFW_invoke_CharMods && isInputReady) {
GLFW_invoke_CharMods(showingWindow, codepoint, mods);
return JNI_TRUE;
}
return JNI_FALSE;
}
/*
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);
}
}
*/
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jint x, jint y) {
if (GLFW_invoke_CursorPos && isInputReady) {
if (GLFW_invoke_CursorEnter && !isCursorEntered) {
isCursorEntered = true;
GLFW_invoke_CursorEnter(showingWindow, entered);
}
if (isGrabbing) {
if (!isPrepareGrabPos) {
grabCursorX += x - lastCursorX;
grabCursorY += y - lastCursorY;
} else {
isPrepareGrabPos = false;
lastCursorX = x;
lastCursotY = y;
return;
}
}
GLFW_invoke_CursorPos(showingWindow, (double) (isGrabbing ? grabCursorX : x), (double) (isGrabbing ? grabCursorY : y));
lastCursorX = x;
lastCursotY = y;
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendFramebufferSize(JNIEnv* env, jclass clazz, jint width, jint height) {
if (GLFW_invoke_FramebufferSize && isInputReady) {
GLFW_invoke_FramebufferSize(showingWindow, width, height);
}
}
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) {
GLFW_invoke_Key(showingWindow, key, scancode, action, mods);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(JNIEnv* env, jclass clazz, jint button, jint action, jint mods) {
if (isInputReady) {
if (button == -1) {
// Notify to prepare set new grab pos
isPrepareGrabPos = true;
} else if (GLFW_invoke_MouseButton) {
GLFW_invoke_MouseButton(showingWindow, button, action, mods);
}
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEnv* env, jclass clazz, jdouble xoffset, jdouble yoffset) {
if (GLFW_invoke_Scroll && isInputReady) {
GLFW_invoke_Scroll(showingWindow, (double) xoffset, (double) yoffset);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendWindowSize(JNIEnv* env, jclass clazz, jint x, jint y) {
if (GLFW_invoke_WindowSize && isInputReady) {
GLFW_invoke_WindowSize(showingWindow, width, height);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nativeSetShowingWindow(JNIEnv* env, jclass clazz, jlong window) {
showingWindow = (long) window;
}
#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 = &GLFW_invoke_##NAME; \
GLFW_invoke_##NAME = (GLFW_invoke_##NAME##_func*) (uintptr_t) callbackptr; \
return (jlong) (uintptr_t) *oldCallback; \
}
ADD_CALLBACK_WWIN(Char);
ADD_CALLBACK_WWIN(CharMods);
ADD_CALLBACK_WWIN(CursorEnter);
ADD_CALLBACK_WWIN(CursorPos);
ADD_CALLBACK_WWIN(FramebufferSize);
ADD_CALLBACK_WWIN(MouseButton);
ADD_CALLBACK_WWIN(Scroll);
ADD_CALLBACK_WWIN(WindowSize);
#undef ADD_CALLBACK_WWIN
/*
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetCharCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_Char;
GLFW_invoke_Char = (GLFW_invoke_Char_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetCharModsCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_CharMods;
GLFW_invoke_CharMods = (GLFW_invoke_CharMods_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetCursorEnterCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_CursorEnter;
GLFW_invoke_CursorEnter = (GLFW_invoke_CursorEnter_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetCursorPosCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_CursorPos;
GLFW_invoke_CursorPos = (GLFW_invoke_CursorPos_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetFramebufferSizeCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_FramebufferSize;
GLFW_invoke_FramebufferSize = (GLFW_invoke_FramebufferSize_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetKeyCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_Key;
GLFW_invoke_Key = (GLFW_invoke_Key_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetMouseButtonCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_MouseButton;
GLFW_invoke_MouseButton = (GLFW_invoke_MouseButton_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetScrollCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_Scroll;
GLFW_invoke_Scroll = (GLFW_invoke_Scroll_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetWindowSizeCallback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) {
void* oldCallback = &GLFW_invoke_WindowSize;
GLFW_invoke_WindowSize = (GLFW_invoke_WindowSize_func*) (uintptr_t) callbackptr;
return (jlong) (uintptr_t) *oldCallback;
}
*/
/*
* Class: org_lwjgl_glfw_GLFW
* Method: nglfwSetInputReady
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetInputReady(JNIEnv *env, jclass cls) {
isInputReady = true;
}

View File

@ -11,7 +11,11 @@ JavaVM* dalvikJavaVMPtr;
JNIEnv* dalvikJNIEnvPtr_ANDROID;
JNIEnv* dalvikJNIEnvPtr_JRE;
bool isAndroidThreadAttached, isRuntimeThreadAttached;
int grabCursorX, grabCursorY, lastCursorX, lastCursorY;
long showingWindow;
bool isAndroidThreadAttached, isRuntimeThreadAttached, isInputReady, isCursorEntered, isPrepareGrabPos;
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray);
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows);