Skip to content

Commit

Permalink
native: add UTF-8 cuttext handling
Browse files Browse the repository at this point in the history
Closes #234
  • Loading branch information
bk138 committed Dec 19, 2024
1 parent 68bbeaa commit 19c1708
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ If you have a general question, it's best to [ask in the community chat](https:/
* Injection of remote pointer and basic keyboard events (Latin-1 charset plus some special keys, into EditText widgets only).
* Handling of client-to-server text copy & paste. Note that server-to-client copy & paste only works
automatically for text selected in editable text fields or manually by sharing text to droidVNC-NG
via Android's Share-To functionality. Also, only text in the Latin-1 encoding range is currently supported.
via Android's Share-To functionality.
* Handling of special keys to trigger 'Recent Apps' overview, Home button, Back button and Power button.
* Android permission handling.
* Screen rotation handling.
Expand Down
48 changes: 41 additions & 7 deletions app/src/main/cpp/droidvnc-ng.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,27 @@ static void onCutText(char *text, __unused int len, rfbClientPtr cl)
(*theVM)->DetachCurrentThread(theVM);
}

static void onCutTextUTF8(char *text, __unused int len, rfbClientPtr cl)
{
JNIEnv *env = NULL;
if ((*theVM)->AttachCurrentThread(theVM, &env, NULL) != 0) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "onCutTextUTF8: could not attach thread, there will be no input");
return;
}

jstring jText = (*env)->NewStringUTF(env, text);

jmethodID mid = (*env)->GetStaticMethodID(env, theInputService, "onCutText", "(Ljava/lang/String;J)V");
(*env)->CallStaticVoidMethod(env, theInputService, mid, jText, (jlong)cl);

(*env)->DeleteLocalRef(env, jText);

if ((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);

(*theVM)->DetachCurrentThread(theVM);
}

void onClientDisconnected(rfbClientPtr cl)
{
JNIEnv *env = NULL;
Expand Down Expand Up @@ -312,7 +333,7 @@ JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncS
theScreen->ptrAddEvent = onPointerEvent;
theScreen->kbdAddEvent = onKeyEvent;
theScreen->setXCutText = onCutText;
theScreen->setXCutTextUTF8 = onCutText;
theScreen->setXCutTextUTF8 = onCutTextUTF8;
theScreen->newClientHook = onClientConnected;

theScreen->port = port;
Expand Down Expand Up @@ -510,14 +531,27 @@ Java_net_christianbeier_droidvnc_1ng_MainService_vncSendCutText(JNIEnv *env, __u

// copy byte array contents to C char array on the stack, +1 for null-terminator
jsize latin1BytesLength = (*env)->GetArrayLength(env, latin1Bytes);
char cText[latin1BytesLength+1];
(*env)->GetByteArrayRegion(env, latin1Bytes, 0, latin1BytesLength, (jbyte*)cText);
cText[latin1BytesLength] = '\0'; // Null-terminate the C string
char cLatin1Text[latin1BytesLength + 1];
(*env)->GetByteArrayRegion(env, latin1Bytes, 0, latin1BytesLength, (jbyte*)cLatin1Text);
cLatin1Text[latin1BytesLength] = '\0'; // Null-terminate the C string

// we can clean up local references here already, cText is on the stack
// we can clean up local references here already, cLatin1Text is on the stack
(*env)->DeleteLocalRef(env, jCharsetName);
(*env)->DeleteLocalRef(env, latin1Bytes);

// Send!
rfbSendServerCutText(theScreen, cText, (int) strlen(cText));
/*
* Get UTF-8 string, too
*/
const char *cUTF8Text = (*env)->GetStringUTFChars(env, text, NULL);

/*
* Send!
*/
rfbSendServerCutTextUTF8(theScreen, (char*) cUTF8Text, (int) strlen(cUTF8Text), cLatin1Text, (int) strlen(cLatin1Text));

/*
* Clean up
*/
if (cUTF8Text)
(*env)->ReleaseStringUTFChars(env, text, cUTF8Text);
}

0 comments on commit 19c1708

Please sign in to comment.