XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t kc,
unsigned int needed)
{
- darray_resize0(darray_item(keymap->key_sym_map, kc).syms, needed);
+ darray_resize0(XkbKey(keymap, kc)->sym_map.syms, needed);
return true;
}
{
size_t old_ndx, old_num_acts, new_ndx;
+ key = XkbKey(keymap, kc);
+
if (needed == 0) {
- darray_item(keymap->key_acts, kc) = 0;
+ key->acts_index = 0;
return NULL;
}
* space for the key at the end, and leave the old space alone.
*/
- old_ndx = darray_item(keymap->key_acts, kc);
+ old_ndx = key->acts_index;
old_num_acts = XkbKeyNumActions(keymap, kc);
new_ndx = darray_size(keymap->acts);
darray_resize0(keymap->acts, new_ndx + needed);
- darray_item(keymap->key_acts, kc) = new_ndx;
+ key->acts_index = new_ndx;
/*
* The key was already in the array, copy the old actions to the
static void
free_sym_maps(struct xkb_keymap *keymap)
{
- struct xkb_sym_map *sym_map;
+ struct xkb_key *key;
- darray_foreach(sym_map, keymap->key_sym_map) {
- free(sym_map->sym_index);
- free(sym_map->num_syms);
- darray_free(sym_map->syms);
+ darray_foreach(key, keymap->keys) {
+ free(key->sym_map.sym_index);
+ free(key->sym_map.num_syms);
+ darray_free(key->sym_map.syms);
}
- darray_free(keymap->key_sym_map);
}
static void
for (i = 0; i < XkbNumKbdGroups; i++)
free(keymap->group_names[i]);
- darray_free(keymap->key_names);
darray_free(keymap->key_aliases);
free(keymap->keycodes_section_name);
free_types(keymap);
free_sym_maps(keymap);
- free(keymap->modmap);
- free(keymap->explicit);
- darray_free(keymap->key_acts);
darray_free(keymap->acts);
- free(keymap->behaviors);
- free(keymap->vmodmap);
darray_free(keymap->sym_interpret);
free_names(keymap);
- free(keymap->per_key_repeat);
+ darray_free(keymap->keys);
xkb_context_unref(keymap->ctx);
free(keymap);
}
size_t *offset)
{
xkb_keycode_t kc;
+ struct xkb_key *key;
struct xkb_key_alias *alias;
int i;
keymap->max_key_code);
for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
- if (darray_item(keymap->key_names, kc).name[0] == '\0')
+ key = XkbKey(keymap, kc);
+ if (key->name.name[0] == '\0')
continue;
write_buf(keymap, buf, size, offset, "\t\t%6s = %d;\n",
- XkbcKeyNameText(darray_item(keymap->key_names, kc).name),
- kc);
+ XkbcKeyNameText(key->name.name), kc);
}
for (i = 0; i < XkbNumIndicators; i++) {
write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
size_t *offset)
{
+ struct xkb_key *key;
xkb_keycode_t kc;
int group, tmp;
bool showActions;
for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
bool simple = true;
+ key = XkbKey(keymap, kc);
if (xkb_key_num_groups(keymap, kc) == 0)
continue;
write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
- XkbcKeyNameText(darray_item(keymap->key_names, kc).name));
- if (keymap->explicit) {
- if ((keymap->explicit[kc] & XkbExplicitKeyTypesMask)) {
- bool multi_type = false;
- int type = XkbKeyTypeIndex(keymap, kc, 0);
+ XkbcKeyNameText(key->name.name));
- simple = false;
+ if (key->explicit & XkbExplicitKeyTypesMask) {
+ bool multi_type = false;
+ int type = XkbKeyTypeIndex(keymap, kc, 0);
- for (group = 0; group < xkb_key_num_groups(keymap, kc);
- group++) {
- if (XkbKeyTypeIndex(keymap, kc, group) != type) {
- multi_type = true;
- break;
- }
- }
- if (multi_type) {
- for (group = 0;
- group < xkb_key_num_groups(keymap, kc);
- group++) {
- if (!(keymap->explicit[kc] & (1 << group)))
- continue;
- type = XkbKeyTypeIndex(keymap, kc, group);
- write_buf(keymap, buf, size, offset,
- "\n\t\t\ttype[group%d]= \"%s\",",
- group + 1,
- darray_item(keymap->types, type).name);
- }
+ simple = false;
+
+ for (group = 0; group < xkb_key_num_groups(keymap, kc);
+ group++) {
+ if (XkbKeyTypeIndex(keymap, kc, group) != type) {
+ multi_type = true;
+ break;
}
- else {
+ }
+
+ if (multi_type) {
+ for (group = 0;
+ group < xkb_key_num_groups(keymap, kc);
+ group++) {
+ if (!(key->explicit & (1 << group)))
+ continue;
+ type = XkbKeyTypeIndex(keymap, kc, group);
write_buf(keymap, buf, size, offset,
- "\n\t\t\ttype= \"%s\",",
+ "\n\t\t\ttype[group%d]= \"%s\",",
+ group + 1,
darray_item(keymap->types, type).name);
}
}
- if (keymap->explicit[kc] & XkbExplicitAutoRepeatMask) {
- if (keymap->per_key_repeat[kc / 8] & (1 << (kc % 8)))
- write_buf(keymap, buf, size, offset,
- "\n\t\t\trepeat= Yes,");
- else
- write_buf(keymap, buf, size, offset,
- "\n\t\t\trepeat= No,");
- simple = false;
- }
- if (keymap->vmodmap[kc] &&
- (keymap->explicit[kc] & XkbExplicitVModMapMask)) {
+ else {
write_buf(keymap, buf, size, offset,
- "\n\t\t\tvirtualMods= %s,",
- get_mod_mask_text(keymap, 0, keymap->vmodmap[kc]));
+ "\n\t\t\ttype= \"%s\",",
+ darray_item(keymap->types, type).name);
}
}
+ if (key->explicit & XkbExplicitAutoRepeatMask) {
+ if (key->repeats)
+ write_buf(keymap, buf, size, offset,
+ "\n\t\t\trepeat= Yes,");
+ else
+ write_buf(keymap, buf, size, offset,
+ "\n\t\t\trepeat= No,");
+ simple = false;
+ }
+
+ if (key->vmodmap && (key->explicit & XkbExplicitVModMapMask)) {
+ write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
+ get_mod_mask_text(keymap, 0, key->vmodmap));
+ }
+
switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, kc))) {
case XkbClampIntoRange:
write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
break;
}
- if (keymap->explicit == NULL ||
- (keymap->explicit[kc] & XkbExplicitInterpretMask))
+ if (key->explicit & XkbExplicitInterpretMask)
showActions = XkbKeyHasActions(keymap, kc);
else
showActions = false;
write_buf(keymap, buf, size, offset, "\n\t\t};\n");
}
}
- if (keymap->modmap) {
- for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
- int mod;
- if (keymap->modmap[kc] == 0)
- continue;
+ for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
+ int mod;
+ key = XkbKey(keymap, kc);
- for (mod = 0; mod < XkbNumModifiers; mod++) {
- if (!(keymap->modmap[kc] & (1 << mod)))
- continue;
+ if (key->modmap == 0)
+ continue;
- write_buf(keymap, buf, size, offset,
- "\t\tmodifier_map %s { %s };\n",
- get_mod_index_text(mod),
- XkbcKeyNameText(darray_item(keymap->key_names,
- kc).name));
- }
+ for (mod = 0; mod < XkbNumModifiers; mod++) {
+ if (!(key->modmap & (1 << mod)))
+ continue;
+
+ write_buf(keymap, buf, size, offset,
+ "\t\tmodifier_map %s { %s };\n",
+ get_mod_index_text(mod),
+ XkbcKeyNameText(key->name.name));
}
}
_X_EXPORT int
xkb_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- return !!(keymap->per_key_repeat[kc / 8] & (1 << (kc % 8)));
+ if (!XkbKeycodeInRange(keymap, kc))
+ return 0;
+ return XkbKey(keymap, kc)->repeats;
}
unsigned int axt_ctrls_values;
};
+struct xkb_key {
+ struct xkb_key_name name;
+ unsigned char explicit;
+ struct xkb_sym_map sym_map;
+ unsigned char modmap;
+ uint32_t vmodmap;
+ struct xkb_behavior behavior;
+ bool repeats;
+ /* Index into keymap->acts */
+ size_t acts_index;
+};
+
/* Common keyboard description structure */
struct xkb_keymap {
struct xkb_context *ctx;
xkb_keycode_t min_key_code;
xkb_keycode_t max_key_code;
- /* key -> key name mapping */
- darray(struct xkb_key_name) key_names;
+ darray(struct xkb_key) keys;
+
/* aliases in no particular order */
darray(struct xkb_key_alias) key_aliases;
- /* key -> explicit flags mapping */
- unsigned char *explicit;
-
darray(struct xkb_key_type) types;
- /* key -> symbols mapping */
- darray(struct xkb_sym_map) key_sym_map;
-
darray(struct xkb_sym_interpret) sym_interpret;
- /* key -> mod mapping */
- unsigned char *modmap;
- /* key -> vmod mapping */
- uint32_t *vmodmap;
/* vmod -> mod mapping */
uint32_t vmods[XkbNumVirtualMods];
char *vmod_names[XkbNumVirtualMods];
struct xkb_mods groups[XkbNumKbdGroups];
char *group_names[XkbNumKbdGroups];
- /* key -> actions mapping: acts[key_acts[keycode]] */
darray(union xkb_action) acts;
- darray(size_t) key_acts;
-
- /* key -> behavior mapping */
- struct xkb_behavior *behaviors;
-
- /* key -> should repeat mapping - one bit per key */
- unsigned char *per_key_repeat;
struct xkb_indicator_map indicators[XkbNumIndicators];
char *indicator_names[XkbNumIndicators];
char *compat_section_name;
};
+static inline struct xkb_key *
+XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ return &darray_item(keymap->keys, kc);
+}
+
static inline unsigned char
XkbNumGroups(unsigned char group_info)
{
static inline unsigned char
XkbKeyGroupInfo(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- return darray_item(keymap->key_sym_map, kc).group_info;
+ return XkbKey(keymap, kc)->sym_map.group_info;
}
static inline unsigned char
XkbKeyTypeIndex(struct xkb_keymap *keymap, xkb_keycode_t kc,
unsigned int group)
{
- return darray_item(keymap->key_sym_map, kc).kt_index[group & 0x3];
+ return XkbKey(keymap, kc)->sym_map.kt_index[group & 0x3];
}
static inline struct xkb_key_type *
static inline unsigned char
XkbKeyGroupsWidth(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- return darray_item(keymap->key_sym_map, kc).width;
+ return XkbKey(keymap, kc)->sym_map.width;
}
static inline unsigned int
unsigned int group, unsigned int level)
{
unsigned char width = XkbKeyGroupsWidth(keymap, kc);
- return darray_item(keymap->key_sym_map,
- kc).num_syms[group * width + level];
+ return XkbKey(keymap, kc)->sym_map.num_syms[group * width + level];
}
static inline xkb_keysym_t *
XkbKeySym(struct xkb_keymap *keymap, xkb_keycode_t kc, int ndx)
{
- return &darray_item(darray_item(keymap->key_sym_map, kc).syms, ndx);
+ return &darray_item(XkbKey(keymap, kc)->sym_map.syms, ndx);
}
static inline int
unsigned group, unsigned int level)
{
unsigned char width = XkbKeyGroupsWidth(keymap, kc);
- return darray_item(keymap->key_sym_map,
- kc).sym_index[group * width + level];
+ return XkbKey(keymap, kc)->sym_map.sym_index[group * width + level];
}
static inline xkb_keysym_t *
static inline bool
XkbKeyHasActions(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- return darray_item(keymap->key_acts, kc) != 0;
+ return XkbKey(keymap, kc)->acts_index != 0;
}
static inline unsigned char
static inline union xkb_action *
XkbKeyActionsPtr(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- return darray_mem(keymap->acts, darray_item(keymap->key_acts, kc));
+ struct xkb_key *key = XkbKey(keymap, kc);
+ return darray_mem(keymap->acts, key->acts_index);
}
static inline union xkb_action *
continue;
if (level == 0 || !(interp->match & XkbSI_LevelOneOnly))
- mods = keymap->modmap[kc];
+ mods = XkbKey(keymap, kc)->modmap;
else
mods = 0;
int num_acts = 0;
int group, level;
int width = XkbKeyGroupsWidth(keymap, kc);
+ struct xkb_key *key;
int i;
+ key = XkbKey(keymap, kc);
+
/* If we've been told not to bind interps to this key, then don't. */
- if (keymap->explicit[kc] & XkbExplicitInterpretMask)
+ if (key->explicit & XkbExplicitInterpretMask)
return true;
for (i = 0; i < INTERP_SIZE; i++)
/* Infer default key behaviours from the base level. */
if (group == 0 && level == 0) {
- if (!(keymap->explicit[kc] & XkbExplicitAutoRepeatMask) &&
+ if (!(key->explicit & XkbExplicitAutoRepeatMask) &&
(!interp || interp->flags & XkbSI_AutoRepeat))
- keymap->per_key_repeat[kc / 8] |= (1 << (kc % 8));
- if (!(keymap->explicit[kc] & XkbExplicitBehaviorMask) &&
+ key->repeats = true;
+ if (!(key->explicit & XkbExplicitBehaviorMask) &&
interp && (interp->flags & XkbSI_LockingKey))
- keymap->behaviors[kc].type = XkbKB_Lock;
+ key->behavior.type = XkbKB_Lock;
}
if (!interp)
}
}
- if (!(keymap->explicit[kc] & XkbExplicitVModMapMask))
- keymap->vmodmap[kc] = vmodmask;
+ if (!(key->explicit & XkbExplicitVModMapMask))
+ key->vmodmap = vmodmask;
return true;
#undef INTERP_SIZE
UpdateModifiersFromCompat(struct xkb_keymap *keymap)
{
xkb_keycode_t kc;
+ struct xkb_key *key;
int i;
struct xkb_key_type *type;
struct xkb_kt_map_entry *entry;
for (i = 0; i < XkbNumVirtualMods; i++)
keymap->vmods[i] = 0;
for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
- if (!keymap->vmodmap[kc])
+ key = XkbKey(keymap, kc);
+ if (!key->vmodmap)
continue;
for (i = 0; i < XkbNumVirtualMods; i++) {
- if (!(keymap->vmodmap[kc] & (1 << i)))
+ if (!(key->vmodmap & (1 << i)))
continue;
- keymap->vmods[i] |= keymap->modmap[kc];
+ keymap->vmods[i] |= key->modmap;
}
}
/* Update action modifiers. */
for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
union xkb_action *acts = XkbKeyActionsPtr(keymap, kc);
+ key = XkbKey(keymap, kc);
for (i = 0; i < XkbKeyNumActions(keymap, kc); i++) {
if (acts[i].any.type == XkbSA_NoAction)
continue;
- UpdateActionMods(keymap, &acts[i], keymap->modmap[kc]);
+ UpdateActionMods(keymap, &acts[i], key->modmap);
}
}
else
keymap->max_key_code = info.computedMax;
- darray_resize0(keymap->key_names, keymap->max_key_code + 1);
+ darray_resize0(keymap->keys, keymap->max_key_code + 1);
for (kc = info.computedMin; kc <= info.computedMax; kc++)
LongToKeyName(darray_item(info.names, kc),
- darray_item(keymap->key_names, kc).name);
+ XkbKey(keymap, kc)->name.name);
if (info.name)
keymap->keycodes_section_name = strdup(info.name);
xkb_keycode_t *kc_rtrn, bool use_aliases, bool create,
xkb_keycode_t start_from)
{
- unsigned n;
+ xkb_keycode_t kc;
+ struct xkb_key *key;
if (start_from < keymap->min_key_code)
start_from = keymap->min_key_code;
*kc_rtrn = 0; /* some callers rely on this */
- if (!darray_empty(keymap->key_names)) {
- for (n = start_from; n <= keymap->max_key_code; n++) {
- unsigned long tmp;
- tmp = KeyNameToLong(darray_item(keymap->key_names, n).name);
- if (tmp == name) {
- *kc_rtrn = n;
- return true;
- }
- }
- if (use_aliases) {
- unsigned long new_name;
- if (FindKeyNameForAlias(keymap, name, &new_name))
- return FindNamedKey(keymap, new_name, kc_rtrn, false,
- create, 0);
+ for (kc = start_from; kc <= keymap->max_key_code; kc++) {
+ unsigned long tmp;
+ key = XkbKey(keymap, kc);
+
+ tmp = KeyNameToLong(key->name.name);
+ if (tmp == name) {
+ *kc_rtrn = kc;
+ return true;
}
}
+ if (use_aliases) {
+ unsigned long new_name;
+ if (FindKeyNameForAlias(keymap, name, &new_name))
+ return FindNamedKey(keymap, new_name, kc_rtrn, false,
+ create, 0);
+ }
+
if (create) {
- darray_resize0(keymap->key_names, keymap->max_key_code + 1);
+ darray_resize0(keymap->keys, keymap->max_key_code + 1);
/* Find first unused keycode and store our key here */
- for (n = keymap->min_key_code; n <= keymap->max_key_code; n++) {
- if (darray_item(keymap->key_names, n).name[0] == '\0') {
+ for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
+ key = XkbKey(keymap, kc);
+
+ if (key->name.name[0] == '\0') {
char buf[XkbKeyNameLength + 1];
LongToKeyName(name, buf);
- memcpy(darray_item(keymap->key_names, n).name, buf,
- XkbKeyNameLength);
- *kc_rtrn = n;
+ memcpy(key->name.name, buf, XkbKeyNameLength);
+ *kc_rtrn = kc;
return true;
}
}
{
unsigned int i;
xkb_keycode_t kc;
+ struct xkb_key *key;
unsigned int sizeSyms = 0;
unsigned width, tmp, nGroups;
struct xkb_key_type * type;
return false;
}
+ key = XkbKey(keymap, kc);
+
haveActions = false;
for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) {
if (((i + 1) > nGroups)
}
if (FindNamedType(keymap, keyi->types[i], &types[i])) {
if (!autoType || keyi->numLevels[i] > 2)
- keymap->explicit[kc] |= (1 << i);
+ key->explicit |= (1 << i);
}
else {
if (warningLevel >= 3) {
longText(keyi->name), kc);
return false;
}
- keymap->explicit[kc] |= XkbExplicitInterpretMask;
+ key->explicit |= XkbExplicitInterpretMask;
}
else
outActs = NULL;
- sym_map = &darray_item(keymap->key_sym_map, kc);
+ sym_map = &key->sym_map;
if (keyi->defs.defined & _Key_GroupInfo)
i = keyi->groupInfo;
break;
default:
- keymap->behaviors[kc] = keyi->behavior;
- keymap->explicit[kc] |= XkbExplicitBehaviorMask;
+ key->behavior = keyi->behavior;
+ key->explicit |= XkbExplicitBehaviorMask;
break;
}
if (keyi->defs.defined & _Key_VModMap) {
- keymap->vmodmap[kc] = keyi->vmodmap;
- keymap->explicit[kc] |= XkbExplicitVModMapMask;
+ key->vmodmap = keyi->vmodmap;
+ key->explicit |= XkbExplicitVModMapMask;
}
if (keyi->repeat != RepeatUndefined) {
- if (keyi->repeat == RepeatYes)
- keymap->per_key_repeat[kc / 8] |= (1 << (kc % 8));
- else
- keymap->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
- keymap->explicit[kc] |= XkbExplicitAutoRepeatMask;
+ key->repeats = keyi->repeat == RepeatYes;
+ key->explicit |= XkbExplicitAutoRepeatMask;
}
/* do the same thing for the next key */
}
return false;
}
- keymap->modmap[kc] |= (1 << entry->modifier);
+
+ XkbKey(keymap, kc)->modmap |= (1 << entry->modifier);
return true;
}
{
size_t nKeys = keymap->max_key_code + 1;
- darray_resize0(keymap->key_sym_map, nKeys);
-
- keymap->modmap = calloc(nKeys, sizeof(*keymap->modmap));
- if (!keymap->modmap)
- return false;
-
- keymap->explicit = calloc(nKeys, sizeof(*keymap->explicit));
- if (!keymap->explicit)
- return false;
+ darray_resize0(keymap->keys, nKeys);
darray_resize0(keymap->acts, darray_size(keymap->acts) + 32 + 1);
- darray_resize0(keymap->key_acts, nKeys);
-
- keymap->behaviors = calloc(nKeys, sizeof(*keymap->behaviors));
- if (!keymap->behaviors)
- return false;
-
- keymap->vmodmap = calloc(nKeys, sizeof(*keymap->vmodmap));
- if (!keymap->vmodmap)
- return false;
-
- keymap->per_key_repeat = calloc(nKeys / 8, 1);
- if (!keymap->per_key_repeat)
- return false;
return true;
}
int i;
bool ok;
xkb_keycode_t kc;
+ struct xkb_key *key;
SymbolsInfo info;
KeyInfo *keyi;
if (warningLevel > 3) {
for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
- if (darray_item(keymap->key_names, kc).name[0] == '\0')
+ key = XkbKey(keymap, kc);
+ if (key->name.name[0] == '\0')
continue;
- if (XkbKeyNumGroups(keymap, kc) < 1) {
- char buf[5];
- memcpy(buf, darray_item(keymap->key_names, kc).name, 4);
- buf[4] = '\0';
- WARN("No symbols defined for <%s> (keycode %d)\n", buf, kc);
- }
+ if (XkbKeyNumGroups(keymap, kc) < 1)
+ WARN("No symbols defined for <%.4s> (keycode %d)\n",
+ key->name.name, kc);
}
}