我正在为一个简单的Window Manager中集成的Linux创建一个屏幕键盘。我目前正在使用XCB,现在我想做假的击键。使用xtest扩展程序一切正常,除了我无法从我想要的关键字中获取真正的密钥代码的细节。
目前我正在使用xcb_key_symbols_get_keycode,然后我使用xcb_key_symbols_get_keysym来了解获取该符号所需的修饰符。当配置的键盘是美国键盘时,这可以正常工作。但我有一个西班牙语键盘,这个电话只返回美国配置。在西班牙语键盘中,使用右侧alt(altgr)获得了几个符号,但前一个调用似乎不支持它。
那么,我怎样才能获得获取任何密钥所需的密钥代码?我认为我需要XKB扩展,但我一直无法为XCB找到它们,我也不想为XLib重写整个窗口管理器。
感谢。
答案 0 :(得分:1)
这可能是一个过时的问题,但我发现它仍然有效。
你可以通过xcb启用xkb扩展,然后通过xcb API(或者更具体地说,来自xkb keymap的状态)获取keymap,它的布局以及该布局的相应keysym。
链接:
xcb_x11
次呼叫之前创建扩展名)。 (使用设备ID,您可以调用xkb_x11_keymap_new_from_device
返回xkb_keymap
指针)。xkb_state_key_get_sym()
)在这里,您可以使用xkb_state获取相应密钥的sym。我不得不承认,我实际上并没有完全做到这一点,但是(仅限于keymap / layout / state事情)。但它应该足以让你开始。 :)
答案 1 :(得分:0)
以下代码将打印整个 keycode-to-keysym 映射。它相当于xmodmap -pk
或xmodmap -pke
。也就是说,给定任何键码,它会为您提供与该键码相关联的键盘。
(除了它只显示 keysym值,而不是 keysym名称,您可以在/usr/include/X11/keysymdef.h
中找到或使用Xlib' s {{1我并不认为存在该函数的XCB端口,但您可以根据XKeysymToString()
编写自己的端口。)(在我的X服务器上,每个键代码有7个密钥码,我想知道X服务器是否可以支持更多......)
keysymdef.h
如果你想要相反的映射(密钥到键码),你可能需要/*
gcc keymap.c -o keymap -lxcb && ./keymap
*/
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
void xcb_show_keyboard_mapping(xcb_connection_t* connection, const xcb_setup_t* setup){
xcb_get_keyboard_mapping_reply_t* keyboard_mapping = xcb_get_keyboard_mapping_reply(connection, xcb_get_keyboard_mapping(connection, setup->min_keycode, setup->max_keycode - setup->min_keycode + 1), NULL);
int nkeycodes = keyboard_mapping->length / keyboard_mapping->keysyms_per_keycode;
int nkeysyms = keyboard_mapping->length;
xcb_keysym_t* keysyms = (xcb_keysym_t*)(keyboard_mapping + 1); // `xcb_keycode_t` is just a `typedef u8`, and `xcb_keysym_t` is just a `typedef u32`
printf("nkeycodes %u nkeysyms %u keysyms_per_keycode %u\n\n", nkeycodes, nkeysyms, keyboard_mapping->keysyms_per_keycode);
for(int keycode_idx=0; keycode_idx < nkeycodes; ++keycode_idx){
printf("keycode %3u ", setup->min_keycode + keycode_idx);
for(int keysym_idx=0; keysym_idx < keyboard_mapping->keysyms_per_keycode; ++keysym_idx){
printf(" %8x", keysyms[keysym_idx + keycode_idx * keyboard_mapping->keysyms_per_keycode]);
}
putchar('\n');
}
free(keyboard_mapping);
}
int main(){
xcb_connection_t* connection = xcb_connect(NULL, NULL);
const xcb_setup_t* setup = xcb_get_setup(connection);
xcb_show_keyboard_mapping(connection, setup);
xcb_disconnect(connection);
}
,我不知道。
不,你不需要XKB来处理键盘内容。您可能想要的大部分内容都可以通过核心X协议来完成,包括不限来修改前面提到的keycode-to-keysym映射,抓取键盘,抓取鼠标,发送键盘/鼠标输入,使用所有8个修饰符,并编写&#34;伪Unicode&#34; (即你在xcb_key_symbols_get_keycode()
中找到的所有符号,我认为这些符号都是Unicode,但确实包含很多内容。)