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
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocClientMap(struct xkb_keymap *keymap, unsigned which,
|
|
|
|
unsigned nTotalTypes)
|
2012-04-10 17:02:45 -06:00
|
|
|
{
|
|
|
|
struct xkb_client_map * map;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap || ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes)))
|
2012-04-10 17:02:45 -06:00
|
|
|
return BadValue;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->map) {
|
2012-04-10 17:02:45 -06:00
|
|
|
map = uTypedCalloc(1, struct xkb_client_map);
|
|
|
|
if (!map)
|
|
|
|
return BadAlloc;
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->map = map;
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
|
|
|
else
|
2012-05-09 08:15:30 -06:00
|
|
|
map = keymap->map;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
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) {
|
2012-05-09 08:15:30 -06:00
|
|
|
map->key_sym_map = uTypedCalloc(keymap->max_key_code + 1,
|
2012-04-10 17:02:45 -06:00
|
|
|
struct xkb_sym_map);
|
|
|
|
if (!map->key_sym_map)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (which & XkbModifierMapMask) {
|
|
|
|
if (!map->modmap) {
|
2012-05-09 08:15:30 -06:00
|
|
|
map->modmap = uTypedCalloc(keymap->max_key_code + 1,
|
|
|
|
unsigned char);
|
2012-04-10 17:02:45 -06:00
|
|
|
if (!map->modmap)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocServerMap(struct xkb_keymap *keymap, unsigned which,
|
|
|
|
unsigned nNewActions)
|
2012-04-10 17:02:45 -06:00
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
struct xkb_server_map * map;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2012-04-10 17:02:45 -06:00
|
|
|
return BadMatch;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->server) {
|
2012-04-10 17:02:45 -06:00
|
|
|
map = uTypedCalloc(1, struct xkb_server_map);
|
|
|
|
if (!map)
|
|
|
|
return BadAlloc;
|
|
|
|
|
|
|
|
for (i = 0; i < XkbNumVirtualMods; i++)
|
|
|
|
map->vmods[i] = XkbNoModifierMask;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->server = map;
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
|
|
|
else
|
2012-05-09 08:15:30 -06:00
|
|
|
map = keymap->server;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
if (!which)
|
|
|
|
return Success;
|
|
|
|
|
|
|
|
if (!map->explicit) {
|
2012-05-09 08:15:30 -06:00
|
|
|
i = keymap->max_key_code + 1;
|
2012-04-10 17:02:45 -06:00
|
|
|
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) {
|
2012-05-09 08:15:30 -06:00
|
|
|
i = keymap->max_key_code + 1;
|
2012-04-10 17:02:45 -06:00
|
|
|
map->key_acts = uTypedCalloc(i, unsigned short);
|
|
|
|
if (!map->key_acts)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!map->behaviors) {
|
2012-05-09 08:15:30 -06:00
|
|
|
i = keymap->max_key_code + 1;
|
2012-04-10 17:02:45 -06:00
|
|
|
map->behaviors = uTypedCalloc(i, struct xkb_behavior);
|
|
|
|
if (!map->behaviors)
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!map->vmodmap) {
|
2012-05-09 08:15:30 -06:00
|
|
|
i = keymap->max_key_code + 1;
|
2012-04-10 17:02:45 -06:00
|
|
|
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
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t key,
|
2012-04-10 17:02:45 -06:00
|
|
|
unsigned int needed)
|
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->map->key_sym_map[key].size_syms >= needed)
|
2012-04-10 17:02:45 -06:00
|
|
|
return true;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->map->key_sym_map[key].syms =
|
|
|
|
uTypedRecalloc(keymap->map->key_sym_map[key].syms,
|
|
|
|
keymap->map->key_sym_map[key].size_syms,
|
2012-04-10 17:02:45 -06:00
|
|
|
needed,
|
|
|
|
xkb_keysym_t);
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->map->key_sym_map[key].syms) {
|
|
|
|
keymap->map->key_sym_map[key].size_syms = 0;
|
2012-04-10 17:02:45 -06:00
|
|
|
return false;
|
|
|
|
}
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->map->key_sym_map[key].size_syms = needed;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
union xkb_action *
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t key,
|
|
|
|
uint32_t needed)
|
2012-04-10 17:02:45 -06:00
|
|
|
{
|
|
|
|
xkb_keycode_t i, nActs;
|
|
|
|
union xkb_action *newActs;
|
|
|
|
|
|
|
|
if (needed == 0) {
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->server->key_acts[key] = 0;
|
2012-04-10 17:02:45 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (XkbKeyHasActions(keymap, key) &&
|
|
|
|
(XkbKeyGroupsWidth(keymap, key) >= needed))
|
|
|
|
return XkbKeyActionsPtr(keymap, key);
|
2012-04-10 17:02:45 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
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;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
return &keymap->server->acts[keymap->server->key_acts[key]];
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->server->size_acts = keymap->server->num_acts + needed + 8;
|
|
|
|
newActs = uTypedCalloc(keymap->server->size_acts, union xkb_action);
|
2012-04-10 17:02:45 -06:00
|
|
|
if (!newActs)
|
|
|
|
return NULL;
|
|
|
|
newActs[0].type = XkbSA_NoAction;
|
|
|
|
nActs = 1;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
|
2012-04-10 17:02:45 -06:00
|
|
|
xkb_keycode_t nKeyActs, nCopy;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if ((keymap->server->key_acts[i] == 0) && (i != key))
|
2012-04-10 17:02:45 -06:00
|
|
|
continue;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
nCopy = nKeyActs = XkbKeyNumActions(keymap, i);
|
2012-04-10 17:02:45 -06:00
|
|
|
if (i == key) {
|
|
|
|
nKeyActs= needed;
|
|
|
|
if (needed < nCopy)
|
|
|
|
nCopy = needed;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nCopy > 0)
|
2012-05-09 08:15:30 -06:00
|
|
|
memcpy(&newActs[nActs], XkbKeyActionsPtr(keymap, i),
|
2012-04-10 17:02:45 -06:00
|
|
|
nCopy * sizeof(union xkb_action));
|
|
|
|
if (nCopy < nKeyActs)
|
|
|
|
memset(&newActs[nActs + nCopy], 0,
|
|
|
|
(nKeyActs - nCopy) * sizeof(union xkb_action));
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->server->key_acts[i] = nActs;
|
2012-04-10 17:02:45 -06:00
|
|
|
nActs += nKeyActs;
|
|
|
|
}
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
free(keymap->server->acts);
|
|
|
|
keymap->server->acts = newActs;
|
|
|
|
keymap->server->num_acts = nActs;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
return &keymap->server->acts[keymap->server->key_acts[key]];
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcFreeClientMap(struct xkb_keymap *keymap)
|
2012-04-10 17:02:45 -06:00
|
|
|
{
|
|
|
|
struct xkb_client_map * map;
|
|
|
|
struct xkb_key_type * type;
|
|
|
|
xkb_keycode_t key;
|
|
|
|
int i;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap || !keymap->map)
|
2012-04-10 17:02:45 -06:00
|
|
|
return;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
map = keymap->map;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
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) {
|
2012-05-09 08:15:30 -06:00
|
|
|
for (key = keymap->min_key_code; key < keymap->max_key_code; key++) {
|
2012-04-10 17:02:45 -06:00
|
|
|
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);
|
2012-05-09 08:15:30 -06:00
|
|
|
free(keymap->map);
|
|
|
|
keymap->map = NULL;
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcFreeServerMap(struct xkb_keymap *keymap)
|
2012-04-10 17:02:45 -06:00
|
|
|
{
|
|
|
|
struct xkb_server_map * map;
|
|
|
|
|
2012-05-13 01:38:51 -06:00
|
|
|
if (!keymap || !keymap->server)
|
2012-04-10 17:02:45 -06:00
|
|
|
return;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
map = keymap->server;
|
2012-04-10 17:02:45 -06:00
|
|
|
|
|
|
|
free(map->explicit);
|
|
|
|
free(map->key_acts);
|
|
|
|
free(map->acts);
|
|
|
|
free(map->behaviors);
|
|
|
|
free(map->vmodmap);
|
2012-05-09 08:15:30 -06:00
|
|
|
free(keymap->server);
|
|
|
|
keymap->server = NULL;
|
2012-04-10 17:02:45 -06:00
|
|
|
}
|
2009-03-19 17:57:01 -06:00
|
|
|
|
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocCompatMap(struct xkb_keymap *keymap, 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
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadMatch;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->compat) {
|
|
|
|
if (keymap->compat->size_si >= nSI)
|
2009-03-25 16:41:21 -06:00
|
|
|
return Success;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
compat = keymap->compat;
|
2009-03-25 16:41:21 -06:00
|
|
|
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));
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->compat = compat;
|
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-05-09 08:15:30 -06:00
|
|
|
XkbcFreeCompatMap(struct xkb_keymap *keymap)
|
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
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap || !keymap->compat)
|
2009-03-25 16:41:21 -06:00
|
|
|
return;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
compat = keymap->compat;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-03-02 06:56:03 -07:00
|
|
|
free(compat->sym_interpret);
|
|
|
|
free(compat);
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->compat = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocNames(struct xkb_keymap *keymap, 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
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadMatch;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->names) {
|
|
|
|
keymap->names = uTypedCalloc(1, struct xkb_names);
|
|
|
|
if (!keymap->names)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadAlloc;
|
|
|
|
}
|
2012-05-09 08:15:30 -06:00
|
|
|
names = keymap->names;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if ((which & XkbKTLevelNamesMask) && keymap->map && keymap->map->types) {
|
2009-03-25 16:41:21 -06:00
|
|
|
int i;
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_key_type * type;
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
type = keymap->map->types;
|
|
|
|
for (i = 0; i < keymap->map->num_types; i++, type++) {
|
2009-03-25 16:41:21 -06:00
|
|
|
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-05-09 08:15:30 -06:00
|
|
|
names->keys = uTypedCalloc(keymap->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-05-09 08:15:30 -06:00
|
|
|
XkbcFreeNames(struct xkb_keymap *keymap)
|
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
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap || !keymap->names)
|
2009-03-25 16:41:21 -06:00
|
|
|
return;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
names = keymap->names;
|
|
|
|
map = keymap->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-05-21 23:04:59 -06:00
|
|
|
free(UNCONSTIFY(type->level_names[j]));
|
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);
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->names = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocControls(struct xkb_keymap *keymap)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadMatch;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->ctrls) {
|
|
|
|
keymap->ctrls = uTypedCalloc(1, struct xkb_controls);
|
|
|
|
if (!keymap->ctrls)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadAlloc;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
2009-03-25 16:41:21 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->ctrls->per_key_repeat = uTypedCalloc(keymap->max_key_code >> 3,
|
|
|
|
unsigned char);
|
|
|
|
if (!keymap->ctrls->per_key_repeat)
|
2012-04-10 16:55:50 -06:00
|
|
|
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-05-09 08:15:30 -06:00
|
|
|
XkbcFreeControls(struct xkb_keymap *keymap)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap && keymap->ctrls) {
|
|
|
|
free(keymap->ctrls->per_key_repeat);
|
|
|
|
free(keymap->ctrls);
|
|
|
|
keymap->ctrls = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcAllocIndicatorMaps(struct xkb_keymap *keymap)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2009-03-25 16:41:21 -06:00
|
|
|
return BadMatch;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap->indicators) {
|
|
|
|
keymap->indicators = uTypedCalloc(1, struct xkb_indicator);
|
|
|
|
if (!keymap->indicators)
|
2009-03-25 16:41:21 -06:00
|
|
|
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-05-09 08:15:30 -06:00
|
|
|
XkbcFreeIndicatorMaps(struct xkb_keymap *keymap)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap) {
|
|
|
|
free(keymap->indicators);
|
|
|
|
keymap->indicators = NULL;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-03 08:14:16 -06:00
|
|
|
struct xkb_keymap *
|
2012-05-11 08:03:43 -06:00
|
|
|
XkbcAllocKeyboard(struct xkb_context *ctx)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
struct xkb_keymap *keymap;
|
2009-03-19 17:57:01 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap = uTypedCalloc(1, struct xkb_keymap);
|
|
|
|
if (!keymap)
|
2012-03-27 10:22:35 -06:00
|
|
|
return NULL;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->refcnt = 1;
|
2012-05-11 08:03:43 -06:00
|
|
|
keymap->ctx = xkb_context_ref(ctx);
|
2012-03-22 11:39:12 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
return keymap;
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcFreeKeyboard(struct xkb_keymap *keymap)
|
2009-03-19 17:57:01 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!keymap)
|
2009-03-25 16:41:21 -06:00
|
|
|
return;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
XkbcFreeClientMap(keymap);
|
|
|
|
XkbcFreeServerMap(keymap);
|
|
|
|
XkbcFreeCompatMap(keymap);
|
|
|
|
XkbcFreeIndicatorMaps(keymap);
|
|
|
|
XkbcFreeNames(keymap);
|
|
|
|
XkbcFreeControls(keymap);
|
2012-05-11 08:03:43 -06:00
|
|
|
xkb_context_unref(keymap->ctx);
|
2012-05-09 08:15:30 -06:00
|
|
|
free(keymap);
|
2009-03-19 17:57:01 -06:00
|
|
|
}
|