diff --git a/app/src/main/cpp/native-vnc.cpp b/app/src/main/cpp/native-vnc.cpp index 049916dc..e6780810 100644 --- a/app/src/main/cpp/native-vnc.cpp +++ b/app/src/main/cpp/native-vnc.cpp @@ -126,15 +126,23 @@ static void onBell(rfbClient *client) { env->CallVoidMethod(obj, mid); } -static void onGotXCutText(rfbClient *client, const char *text, int len) { +static void onGotXCutText(rfbClient *client, const char *text, int len, bool is_utf8) { auto obj = getManagedClient(client); auto env = context.getEnv(); auto cls = context.managedCls; - jmethodID mid = env->GetMethodID(cls, "cbGotXCutText", "([B)V"); + jmethodID mid = env->GetMethodID(cls, "cbGotXCutText", "([BZ)V"); jbyteArray bytes = env->NewByteArray(len); env->SetByteArrayRegion(bytes, 0, len, reinterpret_cast(text)); - env->CallVoidMethod(obj, mid, bytes); + env->CallVoidMethod(obj, mid, bytes, is_utf8); +} + +static void onGotXCutTextLatin1(rfbClient *client, const char *text, int len) { + onGotXCutText(client, text, len, false); +} + +static void onGotXCutTextUTF8(rfbClient *client, const char *text, int len) { + onGotXCutText(client, text, len, true); } static rfbBool onHandleCursorPos(rfbClient *client, int x, int y) { @@ -231,7 +239,8 @@ static void setCallbacks(rfbClient *client) { client->GetPassword = onGetPassword; client->GetCredential = onGetCredential; client->Bell = onBell; - client->GotXCutText = onGotXCutText; + client->GotXCutText = onGotXCutTextLatin1; + client->GotXCutTextUTF8 = onGotXCutTextUTF8; client->HandleCursorPos = onHandleCursorPos; client->FinishedFrameBufferUpdate = onFinishedFrameBufferUpdate; client->MallocFrameBuffer = onMallocFrameBuffer; @@ -377,12 +386,16 @@ Java_com_gaurav_avnc_vnc_VncClient_nativeSendPointerEvent(JNIEnv *env, jobject t extern "C" JNIEXPORT jboolean JNICALL -Java_com_gaurav_avnc_vnc_VncClient_nativeSendCutText(JNIEnv *env, jobject thiz, jlong client_ptr, jbyteArray bytes) { +Java_com_gaurav_avnc_vnc_VncClient_nativeSendCutText(JNIEnv *env, jobject thiz, jlong client_ptr, jbyteArray bytes, + jboolean is_utf8) { + auto client = (rfbClient *) client_ptr; auto textBuffer = env->GetByteArrayElements(bytes, nullptr); auto textLen = env->GetArrayLength(bytes); auto textChars = reinterpret_cast(textBuffer); - rfbBool result = SendClientCutText((rfbClient *) client_ptr, textChars, textLen); + rfbBool result = is_utf8 + ? SendClientCutTextUTF8(client, textChars, textLen) + : SendClientCutText(client, textChars, textLen); env->ReleaseByteArrayElements(bytes, textBuffer, JNI_ABORT); return (jboolean) result; diff --git a/app/src/main/java/com/gaurav/avnc/vnc/VncClient.kt b/app/src/main/java/com/gaurav/avnc/vnc/VncClient.kt index bc7bfc14..8bd1f4bd 100644 --- a/app/src/main/java/com/gaurav/avnc/vnc/VncClient.kt +++ b/app/src/main/java/com/gaurav/avnc/vnc/VncClient.kt @@ -183,7 +183,8 @@ class VncClient(private val observer: Observer) { * Sends text to remote desktop's clipboard. */ fun sendCutText(text: String) = executeSend { - nativeSendCutText(nativePtr, text.toByteArray(StandardCharsets.ISO_8859_1)) + if (!nativeSendCutText(nativePtr, text.toByteArray(StandardCharsets.UTF_8), true)) + nativeSendCutText(nativePtr, text.toByteArray(StandardCharsets.ISO_8859_1), false) } /** @@ -227,7 +228,7 @@ class VncClient(private val observer: Observer) { private external fun nativeProcessServerMessage(clientPtr: Long, uSecTimeout: Int): Boolean private external fun nativeSendKeyEvent(clientPtr: Long, keySym: Int, xtCode: Int, isDown: Boolean): Boolean private external fun nativeSendPointerEvent(clientPtr: Long, x: Int, y: Int, mask: Int): Boolean - private external fun nativeSendCutText(clientPtr: Long, bytes: ByteArray): Boolean + private external fun nativeSendCutText(clientPtr: Long, bytes: ByteArray, isUTF8: Boolean): Boolean private external fun nativeRefreshFrameBuffer(clientPtr: Long): Boolean private external fun nativeGetDesktopName(clientPtr: Long): String private external fun nativeGetWidth(clientPtr: Long): Int @@ -245,8 +246,10 @@ class VncClient(private val observer: Observer) { private fun cbGetCredential() = observer.onCredentialRequired() @Keep - private fun cbGotXCutText(bytes: ByteArray) { - observer.onGotXCutText(StandardCharsets.ISO_8859_1.decode(ByteBuffer.wrap(bytes)).toString()) + private fun cbGotXCutText(bytes: ByteArray, isUTF8: Boolean) { + (if (isUTF8) StandardCharsets.UTF_8 else StandardCharsets.ISO_8859_1).let { + observer.onGotXCutText(it.decode(ByteBuffer.wrap(bytes)).toString()) + } } @Keep diff --git a/extern/libvncserver b/extern/libvncserver index f979f6ae..f79149f9 160000 --- a/extern/libvncserver +++ b/extern/libvncserver @@ -1 +1 @@ -Subproject commit f979f6ae1394d78c5a5fd1033315586789edf0a9 +Subproject commit f79149f9aedddf2cf423f90b36ce659ce81dfce0