Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Keyboard 使用XCB获取键盘布局和键盘符号_Keyboard_Xcb - Fatal编程技术网

Keyboard 使用XCB获取键盘布局和键盘符号

Keyboard 使用XCB获取键盘布局和键盘符号,keyboard,xcb,Keyboard,Xcb,我正在为Linux创建一个屏幕键盘,它集成在一个简单的窗口管理器中。我目前正在使用XCB,现在我想做一些假击键。使用xtest扩展,一切都可以正常工作,除了我无法从我想要输入的键值中获得真正的键码的细节 目前我正在使用xcb_key_symbols_get_keycode,然后我使用xcb_key_symbols_get_keysym来知道我需要哪个修饰符来获得那个符号。当配置的键盘为美国键盘时,此功能正常工作。但是我有一个西班牙语键盘,这个调用只返回USA配置。在西班牙语键盘中,几个符号是通过

我正在为Linux创建一个屏幕键盘,它集成在一个简单的窗口管理器中。我目前正在使用XCB,现在我想做一些假击键。使用xtest扩展,一切都可以正常工作,除了我无法从我想要输入的键值中获得真正的键码的细节

目前我正在使用xcb_key_symbols_get_keycode,然后我使用xcb_key_symbols_get_keysym来知道我需要哪个修饰符来获得那个符号。当配置的键盘为美国键盘时,此功能正常工作。但是我有一个西班牙语键盘,这个调用只返回USA配置。在西班牙语键盘中,几个符号是通过正确的alt(altgr)来获得的,但是前面的调用似乎不支持它

那么,我怎样才能获得获得任何keysym所需的keycodes呢?我假设我需要XKB扩展,但我一直无法为XCB找到它们,我不想为XLib重写整个窗口管理器


谢谢。

这可能是一个过时的问题,但我发现它仍然有效

您可以通过xcb启用xkb扩展,然后通过xcbapi(或者更具体地说,从xkb键映射的状态)获取键映射、它的布局以及该布局的相应键符号

链接:

  • 设置xkb扩展名并获取设备id(请参阅上一链接:在尝试访问任何
    xcb_x11
    调用之前,必须创建扩展名)。(使用设备id,您可以从\u device调用
    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);
}