提问人:Irbis 提问时间:10/25/2023 最后编辑:Irbis 更新时间:10/28/2023 访问量:60
UTF-8 输入和使用 XGetICValues
UTF-8 input and using XGetICValues
问:
我找到了一个 UTF-8 输入的示例(接受的答案),但我想知道该示例是否正确。结果可以传递给:XGetICValues
XSelectInput
unsigned long mask = 0;
if (!XGetICValues(ic, XNFilterEvents, &mask, NULL))
{
XSelectInput(dpy, win, other_masks | mask);
}
您能解释一下上述代码的含义吗?是否必须获得正确的 UTF-8 输入?执行上述代码后,我是否也应该调用?XFilterEvent
答:
执行上述代码后,我是否也应该调用 XFilterEvent ?
我怀疑您应该:为了正确处理 UTF-8 输入,不仅要获取事件掩码和选择输入事件,还要可能过滤这些事件以正确处理多字节或特殊输入序列。
应在事件循环中使用 XFilterEvent
。它将有助于管理输入法以正确解释多字节或特殊键序列。
正如“XLIB 编程手册/过滤事件”中提到的,它是在 XNextEvent()
之后调用的。
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
// Your initialization code
while(1) {
XNextEvent(dpy, &ev);
if (XFilterEvent(&ev, win)) // Filter the event through the input method
continue;
switch(ev.type){
case MappingNotify:
XRefreshKeyboardMapping(&ev.xmapping);
break;
case KeyPress:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
printf("count: %d\n", count);
if (status == XBufferOverflow)
printf("BufferOverflow\n");
if (count)
printf("buffer: %.*s\n", count, buf);
if (status == XLookupKeySym || status == XLookupBoth) {
printf("status: %d\n", status);
}
printf("pressed KEY: %d\n", (int)keysym);
}
break;
case KeyRelease:
// Rest of your code for other cases
}
fflush(stdout);
}
}
如果返回 ,则表示事件已由输入法过滤和处理,则执行该语句以跳过循环的其余部分并处理下一个事件。XFilterEvent
True
continue
+--------------------+ XNFilterEvents +--------------+
| Input Context (IC) |------------------------->| Event Mask |
+--------------------+ +--------------+
| |
XGetICValues Retrieved Mask
| |
V V
+--------------------+ other_masks | mask +--------------+
| XSelectInput |------------------------->| Event Input |
+--------------------+ +--------------+
| |
| +--------------+
| | X Event |
| +--------------+
| |
V V
+--------------------+ XFilterEvent +--------------+
| Event Loop |------------------------->| Event Filter |
+--------------------+ (optional) +--------------+
- 查询输入上下文 (IC) 以获取事件掩码,这是了解要侦听哪些事件所需的。
XSelectInput
XSelectInput
与其他掩码和检索到的掩码的组合一起调用,以指定应为指定窗口报告的事件。- 在事件循环中,被调用以过滤事件队列中的相关输入事件,这在处理多字节或特殊输入序列时特别有用。此步骤标记为可选,因为它基于处理特殊输入序列的要求。
XFilterEvent
评论
既然这是我的例子/答案,我觉得有义务插话。
在我的示例中,对于我的特定 IM,您无需调用 .它将掩码设置为我无论如何都设置的掩码。但是,通常,对于输入掩码的其他选择和/或其他输入方法,您确实需要调用 。XGetICValues
KeyPressMask|KeyReleaseMask
XGetICValues
显然,如果您不设置其中任何一个或自己,它将不起作用。但远不止于此。如果输入法涉及屏幕键盘,则 IM 将需要处理鼠标事件,如果不使用 .KeyPressMask
KeyReleaseMask
XGetICValues
所以一般来说,是的,请调用并将掩码传递给 .是的,您确实需要打电话,因为这就是 IM 魔术发生的地方。XSelectInput
XSelectInput
XFilterEvent
我将更新您参考的答案以反映这一点。
评论