mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-15 15:48:26 -04:00
Implement AWT clipboard for copy-paste on 1.12.2 and lower
This commit is contained in:
parent
fcafb3ecfa
commit
fe8fb7bd20
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
HEllo PeopLE
|
||||
HEllo PeopLE1
|
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
20230118
|
||||
20230712
|
||||
|
@ -8,9 +8,15 @@ public class AWTInputBridge {
|
||||
|
||||
public static void sendKey(char keychar, int keycode) {
|
||||
// TODO: Android -> AWT keycode mapping
|
||||
nativeSendData(EVENT_TYPE_KEY, (int) keychar, keycode, 1, 0);
|
||||
nativeSendData(EVENT_TYPE_KEY, (int) keychar, keycode, 0, 0);
|
||||
}
|
||||
|
||||
public static void sendKey(char keychar, int keycode, int state) {
|
||||
// TODO: Android -> AWT keycode mapping
|
||||
nativeSendData(EVENT_TYPE_KEY, (int) keychar, keycode, state, 0);
|
||||
}
|
||||
|
||||
public static void sendChar(char keychar){
|
||||
nativeSendData(EVENT_TYPE_CHAR, (int) keychar, 0, 0, 0);
|
||||
}
|
||||
@ -33,6 +39,6 @@ public class AWTInputBridge {
|
||||
}
|
||||
|
||||
public static native void nativeSendData(int type, int i1, int i2, int i3, int i4);
|
||||
@SuppressWarnings("unused") public static native void nativePutClipboard(String data); //TODO: feed the AWT clipboard
|
||||
public static native void nativeClipboardReceived(String data, String mimeTypeSub);
|
||||
public static native void nativeMoveWindow(int xoff, int yoff);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.kdt.pojavlaunch;
|
||||
import static net.kdt.pojavlaunch.MainActivity.fullyExit;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipboardManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
@ -64,6 +65,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
}catch (IOException e) {
|
||||
Tools.showError(this, e, true);
|
||||
}
|
||||
MainActivity.GLOBAL_CLIPBOARD = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
mTouchCharInput = findViewById(R.id.awt_touch_char);
|
||||
mTouchCharInput.setCharacterSender(new AwtCharSender());
|
||||
|
||||
@ -328,6 +330,18 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
public void toggleKeyboard(View view) {
|
||||
mTouchCharInput.switchKeyboardState();
|
||||
}
|
||||
public void performCopy(View view) {
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 1);
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_C);
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 0);
|
||||
}
|
||||
|
||||
public void performPaste(View view) {
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 1);
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_V);
|
||||
AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 0);
|
||||
}
|
||||
|
||||
public int getJavaVersion(File modFile) {
|
||||
try (ZipFile zipFile = new ZipFile(modFile)){
|
||||
ZipEntry manifest = zipFile.getEntry("META-INF/MANIFEST.MF");
|
||||
|
@ -11,6 +11,7 @@ import static org.lwjgl.glfw.CallbackBridge.windowWidth;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -546,6 +547,38 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
|
||||
});
|
||||
}
|
||||
|
||||
public static void querySystemClipboard() {
|
||||
Tools.runOnUiThread(()->{
|
||||
ClipData clipData = GLOBAL_CLIPBOARD.getPrimaryClip();
|
||||
if(clipData == null) {
|
||||
AWTInputBridge.nativeClipboardReceived(null, null);
|
||||
return;
|
||||
}
|
||||
ClipData.Item firstClipItem = clipData.getItemAt(0);
|
||||
//TODO: coerce to HTML if the clip item is styled
|
||||
CharSequence clipItemText = firstClipItem.getText();
|
||||
if(clipItemText == null) {
|
||||
AWTInputBridge.nativeClipboardReceived(null, null);
|
||||
return;
|
||||
}
|
||||
AWTInputBridge.nativeClipboardReceived(clipItemText.toString(), "plain");
|
||||
});
|
||||
}
|
||||
|
||||
public static void putClipboardData(String data, String mimeType) {
|
||||
Tools.runOnUiThread(()-> {
|
||||
ClipData clipData = null;
|
||||
switch(mimeType) {
|
||||
case "text/plain":
|
||||
clipData = ClipData.newPlainText("AWT Paste", data);
|
||||
break;
|
||||
case "text/html":
|
||||
clipData = ClipData.newHtmlText("AWT Paste", data, data);
|
||||
}
|
||||
if(clipData != null) GLOBAL_CLIPBOARD.setPrimaryClip(clipData);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedMenu() {
|
||||
drawerLayout.openDrawer(navDrawer);
|
||||
|
@ -8,7 +8,6 @@ static JavaVM* dalvikJavaVMPtr;
|
||||
static JavaVM* runtimeJavaVMPtr;
|
||||
static JNIEnv* runtimeJNIEnvPtr_GRAPHICS;
|
||||
static JNIEnv* runtimeJNIEnvPtr_INPUT;
|
||||
static JNIEnv* runtimeJNIEnvPtr_CLIPBOARD;
|
||||
jclass class_CTCScreen;
|
||||
jmethodID method_GetRGB;
|
||||
|
||||
@ -18,13 +17,18 @@ jmethodID method_ReceiveInput;
|
||||
jclass class_MainActivity;
|
||||
jmethodID method_OpenLink;
|
||||
jmethodID method_OpenPath;
|
||||
jmethodID method_QuerySystemClipboard;
|
||||
jmethodID method_PutClipboardData;
|
||||
|
||||
jclass class_Frame;
|
||||
jclass class_Rectangle;
|
||||
jclass class_CTCClipboard = NULL;
|
||||
jmethodID constructor_Rectangle;
|
||||
jmethodID method_GetFrames;
|
||||
jmethodID method_GetBounds;
|
||||
jmethodID method_SetBounds;
|
||||
jmethodID method_SystemClipboardDataReceived = NULL;
|
||||
|
||||
jfieldID field_x;
|
||||
jfieldID field_y;
|
||||
|
||||
@ -37,6 +41,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
class_MainActivity = (*env)->NewGlobalRef(env,(*env)->FindClass(env, "net/kdt/pojavlaunch/MainActivity"));
|
||||
method_OpenLink= (*env)->GetStaticMethodID(env, class_MainActivity, "openLink", "(Ljava/lang/String;)V");
|
||||
method_OpenPath= (*env)->GetStaticMethodID(env, class_MainActivity, "openLink", "(Ljava/lang/String;)V");
|
||||
method_QuerySystemClipboard = (*env)->GetStaticMethodID(env, class_MainActivity, "querySystemClipboard", "()V");
|
||||
method_PutClipboardData = (*env)->GetStaticMethodID(env, class_MainActivity, "putClipboardData", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
} else if (dalvikJavaVMPtr != vm) {
|
||||
runtimeJavaVMPtr = vm;
|
||||
}
|
||||
@ -118,33 +124,43 @@ JNIEXPORT jintArray JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_renderAWTScr
|
||||
return androidRgbArray;
|
||||
}
|
||||
|
||||
jobject clipboard = NULL;
|
||||
jclass clipboardClass;
|
||||
static jobject obtainClipboard(JNIEnv *env) {
|
||||
jclass toolkitClass = (*runtimeJNIEnvPtr_CLIPBOARD)->FindClass(runtimeJNIEnvPtr_CLIPBOARD,"java/awt/Toolkit");
|
||||
jobject toolkit = (*runtimeJNIEnvPtr_CLIPBOARD)->CallStaticObjectMethod(runtimeJNIEnvPtr_CLIPBOARD,toolkitClass,(*runtimeJNIEnvPtr_CLIPBOARD)->GetStaticMethodID(runtimeJNIEnvPtr_CLIPBOARD,toolkitClass,"getDefaultToolkit", "()Ljava/awt/Toolkit;"));
|
||||
clipboardClass = (*runtimeJNIEnvPtr_CLIPBOARD)->NewGlobalRef(runtimeJNIEnvPtr_CLIPBOARD,(*runtimeJNIEnvPtr_CLIPBOARD)->FindClass(runtimeJNIEnvPtr_CLIPBOARD,"java/awt/datatransfer/Clipboard"));
|
||||
clipboard = (*runtimeJNIEnvPtr_CLIPBOARD)->NewGlobalRef(runtimeJNIEnvPtr_CLIPBOARD,(*runtimeJNIEnvPtr_CLIPBOARD)->CallObjectMethod(runtimeJNIEnvPtr_CLIPBOARD,toolkit,(*runtimeJNIEnvPtr_CLIPBOARD)->GetMethodID(runtimeJNIEnvPtr_CLIPBOARD,toolkitClass,"getSystemClipboard", "()Ljava/awt/datatransfer/Clipboard;")));
|
||||
(*runtimeJNIEnvPtr_CLIPBOARD)->DeleteLocalRef(runtimeJNIEnvPtr_CLIPBOARD,toolkitClass);
|
||||
(*runtimeJNIEnvPtr_CLIPBOARD)->DeleteLocalRef(runtimeJNIEnvPtr_CLIPBOARD,toolkit);
|
||||
JNIEXPORT void JNICALL Java_net_java_openjdk_cacio_ctc_CTCClipboard_nQuerySystemClipboard(JNIEnv *env, jclass clazz) {
|
||||
JNIEnv *dalvikEnv;char detachable = 0;
|
||||
if((*dalvikJavaVMPtr)->GetEnv(dalvikJavaVMPtr, (void **) &dalvikEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||
(*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, &dalvikEnv, NULL);
|
||||
detachable = 1;
|
||||
}
|
||||
if(method_SystemClipboardDataReceived == NULL) {
|
||||
class_CTCClipboard = (*env)->NewGlobalRef(env, clazz);
|
||||
method_SystemClipboardDataReceived = (*env)->GetStaticMethodID(env, clazz, "systemClipboardDataReceived", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
}
|
||||
(*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, class_MainActivity, method_QuerySystemClipboard);
|
||||
if(detachable) (*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_kdt_pojavlaunch_AWTInputBridge_nativePutClipboard(JNIEnv *env, jclass clazz,
|
||||
jstring data) {
|
||||
if (runtimeJNIEnvPtr_CLIPBOARD == NULL) {
|
||||
if (runtimeJavaVMPtr != NULL) {
|
||||
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &runtimeJNIEnvPtr_CLIPBOARD, NULL);
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
JNIEXPORT void JNICALL Java_net_java_openjdk_cacio_ctc_CTCClipboard_nPutClipboardData(JNIEnv* env, jclass clazz, jstring clipboardData, jstring clipboardDataMime) {
|
||||
JNIEnv *dalvikEnv;char detachable = 0;
|
||||
if((*dalvikJavaVMPtr)->GetEnv(dalvikJavaVMPtr, (void **) &dalvikEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||
(*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, &dalvikEnv, NULL);
|
||||
detachable = 1;
|
||||
}
|
||||
if(clipboard == NULL) obtainClipboard(runtimeJNIEnvPtr_CLIPBOARD);
|
||||
jclass stringSelection = (*runtimeJNIEnvPtr_CLIPBOARD)->FindClass(runtimeJNIEnvPtr_CLIPBOARD,"java/awt/datatransfer/StringSelection");
|
||||
jobject o_stringSelection = (*runtimeJNIEnvPtr_CLIPBOARD)->NewObject(runtimeJNIEnvPtr_CLIPBOARD,stringSelection,(*runtimeJNIEnvPtr_CLIPBOARD)->GetMethodID(runtimeJNIEnvPtr_CLIPBOARD,stringSelection,"<init>", "(Ljava/lang/String;)V"),NULL);
|
||||
(*runtimeJNIEnvPtr_CLIPBOARD)->CallVoidMethod(runtimeJNIEnvPtr_CLIPBOARD,clipboard,(*runtimeJNIEnvPtr_CLIPBOARD)->GetMethodID(env,clipboardClass,"setContents", "(Ljava/awt/datatransfer/Transferable;Ljava/awt/datatransfer/ClipboardOwner;)V"),o_stringSelection,NULL);
|
||||
(*runtimeJNIEnvPtr_CLIPBOARD)->DeleteLocalRef(runtimeJNIEnvPtr_CLIPBOARD,stringSelection);
|
||||
(*runtimeJNIEnvPtr_CLIPBOARD)->DeleteLocalRef(runtimeJNIEnvPtr_CLIPBOARD,o_stringSelection);
|
||||
|
||||
const char* dataChars = (*env)->GetStringUTFChars(env, clipboardData, NULL);
|
||||
const char* mimeChars = (*env)->GetStringUTFChars(env, clipboardDataMime, NULL);
|
||||
(*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, class_MainActivity, method_PutClipboardData,
|
||||
(*dalvikEnv)->NewStringUTF(dalvikEnv, dataChars),
|
||||
(*dalvikEnv)->NewStringUTF(dalvikEnv, mimeChars));
|
||||
(*env)->ReleaseStringUTFChars(env, clipboardData, dataChars);
|
||||
(*env)->ReleaseStringUTFChars(env, clipboardDataMime, mimeChars);
|
||||
if(detachable) (*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_github_caciocavallosilano_cacio_ctc_CTCClipboard_nQuerySystemClipboard(JNIEnv *env, jclass clazz) {
|
||||
Java_net_java_openjdk_cacio_ctc_CTCClipboard_nQuerySystemClipboard(env, clazz);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_github_caciocavallosilano_cacio_ctc_CTCClipboard_nPutClipboardData(JNIEnv* env, jclass clazz, jstring clipboardData, jstring clipboardDataMime) {
|
||||
Java_net_java_openjdk_cacio_ctc_CTCClipboard_nPutClipboardData(env, clazz, clipboardData, clipboardDataMime);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_openjdk_cacio_ctc_CTCDesktopPeer_openFile(JNIEnv *env, jclass clazz, jstring filePath) {
|
||||
@ -171,6 +187,24 @@ JNIEXPORT void JNICALL Java_net_java_openjdk_cacio_ctc_CTCDesktopPeer_openUri(JN
|
||||
if(detachable) (*dalvikJavaVMPtr)->DetachCurrentThread(dalvikJavaVMPtr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_AWTInputBridge_nativeClipboardReceived(JNIEnv *env, jclass clazz, jstring clipboardData, jstring clipboardDataMime) {
|
||||
if(method_SystemClipboardDataReceived == NULL || class_CTCClipboard == NULL) return;
|
||||
if (runtimeJNIEnvPtr_INPUT == NULL) {
|
||||
if (runtimeJavaVMPtr == NULL) {
|
||||
return;
|
||||
} else {
|
||||
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &runtimeJNIEnvPtr_INPUT, NULL);
|
||||
}
|
||||
}
|
||||
const char* dataChars = clipboardData != NULL ? (*env)->GetStringUTFChars(env, clipboardData, NULL) : NULL;
|
||||
const char* mimeChars = clipboardDataMime != NULL ? (*env)->GetStringUTFChars(env, clipboardDataMime, NULL) : NULL;
|
||||
(*runtimeJNIEnvPtr_INPUT)->CallStaticVoidMethod(runtimeJNIEnvPtr_INPUT, class_CTCClipboard, method_SystemClipboardDataReceived,
|
||||
clipboardData != NULL ? (*runtimeJNIEnvPtr_INPUT)->NewStringUTF(runtimeJNIEnvPtr_INPUT, dataChars) : NULL,
|
||||
clipboardDataMime != NULL ? (*runtimeJNIEnvPtr_INPUT)->NewStringUTF(runtimeJNIEnvPtr_INPUT, mimeChars) : NULL);
|
||||
if(dataChars != NULL) (*env)->ReleaseStringUTFChars(env, clipboardData, dataChars);
|
||||
if(mimeChars != NULL) (*env)->ReleaseStringUTFChars(env, clipboardDataMime, mimeChars);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_kdt_pojavlaunch_AWTInputBridge_nativeMoveWindow(JNIEnv *env, jclass clazz, jint xoff, jint yoff) {
|
||||
if (runtimeJNIEnvPtr_INPUT == NULL) {
|
||||
|
@ -86,12 +86,39 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/installmod_btn3" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/control_button"
|
||||
android:onClick="toggleKeyboard"
|
||||
android:text="Keyboard"
|
||||
android:onClick="toggleKeyboard"/>
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/control_button"
|
||||
android:onClick="performCopy"
|
||||
android:text="Copy"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/control_button"
|
||||
android:onClick="performPaste"
|
||||
android:text="Paste"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button3" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/installmod_mouse_pri"
|
||||
|
Loading…
x
Reference in New Issue
Block a user