}
int
-XkbcCopyKeyType(struct xkb_key_type * from, struct xkb_key_type * into)
+XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into)
{
int i;
if (!from || !into)
return BadMatch;
- free(into->map);
- into->map = NULL;
+ darray_free(into->map);
free(into->preserve);
- into->preserve= NULL;
for (i = 0; i < into->num_levels; i++)
free(UNCONSTIFY(into->level_names[i]));
free(into->level_names);
- into->level_names = NULL;
*into = *from;
- if (from->map && (into->map_count > 0)) {
- into->map = uTypedCalloc(into->map_count, struct xkb_kt_map_entry);
- if (!into->map)
- return BadAlloc;
- memcpy(into->map, from->map,
- into->map_count * sizeof(struct xkb_kt_map_entry));
- }
+ darray_init(into->map);
+ darray_from_items(into->map,
+ &darray_item(from->map, 0),
+ darray_size(from->map));
- if (from->preserve && (into->map_count > 0)) {
- into->preserve = uTypedCalloc(into->map_count, struct xkb_mods);
+ if (from->preserve && !darray_empty(into->map)) {
+ into->preserve = calloc(darray_size(into->map),
+ sizeof(*into->preserve));
if (!into->preserve)
return BadAlloc;
memcpy(into->preserve, from->preserve,
- into->map_count * sizeof(struct xkb_mods));
+ darray_size(into->map) * sizeof(*into->preserve));
}
if (from->level_names && (into->num_levels > 0)) {
darray_foreach(type, map->types) {
int j;
- free(type->map);
+ darray_free(type->map);
free(type->preserve);
for (j = 0; j < type->num_levels; j++)
free(UNCONSTIFY(type->level_names[j]));
unsigned nNewActions);
extern int
-XkbcCopyKeyType(struct xkb_key_type *from, struct xkb_key_type *into);
+XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into);
extern bool
XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t key,
* darray_init(foo.a);
* darray_free(foo.a);
*
+ * const struct {
+ * darray(int) a;
+ * } foo = {
+ * .a = darray_lit({1, 2, 3})
+ * };
+ *
* Typedefs for darrays of common types:
*
* darray_char, darray_schar, darray_uchar
#define darray(type) struct {type *item; size_t size; size_t alloc;}
#define darray_new() {0,0,0}
+#define darray_lit(c_array) {(c_array), sizeof(c_array) / sizeof(*(c_array)), 0}
#define darray_init(arr) do {(arr).item=0; (arr).size=0; (arr).alloc=0;} while(0)
#define darray_free(arr) do {free((arr).item);} while(0)
{
struct xkb_keymap *keymap = state->keymap;
struct xkb_key_type *type = XkbKeyType(keymap, key, group);
+ struct xkb_kt_map_entry *entry;
unsigned int active_mods = state->mods & type->mods.mask;
- int i;
- for (i = 0; i < type->map_count; i++) {
- if (!type->map[i].active)
+ darray_foreach(entry, type->map) {
+ if (!entry->active)
continue;
- if (type->map[i].mods.mask == active_mods)
- return type->map[i].level;
+
+ if (entry->mods.mask == active_mods)
+ return entry->level;
}
return 0;
#include "xkb-priv.h"
#include "alloc.h"
-#define mapSize(m) (sizeof(m) / sizeof(struct xkb_kt_map_entry))
static struct xkb_kt_map_entry map2Level[]= {
- { true, ShiftMask, {1, ShiftMask, 0} }
+ {
+ .active = true,
+ .level = ShiftMask,
+ .mods = {.mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+ }
};
static struct xkb_kt_map_entry mapAlpha[]= {
- { true, ShiftMask, { 1, ShiftMask, 0 } },
- { true, LockMask, { 0, LockMask, 0 } }
+ {
+ .active = true,
+ .level = ShiftMask,
+ .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+ },
+ {
+ .active = true,
+ .level = LockMask,
+ .mods = { .mask = 0, .vmods = LockMask, .real_mods = 0 }
+ }
};
static struct xkb_mods preAlpha[]= {
- { 0, 0, 0 },
- { LockMask, LockMask, 0 }
+ { .mask = 0, .vmods = 0, .real_mods = 0 },
+ { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
};
#define NL_VMOD_MASK 0
-static struct xkb_kt_map_entry mapKeypad[]= {
- { true, ShiftMask, { 1, ShiftMask, 0 } },
- { false, 0, { 1, 0, NL_VMOD_MASK } }
+static struct xkb_kt_map_entry mapKeypad[]= {
+ {
+ .active = true,
+ .level = ShiftMask,
+ .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+ },
+ {
+ .active = false,
+ .level = 0,
+ .mods = { .mask = 1, .vmods = 0, .real_mods = NL_VMOD_MASK }
+ }
};
-static struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
- { { 0, 0, 0 },
- 1, /* num_levels */
- 0, /* map_count */
- NULL, NULL,
- NULL, NULL
+static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
+ {
+ .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
+ .num_levels = 1,
+ .preserve = NULL,
+ .name = NULL,
+ .level_names = NULL
},
- { { ShiftMask, ShiftMask, 0 },
- 2, /* num_levels */
- mapSize(map2Level), /* map_count */
- map2Level, NULL,
- NULL, NULL
+ {
+ .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
+ .num_levels = 2,
+ .map = darray_lit(map2Level),
+ .preserve = NULL,
+ .name = NULL,
+ .level_names = NULL
},
- { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
- 2, /* num_levels */
- mapSize(mapAlpha), /* map_count */
- mapAlpha, preAlpha,
- NULL, NULL
+ {
+ .mods = { .mask = ShiftMask|LockMask, .vmods = ShiftMask|LockMask, .real_mods = 0 },
+ .num_levels = 2,
+ .map = darray_lit(mapAlpha),
+ .preserve = preAlpha,
+ .name = NULL,
+ .level_names = NULL
},
- { { ShiftMask, ShiftMask, NL_VMOD_MASK },
- 2, /* num_levels */
- mapSize(mapKeypad), /* map_count */
- mapKeypad, NULL,
- NULL, NULL
+ {
+ .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = NL_VMOD_MASK },
+ .num_levels = 2,
+ .map = darray_lit(mapKeypad),
+ .preserve = NULL,
+ .name = NULL,
+ .level_names = NULL
}
};
int keypadVMod)
{
struct xkb_client_map * map;
- struct xkb_key_type *from;
+ const struct xkb_key_type *from;
int rtrn;
if (!keymap)
if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) &&
(rtrn == Success)) {
+ struct xkb_kt_map_entry *entry;
type->mods.vmods = (1 << keypadVMod);
- type->map[0].active = true;
- type->map[0].mods.mask = ShiftMask;
- type->map[0].mods.real_mods = ShiftMask;
- type->map[0].mods.vmods = 0;
- type->map[0].level = 1;
- type->map[1].active = false;
- type->map[1].mods.mask = 0;
- type->map[1].mods.real_mods = 0;
- type->map[1].mods.vmods = (1 << keypadVMod);
- type->map[1].level = 1;
+
+ entry = &darray_item(type->map, 0);
+ entry->active = true;
+ entry->mods.mask = ShiftMask;
+ entry->mods.real_mods = ShiftMask;
+ entry->mods.vmods = 0;
+ entry->level = 1;
+
+ entry = &darray_item(type->map, 1);
+ entry->active = false;
+ entry->mods.mask = 0;
+ entry->mods.real_mods = 0;
+ entry->mods.vmods = (1 << keypadVMod);
+ entry->level = 1;
}
}
struct xkb_key_type {
struct xkb_mods mods;
uint16_t num_levels;
- unsigned char map_count;
- struct xkb_kt_map_entry * map;
+ darray(struct xkb_kt_map_entry) map;
struct xkb_mods * preserve;
const char *name;
const char **level_names;
XkbcComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type,
unsigned char *map_rtrn)
{
- int i;
unsigned tmp;
struct xkb_kt_map_entry * entry = NULL;
return false;
type->mods.mask = tmp | type->mods.real_mods;
- entry = type->map;
- for (i = 0; i < type->map_count; i++, entry++) {
+ darray_foreach(entry, type->map) {
tmp = 0;
if (entry->mods.vmods != 0) {
if (!VirtualModsToReal(keymap, entry->mods.vmods, &tmp))
if (map_rtrn) {
memset(map_rtrn, 0, type->mods.mask + 1);
if (entry && entry->active)
- for (i = 0; i < type->map_count; i++)
- map_rtrn[type->map[i].mods.mask] = type->map[i].level;
+ darray_foreach(entry, type->map)
+ map_rtrn[entry->mods.mask] = entry->level;
}
return true;
xkb_keycode_t key;
int i;
struct xkb_key_type *type;
+ struct xkb_kt_map_entry *entry;
/* Find all the interprets for the key and bind them to actions,
* which will also update the vmodmap. */
continue;
mask |= keymap->server->vmods[j];
}
- for (j = 0; j < type->map_count; j++) {
- struct xkb_mods *mods = &type->map[j].mods;
- mods->mask = mods->real_mods | VModsToReal(keymap, mods->vmods);
- }
+
+ darray_foreach(entry, type->map)
+ entry->mods.mask = entry->mods.real_mods |
+ VModsToReal(keymap, entry->mods.vmods);
}
/* Update action modifiers. */
unsigned vmask;
bool groupInfo;
unsigned numLevels;
- unsigned nEntries;
- unsigned szEntries;
- struct xkb_kt_map_entry * entries;
+ darray(struct xkb_kt_map_entry) entries;
PreserveInfo *preserve;
unsigned szNames;
xkb_atom_t *lvlNames;
info->dflt.vmask = 0;
info->dflt.groupInfo = false;
info->dflt.numLevels = 1;
- info->dflt.nEntries = info->dflt.szEntries = 0;
- info->dflt.entries = NULL;
+ darray_init(info->dflt.entries);
info->dflt.szNames = 0;
info->dflt.lvlNames = NULL;
info->dflt.preserve = NULL;
if (from != NULL)
{
info->dflt = from->dflt;
- if (from->dflt.entries)
- {
- info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
- struct xkb_kt_map_entry);
- if (info->dflt.entries)
- {
- unsigned sz = from->dflt.nEntries * sizeof(struct xkb_kt_map_entry);
- memcpy(info->dflt.entries, from->dflt.entries, sz);
- }
- }
+
+ darray_init(info->dflt.entries);
+ darray_from_items(info->dflt.entries,
+ &darray_item(from->dflt.entries, 0),
+ darray_size(from->dflt.entries));
+
if (from->dflt.lvlNames)
{
info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, xkb_atom_t);
static void
FreeKeyTypeInfo(KeyTypeInfo * type)
{
- free(type->entries);
- type->entries = NULL;
+ darray_free(type->entries);
+ darray_init(type->entries);
free(type->lvlNames);
type->lvlNames = NULL;
if (type->preserve != NULL)
}
FreeKeyTypeInfo(old);
*old = *new;
- new->szEntries = new->nEntries = 0;
- new->entries = NULL;
+ darray_init(new->entries);
new->preserve = NULL;
new->lvlNames = NULL;
old->defs.next = &next->defs;
return false;
*old = *new;
old->defs.next = NULL;
- new->nEntries = new->szEntries = 0;
- new->entries = NULL;
+ darray_init(new->entries);
new->szNames = 0;
new->lvlNames = NULL;
new->preserve = NULL;
static struct xkb_kt_map_entry *
FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
{
- unsigned int i;
- struct xkb_kt_map_entry * entry;
+ struct xkb_kt_map_entry *entry;
- for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
- {
- if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
+ darray_foreach(entry, type->entries)
+ if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
return entry;
- }
+
return NULL;
}
{
unsigned int i, n;
- for (i = 0; i < type->nEntries; i++)
- {
- if (type->entries[i].level == 0)
- {
- for (n = i; n < type->nEntries - 1; n++)
- {
- type->entries[n] = type->entries[n + 1];
- }
- type->nEntries--;
+ /* TODO: Be just a bit more clever here. */
+ for (i = 0; i < darray_size(type->entries); i++) {
+ if (darray_item(type->entries, i).level == 0) {
+ for (n = i; n < darray_size(type->entries) - 1; n++)
+ darray_item(type->entries, n) =
+ darray_item(type->entries, n + 1);
+ (void)darray_pop(type->entries);
}
}
}
-/**
- * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
- * necessary.
- */
static struct xkb_kt_map_entry *
NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
{
- if (type->entries == NULL)
- {
- type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
- if (type->entries == NULL)
- {
- ERROR("Couldn't allocate map entries for %s\n",
- TypeTxt(keymap, type));
- ACTION("Map entries lost\n");
- return NULL;
- }
- type->szEntries = 2;
- type->nEntries = 0;
- }
- else if (type->nEntries >= type->szEntries)
- {
- type->szEntries *= 2;
- type->entries = uTypedRecalloc(type->entries,
- type->nEntries, type->szEntries,
- struct xkb_kt_map_entry);
- if (type->entries == NULL)
- {
- ERROR("Couldn't reallocate map entries for %s\n",
- TypeTxt(keymap, type));
- ACTION("Map entries lost\n");
- return NULL;
- }
- }
- return &type->entries[type->nEntries++];
+ darray_resize0(type->entries, darray_size(type->entries) + 1);
+ return &darray_item(type->entries, darray_size(type->entries) - 1);
}
static bool
{
unsigned int i;
KeyTypeInfo type;
+ struct xkb_kt_map_entry *entry;
if (def->merge != MergeDefault)
merge = def->merge;
type.vmask = info->dflt.vmask;
type.groupInfo = info->dflt.groupInfo;
type.numLevels = 1;
- type.nEntries = type.szEntries = 0;
- type.entries = NULL;
+ darray_init(type.entries);
type.szNames = 0;
type.lvlNames = NULL;
type.preserve = NULL;
/* now copy any appropriate map, preserve or level names from the */
/* default type */
- for (i = 0; i < info->dflt.nEntries; i++)
- {
- struct xkb_kt_map_entry * dflt;
- dflt = &info->dflt.entries[i];
- if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
- ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
- {
- AddMapEntry(keymap, &type, dflt, false, false);
- }
+ darray_foreach(entry, info->dflt.entries) {
+ if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
+ (entry->mods.vmods & type.vmask) == entry->mods.vmods)
+ AddMapEntry(keymap, &type, entry, false, false);
}
if (info->dflt.preserve)
{
ACTION("Aborting\n");
return false;
}
- pre->matchingMapIndex = match - def->entries;
+ pre->matchingMapIndex = match - &darray_item(def->entries, 0);
}
type->mods.real_mods = def->mask;
type->mods.vmods = def->vmask;
type->num_levels = def->numLevels;
- type->map_count = def->nEntries;
- type->map = def->entries;
+ memcpy(&type->map, &def->entries, sizeof(def->entries));
if (def->preserve)
{
- type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
+ type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
if (!type->preserve)
{
WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
type->level_names = NULL;
}
- def->nEntries = def->szEntries = 0;
- def->entries = NULL;
+ darray_init(def->entries);
return XkbcComputeEffectiveMap(keymap, type, NULL);
}