我正在尝试以编程方式修改 X11 中 xkb 键盘映射的一些属性。在里面XkbClientMapRec
struct map
的成员XkbDescRec
struct,我们有以下成员:
typedef struct { /* Client Map */
unsigned char size_types; /* # occupied entries in types */
unsigned char num_types; /* # entries in types */
XkbKeyTypePtr types; /* vector of key types used by this keymap */
unsigned short size_syms; /* length of the syms array */
unsigned short num_syms; /* # entries in syms */
KeySym * syms; /* linear 2d tables of keysyms, 1 per key */
XkbSymMapPtr key_sym_map; /* 1 per keycode, maps keycode to syms */
unsigned char * modmap; /* 1 per keycode, real mods bound to key */
} XkbClientMapRec, *XkbClientMapPtr;
然后,我们有 XkbSymMapRec 结构,在这里:
#define XkbNumKbdGroups 4
#define XkbMaxKbdGroup (XkbNumKbdGroups-1)
typedef struct { /* map to keysyms for a single keycode */
unsigned char kt_index[XkbNumKbdGroups]; /* key type index for each group */
unsigned char group_info; /* # of groups and out of range group handling */
unsigned char width; /* max # of shift levels for key */
unsigned short offset; /* index to keysym table in syms array */
} XkbSymMapRec, *XkbSymMapPtr;
The KeySym * syms
数组中的XkbClientMapRec
数组当然只是一个数组KeySym
s(实际上是一个二维数组的数组),定义在keysymdefs.h
.
不管怎样,我想知道如何添加全新的KeySym
到那个syms
大批。基本上,我想完全更改键盘上某个键代码的映射,并且我想要等同的 KeySym 通常不在KeySym
s 数组。将键码重新分配给现有的和已定义的一组KeySym
s 很简单 - 例如,如果我希望键码 45 执行与键码 63 相同的操作,我会这样做:
XkbDescPtr desc = XkbGetKeyboard( curr_display, XkbAllComponentsMask, XkbUseCoreKbd );
XkbSymMapRec * client_map = desc->map;
client_map->key_sym_map[ 45 ] = client_map->key_sym_map[ 23 ];
XkbMapChangesRec changes;
changes.changed = XkbKeySymsMask;
changes.first_key_sym = 45;
changes.num_key_syms = 1;
XkbChangeMap( curr_display, desc, &changes );
这有效,但这不是我想要的。我想创造全新的KeySym
条目在client_map->sym
并分配client_map->key_sym_map[ 45 ]->kt_index[ 0..n ]
到那些新条目。不幸的是,这似乎不可能? XbkMapChangesRec 结构没有任何方式规定KeySym * syms
数组已被重新分配给更大的东西。它拥有的最好的就是XkbKeySymsMask
这仅适用于更改key_sym_map
.
有任何想法吗?