diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar b/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar index 778ad9356..fa2db2a12 100644 Binary files a/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar and b/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-shared-1.10-SNAPSHOT.jar b/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-shared-1.10-SNAPSHOT.jar index 9741cd0b6..5171bec54 100644 Binary files a/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-shared-1.10-SNAPSHOT.jar and b/app_pojavlauncher/src/main/assets/components/caciocavallo/cacio-shared-1.10-SNAPSHOT.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo/version b/app_pojavlauncher/src/main/assets/components/caciocavallo/version index a902c66f7..7f1b85e53 100644 --- a/app_pojavlauncher/src/main/assets/components/caciocavallo/version +++ b/app_pojavlauncher/src/main/assets/components/caciocavallo/version @@ -1 +1 @@ -HEllo PeopLE \ No newline at end of file +HEllo PeopLE1 \ No newline at end of file diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-shared-1.18-SNAPSHOT.jar b/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-shared-1.18-SNAPSHOT.jar index 0d4859d2d..39d65c525 100644 Binary files a/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-shared-1.18-SNAPSHOT.jar and b/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-shared-1.18-SNAPSHOT.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar b/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar index 91bc64206..59f113b1f 100644 Binary files a/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar and b/app_pojavlauncher/src/main/assets/components/caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/caciocavallo17/version b/app_pojavlauncher/src/main/assets/components/caciocavallo17/version index 5943f2b39..b130beac0 100644 --- a/app_pojavlauncher/src/main/assets/components/caciocavallo17/version +++ b/app_pojavlauncher/src/main/assets/components/caciocavallo17/version @@ -1 +1 @@ -20230118 +20230712 diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputBridge.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputBridge.java index ec0e3d2de..f5153bad0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputBridge.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputBridge.java @@ -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); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index d38b8db78..bf3c3f781 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -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"); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java index 68d8f3e83..3b6d8abff 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -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); diff --git a/app_pojavlauncher/src/main/jni/awt_bridge.c b/app_pojavlauncher/src/main/jni/awt_bridge.c index 31b0051f1..27bcc6500 100644 --- a/app_pojavlauncher/src/main/jni/awt_bridge.c +++ b/app_pojavlauncher/src/main/jni/awt_bridge.c @@ -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,"", "(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) { diff --git a/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml b/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml index 3863b1469..d5a3fbe4c 100644 --- a/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml +++ b/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml @@ -86,12 +86,39 @@ app:layout_constraintTop_toBottomOf="@+id/installmod_btn3" />