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-03-23 16:12:08 -06:00
|
|
|
#include "utils.h"
|
2009-04-08 08:46:25 -06:00
|
|
|
#include "xkballoc.h"
|
2012-02-15 04:49:10 -07:00
|
|
|
#include "xkbcommon/xkbcommon.h"
|
2009-03-05 19:20:15 -07:00
|
|
|
#include "XKBcommonint.h"
|
2009-03-19 17:57:01 -06:00
|
|
|
#include <X11/extensions/XKB.h>
|
|
|
|
|
|
|
|
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
|
|
|
}
|