(1.13+) Handle ingame opening folder/link + Fix copy/paste

This commit is contained in:
khanhduytran0 2022-06-07 21:07:19 +07:00
parent 4670c522a9
commit cec4d56c9e
8 changed files with 95 additions and 21 deletions

View File

@ -1 +1 @@
1652206097040
1654610266310

View File

@ -37,6 +37,7 @@ import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.lwjgl.glfw.*;
import android.net.*;
public class BaseMainActivity extends BaseActivity {
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
@ -418,4 +419,17 @@ public class BaseMainActivity extends BaseActivity {
});
b.show();
}
public static void openLink(String link) {
Context ctx = touchpad.getContext(); // no more better way to obtain a context statically
((Activity)ctx).runOnUiThread(() -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(link.replace("file://", "content://")), "*/*");
ctx.startActivity(intent);
} catch (Throwable th) {
Tools.showError(ctx, th);
}
});
}
}

View File

@ -11,6 +11,7 @@ public class CallbackBridge {
public static final int CLIPBOARD_COPY = 2000;
public static final int CLIPBOARD_PASTE = 2001;
public static final int CLIPBOARD_OPEN = 2002;
public static volatile int windowWidth, windowHeight;
public static volatile int physicalWidth, physicalHeight;
@ -136,6 +137,9 @@ public class CallbackBridge {
return "";
}
case CLIPBOARD_OPEN:
BaseMainActivity.openLink(copy);
return null;
default: return null;
}
}

View File

@ -10,9 +10,12 @@
* - Implements glfwSetCursorPos() to handle grab camera pos correctly.
*/
#include <stdlib.h>
#include <jni.h>
#include <assert.h>
#include <dlfcn.h>
#include <jni.h>
#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#include "utils.h"
@ -27,6 +30,8 @@
#define EVENT_TYPE_SCROLL 1007
#define EVENT_TYPE_WINDOW_SIZE 1008
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);
@ -55,6 +60,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
} else if (dalvikJavaVMPtr != vm) {
runtimeJavaVMPtr = vm;
(*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4);
hookExec();
}
isGrabbing = JNI_FALSE;
@ -72,7 +78,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
DetachCurrentThread(vm);
*/
dalvikJNIEnvPtr_JRE = NULL;
//dalvikJNIEnvPtr_JRE = NULL;
runtimeJNIEnvPtr_ANDROID = NULL;
}
@ -148,6 +154,41 @@ void closeGLFWWindow() {
exit(-1);
}
/**
* Hooked version of java.lang.UNIXProcess.forkAndExec()
* which is used to handle the "open" command.
*/
jint
hooked_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) {
char *pProg = (char *)((*env)->GetByteArrayElements(env, prog, NULL));
// Here we only handle the "xdg-open" command
if (strcmp(basename(pProg), "xdg-open")) {
(*env)->ReleaseByteArrayElements(env, prog, (jbyte *)pProg, 0);
return orig_ProcessImpl_forkAndExec(env, process, mode, helperpath, prog, argBlock, argc, envBlock, envc, dir, std_fds, redirectErrorStream);
}
(*env)->ReleaseByteArrayElements(env, prog, (jbyte *)pProg, 0);
Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(env, NULL, /* CLIPBOARD_OPEN */ 2002, argBlock);
return 0;
}
void hookExec() {
jclass cls;
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");
} else {
cls = (*runtimeJNIEnvPtr_JRE)->FindClass(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);
printf("Registered forkAndExec\n");
}
JNIEXPORT void JNICALL
Java_org_lwjgl_glfw_CallbackBridge_nativeSetUseInputStackQueue(JNIEnv *env, jclass clazz,
jboolean use_input_stack_queue) {
@ -164,10 +205,10 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThread
//isUseStackQueueCall = (int) isUseStackQueueBool;
if (isAndroid) {
result = attachThread(true, &runtimeJNIEnvPtr_ANDROID);
} else {
} /* else {
result = attachThread(false, &dalvikJNIEnvPtr_JRE);
// getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
}
} */
if (isUseStackQueueCall && isAndroid && result) {
isPrepareGrabPos = true;
@ -175,7 +216,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThread
return result;
}
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jstring copySrc) {
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);
#endif
@ -189,9 +230,20 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNI
assert(bridgeMethod != NULL);
LOGD("Clipboard: Converting string\n");
jstring copyDst = convertStringJVM(env, dalvikEnv, copySrc);
char *copySrcC = NULL;
jstring copyDst = NULL;
if (copySrc) {
copySrcC = (char *)((*env)->GetByteArrayElements(env, copySrc, NULL));
copyDst = (*dalvikEnv)->NewStringUTF(dalvikEnv, copySrcC);
}
LOGD("Clipboard: Calling 2nd\n");
jstring pasteDst = convertStringJVM(dalvikEnv, env, (jstring) (*dalvikEnv)->CallStaticObjectMethod(dalvikEnv, bridgeClazz, bridgeMethod, action, copyDst));
if (copySrc) {
(*dalvikEnv)->DeleteLocalRef(dalvikEnv, copyDst);
(*env)->ReleaseByteArrayElements(env, copySrc, (jbyte *)copySrcC, 0);
}
(*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr);
return pasteDst;
}
@ -368,13 +420,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib(
return; // nothing to do yet
}
jclass glfwClazz = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW");
jclass glfwClazz = (*env)->FindClass(env, "org/lwjgl/glfw/GLFW");
assert(glfwClazz != NULL);
jmethodID glfwMethod = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, glfwClazz, "glfwSetWindowAttrib", "(JII)V");
jmethodID glfwMethod = (*env)->GetStaticMethodID(env, glfwClazz, "glfwSetWindowAttrib", "(JII)V");
assert(glfwMethod != NULL);
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
runtimeJNIEnvPtr_JRE,
(*env)->CallStaticVoidMethod(
env,
glfwClazz, glfwMethod,
(jlong) showingWindow, attrib, value
);

View File

@ -8,7 +8,7 @@ static JNIEnv* runtimeJNIEnvPtr_JRE;
static JavaVM* dalvikJavaVMPtr;
static JNIEnv* dalvikJNIEnvPtr_ANDROID;
static JNIEnv* dalvikJNIEnvPtr_JRE;
//static JNIEnv* dalvikJNIEnvPtr_JRE;
static long showingWindow;
@ -23,4 +23,6 @@ void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charAr
jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr);
void closeGLFWWindow();
void hookExec();
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jbyteArray copySrc);

View File

@ -71,7 +71,7 @@ public class CallbackBridge {
}
public static native void nativeSendData(boolean isAndroid, int type, String data);
public static native boolean nativeSetInputReady(boolean ready);
public static native String nativeClipboard(int action, String copy);
public static native String nativeClipboard(int action, byte[] copy);
public static native void nativeAttachThreadToOther(boolean isAndroid, boolean isUseStackQueueBool);
private static native void nativeSetGrabbing(boolean grab, int xset, int yset);
public static native void setClass();

View File

@ -810,7 +810,7 @@ public class GLFW
static boolean isGLFWReady;
public static boolean glfwInit() {
if (!isGLFWReady) {
CallbackBridge.nativeAttachThreadToOther(false, false);
//CallbackBridge.nativeAttachThreadToOther(false, false);
mGLFWInitialTime = (double) System.nanoTime();
long __functionAddress = Functions.Init;
isGLFWReady = invokeI(__functionAddress) != 0;
@ -1233,11 +1233,13 @@ public class GLFW
}
public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer string) {
glfwSetClipboardString(window, memUTF8Safe(string));
byte[] arr = new byte[string.remaining()];
string.get(arr);
CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_COPY, arr);
}
public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") CharSequence string) {
CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_COPY, string.toString());
glfwSetClipboardString(window, memUTF8Safe(string));
}
public static String glfwGetClipboardString(@NativeType("GLFWwindow *") long window) {