********************************************************/
-#include <X11/keysym.h>
-
#include "xkbcomp-priv.h"
#include "parseutils.h"
#include "action.h"
unsigned repeat;
struct xkb_behavior behavior;
unsigned short vmodmap;
- unsigned long allowNone;
xkb_atom_t dfltType;
} KeyInfo;
InitKeyInfo(KeyInfo * info)
{
int i;
- static char dflt[4] = "*";
+ static const char dflt[4] = "*";
info->defs.defined = 0;
info->defs.fileID = 0;
info->behavior.data = 0;
info->vmodmap = 0;
info->repeat = RepeatUndefined;
- info->allowNone = 0;
}
/**
info->behavior.data = 0;
info->vmodmap = 0;
info->repeat = RepeatUndefined;
- info->allowNone = 0;
}
/**
} u;
} ModMapEntry;
-#define SYMBOLS_INIT_SIZE 110
-#define SYMBOLS_CHUNK 20
+#define SYMBOLS_INIT_SIZE 110
+
typedef struct _SymbolsInfo
{
char *name; /* e.g. pc+us+inet(evdev) */
unsigned fileID;
unsigned merge;
unsigned explicit_group;
- unsigned groupInfo;
- unsigned szKeys;
- unsigned nKeys;
- KeyInfo *keys;
+ darray(KeyInfo) keys;
KeyInfo dflt;
VModInfo vmods;
ActionInfo *action;
info->errorCount = 0;
info->fileID = 0;
info->merge = MergeOverride;
- info->groupInfo = 0;
- info->szKeys = SYMBOLS_INIT_SIZE;
- info->nKeys = 0;
- info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
+ darray_init(info->keys);
+ darray_growalloc(info->keys, SYMBOLS_INIT_SIZE);
info->modMap = NULL;
for (i = 0; i < XkbNumKbdGroups; i++)
info->groupNames[i] = XKB_ATOM_NONE;
static void
FreeSymbolsInfo(SymbolsInfo * info)
{
- unsigned int i;
+ KeyInfo *key;
free(info->name);
- if (info->keys)
- {
- for (i = 0; i < info->nKeys; i++)
- FreeKeyInfo(&info->keys[i]);
- free(info->keys);
- }
+ darray_foreach(key, info->keys)
+ FreeKeyInfo(key);
+ darray_free(info->keys);
if (info->modMap)
ClearCommonInfo(&info->modMap->defs);
if (info->aliases)
return true;
}
+enum key_group_selector {
+ NONE = 0,
+ FROM = (1 << 0),
+ TO = (1 << 1),
+};
+
static bool
MergeKeyGroups(SymbolsInfo * info,
KeyInfo * into, KeyInfo * from, unsigned group)
{
xkb_keysym_t *resultSyms = NULL;
+ enum key_group_selector using = NONE;
union xkb_action *resultActs;
unsigned int resultWidth;
unsigned int resultSize = 0;
if (into->symsMapNumEntries[group] && (i < into->numLevels[group]))
toSize = into->symsMapNumEntries[group][i];
- if ((fromSize != 0 && toSize == 0) || clobber)
+ if (fromSize == 0)
+ {
+ resultSize += toSize;
+ using |= TO;
+ }
+ else if (toSize == 0 || clobber)
+ {
resultSize += fromSize;
+ using |= FROM;
+ }
else
+ {
resultSize += toSize;
+ using |= TO;
+ }
}
if (resultSize == 0)
goto out;
+ if (using == FROM)
+ {
+ resultSyms = from->syms[group];
+ goto out;
+ }
+ else if (using == TO)
+ {
+ resultSyms = into->syms[group];
+ goto out;
+ }
+
resultSyms = uTypedCalloc(resultSize, xkb_keysym_t);
if (!resultSyms)
{
for (i = 0; i < resultWidth; i++)
{
- enum { NONE, FROM, TO } use;
+ enum key_group_selector use = NONE;
unsigned int fromSize = 0;
unsigned int toSize = 0;
- if (from->symsMapNumEntries[group] && (i < from->numLevels[group]))
+ if (i < from->numLevels[group])
fromSize = from->symsMapNumEntries[group][i];
- if (into->symsMapNumEntries[group] && (i < into->numLevels[group]))
+ if (i < into->numLevels[group])
toSize = into->symsMapNumEntries[group][i];
- if (!fromSize && !toSize)
+ if (fromSize == 0 && toSize == 0)
{
into->symsMapIndex[group][i] = -1;
into->symsMapNumEntries[group][i] = 0;
continue;
}
- if ((fromSize && !toSize) || clobber)
+ if (fromSize == 0)
+ use = TO;
+ else if (toSize == 0 || clobber)
use = FROM;
else
use = TO;
else
{
memcpy(&resultSyms[cur_idx],
- &into->syms[group][from->symsMapIndex[group][i]],
+ &into->syms[group][into->symsMapIndex[group][i]],
into->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t));
into->symsMapIndex[group][i] = cur_idx;
}
if (resultActs != from->acts[group])
free(from->acts[group]);
into->numLevels[group] = resultWidth;
- free(into->syms[group]);
+ if (resultSyms != into->syms[group])
+ free(into->syms[group]);
into->syms[group] = resultSyms;
- free(from->syms[group]);
+ if (resultSyms != from->syms[group])
+ free(from->syms[group]);
from->syms[group] = NULL;
from->sizeSyms[group] = 0;
into->sizeSyms[group] = resultSize;
from->symsMapNumEntries[group] = NULL;
into->acts[group] = resultActs;
from->acts[group] = NULL;
- into->symsDefined |= (1 << group);
+ if (into->syms[group])
+ into->symsDefined |= (1 << group);
from->symsDefined &= ~(1 << group);
into->actsDefined |= (1 << group);
from->actsDefined &= ~(1 << group);
static bool
AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap)
{
- unsigned int i;
unsigned long real_name;
+ KeyInfo *iter, *new;
+
+ darray_foreach(iter, info->keys)
+ if (iter->name == key->name)
+ return MergeKeys(info, keymap, iter, key);
- for (i = 0; i < info->nKeys; i++)
- {
- if (info->keys[i].name == key->name)
- return MergeKeys(info, keymap, &info->keys[i], key);
- }
if (FindKeyNameForAlias(keymap, key->name, &real_name))
- {
- for (i = 0; i < info->nKeys; i++)
- {
- if (info->keys[i].name == real_name)
- return MergeKeys(info, keymap, &info->keys[i], key);
- }
- }
- if (info->nKeys >= info->szKeys)
- {
- info->szKeys += SYMBOLS_CHUNK;
- info->keys =
- uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
- if (!info->keys)
- {
- WSGO("Could not allocate key symbols descriptions\n");
- ACTION("Some key symbols definitions may be lost\n");
- return false;
- }
- }
- return CopyKeyInfo(key, &info->keys[info->nKeys++], true);
+ darray_foreach(iter, info->keys)
+ if (iter->name == real_name)
+ return MergeKeys(info, keymap, iter, key);
+
+ darray_resize0(info->keys, darray_size(info->keys) + 1);
+ new = &darray_item(info->keys, darray_size(info->keys) - 1);
+ return CopyKeyInfo(key, new, true);
}
static bool
into->groupNames[i] = from->groupNames[i];
}
}
- for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
- {
+
+ darray_foreach(key, from->keys) {
if (merge != MergeDefault)
key->defs.merge = merge;
+
if (!AddKeySymbols(into, key, keymap))
into->errorCount++;
}
+
if (from->modMap != NULL)
{
ModMapEntry *mm, *next;
into->errorCount++;
}
-typedef void (*FileHandler) (XkbFile *rtrn, struct xkb_keymap *keymap,
- unsigned merge, SymbolsInfo *included);
+static void
+HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
+ unsigned merge, SymbolsInfo *info);
static bool
HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
- SymbolsInfo *info, FileHandler hndlr)
+ SymbolsInfo *info)
{
unsigned newMerge;
XkbFile *rtrn;
{
included.explicit_group = info->explicit_group;
}
- (*hndlr) (rtrn, keymap, MergeOverride, &included);
+ HandleSymbolsFile(rtrn, keymap, MergeOverride, &included);
if (stmt->stmt != NULL)
{
free(included.name);
{
next_incl.explicit_group = info->explicit_group;
}
- (*hndlr) (rtrn, keymap, MergeOverride, &next_incl);
+ HandleSymbolsFile(rtrn, keymap, MergeOverride, &next_incl);
MergeIncludedSymbols(&included, &next_incl, op, keymap);
FreeSymbolsInfo(&next_incl);
FreeXKBFile(rtrn);
ACTION("Ignoring duplicate definition\n");
return false;
}
- nSyms = value->value.list.nSyms;
- nLevels = value->value.list.nLevels;
+ nSyms = darray_size(value->value.list.syms);
+ nLevels = darray_size(value->value.list.symsMapIndex);
if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
(!ResizeKeyGroup(key, ndx, nLevels, nSyms, false)))
{
}
key->symsDefined |= (1 << ndx);
for (i = 0; i < nLevels; i++) {
- key->symsMapIndex[ndx][i] = value->value.list.symsMapIndex[i];
- key->symsMapNumEntries[ndx][i] = value->value.list.symsNumEntries[i];
+ key->symsMapIndex[ndx][i] =
+ darray_item(value->value.list.symsMapIndex, i);
+ key->symsMapNumEntries[ndx][i] =
+ darray_item(value->value.list.symsNumEntries, i);
+
for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) {
if (key->symsMapIndex[ndx][i] + j >= nSyms)
abort();
- if (!LookupKeysym(value->value.list.syms[value->value.list.symsMapIndex[i] + j],
+ if (!LookupKeysym(darray_item(value->value.list.syms,
+ darray_item(value->value.list.symsMapIndex, i) + j),
&key->syms[ndx][key->symsMapIndex[ndx][i] + j])) {
WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
- value->value.list.syms[i], longText(key->name), ndx + 1,
+ darray_item(value->value.list.syms, i),
+ longText(key->name),
+ ndx + 1,
xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
while (--j >= 0)
- key->syms[ndx][key->symsMapIndex[ndx][i] + j] = NoSymbol;
+ key->syms[ndx][key->symsMapIndex[ndx][i] + j] = XKB_KEY_NoSymbol;
key->symsMapIndex[ndx][i] = -1;
key->symsMapNumEntries[ndx][i] = 0;
break;
}
+ if (key->symsMapNumEntries[ndx][i] == 1 &&
+ key->syms[ndx][key->symsMapIndex[ndx][i] + j] == XKB_KEY_NoSymbol) {
+ key->symsMapIndex[ndx][i] = -1;
+ key->symsMapNumEntries[ndx][i] = 0;
+ }
}
}
for (j = key->numLevels[ndx] - 1;
static int
HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
{
- ExprResult elem, field, tmp;
+ ExprResult elem, field;
ExprDef *arrayNdx;
bool ret;
&& ((strcasecmp(field.str, "groupswrap") == 0) ||
(strcasecmp(field.str, "wrapgroups") == 0)))
{
- if (!ExprResolveBoolean(keymap->ctx, stmt->value, &tmp))
- {
- ERROR("Illegal setting for global groupsWrap\n");
- ACTION("Non-boolean value ignored\n");
- ret = false;
- }
- else {
- if (tmp.uval)
- info->groupInfo = XkbWrapIntoRange;
- else
- info->groupInfo = XkbClampIntoRange;
- ret = true;
- }
+ ERROR("Global \"groupswrap\" not supported\n");
+ ACTION("Ignored\n");
+ ret = true;
}
else if ((elem.str == NULL)
&& ((strcasecmp(field.str, "groupsclamp") == 0) ||
(strcasecmp(field.str, "clampgroups") == 0)))
{
- if (!ExprResolveBoolean(keymap->ctx, stmt->value, &tmp))
- {
- ERROR("Illegal setting for global groupsClamp\n");
- ACTION("Non-boolean value ignored\n");
- return false;
- }
- else {
- if (tmp.uval)
- info->groupInfo = XkbClampIntoRange;
- else
- info->groupInfo = XkbWrapIntoRange;
- ret = true;
- }
+ ERROR("Global \"groupsclamp\" not supported\n");
+ ACTION("Ignored\n");
+ ret = true;
}
else if ((elem.str == NULL)
&& ((strcasecmp(field.str, "groupsredirect") == 0) ||
(strcasecmp(field.str, "redirectgroups") == 0)))
{
- if (!ExprResolveGroup(keymap->ctx, stmt->value, &tmp))
- {
- ERROR("Illegal group index for global groupsRedirect\n");
- ACTION("Definition with non-integer group ignored\n");
- ret = false;
- }
- else {
- info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
- tmp.uval);
- ret = true;
- }
+ ERROR("Global \"groupsredirect\" not supported\n");
+ ACTION("Ignored\n");
+ ret = true;
}
else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
{
ERROR("Radio groups not supported\n");
- ACTION("Ignoring \"allow none\" specification\n");
- ret = false;
+ ACTION("Ignoring \"allownone\" specification\n");
+ ret = true;
}
else {
ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
switch (stmt->stmtType)
{
case StmtInclude:
- if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info,
- HandleSymbolsFile))
+ if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
info->errorCount++;
break;
case StmtSymbolsDef:
static bool
FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
{
- unsigned n;
+ unsigned n = 0;
const char *name = xkb_atom_text(keymap->ctx, atom);
+ struct xkb_key_type *type;
- if (keymap && keymap->map && keymap->map->types)
- {
- for (n = 0; n < keymap->map->num_types; n++)
- {
- if (strcmp(keymap->map->types[n].name, name) == 0)
- {
+ if (keymap && keymap->map) {
+ darray_foreach(type, keymap->map->types) {
+ if (strcmp(type->name, name) == 0) {
*type_rtrn = n;
return true;
}
+ n++;
}
}
return false;
identical = false;
break;
}
- if ((key->symsMapIndex[i] != key->symsMapIndex[i]) &&
+ if ((key->symsMapIndex[i] != key->symsMapIndex[0]) &&
(key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL ||
memcmp(key->symsMapIndex[i], key->symsMapIndex[0],
key->numLevels[0] * sizeof(int))))
identical = false;
continue;
}
- if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[i]) &&
+ if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[0]) &&
(key->symsMapNumEntries[i] == NULL ||
key->symsMapNumEntries[0] == NULL ||
memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
unsigned types[XkbNumKbdGroups];
union xkb_action *outActs;
unsigned int symIndex = 0;
+ struct xkb_sym_map *sym_map;
useAlias = (start_from == 0);
types[i] = XkbTwoLevelIndex;
}
/* if the type specifies fewer levels than the key has, shrink the key */
- type = &keymap->map->types[types[i]];
+ type = &darray_item(keymap->map->types, types[i]);
if (type->num_levels < key->numLevels[i])
{
if (warningLevel > 0)
}
else
outActs = NULL;
+
+ sym_map = &darray_item(keymap->map->key_sym_map, kc);
+
if (key->defs.defined & _Key_GroupInfo)
i = key->groupInfo;
else
- i = keymap->map->key_sym_map[kc].group_info;
-
- keymap->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
- keymap->map->key_sym_map[kc].width = width;
- keymap->map->key_sym_map[kc].sym_index = uTypedCalloc(nGroups * width,
- int);
- keymap->map->key_sym_map[kc].num_syms = uTypedCalloc(nGroups * width,
- unsigned int);
+ 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);
+
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 (key->numLevels[i])
- keymap->map->key_sym_map[kc].kt_index[i] = types[i];
+ sym_map->kt_index[i] = types[i];
if (key->sizeSyms[i] != 0)
{
/* fill key to "width" symbols*/
{
if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
{
- memcpy(&keymap->map->key_sym_map[kc].syms[symIndex],
+ memcpy(&sym_map->syms[symIndex],
&key->syms[i][key->symsMapIndex[i][tmp]],
key->symsMapNumEntries[i][tmp] *
sizeof(xkb_keysym_t));
- keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] =
- symIndex;
- keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] =
+ sym_map->sym_index[(i * width) + tmp] = symIndex;
+ sym_map->num_syms[(i * width) + tmp] =
key->symsMapNumEntries[i][tmp];
- symIndex +=
- keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp];
+ symIndex += sym_map->num_syms[(i * width) + tmp];
}
else
{
- keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] = -1;
- keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] = 0;
+ sym_map->sym_index[(i * width) + tmp] = -1;
+ sym_map->num_syms[(i * width) + tmp] = 0;
}
if ((outActs != NULL) && (key->acts[i] != NULL))
{
HandleSymbolsFile(file, keymap, merge, &info);
- if (info.nKeys == 0)
+ if (darray_empty(info.keys))
goto err_info;
if (info.errorCount != 0)
for (i = 0; i < XkbNumKbdGroups; i++) {
if (info.groupNames[i] != XKB_ATOM_NONE) {
- free(UNCONSTIFY(keymap->names->groups[i]));
+ free(keymap->names->groups[i]);
keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
info.groupNames[i]);
}
}
/* sanitize keys */
- for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
+ darray_foreach(key, info.keys)
PrepareKeyDef(key);
/* copy! */
- for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
+ darray_foreach(key, info.keys)
if (!CopySymbolsDef(keymap, key, 0))
info.errorCount++;
if (warningLevel > 3) {
for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
- if (keymap->names->keys[i].name[0] == '\0')
+ if (darray_item(keymap->names->keys, i).name[0] == '\0')
continue;
if (XkbKeyNumGroups(keymap, i) < 1) {
char buf[5];
- memcpy(buf, keymap->names->keys[i].name, 4);
+ memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
buf[4] = '\0';
WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
}