/*
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.
*/

#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>

int
XkbcAllocCompatMap(struct xkb_desc * xkb, unsigned which, unsigned nSI)
{
    struct xkb_compat_map * compat;
    struct xkb_sym_interpret *prev_interpret;

    if (!xkb)
        return BadMatch;

    if (xkb->compat) {
        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;
        compat->sym_interpret = _XkbTypedRealloc(compat->sym_interpret,
                                                 nSI, struct xkb_sym_interpret);
        if (!compat->sym_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, struct xkb_sym_interpret);

        return Success;
    }

    compat = _XkbTypedCalloc(1, struct xkb_compat_map);
    if (!compat)
        return BadAlloc;

    if (nSI > 0) {
        compat->sym_interpret = _XkbTypedCalloc(nSI, struct xkb_sym_interpret);
        if (!compat->sym_interpret) {
            free(compat);
            return BadAlloc;
        }
    }
    compat->size_si = nSI;
    compat->num_si = 0;
    bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(struct xkb_mods));
    xkb->compat = compat;

    return Success;
}


static void
XkbcFreeCompatMap(struct xkb_desc * xkb, unsigned which, Bool freeMap)
{
    struct xkb_compat_map * compat;

    if (!xkb || !xkb->compat)
        return;

    compat = xkb->compat;
    if (freeMap)
        which = XkbAllCompatMask;

    if (which & XkbGroupCompatMask)
        bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(struct xkb_mods));

    if (which & XkbSymInterpMask) {
        if (compat->sym_interpret && (compat->size_si > 0))
            free(compat->sym_interpret);
        compat->size_si = compat->num_si = 0;
        compat->sym_interpret = NULL;
    }

    if (freeMap) {
        free(compat);
        xkb->compat = NULL;
    }
}

int
XkbcAllocNames(struct xkb_desc * xkb, unsigned which, int nTotalRG, int nTotalAliases)
{
    struct xkb_names * names;

    if (!xkb)
        return BadMatch;

    if (!xkb->names) {
        xkb->names = _XkbTypedCalloc(1, struct xkb_names);
        if (!xkb->names)
            return BadAlloc;
    }
    names = xkb->names;

    if ((which & XkbKTLevelNamesMask) && xkb->map && xkb->map->types) {
        int i;
        struct xkb_key_type * type;

        type = xkb->map->types;
        for (i = 0; i < xkb->map->num_types; i++, type++) {
            if (!type->level_names) {
                type->level_names = _XkbTypedCalloc(type->num_levels, uint32_t);
                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, struct xkb_key_name);
        if (!names->keys)
            return BadAlloc;
    }

    if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
        if (!names->key_aliases)
            names->key_aliases = _XkbTypedCalloc(nTotalAliases,
                                                 struct xkb_key_alias);
        else if (nTotalAliases > names->num_key_aliases) {
            struct xkb_key_alias *prev_aliases = names->key_aliases;

            names->key_aliases = _XkbTypedRealloc(names->key_aliases,
                                                  nTotalAliases,
                                                  struct xkb_key_alias);
            if (names->key_aliases)
                _XkbClearElems(names->key_aliases, names->num_key_aliases,
                               nTotalAliases - 1, struct xkb_key_alias);
            else
                free(prev_aliases);
        }

        if (!names->key_aliases) {
            names->num_key_aliases = 0;
            return BadAlloc;
        }

        names->num_key_aliases = nTotalAliases;
    }

    if ((which & XkbRGNamesMask) && (nTotalRG > 0)) {
        if (!names->radio_groups)
            names->radio_groups = _XkbTypedCalloc(nTotalRG, uint32_t);
        else if (nTotalRG > names->num_rg) {
            uint32_t *prev_radio_groups = names->radio_groups;

            names->radio_groups = _XkbTypedRealloc(names->radio_groups,
                                                   nTotalRG, uint32_t);
            if (names->radio_groups)
                _XkbClearElems(names->radio_groups, names->num_rg,
                               nTotalRG - 1, uint32_t);
            else
                free(prev_radio_groups);
        }

        if (!names->radio_groups)
            return BadAlloc;

        names->num_rg = nTotalRG;
    }

    return Success;
}

static void
XkbcFreeNames(struct xkb_desc * xkb, unsigned which, Bool freeMap)
{
    struct xkb_names * names;

    if (!xkb || !xkb->names)
        return;

    names = xkb->names;
    if (freeMap)
        which = XkbAllNamesMask;

    if (which & XkbKTLevelNamesMask) {
        struct xkb_client_map * map = xkb->map;

        if (map && map->types) {
            int i;
            struct xkb_key_type * type = map->types;

            for (i = 0; i < map->num_types; i++, type++) {
                if (type->level_names) {
                    free(type->level_names);
                    type->level_names = NULL;
                }
            }
        }
    }

    if ((which & XkbKeyNamesMask) && names->keys) {
        free(names->keys);
        names->keys = NULL;
        names->num_keys = 0;
    }

    if ((which & XkbKeyAliasesMask) && names->key_aliases) {
        free(names->key_aliases);
        names->key_aliases = NULL;
        names->num_key_aliases = 0;
    }

    if ((which & XkbRGNamesMask) && names->radio_groups) {
        free(names->radio_groups);
        names->radio_groups = NULL;
        names->num_rg = 0;
    }

    if (freeMap) {
        free(names);
        xkb->names = NULL;
    }
}

int
XkbcAllocControls(struct xkb_desc * xkb, unsigned which)
{
    if (!xkb)
        return BadMatch;

    if (!xkb->ctrls) {
        xkb->ctrls = _XkbTypedCalloc(1, struct xkb_controls);
        if (!xkb->ctrls)
            return BadAlloc;
    }

    return Success;
}

static void
XkbcFreeControls(struct xkb_desc * xkb, unsigned which, Bool freeMap)
{
    if (freeMap && xkb && xkb->ctrls) {
        free(xkb->ctrls);
        xkb->ctrls = NULL;
    }
}

int
XkbcAllocIndicatorMaps(struct xkb_desc * xkb)
{
    if (!xkb)
        return BadMatch;

    if (!xkb->indicators) {
        xkb->indicators = _XkbTypedCalloc(1, struct xkb_indicator);
        if (!xkb->indicators)
            return BadAlloc;
    }

    return Success;
}

static void
XkbcFreeIndicatorMaps(struct xkb_desc * xkb)
{
    if (xkb && xkb->indicators) {
        free(xkb->indicators);
        xkb->indicators = NULL;
    }
}

struct xkb_desc *
XkbcAllocKeyboard(void)
{
    struct xkb_desc *xkb;

    xkb = _XkbTypedCalloc(1, struct xkb_desc);
    if (xkb)
        xkb->device_spec = XkbUseCoreKbd;
    return xkb;
}

void
XkbcFreeKeyboard(struct xkb_desc * xkb, unsigned which, Bool freeAll)
{
    if (!xkb)
        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)
        free(xkb);
}
