typedef struct _KeyInfo {
CommonInfo defs;
unsigned long name; /* the 4 chars of the key name, as long */
- unsigned char groupInfo;
unsigned char typesDefined;
unsigned char symsDefined;
unsigned char actsDefined;
struct xkb_behavior behavior;
unsigned short vmodmap;
xkb_atom_t dfltType;
+
+ uint8_t out_of_range_group_action;
+ uint8_t out_of_range_group_number;
} KeyInfo;
/**
keyi->defs.merge = MERGE_OVERRIDE;
keyi->defs.next = NULL;
keyi->name = KeyNameToLong(dflt);
- keyi->groupInfo = 0;
keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 0;
for (i = 0; i < XkbNumKbdGroups; i++) {
keyi->behavior.data = 0;
keyi->vmodmap = 0;
keyi->repeat = RepeatUndefined;
+ keyi->out_of_range_group_action = 0;
+ keyi->out_of_range_group_number = 0;
}
-/**
- * Free memory associated with this key keyi and reset to sane values.
- */
static void
FreeKeyInfo(KeyInfo *keyi)
{
int i;
- keyi->defs.defined = 0;
- keyi->defs.file_id = 0;
- keyi->defs.merge = MERGE_OVERRIDE;
- keyi->defs.next = NULL;
- keyi->groupkeyi = 0;
- keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 0;
for (i = 0; i < XkbNumKbdGroups; i++) {
- keyi->numLevels[i] = 0;
- keyi->types[i] = XKB_ATOM_NONE;
darray_free(keyi->syms[i]);
darray_free(keyi->symsMapIndex[i]);
darray_free(keyi->symsMapNumEntries[i]);
darray_free(keyi->acts[i]);
}
- keyi->dfltType = XKB_ATOM_NONE;
- keyi->behavior.type = XkbKB_Default;
- keyi->behavior.data = 0;
- keyi->vmodmap = 0;
- keyi->repeat = RepeatUndefined;
}
/**
KeyInfo *keyi;
free(info->name);
- darray_foreach(keyi, info->keys)
+ darray_foreach(keyi, info->keys) {
FreeKeyInfo(keyi);
+ }
darray_free(info->keys);
if (info->modMap)
ClearCommonInfo(&info->modMap->defs);
into->defs.defined |= _Key_Type_Dflt;
}
if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) {
- into->groupInfo = from->groupInfo;
+ into->out_of_range_group_action = from->out_of_range_group_action;
+ into->out_of_range_group_number = from->out_of_range_group_number;
into->defs.defined |= _Key_GroupInfo;
}
if (collide) {
return false;
}
if (tmp.uval)
- keyi->groupInfo = XkbWrapIntoRange;
+ keyi->out_of_range_group_action = XkbWrapIntoRange;
else
- keyi->groupInfo = XkbClampIntoRange;
+ keyi->out_of_range_group_action = XkbClampIntoRange;
keyi->defs.defined |= _Key_GroupInfo;
}
else if ((strcasecmp(field, "groupsclamp") == 0) ||
return false;
}
if (tmp.uval)
- keyi->groupInfo = XkbClampIntoRange;
+ keyi->out_of_range_group_action = XkbClampIntoRange;
else
- keyi->groupInfo = XkbWrapIntoRange;
+ keyi->out_of_range_group_action = XkbWrapIntoRange;
keyi->defs.defined |= _Key_GroupInfo;
}
else if ((strcasecmp(field, "groupsredirect") == 0) ||
ACTION("Definition with non-integer group ignored\n");
return false;
}
- keyi->groupInfo =
- XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
+ keyi->out_of_range_group_action = XkbRedirectIntoRange;
+ keyi->out_of_range_group_number = tmp.uval - 1;
keyi->defs.defined |= _Key_GroupInfo;
}
else {
}
/**
- * Given a keysym @sym, find the keycode which generates it
- * (returned in @kc_rtrn). This is used for example in a modifier
- * map definition, such as:
+ * Given a keysym @sym, return a key which generates it, or NULL.
+ * This is used for example in a modifier map definition, such as:
* modifier_map Lock { Caps_Lock };
* where we want to add the Lock modifier to the modmap of the key
* which matches the keysym Caps_Lock.
* is chosen first by lowest group in which the keysym appears, than
* by lowest level and than by lowest key code.
*/
-static bool
-FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
- xkb_keycode_t *kc_rtrn)
+static struct xkb_key *
+FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym)
{
- xkb_keycode_t kc;
+ struct xkb_key *key, *ret = NULL;
unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
- for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
- for (group = 0; group < XkbKeyNumGroups(keymap, kc); group++) {
- for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
+ xkb_foreach_key(key, keymap) {
+ for (group = 0; group < key->num_groups; group++) {
+ for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
level++) {
- if (XkbKeyNumSyms(keymap, kc, group, level) != 1 ||
- (XkbKeySymEntry(keymap, kc, group, level))[0] != sym)
+ if (XkbKeyNumSyms(key, group, level) != 1 ||
+ (XkbKeySymEntry(key, group, level))[0] != sym)
continue;
/*
*/
if (group < min_group ||
(group == min_group && level < min_level)) {
- *kc_rtrn = kc;
+ ret = key;
if (group == 0 && level == 0) {
- return true;
+ return ret;
}
else {
min_group = group;
}
}
- return min_group != UINT_MAX;
+ return ret;
}
/**
{
unsigned int i;
xkb_keycode_t kc;
+ struct xkb_key *key;
unsigned int sizeSyms = 0;
unsigned width, tmp, nGroups;
struct xkb_key_type * type;
unsigned types[XkbNumKbdGroups];
union xkb_action *outActs;
unsigned int symIndex = 0;
- struct xkb_sym_map *sym_map;
useAlias = (start_from == 0);
- /* get the keycode for the key. */
- if (!FindNamedKey(keymap, keyi->name, &kc, useAlias,
- CreateKeyNames(keymap), start_from)) {
- if ((start_from == 0) && (warningLevel >= 5)) {
+ key = FindNamedKey(keymap, keyi->name, useAlias,
+ CreateKeyNames(keymap), start_from);
+ if (!key) {
+ if (start_from == 0 && warningLevel >= 5) {
WARN("Key %s not found in keycodes\n", longText(keyi->name));
ACTION("Symbols ignored\n");
}
return false;
}
+ kc = XkbKeyGetKeycode(keymap, key);
haveActions = false;
for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) {
}
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) {
sizeSyms += darray_size(keyi->syms[i]);
}
- if (!XkbcResizeKeySyms(keymap, kc, sizeSyms)) {
- WSGO("Could not enlarge symbols for %s (keycode %d)\n",
- longText(keyi->name), kc);
- return false;
- }
+ darray_resize0(key->syms, sizeSyms);
+
if (haveActions) {
- outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
+ outActs = XkbcResizeKeyActions(keymap, key, width * nGroups);
if (outActs == NULL) {
WSGO("Could not enlarge actions for %s (key %d)\n",
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);
-
- if (keyi->defs.defined & _Key_GroupInfo)
- i = keyi->groupInfo;
- else
- i = sym_map->group_info;
-
- sym_map->group_info = XkbSetNumGroups(i, nGroups);
- sym_map->width = width;
- sym_map->sym_index = uTypedCalloc(nGroups * width, int);
- sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
+ key->num_groups = nGroups;
+ if (keyi->defs.defined & _Key_GroupInfo) {
+ key->out_of_range_group_number = keyi->out_of_range_group_number;
+ key->out_of_range_group_action = keyi->out_of_range_group_action;
+ }
+ key->width = width;
+ key->sym_index = calloc(nGroups * width, sizeof(*key->sym_index));
+ key->num_syms = calloc(nGroups * width, sizeof(*key->num_syms));
for (i = 0; i < nGroups; i++) {
/* assign kt_index[i] to the index of the type in map->types.
* FIXME: There should be a better fix for this.
*/
if (keyi->numLevels[i])
- sym_map->kt_index[i] = types[i];
+ key->kt_index[i] = types[i];
if (!darray_empty(keyi->syms[i])) {
/* fill key to "width" symbols*/
for (tmp = 0; tmp < width; tmp++) {
if (tmp < keyi->numLevels[i] &&
darray_item(keyi->symsMapNumEntries[i], tmp) != 0) {
- memcpy(darray_mem(sym_map->syms, symIndex),
+ memcpy(darray_mem(key->syms, symIndex),
darray_mem(keyi->syms[i],
darray_item(keyi->symsMapIndex[i], tmp)),
darray_item(keyi->symsMapNumEntries[i],
tmp) * sizeof(xkb_keysym_t));
- sym_map->sym_index[(i * width) + tmp] = symIndex;
- sym_map->num_syms[(i * width) + tmp] =
+ key->sym_index[(i * width) + tmp] = symIndex;
+ key->num_syms[(i * width) + tmp] =
darray_item(keyi->symsMapNumEntries[i], tmp);
- symIndex += sym_map->num_syms[(i * width) + tmp];
+ symIndex += key->num_syms[(i * width) + tmp];
}
else {
- sym_map->sym_index[(i * width) + tmp] = -1;
- sym_map->num_syms[(i * width) + tmp] = 0;
+ key->sym_index[(i * width) + tmp] = -1;
+ key->num_syms[(i * width) + tmp] = 0;
}
if (outActs != NULL && !darray_empty(keyi->acts[i])) {
if (tmp < keyi->numLevels[i])
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 */
static bool
CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
{
- xkb_keycode_t kc;
-
- if (!entry->haveSymbol &&
- !FindNamedKey(keymap, entry->u.keyName, &kc, true,
- CreateKeyNames(keymap), 0)) {
- if (warningLevel >= 5) {
- WARN("Key %s not found in keycodes\n",
- longText(entry->u.keyName));
- ACTION("Modifier map entry for %s not updated\n",
- XkbcModIndexText(entry->modifier));
+ struct xkb_key *key;
+
+ if (!entry->haveSymbol) {
+ key = FindNamedKey(keymap, entry->u.keyName, true,
+ CreateKeyNames(keymap), 0);
+ if (!key) {
+ if (warningLevel >= 5) {
+ WARN("Key %s not found in keycodes\n",
+ longText(entry->u.keyName));
+ ACTION("Modifier map entry for %s not updated\n",
+ XkbcModIndexText(entry->modifier));
+ }
+ return false;
}
- return false;
}
- else if (entry->haveSymbol &&
- !FindKeyForSymbol(keymap, entry->u.keySym, &kc)) {
- if (warningLevel > 5) {
- WARN("Key \"%s\" not found in symbol map\n",
- XkbcKeysymText(entry->u.keySym));
- ACTION("Modifier map entry for %s not updated\n",
- XkbcModIndexText(entry->modifier));
+ else {
+ key = FindKeyForSymbol(keymap, entry->u.keySym);
+ if (!key) {
+ if (warningLevel > 5) {
+ WARN("Key \"%s\" not found in symbol map\n",
+ XkbcKeysymText(entry->u.keySym));
+ ACTION("Modifier map entry for %s not updated\n",
+ XkbcModIndexText(entry->modifier));
+ }
+ return false;
}
- return false;
}
- keymap->modmap[kc] |= (1 << entry->modifier);
- return true;
-}
-
-static bool
-InitKeymapForSymbols(struct xkb_keymap *keymap)
-{
- 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->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;
+ key->modmap |= (1 << entry->modifier);
return true;
}
enum merge_mode merge)
{
int i;
- bool ok;
- xkb_keycode_t kc;
+ struct xkb_key *key;
SymbolsInfo info;
KeyInfo *keyi;
if (info.errorCount != 0)
goto err_info;
- ok = InitKeymapForSymbols(keymap);
- if (!ok)
- goto err_info;
+ darray_resize0(keymap->acts, darray_size(keymap->acts) + 32 + 1);
if (info.name)
keymap->symbols_section_name = strdup(info.name);
info.errorCount++;
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')
+ xkb_foreach_key(key, keymap) {
+ if (key->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 (key->num_groups < 1)
+ WARN("No symbols defined for <%.4s> (keycode %d)\n",
+ key->name, XkbKeyGetKeycode(keymap, key));
}
}