mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-15 07:39:00 -04:00
(1.13+) Handle ingame opening folder/link + Fix copy/paste
This commit is contained in:
parent
4670c522a9
commit
cec4d56c9e
Binary file not shown.
@ -1 +1 @@
|
|||||||
1652206097040
|
1654610266310
|
@ -37,6 +37,7 @@ import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
|||||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||||
|
|
||||||
import org.lwjgl.glfw.*;
|
import org.lwjgl.glfw.*;
|
||||||
|
import android.net.*;
|
||||||
|
|
||||||
public class BaseMainActivity extends BaseActivity {
|
public class BaseMainActivity extends BaseActivity {
|
||||||
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
|
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
|
||||||
@ -418,4 +419,17 @@ public class BaseMainActivity extends BaseActivity {
|
|||||||
});
|
});
|
||||||
b.show();
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ public class CallbackBridge {
|
|||||||
|
|
||||||
public static final int CLIPBOARD_COPY = 2000;
|
public static final int CLIPBOARD_COPY = 2000;
|
||||||
public static final int CLIPBOARD_PASTE = 2001;
|
public static final int CLIPBOARD_PASTE = 2001;
|
||||||
|
public static final int CLIPBOARD_OPEN = 2002;
|
||||||
|
|
||||||
public static volatile int windowWidth, windowHeight;
|
public static volatile int windowWidth, windowHeight;
|
||||||
public static volatile int physicalWidth, physicalHeight;
|
public static volatile int physicalWidth, physicalHeight;
|
||||||
@ -136,6 +137,9 @@ public class CallbackBridge {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CLIPBOARD_OPEN:
|
||||||
|
BaseMainActivity.openLink(copy);
|
||||||
|
return null;
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,12 @@
|
|||||||
* - Implements glfwSetCursorPos() to handle grab camera pos correctly.
|
* - Implements glfwSetCursorPos() to handle grab camera pos correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -27,6 +30,8 @@
|
|||||||
#define EVENT_TYPE_SCROLL 1007
|
#define EVENT_TYPE_SCROLL 1007
|
||||||
#define EVENT_TYPE_WINDOW_SIZE 1008
|
#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_Char_func(void* window, unsigned int codepoint);
|
||||||
typedef void GLFW_invoke_CharMods_func(void* window, unsigned int codepoint, int mods);
|
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_CursorEnter_func(void* window, int entered);
|
||||||
@ -55,6 +60,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
} else if (dalvikJavaVMPtr != vm) {
|
} else if (dalvikJavaVMPtr != vm) {
|
||||||
runtimeJavaVMPtr = vm;
|
runtimeJavaVMPtr = vm;
|
||||||
(*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4);
|
(*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4);
|
||||||
|
hookExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
isGrabbing = JNI_FALSE;
|
isGrabbing = JNI_FALSE;
|
||||||
@ -72,7 +78,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
|||||||
DetachCurrentThread(vm);
|
DetachCurrentThread(vm);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dalvikJNIEnvPtr_JRE = NULL;
|
//dalvikJNIEnvPtr_JRE = NULL;
|
||||||
runtimeJNIEnvPtr_ANDROID = NULL;
|
runtimeJNIEnvPtr_ANDROID = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +154,41 @@ void closeGLFWWindow() {
|
|||||||
exit(-1);
|
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
|
JNIEXPORT void JNICALL
|
||||||
Java_org_lwjgl_glfw_CallbackBridge_nativeSetUseInputStackQueue(JNIEnv *env, jclass clazz,
|
Java_org_lwjgl_glfw_CallbackBridge_nativeSetUseInputStackQueue(JNIEnv *env, jclass clazz,
|
||||||
jboolean use_input_stack_queue) {
|
jboolean use_input_stack_queue) {
|
||||||
@ -164,10 +205,10 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThread
|
|||||||
//isUseStackQueueCall = (int) isUseStackQueueBool;
|
//isUseStackQueueCall = (int) isUseStackQueueBool;
|
||||||
if (isAndroid) {
|
if (isAndroid) {
|
||||||
result = attachThread(true, &runtimeJNIEnvPtr_ANDROID);
|
result = attachThread(true, &runtimeJNIEnvPtr_ANDROID);
|
||||||
} else {
|
} /* else {
|
||||||
result = attachThread(false, &dalvikJNIEnvPtr_JRE);
|
result = attachThread(false, &dalvikJNIEnvPtr_JRE);
|
||||||
// getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
|
// getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
|
||||||
}
|
} */
|
||||||
|
|
||||||
if (isUseStackQueueCall && isAndroid && result) {
|
if (isUseStackQueueCall && isAndroid && result) {
|
||||||
isPrepareGrabPos = true;
|
isPrepareGrabPos = true;
|
||||||
@ -175,7 +216,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThread
|
|||||||
return result;
|
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
|
#ifdef DEBUG
|
||||||
LOGD("Debug: Clipboard access is going on\n", isUseStackQueueCall);
|
LOGD("Debug: Clipboard access is going on\n", isUseStackQueueCall);
|
||||||
#endif
|
#endif
|
||||||
@ -185,13 +226,24 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNI
|
|||||||
assert(dalvikEnv != NULL);
|
assert(dalvikEnv != NULL);
|
||||||
assert(bridgeClazz != NULL);
|
assert(bridgeClazz != NULL);
|
||||||
LOGD("Clipboard: Obtaining method\n");
|
LOGD("Clipboard: Obtaining method\n");
|
||||||
jmethodID bridgeMethod = (* dalvikEnv)->GetStaticMethodID(dalvikEnv, bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
jmethodID bridgeMethod = (*dalvikEnv)->GetStaticMethodID(dalvikEnv, bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
||||||
assert(bridgeMethod != NULL);
|
assert(bridgeMethod != NULL);
|
||||||
|
|
||||||
LOGD("Clipboard: Converting string\n");
|
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");
|
LOGD("Clipboard: Calling 2nd\n");
|
||||||
jstring pasteDst = convertStringJVM(dalvikEnv, env, (jstring) (*dalvikEnv)->CallStaticObjectMethod(dalvikEnv, bridgeClazz, bridgeMethod, action, copyDst));
|
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);
|
(*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr);
|
||||||
return pasteDst;
|
return pasteDst;
|
||||||
}
|
}
|
||||||
@ -368,13 +420,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib(
|
|||||||
return; // nothing to do yet
|
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);
|
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);
|
assert(glfwMethod != NULL);
|
||||||
|
|
||||||
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
|
(*env)->CallStaticVoidMethod(
|
||||||
runtimeJNIEnvPtr_JRE,
|
env,
|
||||||
glfwClazz, glfwMethod,
|
glfwClazz, glfwMethod,
|
||||||
(jlong) showingWindow, attrib, value
|
(jlong) showingWindow, attrib, value
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,7 @@ static JNIEnv* runtimeJNIEnvPtr_JRE;
|
|||||||
|
|
||||||
static JavaVM* dalvikJavaVMPtr;
|
static JavaVM* dalvikJavaVMPtr;
|
||||||
static JNIEnv* dalvikJNIEnvPtr_ANDROID;
|
static JNIEnv* dalvikJNIEnvPtr_ANDROID;
|
||||||
static JNIEnv* dalvikJNIEnvPtr_JRE;
|
//static JNIEnv* dalvikJNIEnvPtr_JRE;
|
||||||
|
|
||||||
static long showingWindow;
|
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);
|
jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr);
|
||||||
|
|
||||||
void closeGLFWWindow();
|
void closeGLFWWindow();
|
||||||
|
void hookExec();
|
||||||
|
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jbyteArray copySrc);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public class CallbackBridge {
|
|||||||
}
|
}
|
||||||
public static native void nativeSendData(boolean isAndroid, int type, String data);
|
public static native void nativeSendData(boolean isAndroid, int type, String data);
|
||||||
public static native boolean nativeSetInputReady(boolean ready);
|
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);
|
public static native void nativeAttachThreadToOther(boolean isAndroid, boolean isUseStackQueueBool);
|
||||||
private static native void nativeSetGrabbing(boolean grab, int xset, int yset);
|
private static native void nativeSetGrabbing(boolean grab, int xset, int yset);
|
||||||
public static native void setClass();
|
public static native void setClass();
|
||||||
|
@ -810,7 +810,7 @@ public class GLFW
|
|||||||
static boolean isGLFWReady;
|
static boolean isGLFWReady;
|
||||||
public static boolean glfwInit() {
|
public static boolean glfwInit() {
|
||||||
if (!isGLFWReady) {
|
if (!isGLFWReady) {
|
||||||
CallbackBridge.nativeAttachThreadToOther(false, false);
|
//CallbackBridge.nativeAttachThreadToOther(false, false);
|
||||||
mGLFWInitialTime = (double) System.nanoTime();
|
mGLFWInitialTime = (double) System.nanoTime();
|
||||||
long __functionAddress = Functions.Init;
|
long __functionAddress = Functions.Init;
|
||||||
isGLFWReady = invokeI(__functionAddress) != 0;
|
isGLFWReady = invokeI(__functionAddress) != 0;
|
||||||
@ -1233,11 +1233,13 @@ public class GLFW
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer string) {
|
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) {
|
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) {
|
public static String glfwGetClipboardString(@NativeType("GLFWwindow *") long window) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user