2009-03-19 17:57:01 -06:00
|
|
|
/*
|
|
|
|
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and distribute this
|
|
|
|
software and its documentation for any purpose and without
|
|
|
|
fee is hereby granted, provided that the above copyright
|
|
|
|
notice appear in all copies and that both that copyright
|
|
|
|
notice and this permission notice appear in supporting
|
|
|
|
documentation, and that the name of Silicon Graphics not be
|
|
|
|
used in advertising or publicity pertaining to distribution
|
|
|
|
of the software without specific prior written permission.
|
|
|
|
Silicon Graphics makes no representation about the suitability
|
|
|
|
of this software for any purpose. It is provided "as is"
|
|
|
|
without any express or implied warranty.
|
|
|
|
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
|
|
|
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
|
|
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
|
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2012-05-08 05:52:23 -06:00
|
|
|
#include "xkb-priv.h"
|
|
|
|
#include "alloc.h"
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
int
|
|
|
|
XkbcAllocClientMap(struct xkb_keymap * xkb, unsigned which, unsigned nTotalTypes)
|
|
|
|
{
|
|
|
|
struct xkb_client_map * map;
|
|
|
|
|
|
|
|
if (!xkb || ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes)))
|
|
|
|
return BadValue;
|
|
|
|
|
|
|
|
if ((which & XkbKeySymsMask) && !xkb_keymap_keycode_range_is_legal(xkb)) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n",
|
|
|
|
xkb->min_key_code, xkb->max_key_code);
|
|
|
|
#endif
|
|
|
|
return BadValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!xkb->map) {
|
|
|
|
map = uTypedCalloc(1, struct xkb_client_map);
|
|
|
|
if (!map)
|
|
|
|
return BadAlloc;
|
|
|
|
xkb->map = map;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
map = xkb->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(xkb->max_key_code + 1,
|
|
|
|
struct xkb_sym_map);
|
|
|
|
if (!map->key_sym_map)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (which & XkbModifierMapMask) {
|
|
|
|
if (!map->modmap) {
|
|
|
|
map->modmap = uTypedCalloc(xkb->max_key_code + 1, unsigned char);
|
|
|
|
if (!map->modmap)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
XkbcAllocServerMap(struct xkb_keymap * xkb, unsigned which, unsigned nNewActions)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
struct xkb_server_map * map;
|
|
|
|
|
|
|
|
if (!xkb)
|
|
|
|
return BadMatch;
|
|
|
|
|
|
|
|
if (!xkb->server) {
|
|
|
|
map = uTypedCalloc(1, struct xkb_server_map);
|
|
|
|
if (!map)
|
|
|
|
return BadAlloc;
|
|
|
|
|
|
|
|
for (i = 0; i < XkbNumVirtualMods; i++)
|
|
|
|
map->vmods[i] = XkbNoModifierMask;
|
|
|
|
|
|
|
|
xkb->server = map;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
map = xkb->server;
|
|
|
|
|
|
|
|
if (!which)
|
|
|
|
return Success;
|
|
|
|
|
|
|
|
if (!xkb_keymap_keycode_range_is_legal(xkb))
|
|
|
|
return BadMatch;
|
|
|
|
|
|
|
|
if (!map->explicit) {
|
|
|
|
i = xkb->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 = xkb->max_key_code + 1;
|
|
|
|
map->key_acts = uTypedCalloc(i, unsigned short);
|
|
|
|
if (!map->key_acts)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!map->behaviors) {
|
|
|
|
i = xkb->max_key_code + 1;
|
|
|
|
map->behaviors = uTypedCalloc(i, struct xkb_behavior);
|
|
|
|
if (!map->behaviors)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!map->vmodmap) {
|
|
|
|
i = xkb->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 * xkb, xkb_keycode_t key,
|
|
|
|
unsigned int needed)
|
|
|
|
{
|
|
|
|
if (xkb->map->key_sym_map[key].size_syms >= needed)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
xkb->map->key_sym_map[key].syms =
|
|
|
|
uTypedRecalloc(xkb->map->key_sym_map[key].syms,
|
|
|
|
xkb->map->key_sym_map[key].size_syms,
|
|
|
|
needed,
|
|
|
|
xkb_keysym_t);
|
|
|
|
if (!xkb->map->key_sym_map[key].syms) {
|
|
|
|
xkb->map->key_sym_map[key].size_syms = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
xkb->map->key_sym_map[key].size_syms = needed;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
union xkb_action *
|
|
|
|
XkbcResizeKeyActions(struct xkb_keymap * xkb, xkb_keycode_t key, uint32_t needed)
|
|
|
|
{
|
|
|
|
xkb_keycode_t i, nActs;
|
|
|
|
union xkb_action *newActs;
|
|
|
|
|
|
|
|
if (needed == 0) {
|
|
|
|
xkb->server->key_acts[key] = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (XkbKeyHasActions(xkb, key) &&
|
|
|
|
(XkbKeyGroupsWidth(xkb, key) >= needed))
|
|
|
|
return XkbKeyActionsPtr(xkb, key);
|
|
|
|
|
|
|
|
if (xkb->server->size_acts - xkb->server->num_acts >= (int)needed) {
|
|
|
|
xkb->server->key_acts[key] = xkb->server->num_acts;
|
|
|
|
xkb->server->num_acts += needed;
|
|
|
|
|
|
|
|
return &xkb->server->acts[xkb->server->key_acts[key]];
|
|
|
|
}
|
|
|
|
|
|
|
|
xkb->server->size_acts = xkb->server->num_acts + needed + 8;
|
|
|
|
newActs = uTypedCalloc(xkb->server->size_acts, union xkb_action);
|
|
|
|
if (!newActs)
|
|
|
|
return NULL;
|
|
|
|
newActs[0].type = XkbSA_NoAction;
|
|
|
|
nActs = 1;
|
|
|
|
|
|
|
|
for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
|
|
|
|
xkb_keycode_t nKeyActs, nCopy;
|
|
|
|
|
|
|
|
if ((xkb->server->key_acts[i] == 0) && (i != key))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nCopy = nKeyActs = XkbKeyNumActions(xkb, i);
|
|
|
|
if (i == key) {
|
|
|
|
nKeyActs= needed;
|
|
|
|
if (needed < nCopy)
|
|
|
|
nCopy = needed;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nCopy > 0)
|
|
|
|
memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i),
|
|
|
|
nCopy * sizeof(union xkb_action));
|
|
|
|
if (nCopy < nKeyActs)
|
|
|
|
memset(&newActs[nActs + nCopy], 0,
|
|
|
|
(nKeyActs - nCopy) * sizeof(union xkb_action));
|
|
|
|
|
|
|
|
xkb->server->key_acts[i] = nActs;
|
|
|
|
nActs += nKeyActs;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(xkb->server->acts);
|
|
|
|
xkb->server->acts = newActs;
|
|
|
|
xkb->server->num_acts = nActs;
|
|
|
|
|
|
|
|
return &xkb->server->acts[xkb->server->key_acts[key]];
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
XkbcFreeClientMap(struct xkb_keymap * xkb)
|
|
|
|
{
|
|
|
|
struct xkb_client_map * map;
|
|
|
|
struct xkb_key_type * type;
|
|
|
|
xkb_keycode_t key;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!xkb || !xkb->map)
|
|
|
|
return;
|
|
|
|
|
|
|
|
map = xkb->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 = xkb->min_key_code; key < xkb->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(xkb->map);
|
|
|
|
xkb->map = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
XkbcFreeServerMap(struct xkb_keymap * xkb)
|
|
|
|
{
|
|
|
|
struct xkb_server_map * map;
|
|
|
|
|
|
|
|
if (!xkb || !xkb->server)
|
|
|
|
return;
|
|
|
|
|
|
|
|
map = xkb->server;
|
|
|
|
|
|
|
|
free(map->explicit);
|
|
|
|
free(map->key_acts);
|
|
|
|
free(map->acts);
|
|
|
|
free(map->behaviors);
|
|
|
|
free(map->vmodmap);
|
|
|
|
free(xkb->server);
|
|
|
|
xkb->server = NULL;
|
|
|
|
}
|
2009-03-19 17:57:01 -06:00
|
|
|
|
|
|
|
int
|
2012-04-10 16:55:50 -06:00
|
|
|
XkbcAllocCompatMap(struct xkb_keymap *xkb, unsigned nSI)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_compat_map * compat;
|
|
|
|
struct xkb_sym_interpret *prev_interpret;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
|
|
|
if (!xkb)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadMatch;
|
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
if (xkb->compat) {
|
2009-03-25 16:41:21 -06:00
|
|
|
if (xkb->compat->size_si >= nSI)
|
|
|
|
return Success;
|
|
|
|
|
|
|
|
compat = xkb->compat;
|
|
|
|
compat->size_si = nSI;
|
|
|
|
if (!compat->sym_interpret)
|
|
|
|
compat->num_si = 0;
|
|
|
|
|
|
|
|
prev_interpret = compat->sym_interpret;
|
2012-03-23 16:12:08 -06:00
|
|
|
compat->sym_interpret = uTypedRecalloc(compat->sym_interpret,
|
|
|
|
compat->num_si, nSI,
|
|
|
|
struct xkb_sym_interpret);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!compat->sym_interpret) {
|
2010-06-30 14:56:24 -06:00
|
|
|
free(prev_interpret);
|
2009-03-25 16:41:21 -06:00
|
|
|
compat->size_si = compat->num_si = 0;
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-23 16:12:08 -06:00
|
|
|
compat = uTypedCalloc(1, struct xkb_compat_map);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!compat)
|
|
|
|
return BadAlloc;
|
|
|
|
|
|
|
|
if (nSI > 0) {
|
2012-03-23 16:12:08 -06:00
|
|
|
compat->sym_interpret = uTypedCalloc(nSI, struct xkb_sym_interpret);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!compat->sym_interpret) {
|
2010-06-30 14:56:24 -06:00
|
|
|
free(compat);
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
compat->size_si = nSI;
|
|
|
|
compat->num_si = 0;
|
2012-02-29 11:50:17 -07:00
|
|
|
memset(&compat->groups[0], 0, XkbNumKbdGroups * sizeof(struct xkb_mods));
|
2009-03-25 16:41:21 -06:00
|
|
|
xkb->compat = compat;
|
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-27 14:05:52 -06:00
|
|
|
static void
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcFreeCompatMap(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_compat_map * compat;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb || !xkb->compat)
|
|
|
|
return;
|
|
|
|
|
|
|
|
compat = xkb->compat;
|
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
free(compat->sym_interpret);
|
|
|
|
free(compat);
|
|
|
|
xkb->compat = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcAllocNames(struct xkb_keymap * xkb, unsigned which, unsigned nTotalAliases)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_names * names;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
|
|
|
if (!xkb)
|
|
|
|
return BadMatch;
|
|
|
|
|
|
|
|
if (!xkb->names) {
|
2012-03-23 16:12:08 -06:00
|
|
|
xkb->names = uTypedCalloc(1, struct xkb_names);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb->names)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
names = xkb->names;
|
|
|
|
|
|
|
|
if ((which & XkbKTLevelNamesMask) && xkb->map && xkb->map->types) {
|
|
|
|
int i;
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_key_type * type;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
|
|
|
type = xkb->map->types;
|
|
|
|
for (i = 0; i < xkb->map->num_types; i++, type++) {
|
|
|
|
if (!type->level_names) {
|
2012-03-23 16:12:08 -06:00
|
|
|
type->level_names = uTypedCalloc(type->num_levels, const char *);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!type->level_names)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-04 09:52:17 -06:00
|
|
|
if ((which & XkbKeyNamesMask) && !names->keys) {
|
2012-02-15 07:34:08 -07:00
|
|
|
if (!xkb_keymap_keycode_range_is_legal(xkb))
|
|
|
|
return BadMatch;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-23 16:12:08 -06:00
|
|
|
names->keys = uTypedCalloc(xkb->max_key_code + 1, struct xkb_key_name);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!names->keys)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
|
|
|
|
if (!names->key_aliases)
|
2012-03-23 16:12:08 -06:00
|
|
|
names->key_aliases = uTypedCalloc(nTotalAliases,
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_key_alias);
|
2009-03-25 16:41:21 -06:00
|
|
|
else if (nTotalAliases > names->num_key_aliases) {
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_key_alias *prev_aliases = names->key_aliases;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-23 16:12:08 -06:00
|
|
|
names->key_aliases = uTypedRecalloc(names->key_aliases,
|
|
|
|
names->num_key_aliases,
|
|
|
|
nTotalAliases,
|
|
|
|
struct xkb_key_alias);
|
|
|
|
if (!names->key_aliases)
|
2010-06-30 14:56:24 -06:00
|
|
|
free(prev_aliases);
|
2009-03-25 16:41:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!names->key_aliases) {
|
|
|
|
names->num_key_aliases = 0;
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
names->num_key_aliases = nTotalAliases;
|
|
|
|
}
|
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2010-09-27 14:05:52 -06:00
|
|
|
static void
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcFreeNames(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_names * names;
|
2012-03-02 06:56:03 -07:00
|
|
|
struct xkb_client_map * map;
|
2012-03-09 11:53:47 -07:00
|
|
|
int i;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
|
|
|
if (!xkb || !xkb->names)
|
|
|
|
return;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2009-03-25 16:41:21 -06:00
|
|
|
names = xkb->names;
|
2012-03-02 06:56:03 -07:00
|
|
|
map = xkb->map;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
if (map && map->types) {
|
|
|
|
struct xkb_key_type * type = map->types;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
for (i = 0; i < map->num_types; i++, type++) {
|
2012-03-09 11:53:47 -07:00
|
|
|
int j;
|
|
|
|
for (j = 0; j < type->num_levels; j++)
|
2012-03-23 16:29:33 -06:00
|
|
|
free(UNCONSTIFY(type->level_names[i]));
|
2012-03-02 06:56:03 -07:00
|
|
|
free(type->level_names);
|
|
|
|
type->level_names = NULL;
|
2009-03-25 16:41:21 -06:00
|
|
|
}
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-09 11:53:47 -07:00
|
|
|
for (i = 0; i < XkbNumVirtualMods; i++)
|
2012-03-23 16:29:33 -06:00
|
|
|
free(UNCONSTIFY(names->vmods[i]));
|
2012-03-09 11:53:47 -07:00
|
|
|
for (i = 0; i < XkbNumIndicators; i++)
|
2012-03-23 16:29:33 -06:00
|
|
|
free(UNCONSTIFY(names->indicators[i]));
|
2012-03-09 11:53:47 -07:00
|
|
|
for (i = 0; i < XkbNumKbdGroups; i++)
|
2012-03-23 16:29:33 -06:00
|
|
|
free(UNCONSTIFY(names->groups[i]));
|
2012-03-09 11:53:47 -07:00
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
free(names->keys);
|
|
|
|
free(names->key_aliases);
|
|
|
|
free(names);
|
|
|
|
xkb->names = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-04-10 16:55:50 -06:00
|
|
|
XkbcAllocControls(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb)
|
|
|
|
return BadMatch;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb->ctrls) {
|
2012-03-23 16:12:08 -06:00
|
|
|
xkb->ctrls = uTypedCalloc(1, struct xkb_controls);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb->ctrls)
|
|
|
|
return BadAlloc;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-04-10 16:55:50 -06:00
|
|
|
xkb->ctrls->per_key_repeat = uTypedCalloc(xkb->max_key_code << 3,
|
|
|
|
unsigned char);
|
|
|
|
if (!xkb->ctrls->per_key_repeat)
|
|
|
|
return BadAlloc;
|
2012-02-15 07:34:08 -07:00
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2010-09-27 14:05:52 -06:00
|
|
|
static void
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcFreeControls(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-03-02 06:56:03 -07:00
|
|
|
if (xkb && xkb->ctrls) {
|
2012-02-15 17:22:11 -07:00
|
|
|
free(xkb->ctrls->per_key_repeat);
|
2010-06-30 14:56:24 -06:00
|
|
|
free(xkb->ctrls);
|
2009-03-25 16:41:21 -06:00
|
|
|
xkb->ctrls = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcAllocIndicatorMaps(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb)
|
|
|
|
return BadMatch;
|
|
|
|
|
|
|
|
if (!xkb->indicators) {
|
2012-03-23 16:12:08 -06:00
|
|
|
xkb->indicators = uTypedCalloc(1, struct xkb_indicator);
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb->indicators)
|
|
|
|
return BadAlloc;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2010-09-27 14:05:52 -06:00
|
|
|
static void
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcFreeIndicatorMaps(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-02-29 10:56:39 -07:00
|
|
|
if (xkb) {
|
2010-06-30 14:56:24 -06:00
|
|
|
free(xkb->indicators);
|
2009-03-25 16:41:21 -06:00
|
|
|
xkb->indicators = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-03 08:14:16 -06:00
|
|
|
struct xkb_keymap *
|
2012-03-27 10:22:35 -06:00
|
|
|
XkbcAllocKeyboard(struct xkb_context *context)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-04-03 08:14:16 -06:00
|
|
|
struct xkb_keymap *xkb;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2012-04-03 08:14:16 -06:00
|
|
|
xkb = uTypedCalloc(1, struct xkb_keymap);
|
2012-03-27 10:22:35 -06:00
|
|
|
if (!xkb)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
xkb->refcnt = 1;
|
2012-04-05 01:13:24 -06:00
|
|
|
xkb->context = xkb_context_ref(context);
|
2012-03-22 11:39:12 -06:00
|
|
|
|
2009-03-19 17:57:01 -06:00
|
|
|
return xkb;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-04-03 08:14:16 -06:00
|
|
|
XkbcFreeKeyboard(struct xkb_keymap * xkb)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2009-03-25 16:41:21 -06:00
|
|
|
if (!xkb)
|
|
|
|
return;
|
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
XkbcFreeClientMap(xkb);
|
|
|
|
XkbcFreeServerMap(xkb);
|
|
|
|
XkbcFreeCompatMap(xkb);
|
|
|
|
XkbcFreeIndicatorMaps(xkb);
|
|
|
|
XkbcFreeNames(xkb);
|
|
|
|
XkbcFreeControls(xkb);
|
2012-03-27 10:22:35 -06:00
|
|
|
xkb_context_unref(xkb->context);
|
2012-03-02 06:56:03 -07:00
|
|
|
free(xkb);
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|