THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "xkballoc.h"
-#include "xkbgeom.h"
-#include "X11/extensions/XKBcommon.h"
-#include "XKBcommonint.h"
-#include <X11/extensions/XKB.h>
+#include "xkb-priv.h"
+#include "alloc.h"
int
-XkbcAllocCompatMap(XkbcDescPtr xkb, unsigned which, unsigned nSI)
+XkbcAllocClientMap(struct xkb_keymap *keymap, unsigned which,
+ unsigned nTotalTypes)
{
- XkbCompatMapPtr compat;
- XkbSymInterpretRec *prev_interpret;
+ struct xkb_client_map * map;
- if (!xkb)
+ if (!keymap || ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes)))
+ return BadValue;
+
+ if (!keymap->map) {
+ map = uTypedCalloc(1, struct xkb_client_map);
+ if (!map)
+ return BadAlloc;
+ keymap->map = map;
+ }
+ else
+ map = keymap->map;
+
+ if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) {
+ if (!map->types) {
+ map->types = uTypedCalloc(nTotalTypes, struct xkb_key_type);
+ if (!map->types)
+ return BadAlloc;
+
+ map->num_types = 0;
+ map->size_types = nTotalTypes;
+ }
+ else if (map->size_types < nTotalTypes) {
+ struct xkb_key_type *prev_types = map->types;
+
+ map->types = uTypedRealloc(map->types, nTotalTypes,
+ struct xkb_key_type);
+ if (!map->types) {
+ free(prev_types);
+ map->num_types = map->size_types = 0;
+ return BadAlloc;
+ }
+
+ map->size_types = nTotalTypes;
+ memset(&map->types[map->num_types], 0,
+ (map->size_types - map->num_types) * sizeof(struct xkb_key_type));
+ }
+ }
+
+ if (which & XkbKeySymsMask) {
+ if (!map->key_sym_map) {
+ map->key_sym_map = uTypedCalloc(keymap->max_key_code + 1,
+ struct xkb_sym_map);
+ if (!map->key_sym_map)
+ return BadAlloc;
+ }
+ }
+
+ if (which & XkbModifierMapMask) {
+ if (!map->modmap) {
+ map->modmap = uTypedCalloc(keymap->max_key_code + 1,
+ unsigned char);
+ if (!map->modmap)
+ return BadAlloc;
+ }
+ }
+
+ return Success;
+}
+
+int
+XkbcAllocServerMap(struct xkb_keymap *keymap, unsigned which,
+ unsigned nNewActions)
+{
+ unsigned i;
+ struct xkb_server_map * map;
+
+ if (!keymap)
+ return BadMatch;
+
+ if (!keymap->server) {
+ map = uTypedCalloc(1, struct xkb_server_map);
+ if (!map)
+ return BadAlloc;
+
+ for (i = 0; i < XkbNumVirtualMods; i++)
+ map->vmods[i] = XkbNoModifierMask;
+
+ keymap->server = map;
+ }
+ else
+ map = keymap->server;
+
+ if (!which)
+ return Success;
+
+ if (!map->explicit) {
+ i = keymap->max_key_code + 1;
+ map->explicit = uTypedCalloc(i, unsigned char);
+ if (!map->explicit)
+ return BadAlloc;
+ }
+
+ if (nNewActions < 1)
+ nNewActions = 1;
+
+ if (!map->acts) {
+ map->acts = uTypedCalloc(nNewActions + 1, union xkb_action);
+ if (!map->acts)
+ return BadAlloc;
+ map->num_acts = 1;
+ map->size_acts = nNewActions + 1;
+ }
+ else if ((map->size_acts - map->num_acts) < (int)nNewActions) {
+ unsigned need;
+ union xkb_action *prev_acts = map->acts;
+
+ need = map->num_acts + nNewActions;
+ map->acts = uTypedRealloc(map->acts, need, union xkb_action);
+ if (!map->acts) {
+ free(prev_acts);
+ map->num_acts = map->size_acts = 0;
+ return BadAlloc;
+ }
+
+ map->size_acts = need;
+ memset(&map->acts[map->num_acts], 0,
+ (map->size_acts - map->num_acts) * sizeof(union xkb_action));
+ }
+
+ if (!map->key_acts) {
+ i = keymap->max_key_code + 1;
+ map->key_acts = uTypedCalloc(i, unsigned short);
+ if (!map->key_acts)
+ return BadAlloc;
+ }
+
+ if (!map->behaviors) {
+ i = keymap->max_key_code + 1;
+ map->behaviors = uTypedCalloc(i, struct xkb_behavior);
+ if (!map->behaviors)
+ return BadAlloc;
+ }
+
+ if (!map->vmodmap) {
+ i = keymap->max_key_code + 1;
+ map->vmodmap = uTypedCalloc(i, uint32_t);
+ if (!map->vmodmap)
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+int
+XkbcCopyKeyType(struct xkb_key_type * from, struct xkb_key_type * into)
+{
+ int i;
+
+ if (!from || !into)
return BadMatch;
- if (xkb->compat) {
- if (xkb->compat->size_si >= nSI)
+ free(into->map);
+ into->map = NULL;
+ 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));
+ }
+
+ if (from->preserve && (into->map_count > 0)) {
+ into->preserve = uTypedCalloc(into->map_count, struct xkb_mods);
+ if (!into->preserve)
+ return BadAlloc;
+ memcpy(into->preserve, from->preserve,
+ into->map_count * sizeof(struct xkb_mods));
+ }
+
+ if (from->level_names && (into->num_levels > 0)) {
+ into->level_names = uTypedCalloc(into->num_levels, const char *);
+ if (!into->level_names)
+ return BadAlloc;
+ for (i = 0; i < into->num_levels; i++)
+ into->level_names[i] = strdup(from->level_names[i]);
+ }
+
+ return Success;
+}
+
+bool
+XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t key,
+ unsigned int needed)
+{
+ if (keymap->map->key_sym_map[key].size_syms >= needed)
+ return true;
+
+ keymap->map->key_sym_map[key].syms =
+ uTypedRecalloc(keymap->map->key_sym_map[key].syms,
+ keymap->map->key_sym_map[key].size_syms,
+ needed,
+ xkb_keysym_t);
+ if (!keymap->map->key_sym_map[key].syms) {
+ keymap->map->key_sym_map[key].size_syms = 0;
+ return false;
+ }
+ keymap->map->key_sym_map[key].size_syms = needed;
+
+ return true;
+}
+
+union xkb_action *
+XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t key,
+ uint32_t needed)
+{
+ xkb_keycode_t i, nActs;
+ union xkb_action *newActs;
+
+ if (needed == 0) {
+ keymap->server->key_acts[key] = 0;
+ return NULL;
+ }
+
+ if (XkbKeyHasActions(keymap, key) &&
+ (XkbKeyGroupsWidth(keymap, key) >= needed))
+ return XkbKeyActionsPtr(keymap, key);
+
+ if (keymap->server->size_acts - keymap->server->num_acts >= (int)needed) {
+ keymap->server->key_acts[key] = keymap->server->num_acts;
+ keymap->server->num_acts += needed;
+
+ return &keymap->server->acts[keymap->server->key_acts[key]];
+ }
+
+ keymap->server->size_acts = keymap->server->num_acts + needed + 8;
+ newActs = uTypedCalloc(keymap->server->size_acts, union xkb_action);
+ if (!newActs)
+ return NULL;
+ newActs[0].type = XkbSA_NoAction;
+ nActs = 1;
+
+ for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
+ xkb_keycode_t nKeyActs, nCopy;
+
+ if ((keymap->server->key_acts[i] == 0) && (i != key))
+ continue;
+
+ nCopy = nKeyActs = XkbKeyNumActions(keymap, i);
+ if (i == key) {
+ nKeyActs= needed;
+ if (needed < nCopy)
+ nCopy = needed;
+ }
+
+ if (nCopy > 0)
+ memcpy(&newActs[nActs], XkbKeyActionsPtr(keymap, i),
+ nCopy * sizeof(union xkb_action));
+ if (nCopy < nKeyActs)
+ memset(&newActs[nActs + nCopy], 0,
+ (nKeyActs - nCopy) * sizeof(union xkb_action));
+
+ keymap->server->key_acts[i] = nActs;
+ nActs += nKeyActs;
+ }
+
+ free(keymap->server->acts);
+ keymap->server->acts = newActs;
+ keymap->server->num_acts = nActs;
+
+ return &keymap->server->acts[keymap->server->key_acts[key]];
+}
+
+void
+XkbcFreeClientMap(struct xkb_keymap *keymap)
+{
+ struct xkb_client_map * map;
+ struct xkb_key_type * type;
+ xkb_keycode_t key;
+ int i;
+
+ if (!keymap || !keymap->map)
+ return;
+
+ map = keymap->map;
+
+ for (i = 0, type = map->types; i < map->num_types && type; i++, type++) {
+ int j;
+ free(type->map);
+ free(type->preserve);
+ for (j = 0; j < type->num_levels; j++)
+ free(UNCONSTIFY(type->level_names[j]));
+ free(type->level_names);
+ free(UNCONSTIFY(type->name));
+ }
+ free(map->types);
+
+ if (map->key_sym_map) {
+ for (key = keymap->min_key_code; key < keymap->max_key_code; key++) {
+ free(map->key_sym_map[key].sym_index);
+ free(map->key_sym_map[key].num_syms);
+ free(map->key_sym_map[key].syms);
+ }
+ }
+ free(map->key_sym_map);
+
+ free(map->modmap);
+ free(keymap->map);
+ keymap->map = NULL;
+}
+
+void
+XkbcFreeServerMap(struct xkb_keymap *keymap)
+{
+ struct xkb_server_map * map;
+
+ if (!keymap || !keymap->server)
+ return;
+
+ map = keymap->server;
+
+ free(map->explicit);
+ free(map->key_acts);
+ free(map->acts);
+ free(map->behaviors);
+ free(map->vmodmap);
+ free(keymap->server);
+ keymap->server = NULL;
+}
+
+int
+XkbcAllocCompatMap(struct xkb_keymap *keymap, unsigned nSI)
+{
+ struct xkb_compat_map * compat;
+ struct xkb_sym_interpret *prev_interpret;
+
+ if (!keymap)
+ return BadMatch;
+
+ if (keymap->compat) {
+ if (keymap->compat->size_si >= nSI)
return Success;
- compat = xkb->compat;
+ compat = keymap->compat;
compat->size_si = nSI;
if (!compat->sym_interpret)
compat->num_si = 0;
prev_interpret = compat->sym_interpret;
- compat->sym_interpret = _XkbTypedRealloc(compat->sym_interpret,
- nSI, XkbSymInterpretRec);
+ compat->sym_interpret = uTypedRecalloc(compat->sym_interpret,
+ compat->num_si, nSI,
+ struct xkb_sym_interpret);
if (!compat->sym_interpret) {
- _XkbFree(prev_interpret);
+ free(prev_interpret);
compat->size_si = compat->num_si = 0;
return BadAlloc;
}
- if (compat->num_si != 0)
- _XkbClearElems(compat->sym_interpret, compat->num_si,
- compat->size_si - 1, XkbSymInterpretRec);
-
return Success;
}
- compat = _XkbTypedCalloc(1, XkbCompatMapRec);
+ compat = uTypedCalloc(1, struct xkb_compat_map);
if (!compat)
return BadAlloc;
if (nSI > 0) {
- compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec);
+ compat->sym_interpret = uTypedCalloc(nSI, struct xkb_sym_interpret);
if (!compat->sym_interpret) {
- _XkbFree(compat);
+ free(compat);
return BadAlloc;
}
}
compat->size_si = nSI;
compat->num_si = 0;
- bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec));
- xkb->compat = compat;
+ memset(&compat->groups[0], 0, XkbNumKbdGroups * sizeof(struct xkb_mods));
+ keymap->compat = compat;
return Success;
}
-void
-XkbcFreeCompatMap(XkbcDescPtr xkb, unsigned which, Bool freeMap)
+static void
+XkbcFreeCompatMap(struct xkb_keymap *keymap)
{
- XkbCompatMapPtr compat;
+ struct xkb_compat_map * compat;
- if (!xkb || !xkb->compat)
+ if (!keymap || !keymap->compat)
return;
- compat = xkb->compat;
- if (freeMap)
- which = XkbAllCompatMask;
+ compat = keymap->compat;
- if (which & XkbGroupCompatMask)
- bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec));
-
- if (which & XkbSymInterpMask) {
- if (compat->sym_interpret && (compat->size_si > 0))
- _XkbFree(compat->sym_interpret);
- compat->size_si = compat->num_si = 0;
- compat->sym_interpret = NULL;
- }
-
- if (freeMap) {
- _XkbFree(compat);
- xkb->compat = NULL;
- }
+ free(compat->sym_interpret);
+ free(compat);
+ keymap->compat = NULL;
}
int
-XkbcAllocNames(XkbcDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
+XkbcAllocNames(struct xkb_keymap *keymap, unsigned which,
+ unsigned nTotalAliases)
{
- XkbNamesPtr names;
+ struct xkb_names * names;
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->names) {
- xkb->names = _XkbTypedCalloc(1, XkbNamesRec);
- if (!xkb->names)
+ if (!keymap->names) {
+ keymap->names = uTypedCalloc(1, struct xkb_names);
+ if (!keymap->names)
return BadAlloc;
}
- names = xkb->names;
+ names = keymap->names;
- if ((which & XkbKTLevelNamesMask) && xkb->map && xkb->map->types) {
+ if ((which & XkbKTLevelNamesMask) && keymap->map && keymap->map->types) {
int i;
- XkbKeyTypePtr type;
+ struct xkb_key_type * type;
- type = xkb->map->types;
- for (i = 0; i < xkb->map->num_types; i++, type++) {
+ type = keymap->map->types;
+ for (i = 0; i < keymap->map->num_types; i++, type++) {
if (!type->level_names) {
- type->level_names = _XkbTypedCalloc(type->num_levels, Atom);
+ type->level_names = uTypedCalloc(type->num_levels, const char *);
if (!type->level_names)
return BadAlloc;
}
}
if ((which & XkbKeyNamesMask) && !names->keys) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
- (!XkbIsLegalKeycode(xkb->max_key_code)) ||
- (xkb->max_key_code < xkb->min_key_code))
- return BadValue;
-
- names->keys = _XkbTypedCalloc(xkb->max_key_code + 1, XkbKeyNameRec);
+ names->keys = uTypedCalloc(keymap->max_key_code + 1,
+ struct xkb_key_name);
if (!names->keys)
return BadAlloc;
}
if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
if (!names->key_aliases)
- names->key_aliases = _XkbTypedCalloc(nTotalAliases,
- XkbKeyAliasRec);
+ names->key_aliases = uTypedCalloc(nTotalAliases,
+ struct xkb_key_alias);
else if (nTotalAliases > names->num_key_aliases) {
- XkbKeyAliasRec *prev_aliases = names->key_aliases;
-
- names->key_aliases = _XkbTypedRealloc(names->key_aliases,
- nTotalAliases,
- XkbKeyAliasRec);
- if (names->key_aliases)
- _XkbClearElems(names->key_aliases, names->num_key_aliases,
- nTotalAliases - 1, XkbKeyAliasRec);
- else
- _XkbFree(prev_aliases);
+ struct xkb_key_alias *prev_aliases = names->key_aliases;
+
+ names->key_aliases = uTypedRecalloc(names->key_aliases,
+ names->num_key_aliases,
+ nTotalAliases,
+ struct xkb_key_alias);
+ if (!names->key_aliases)
+ free(prev_aliases);
}
if (!names->key_aliases) {
names->num_key_aliases = nTotalAliases;
}
- if ((which & XkbRGNamesMask) && (nTotalRG > 0)) {
- if (!names->radio_groups)
- names->radio_groups = _XkbTypedCalloc(nTotalRG, Atom);
- else if (nTotalRG > names->num_rg) {
- Atom *prev_radio_groups = names->radio_groups;
-
- names->radio_groups = _XkbTypedRealloc(names->radio_groups,
- nTotalRG, Atom);
- if (names->radio_groups)
- _XkbClearElems(names->radio_groups, names->num_rg,
- nTotalRG - 1, Atom);
- else
- _XkbFree(prev_radio_groups);
- }
-
- if (!names->radio_groups)
- return BadAlloc;
-
- names->num_rg = nTotalRG;
- }
-
return Success;
}
-void
-XkbcFreeNames(XkbcDescPtr xkb, unsigned which, Bool freeMap)
+static void
+XkbcFreeNames(struct xkb_keymap *keymap)
{
- XkbNamesPtr names;
+ struct xkb_names * names;
+ struct xkb_client_map * map;
+ int i;
- if (!xkb || !xkb->names)
+ if (!keymap || !keymap->names)
return;
- names = xkb->names;
- if (freeMap)
- which = XkbAllNamesMask;
+ names = keymap->names;
+ map = keymap->map;
- if (which & XkbKTLevelNamesMask) {
- XkbClientMapPtr map = xkb->map;
+ if (map && map->types) {
+ struct xkb_key_type * type = map->types;
- if (map && map->types) {
- int i;
- XkbKeyTypePtr type = map->types;
-
- for (i = 0; i < map->num_types; i++, type++) {
- if (type->level_names) {
- _XkbFree(type->level_names);
- type->level_names = NULL;
- }
- }
+ for (i = 0; i < map->num_types; i++, type++) {
+ int j;
+ for (j = 0; j < type->num_levels; j++)
+ free(UNCONSTIFY(type->level_names[i]));
+ free(type->level_names);
+ type->level_names = NULL;
}
}
- if ((which & XkbKeyNamesMask) && names->keys) {
- _XkbFree(names->keys);
- names->keys = NULL;
- names->num_keys = 0;
- }
-
- if ((which & XkbKeyAliasesMask) && names->key_aliases) {
- _XkbFree(names->key_aliases);
- names->key_aliases = NULL;
- names->num_key_aliases = 0;
- }
-
- if ((which & XkbRGNamesMask) && names->radio_groups) {
- _XkbFree(names->radio_groups);
- names->radio_groups = NULL;
- names->num_rg = 0;
- }
-
- if (freeMap) {
- _XkbFree(names);
- xkb->names = NULL;
- }
+ for (i = 0; i < XkbNumVirtualMods; i++)
+ free(UNCONSTIFY(names->vmods[i]));
+ for (i = 0; i < XkbNumIndicators; i++)
+ free(UNCONSTIFY(names->indicators[i]));
+ for (i = 0; i < XkbNumKbdGroups; i++)
+ free(UNCONSTIFY(names->groups[i]));
+
+ free(names->keys);
+ free(names->key_aliases);
+ free(names);
+ keymap->names = NULL;
}
int
-XkbcAllocControls(XkbcDescPtr xkb, unsigned which)
+XkbcAllocControls(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->ctrls) {
- xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec);
- if (!xkb->ctrls)
+ if (!keymap->ctrls) {
+ keymap->ctrls = uTypedCalloc(1, struct xkb_controls);
+ if (!keymap->ctrls)
return BadAlloc;
}
+ keymap->ctrls->per_key_repeat = uTypedCalloc(keymap->max_key_code >> 3,
+ unsigned char);
+ if (!keymap->ctrls->per_key_repeat)
+ return BadAlloc;
+
return Success;
}
-void
-XkbcFreeControls(XkbcDescPtr xkb, unsigned which, Bool freeMap)
+static void
+XkbcFreeControls(struct xkb_keymap *keymap)
{
- if (freeMap && xkb && xkb->ctrls) {
- _XkbFree(xkb->ctrls);
- xkb->ctrls = NULL;
+ if (keymap && keymap->ctrls) {
+ free(keymap->ctrls->per_key_repeat);
+ free(keymap->ctrls);
+ keymap->ctrls = NULL;
}
}
int
-XkbcAllocIndicatorMaps(XkbcDescPtr xkb)
+XkbcAllocIndicatorMaps(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->indicators) {
- xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec);
- if (!xkb->indicators)
+ if (!keymap->indicators) {
+ keymap->indicators = uTypedCalloc(1, struct xkb_indicator);
+ if (!keymap->indicators)
return BadAlloc;
}
return Success;
}
-void
-XkbcFreeIndicatorMaps(XkbcDescPtr xkb)
+static void
+XkbcFreeIndicatorMaps(struct xkb_keymap *keymap)
{
- if (xkb && xkb->indicators) {
- _XkbFree(xkb->indicators);
- xkb->indicators = NULL;
+ if (keymap) {
+ free(keymap->indicators);
+ keymap->indicators = NULL;
}
}
-XkbcDescRec *
-XkbcAllocKeyboard(void)
+struct xkb_keymap *
+XkbcAllocKeyboard(struct xkb_context *ctx)
{
- XkbcDescRec *xkb;
+ struct xkb_keymap *keymap;
+
+ keymap = uTypedCalloc(1, struct xkb_keymap);
+ if (!keymap)
+ return NULL;
+
+ keymap->refcnt = 1;
+ keymap->ctx = xkb_context_ref(ctx);
- xkb = _XkbTypedCalloc(1, XkbcDescRec);
- if (xkb)
- xkb->device_spec = XkbUseCoreKbd;
- return xkb;
+ return keymap;
}
void
-XkbcFreeKeyboard(XkbcDescPtr xkb, unsigned which, Bool freeAll)
+XkbcFreeKeyboard(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return;
- if (freeAll)
- which = XkbAllComponentsMask;
-
- if (which & XkbClientMapMask)
- XkbcFreeClientMap(xkb, XkbAllClientInfoMask, True);
- if (which & XkbServerMapMask)
- XkbcFreeServerMap(xkb, XkbAllServerInfoMask, True);
- if (which & XkbCompatMapMask)
- XkbcFreeCompatMap(xkb, XkbAllCompatMask, True);
- if (which & XkbIndicatorMapMask)
- XkbcFreeIndicatorMaps(xkb);
- if (which & XkbNamesMask)
- XkbcFreeNames(xkb, XkbAllNamesMask, True);
- if ((which & XkbGeometryMask) && xkb->geom)
- XkbcFreeGeometry(xkb->geom, XkbGeomAllMask, True);
- if (which & XkbControlsMask)
- XkbcFreeControls(xkb, XkbAllControlsMask, True);
- if (freeAll)
- _XkbFree(xkb);
+ XkbcFreeClientMap(keymap);
+ XkbcFreeServerMap(keymap);
+ XkbcFreeCompatMap(keymap);
+ XkbcFreeIndicatorMaps(keymap);
+ XkbcFreeNames(keymap);
+ XkbcFreeControls(keymap);
+ xkb_context_unref(keymap->ctx);
+ free(keymap);
}