THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "utils.h"
-#include "xkballoc.h"
-#include "xkbcommon/xkbcommon.h"
-#include "XKBcommonint.h"
-#include <X11/extensions/XKB.h>
+#include "xkb-priv.h"
+#include "alloc.h"
int
-XkbcAllocCompatMap(struct xkb_keymap * xkb, unsigned which, unsigned nSI)
+XkbcAllocClientMap(struct xkb_keymap *keymap, unsigned which,
+ unsigned nTotalTypes)
+{
+ struct xkb_client_map * map;
+
+ 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;
+
+ 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 (!xkb)
+ if (!keymap)
return BadMatch;
- if (xkb->compat) {
- if (xkb->compat->size_si >= nSI)
+ 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;
compat->size_si = nSI;
compat->num_si = 0;
memset(&compat->groups[0], 0, XkbNumKbdGroups * sizeof(struct xkb_mods));
- xkb->compat = compat;
+ keymap->compat = compat;
return Success;
}
static void
-XkbcFreeCompatMap(struct xkb_keymap * xkb)
+XkbcFreeCompatMap(struct xkb_keymap *keymap)
{
struct xkb_compat_map * compat;
- if (!xkb || !xkb->compat)
+ if (!keymap || !keymap->compat)
return;
- compat = xkb->compat;
+ compat = keymap->compat;
free(compat->sym_interpret);
free(compat);
- xkb->compat = NULL;
+ keymap->compat = NULL;
}
int
-XkbcAllocNames(struct xkb_keymap * xkb, unsigned which, unsigned nTotalAliases)
+XkbcAllocNames(struct xkb_keymap *keymap, unsigned which,
+ unsigned nTotalAliases)
{
struct xkb_names * names;
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->names) {
- xkb->names = uTypedCalloc(1, struct xkb_names);
- 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;
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 = uTypedCalloc(type->num_levels, const char *);
if (!type->level_names)
}
if ((which & XkbKeyNamesMask) && !names->keys) {
- if (!xkb_keymap_keycode_range_is_legal(xkb))
- return BadMatch;
-
- names->keys = uTypedCalloc(xkb->max_key_code + 1, struct xkb_key_name);
+ names->keys = uTypedCalloc(keymap->max_key_code + 1,
+ struct xkb_key_name);
if (!names->keys)
return BadAlloc;
}
}
static void
-XkbcFreeNames(struct xkb_keymap * xkb)
+XkbcFreeNames(struct xkb_keymap *keymap)
{
struct xkb_names * names;
struct xkb_client_map * map;
int i;
- if (!xkb || !xkb->names)
+ if (!keymap || !keymap->names)
return;
- names = xkb->names;
- map = xkb->map;
+ names = keymap->names;
+ map = keymap->map;
if (map && map->types) {
struct xkb_key_type * type = map->types;
free(names->keys);
free(names->key_aliases);
free(names);
- xkb->names = NULL;
+ keymap->names = NULL;
}
int
-XkbcAllocControls(struct xkb_keymap * xkb, unsigned which)
+XkbcAllocControls(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->ctrls) {
- xkb->ctrls = uTypedCalloc(1, struct xkb_controls);
- if (!xkb->ctrls)
+ if (!keymap->ctrls) {
+ keymap->ctrls = uTypedCalloc(1, struct xkb_controls);
+ if (!keymap->ctrls)
return BadAlloc;
}
- if (!xkb->ctrls->per_key_repeat) {
- xkb->ctrls->per_key_repeat = uTypedCalloc(xkb->max_key_code << 3,
- unsigned char);
- if (!xkb->ctrls->per_key_repeat)
- 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;
}
static void
-XkbcFreeControls(struct xkb_keymap * xkb)
+XkbcFreeControls(struct xkb_keymap *keymap)
{
- if (xkb && xkb->ctrls) {
- free(xkb->ctrls->per_key_repeat);
- free(xkb->ctrls);
- xkb->ctrls = NULL;
+ if (keymap && keymap->ctrls) {
+ free(keymap->ctrls->per_key_repeat);
+ free(keymap->ctrls);
+ keymap->ctrls = NULL;
}
}
int
-XkbcAllocIndicatorMaps(struct xkb_keymap * xkb)
+XkbcAllocIndicatorMaps(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return BadMatch;
- if (!xkb->indicators) {
- xkb->indicators = uTypedCalloc(1, struct xkb_indicator);
- if (!xkb->indicators)
+ if (!keymap->indicators) {
+ keymap->indicators = uTypedCalloc(1, struct xkb_indicator);
+ if (!keymap->indicators)
return BadAlloc;
}
}
static void
-XkbcFreeIndicatorMaps(struct xkb_keymap * xkb)
+XkbcFreeIndicatorMaps(struct xkb_keymap *keymap)
{
- if (xkb) {
- free(xkb->indicators);
- xkb->indicators = NULL;
+ if (keymap) {
+ free(keymap->indicators);
+ keymap->indicators = NULL;
}
}
struct xkb_keymap *
-XkbcAllocKeyboard(struct xkb_context *context)
+XkbcAllocKeyboard(struct xkb_context *ctx)
{
- struct xkb_keymap *xkb;
+ struct xkb_keymap *keymap;
- xkb = uTypedCalloc(1, struct xkb_keymap);
- if (!xkb)
+ keymap = uTypedCalloc(1, struct xkb_keymap);
+ if (!keymap)
return NULL;
- xkb->refcnt = 1;
- xkb_context_ref(context);
- xkb->context = context;
+ keymap->refcnt = 1;
+ keymap->ctx = xkb_context_ref(ctx);
- return xkb;
+ return keymap;
}
void
-XkbcFreeKeyboard(struct xkb_keymap * xkb)
+XkbcFreeKeyboard(struct xkb_keymap *keymap)
{
- if (!xkb)
+ if (!keymap)
return;
- XkbcFreeClientMap(xkb);
- XkbcFreeServerMap(xkb);
- XkbcFreeCompatMap(xkb);
- XkbcFreeIndicatorMaps(xkb);
- XkbcFreeNames(xkb);
- XkbcFreeControls(xkb);
- xkb_context_unref(xkb->context);
- free(xkb);
+ XkbcFreeClientMap(keymap);
+ XkbcFreeServerMap(keymap);
+ XkbcFreeCompatMap(keymap);
+ XkbcFreeIndicatorMaps(keymap);
+ XkbcFreeNames(keymap);
+ XkbcFreeControls(keymap);
+ xkb_context_unref(keymap->ctx);
+ free(keymap);
}