问题
I'm trying to programmatically modify some of the properties of my xkb keyboard mapping in X11. In the XkbClientMapRec struct map member of the XkbDescRec struct, we have the following members:
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;
Then, we have the XkbSymMapRec struct, here:
#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 array in the XkbClientMapRec array is of course just an array of KeySyms (actually, an array of 2D arrays) as defined in keysymdefs.h.
Anyways, what I'm wondering here is how to add completely new KeySyms to that syms array. Basically I want to completely change the mapping for one of the key codes on my keyboard, and the KeySym that I want to equate is with isn't typically in the KeySyms array. Reassigning a keycode to an existing and defined set of KeySyms is easy - for example, if I wanted keycode 45 to do the same thing as keycode 63, I'd do this:
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 );
This works, but it isn't what I want. I want to create completely new KeySym entries in client_map->sym and assign client_map->key_sym_map[ 45 ]->kt_index[ 0..n ] to those new entries. Unfortunately, this doesn't seem to be possible? The XbkMapChangesRec struct doesn't have any way of stipulating that the KeySym * syms array has been reallocated to something larger. The best that it has is XkbKeySymsMask which is ONLY for changes to key_sym_map.
Any ideas?
来源:https://stackoverflow.com/questions/10661998/xkb-how-to-increase-the-number-of-keysyms-in-the-client-map-of-an-xkbdescrec-ke