我正在编写一个应用程序,将 Android 虚拟键盘的按键事件发送到某个客户端。目前,我正在实现 Ubuntu 客户端,发送虚假x11
输入事件。我在将特殊 UTF-8 字符或任何非标准字母表(使用西里尔字母进行测试)转换为 x11 内部表示时遇到问题。函数XStringToKeysym
根本不起作用。它唯一能正确完成的就是转换拉丁字符。
我尝试了不同的编码,但都不能完全发挥作用。
最新的方法是这样的:
char *nativeString = ...; //utf-8 encoding
int k = 0;
unsigned long int code = 0;
char c;
while((c = nativeString[k++]) != '\0' ){
code = code | ((c & 0xFF) << (k-1)*8);
}
这会将一些标点符号添加到工作列表中。不过西里尔字母的处理方式相同。
有什么建议吗?
编辑:
在 Java 端我从套接字获取一个字符串:
String str = ...; // from socket
System.out.println(str); //prints out good
byte[] bytes = str.getBytes("UTF-8");
NativeCall.press(bytes,...);
在本机方面:
JNIEXPORT void JNICALL Java_NativeCall_press(JNIEnv* env, jobject obj, jbyteArray array, jint modifiers) {
Window winFocus;
int revert;
XGetInputFocus(display, &winFocus, &revert);
jboolean copy;
jbyte* bufferPtr = env->GetByteArrayElements(array, NULL);//got the bytes
jsize lengthOfArray = env->GetArrayLength(array);//length
for(int i = 0;i<lengthOfArray;i++){ //print the byte to make sure they are the same as in java code
cout << (bufferPtr[i] & 0xff) << endl;
}
KeySym code = XStringToKeysym((const char *) bufferPtr);//doesn't work
cout << "Code: " << code << endl; //way #1
/*unsigned long int code = 0; //way #2, works with some symbols
for(int i = 0;i<lengthOfArray;i++){
char c = bufferPtr[i];
code = code | ((c & 0xFF) << i*8);
}*/
env->ReleaseByteArrayElements(array, bufferPtr, JNI_ABORT);
//send event, checked, works fine
XKeyEvent event = createKeyEvent(display, winFocus, root_window, true, code, modifiers);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
XFlush(display);
event = createKeyEvent(display, winFocus, root_window, false, code, modifiers);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
XFlush(display);
}