我正在尝试修复xneur键盘切换器。它的作者试图添加XI2支持,但在仅使用XI2的应用程序(例如google chrome)中中断了输入。
而且我坚持使用修饰符过滤。有following code:
// Grab all keys...
if (has_x_input_extension) {
XIEventMask mask;
mask.deviceid = XIAllDevices;
mask.mask_len = XIMaskLen(XI_KeyPress)+
XIMaskLen(XI_KeyRelease);
mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
XISetMask(mask.mask, XI_KeyPress);
XISetMask(mask.mask, XI_KeyRelease);
XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1);
free(mask.mask);
}
else {
XGrabKey(main_window->display, AnyKey, AnyModifier, window, FALSE, GrabModeAsync, GrabModeAsync);
// ...without ModKeys.
grab_modifier_keys(window, FALSE);
}
[grab_modifier_keys
]取消键修饰符。而且我不知道如何对XI2(if
分支)执行相同的操作。
我认为可以忽略event handling loop中的那些事件。像这样的东西:
int is_modifier (XEvent *event)
{
/* ??? */
}
while (1) {
XEvent event;
XNextEvent(display, &event);
if (is_modifier(event)) {
continue;
}
}
但是我不知道如何实现is_modifier
函数。
非常感谢您的帮助
可能不是一个完美的解决方案,但这是我想出的is_modifier
的实现:
Bool is_modifier(KeySym key_sym)
{
XModifierKeymap *modmap = XGetModifierMapping(main_window->display);
if (modmap == NULL) {
return False;
}
KeyCode key_code = XKeysymToKeycode(main_window->display, key_sym);
int size = modmap->max_keypermod * 8;
for (int i = 0; i < size; ++i) {
if (key_code == modmap->modifiermap[i]) {
return True;
}
}
XFreeModifiermap(modmap);
return False;
}