Keyboard 使用XCB获取键盘布局和键盘符号
我正在为Linux创建一个屏幕键盘,它集成在一个简单的窗口管理器中。我目前正在使用XCB,现在我想做一些假击键。使用xtest扩展,一切都可以正常工作,除了我无法从我想要输入的键值中获得真正的键码的细节 目前我正在使用xcb_key_symbols_get_keycode,然后我使用xcb_key_symbols_get_keysym来知道我需要哪个修饰符来获得那个符号。当配置的键盘为美国键盘时,此功能正常工作。但是我有一个西班牙语键盘,这个调用只返回USA配置。在西班牙语键盘中,几个符号是通过正确的alt(altgr)来获得的,但是前面的调用似乎不支持它 那么,我怎样才能获得获得任何keysym所需的keycodes呢?我假设我需要XKB扩展,但我一直无法为XCB找到它们,我不想为XLib重写整个窗口管理器Keyboard 使用XCB获取键盘布局和键盘符号,keyboard,xcb,Keyboard,Xcb,我正在为Linux创建一个屏幕键盘,它集成在一个简单的窗口管理器中。我目前正在使用XCB,现在我想做一些假击键。使用xtest扩展,一切都可以正常工作,除了我无法从我想要输入的键值中获得真正的键码的细节 目前我正在使用xcb_key_symbols_get_keycode,然后我使用xcb_key_symbols_get_keysym来知道我需要哪个修饰符来获得那个符号。当配置的键盘为美国键盘时,此功能正常工作。但是我有一个西班牙语键盘,这个调用只返回USA配置。在西班牙语键盘中,几个符号是通过
谢谢。这可能是一个过时的问题,但我发现它仍然有效 您可以通过xcb启用xkb扩展,然后通过xcbapi(或者更具体地说,从xkb键映射的状态)获取键映射、它的布局以及该布局的相应键符号 链接:
- 设置xkb扩展名并获取设备id(请参阅上一链接:在尝试访问任何
调用之前,必须创建扩展名)。(使用设备id,您可以从\u device调用xcb_x11
xkb\u x11\u keymap\u new\u以返回
指针)xkb\u keymap
- (更重要的是)在这里,您可以使用xkb_状态来获取相应密钥的sym
我必须承认,我实际上并没有完全做到这一点(只是在关键地图/布局/状态方面)。但这应该足以让你开始 以下代码将打印整个keycode到keysym映射。它相当于
xmodmap-pk
或xmodmap-pke
。也就是说,给定任何键码,它会给出与该键码相关联的键符号
(除了它只显示keysym值,而不是keysym名称,您可以在/usr/include/X11/keysymdef.h
或使用Xlib的XKeysymToString()
中找到,我认为该函数不存在XCB端口,但您可以基于keysymdef.h
编写自己的端口)(在我的X服务器上,每个keycode有7个KeySym,我想知道X服务器是否可以支持更多…)
/*
gcc keymap.c-o keymap-lxcb&./keymap
*/
#包括
#包括
#包括
无效xcb_显示键盘映射(xcb_连接\u t*连接,常量xcb_设置\u t*设置){
xcb_获取_键盘_映射_回复_t*键盘_映射=
xcb\u获取\u键盘\u映射\u回复(
联系,,
xcb_获取键盘_映射(
联系,,
设置->最小键代码,
设置->最大键码-设置->最小键码+1),
无效);
int NKEYCODE=键盘映射->长度/键盘映射->每个键码的键符号;
int nkeysyms=键盘映射->长度;
xcb_keysym_t*keysyms=(xcb_keysym_t*)(键盘映射+1);/`xcb_keycode_t`只是一个`typedef u8`,`xcb_keysym_t`只是一个`typedef u32``
printf(“nkeycodes%u nkeysyms%u keysyms\u per\u keycode%u\n\n”,nkeycodes,nkeysyms,键盘映射->keysyms\u per\u keycode);
对于(int-keycode_idx=0;keycode_idx最小键码+键码idx);
对于(int keysym_idx=0;keysym_idxkeysyms_per_keycode;++keysym_idx){
printf(“%8x”,keysyms[keysym\u idx+keycode\u idx*键盘映射->每keycode的keysyms\u]);
}
putchar('\n');
}
免费(键盘映射);
}
int main(){
xcb_connection\u t*connection=xcb_connect(NULL,NULL);
const xcb_setup\u t*setup=xcb_get_setup(连接);
xcb_显示键盘_映射(连接、设置);
xcb_断开(连接);
}
如果您想要相反的映射(keysyms到keycodes),您可能需要xcb\u key\u symbols\u get\u keycode()
,我不知道
不,您不需要XKB来处理键盘内容。您可能需要的大部分内容都可以使用core X协议来完成,包括但不限于修改上述keycode到keysym映射、抓取键盘、抓取鼠标、发送键盘/鼠标输入、使用所有8个修改器以及编写“伪Unicode”(例如,您在
keysymdef.h
中找到的所有符号,我认为它不是Unicode,但确实包含很多东西).问题是我需要的是相反的:从一个keysym获得一个keycode。无论如何,我找到了一个解决方案:将每个keycode生成的keysym以及所有可能的修饰符存储在一个列表中,然后搜索我需要的keysym。
/*
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);
}