XKBAlloc.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBAlloc.c,v 1.4 2000/08/17 19:44:59 cpqbld Exp $ */
21ab64890Smrg/************************************************************
31ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, and distribute this
61ab64890Smrgsoftware and its documentation for any purpose and without
71ab64890Smrgfee is hereby granted, provided that the above copyright
81ab64890Smrgnotice appear in all copies and that both that copyright
91ab64890Smrgnotice and this permission notice appear in supporting
1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1161b2299dSmrgused in advertising or publicity pertaining to distribution
121ab64890Smrgof the software without specific prior written permission.
1361b2299dSmrgSilicon Graphics makes no representation about the suitability
141ab64890Smrgof this software for any purpose. It is provided "as is"
151ab64890Smrgwithout any express or implied warranty.
161ab64890Smrg
1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
251ab64890Smrg
261ab64890Smrg********************************************************/
271ab64890Smrg/* $XFree86: xc/lib/X11/XKBAlloc.c,v 3.5 2001/01/17 19:41:48 dawes Exp $ */
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_DIX_CONFIG_H
301ab64890Smrg#include <dix-config.h>
311ab64890Smrg#elif defined(HAVE_CONFIG_H)
321ab64890Smrg#include <config.h>
331ab64890Smrg#endif
341ab64890Smrg
351ab64890Smrg#ifndef XKB_IN_SERVER
361ab64890Smrg
371ab64890Smrg#include <stdio.h>
381ab64890Smrg#define NEED_REPLIES
391ab64890Smrg#define NEED_EVENTS
401ab64890Smrg#include "Xlibint.h"
411ab64890Smrg#include "XKBlibint.h"
421ab64890Smrg#include <X11/extensions/XKBgeom.h>
431ab64890Smrg#include <X11/extensions/XKBproto.h>
441ab64890Smrg#include "XKBlibint.h"
451ab64890Smrg
4661b2299dSmrg#else
471ab64890Smrg
481ab64890Smrg#include <stdio.h>
491ab64890Smrg#include <X11/X.h>
501ab64890Smrg#define	NEED_EVENTS
511ab64890Smrg#define	NEED_REPLIES
521ab64890Smrg#include <X11/Xproto.h>
531ab64890Smrg#include "misc.h"
541ab64890Smrg#include "inputstr.h"
551ab64890Smrg#include <X11/extensions/XKBsrv.h>
561ab64890Smrg#include <X11/extensions/XKBgeom.h>
571ab64890Smrg
581ab64890Smrg#endif /* XKB_IN_SERVER */
591ab64890Smrg
601ab64890Smrg/***===================================================================***/
611ab64890Smrg
621ab64890Smrg/*ARGSUSED*/
631ab64890SmrgStatus
641ab64890SmrgXkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
651ab64890Smrg{
661ab64890SmrgXkbCompatMapPtr	compat;
671ab64890SmrgXkbSymInterpretRec *prev_interpret;
681ab64890Smrg
691ab64890Smrg    if (!xkb)
701ab64890Smrg	return BadMatch;
711ab64890Smrg    if (xkb->compat) {
721ab64890Smrg	if (xkb->compat->size_si>=nSI)
731ab64890Smrg	    return Success;
741ab64890Smrg	compat= xkb->compat;
751ab64890Smrg	compat->size_si= nSI;
761ab64890Smrg	if (compat->sym_interpret==NULL)
771ab64890Smrg	    compat->num_si= 0;
781ab64890Smrg	prev_interpret = compat->sym_interpret;
791ab64890Smrg	compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
801ab64890Smrg						     nSI,XkbSymInterpretRec);
811ab64890Smrg	if (compat->sym_interpret==NULL) {
821ab64890Smrg	    _XkbFree(prev_interpret);
831ab64890Smrg	    compat->size_si= compat->num_si= 0;
841ab64890Smrg	    return BadAlloc;
851ab64890Smrg	}
861ab64890Smrg	if (compat->num_si!=0) {
871ab64890Smrg	    _XkbClearElems(compat->sym_interpret,compat->num_si,
881ab64890Smrg					compat->size_si-1,XkbSymInterpretRec);
891ab64890Smrg	}
901ab64890Smrg	return Success;
911ab64890Smrg    }
921ab64890Smrg    compat= _XkbTypedCalloc(1,XkbCompatMapRec);
931ab64890Smrg    if (compat==NULL)
941ab64890Smrg	return BadAlloc;
951ab64890Smrg    if (nSI>0) {
961ab64890Smrg	compat->sym_interpret= _XkbTypedCalloc(nSI,XkbSymInterpretRec);
971ab64890Smrg	if (!compat->sym_interpret) {
981ab64890Smrg	    _XkbFree(compat);
991ab64890Smrg	    return BadAlloc;
1001ab64890Smrg	}
1011ab64890Smrg    }
1021ab64890Smrg    compat->size_si= nSI;
1031ab64890Smrg    compat->num_si= 0;
1041ab64890Smrg    bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
1051ab64890Smrg    xkb->compat= compat;
1061ab64890Smrg    return Success;
1071ab64890Smrg}
1081ab64890Smrg
1091ab64890Smrg
1101ab64890Smrgvoid
1111ab64890SmrgXkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
1121ab64890Smrg{
1131ab64890Smrgregister XkbCompatMapPtr compat;
1141ab64890Smrg
1151ab64890Smrg    if ((xkb==NULL)||(xkb->compat==NULL))
1161ab64890Smrg	return;
1171ab64890Smrg    compat= xkb->compat;
1181ab64890Smrg    if (freeMap)
1191ab64890Smrg	which= XkbAllCompatMask;
1201ab64890Smrg    if (which&XkbGroupCompatMask)
1211ab64890Smrg	bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
1221ab64890Smrg    if (which&XkbSymInterpMask) {
1231ab64890Smrg	if ((compat->sym_interpret)&&(compat->size_si>0))
1241ab64890Smrg	    _XkbFree(compat->sym_interpret);
1251ab64890Smrg	compat->size_si= compat->num_si= 0;
1261ab64890Smrg	compat->sym_interpret= NULL;
1271ab64890Smrg    }
1281ab64890Smrg    if (freeMap) {
1291ab64890Smrg	_XkbFree(compat);
1301ab64890Smrg	xkb->compat= NULL;
1311ab64890Smrg    }
1321ab64890Smrg    return;
1331ab64890Smrg}
1341ab64890Smrg
1351ab64890Smrg/***===================================================================***/
1361ab64890Smrg
1371ab64890SmrgStatus
1381ab64890SmrgXkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
1391ab64890Smrg{
1401ab64890SmrgXkbNamesPtr	names;
1411ab64890Smrg
1421ab64890Smrg    if (xkb==NULL)
1431ab64890Smrg	return BadMatch;
1441ab64890Smrg    if (xkb->names==NULL) {
1451ab64890Smrg	xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
1461ab64890Smrg	if (xkb->names==NULL)
1471ab64890Smrg	    return BadAlloc;
1481ab64890Smrg    }
1491ab64890Smrg    names= xkb->names;
1501ab64890Smrg    if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
1511ab64890Smrg	register int	i;
1521ab64890Smrg	XkbKeyTypePtr	type;
1531ab64890Smrg
1541ab64890Smrg	type= xkb->map->types;
1551ab64890Smrg	for (i=0;i<xkb->map->num_types;i++,type++) {
1561ab64890Smrg	    if (type->level_names==NULL) {
1571ab64890Smrg		type->level_names= _XkbTypedCalloc(type->num_levels,Atom);
1581ab64890Smrg		if (type->level_names==NULL)
1591ab64890Smrg		    return BadAlloc;
1601ab64890Smrg	    }
1611ab64890Smrg	}
1621ab64890Smrg    }
1631ab64890Smrg    if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
1641ab64890Smrg	if ((!XkbIsLegalKeycode(xkb->min_key_code))||
1651ab64890Smrg	    (!XkbIsLegalKeycode(xkb->max_key_code))||
16661b2299dSmrg	    (xkb->max_key_code<xkb->min_key_code))
1671ab64890Smrg	    return BadValue;
1681ab64890Smrg	names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec);
1691ab64890Smrg	if (names->keys==NULL)
1701ab64890Smrg	    return BadAlloc;
1711ab64890Smrg    }
1721ab64890Smrg    if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
1731ab64890Smrg	if (names->key_aliases==NULL) {
1741ab64890Smrg	    names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec);
1751ab64890Smrg	}
1761ab64890Smrg	else if (nTotalAliases>names->num_key_aliases) {
1771ab64890Smrg	    XkbKeyAliasRec *prev_aliases = names->key_aliases;
1781ab64890Smrg
1791ab64890Smrg	    names->key_aliases= _XkbTypedRealloc(names->key_aliases,
1801ab64890Smrg						nTotalAliases,XkbKeyAliasRec);
1811ab64890Smrg	    if (names->key_aliases!=NULL) {
1821ab64890Smrg		_XkbClearElems(names->key_aliases,names->num_key_aliases,
1831ab64890Smrg						nTotalAliases-1,XkbKeyAliasRec);
1841ab64890Smrg	    } else {
1851ab64890Smrg		_XkbFree(prev_aliases);
1861ab64890Smrg	    }
1871ab64890Smrg	}
1881ab64890Smrg	if (names->key_aliases==NULL) {
1891ab64890Smrg	    names->num_key_aliases= 0;
1901ab64890Smrg	    return BadAlloc;
1911ab64890Smrg	}
1921ab64890Smrg	names->num_key_aliases= nTotalAliases;
1931ab64890Smrg    }
1941ab64890Smrg    if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
1951ab64890Smrg	if (names->radio_groups==NULL) {
1961ab64890Smrg	    names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom);
1971ab64890Smrg	}
1981ab64890Smrg	else if (nTotalRG>names->num_rg) {
1991ab64890Smrg	    Atom *prev_radio_groups = names->radio_groups;
2001ab64890Smrg
2011ab64890Smrg	    names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG,
2021ab64890Smrg									Atom);
2031ab64890Smrg	    if (names->radio_groups!=NULL) {
2041ab64890Smrg		_XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1,
2051ab64890Smrg									Atom);
2061ab64890Smrg	    } else {
2071ab64890Smrg		_XkbFree(prev_radio_groups);
2081ab64890Smrg	    }
2091ab64890Smrg	}
2101ab64890Smrg	if (names->radio_groups==NULL)
2111ab64890Smrg	    return BadAlloc;
2121ab64890Smrg	names->num_rg= nTotalRG;
2131ab64890Smrg    }
2141ab64890Smrg    return Success;
2151ab64890Smrg}
2161ab64890Smrg
2171ab64890Smrgvoid
2181ab64890SmrgXkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
2191ab64890Smrg{
2201ab64890SmrgXkbNamesPtr	names;
2211ab64890Smrg
2221ab64890Smrg    if ((xkb==NULL)||(xkb->names==NULL))
2231ab64890Smrg	return;
2241ab64890Smrg    names= xkb->names;
2251ab64890Smrg    if (freeMap)
22661b2299dSmrg	which= XkbAllNamesMask;
2271ab64890Smrg    if (which&XkbKTLevelNamesMask) {
2281ab64890Smrg	XkbClientMapPtr	map= xkb->map;
2291ab64890Smrg	if ((map!=NULL)&&(map->types!=NULL)) {
2301ab64890Smrg	    register int 		i;
2311ab64890Smrg	    register XkbKeyTypePtr	type;
2321ab64890Smrg	    type= map->types;
2331ab64890Smrg	    for (i=0;i<map->num_types;i++,type++) {
2341ab64890Smrg		if (type->level_names!=NULL) {
2351ab64890Smrg		    _XkbFree(type->level_names);
2361ab64890Smrg		    type->level_names= NULL;
2371ab64890Smrg		}
2381ab64890Smrg	    }
2391ab64890Smrg	}
2401ab64890Smrg    }
2411ab64890Smrg    if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
2421ab64890Smrg	_XkbFree(names->keys);
2431ab64890Smrg	names->keys= NULL;
2441ab64890Smrg	names->num_keys= 0;
2451ab64890Smrg    }
2461ab64890Smrg    if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
2471ab64890Smrg	_XkbFree(names->key_aliases);
2481ab64890Smrg	names->key_aliases=NULL;
2491ab64890Smrg	names->num_key_aliases=0;
2501ab64890Smrg    }
2511ab64890Smrg    if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
2521ab64890Smrg	_XkbFree(names->radio_groups);
2531ab64890Smrg	names->radio_groups= NULL;
2541ab64890Smrg	names->num_rg= 0;
2551ab64890Smrg    }
2561ab64890Smrg    if (freeMap) {
2571ab64890Smrg	_XkbFree(names);
2581ab64890Smrg	xkb->names= NULL;
2591ab64890Smrg    }
2601ab64890Smrg    return;
2611ab64890Smrg}
2621ab64890Smrg
2631ab64890Smrg/***===================================================================***/
2641ab64890Smrg
2651ab64890Smrg/*ARGSUSED*/
2661ab64890SmrgStatus
2671ab64890SmrgXkbAllocControls(XkbDescPtr xkb,unsigned which)
2681ab64890Smrg{
2691ab64890Smrg    if (xkb==NULL)
2701ab64890Smrg	return BadMatch;
2711ab64890Smrg
2721ab64890Smrg    if (xkb->ctrls==NULL) {
2731ab64890Smrg	xkb->ctrls= _XkbTypedCalloc(1,XkbControlsRec);
2741ab64890Smrg	if (!xkb->ctrls)
2751ab64890Smrg	    return BadAlloc;
2761ab64890Smrg    }
2771ab64890Smrg    return Success;
2781ab64890Smrg}
2791ab64890Smrg
2801ab64890Smrg/*ARGSUSED*/
2811ab64890Smrgvoid
2821ab64890SmrgXkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
2831ab64890Smrg{
2841ab64890Smrg    if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
2851ab64890Smrg	_XkbFree(xkb->ctrls);
2861ab64890Smrg	xkb->ctrls= NULL;
2871ab64890Smrg    }
2881ab64890Smrg    return;
2891ab64890Smrg}
2901ab64890Smrg
2911ab64890Smrg/***===================================================================***/
2921ab64890Smrg
29361b2299dSmrgStatus
2941ab64890SmrgXkbAllocIndicatorMaps(XkbDescPtr xkb)
2951ab64890Smrg{
2961ab64890Smrg    if (xkb==NULL)
2971ab64890Smrg	return BadMatch;
2981ab64890Smrg    if (xkb->indicators==NULL) {
2991ab64890Smrg	xkb->indicators= _XkbTypedCalloc(1,XkbIndicatorRec);
3001ab64890Smrg	if (!xkb->indicators)
3011ab64890Smrg	    return BadAlloc;
3021ab64890Smrg    }
3031ab64890Smrg    return Success;
3041ab64890Smrg}
3051ab64890Smrg
3061ab64890Smrgvoid
3071ab64890SmrgXkbFreeIndicatorMaps(XkbDescPtr xkb)
3081ab64890Smrg{
3091ab64890Smrg    if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
3101ab64890Smrg	_XkbFree(xkb->indicators);
3111ab64890Smrg	xkb->indicators= NULL;
3121ab64890Smrg    }
3131ab64890Smrg    return;
3141ab64890Smrg}
3151ab64890Smrg
3161ab64890Smrg/***====================================================================***/
3171ab64890Smrg
3181ab64890SmrgXkbDescRec	*
3191ab64890SmrgXkbAllocKeyboard(void)
3201ab64890Smrg{
3211ab64890SmrgXkbDescRec *xkb;
3221ab64890Smrg
3231ab64890Smrg    xkb = _XkbTypedCalloc(1,XkbDescRec);
3241ab64890Smrg    if (xkb)
3251ab64890Smrg	xkb->device_spec= XkbUseCoreKbd;
3261ab64890Smrg    return xkb;
3271ab64890Smrg}
3281ab64890Smrg
3291ab64890Smrgvoid
3301ab64890SmrgXkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
3311ab64890Smrg{
3321ab64890Smrg    if (xkb==NULL)
3331ab64890Smrg	return;
3341ab64890Smrg    if (freeAll)
3351ab64890Smrg	which= XkbAllComponentsMask;
3361ab64890Smrg    if (which&XkbClientMapMask)
3371ab64890Smrg	XkbFreeClientMap(xkb,XkbAllClientInfoMask,True);
3381ab64890Smrg    if (which&XkbServerMapMask)
3391ab64890Smrg	XkbFreeServerMap(xkb,XkbAllServerInfoMask,True);
3401ab64890Smrg    if (which&XkbCompatMapMask)
3411ab64890Smrg	XkbFreeCompatMap(xkb,XkbAllCompatMask,True);
3421ab64890Smrg    if (which&XkbIndicatorMapMask)
3431ab64890Smrg	XkbFreeIndicatorMaps(xkb);
3441ab64890Smrg    if (which&XkbNamesMask)
3451ab64890Smrg	XkbFreeNames(xkb,XkbAllNamesMask,True);
3461ab64890Smrg    if ((which&XkbGeometryMask) && (xkb->geom!=NULL))
3471ab64890Smrg	XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True);
3481ab64890Smrg    if (which&XkbControlsMask)
3491ab64890Smrg	XkbFreeControls(xkb,XkbAllControlsMask,True);
3501ab64890Smrg    if (freeAll)
3511ab64890Smrg	_XkbFree(xkb);
3521ab64890Smrg    return;
3531ab64890Smrg}
3541ab64890Smrg
3551ab64890Smrg/***====================================================================***/
3561ab64890Smrg
3571ab64890SmrgXkbDeviceLedInfoPtr
3581ab64890SmrgXkbAddDeviceLedInfo(XkbDeviceInfoPtr devi,unsigned ledClass,unsigned ledId)
3591ab64890Smrg{
3601ab64890SmrgXkbDeviceLedInfoPtr	devli;
3611ab64890Smrgregister int		i;
3621ab64890Smrg
3631ab64890Smrg    if ((!devi)||(!XkbSingleXIClass(ledClass))||(!XkbSingleXIId(ledId)))
3641ab64890Smrg	return NULL;
3651ab64890Smrg    for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
3661ab64890Smrg	if ((devli->led_class==ledClass)&&(devli->led_id==ledId))
3671ab64890Smrg	    return devli;
3681ab64890Smrg    }
3691ab64890Smrg    if (devi->num_leds>=devi->sz_leds) {
3701ab64890Smrg	XkbDeviceLedInfoRec *prev_leds = devi->leds;
37161b2299dSmrg
3721ab64890Smrg	if (devi->sz_leds>0)	devi->sz_leds*= 2;
3731ab64890Smrg	else			devi->sz_leds= 1;
3741ab64890Smrg	devi->leds= _XkbTypedRealloc(devi->leds,devi->sz_leds,
3751ab64890Smrg							XkbDeviceLedInfoRec);
3761ab64890Smrg	if (!devi->leds) {
3771ab64890Smrg	    _XkbFree(prev_leds);
3781ab64890Smrg	    devi->sz_leds= devi->num_leds= 0;
3791ab64890Smrg	    return NULL;
3801ab64890Smrg	}
3811ab64890Smrg	i= devi->num_leds;
3821ab64890Smrg	for (devli=&devi->leds[i];i<devi->sz_leds;i++,devli++) {
3831ab64890Smrg	    bzero(devli,sizeof(XkbDeviceLedInfoRec));
3841ab64890Smrg	    devli->led_class= XkbXINone;
3851ab64890Smrg	    devli->led_id= XkbXINone;
3861ab64890Smrg	}
3871ab64890Smrg    }
3881ab64890Smrg    devli= &devi->leds[devi->num_leds++];
3891ab64890Smrg    bzero(devli,sizeof(XkbDeviceLedInfoRec));
3901ab64890Smrg    devli->led_class= ledClass;
3911ab64890Smrg    devli->led_id= ledId;
3921ab64890Smrg    return devli;
3931ab64890Smrg}
3941ab64890Smrg
3951ab64890SmrgStatus
3961ab64890SmrgXkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi,unsigned newTotal)
3971ab64890Smrg{
3981ab64890Smrg    XkbAction *prev_btn_acts;
3991ab64890Smrg
4001ab64890Smrg    if ((!devi)||(newTotal>255))
4011ab64890Smrg	return BadValue;
4021ab64890Smrg    if ((devi->btn_acts!=NULL)&&(newTotal==devi->num_btns))
4031ab64890Smrg	return Success;
4041ab64890Smrg    if (newTotal==0) {
4051ab64890Smrg	if (devi->btn_acts!=NULL) {
4061ab64890Smrg	    _XkbFree(devi->btn_acts);
4071ab64890Smrg	    devi->btn_acts= NULL;
4081ab64890Smrg	}
4091ab64890Smrg	devi->num_btns= 0;
4101ab64890Smrg	return Success;
4111ab64890Smrg    }
4121ab64890Smrg    prev_btn_acts = devi->btn_acts;
4131ab64890Smrg    devi->btn_acts= _XkbTypedRealloc(devi->btn_acts,newTotal,XkbAction);
4141ab64890Smrg    if (devi->btn_acts==NULL) {
4151ab64890Smrg	_XkbFree(prev_btn_acts);
4161ab64890Smrg	devi->num_btns= 0;
4171ab64890Smrg	return BadAlloc;
4181ab64890Smrg    }
4191ab64890Smrg    if (newTotal>devi->num_btns) {
4201ab64890Smrg	XkbAction *act;
4211ab64890Smrg	act= &devi->btn_acts[devi->num_btns];
4221ab64890Smrg	bzero((char *)act,(newTotal-devi->num_btns)*sizeof(XkbAction));
4231ab64890Smrg    }
4241ab64890Smrg    devi->num_btns= newTotal;
4251ab64890Smrg    return Success;
4261ab64890Smrg}
4271ab64890Smrg
4281ab64890Smrg/*ARGSUSED*/
4291ab64890SmrgXkbDeviceInfoPtr
4301ab64890SmrgXkbAllocDeviceInfo(unsigned deviceSpec,unsigned nButtons,unsigned szLeds)
4311ab64890Smrg{
4321ab64890SmrgXkbDeviceInfoPtr	devi;
4331ab64890Smrg
4341ab64890Smrg    devi= _XkbTypedCalloc(1,XkbDeviceInfoRec);
4351ab64890Smrg    if (devi!=NULL) {
4361ab64890Smrg	devi->device_spec= deviceSpec;
4371ab64890Smrg	devi->has_own_state= False;
4381ab64890Smrg	devi->num_btns= 0;
4391ab64890Smrg	devi->btn_acts= NULL;
4401ab64890Smrg	if (nButtons>0) {
4411ab64890Smrg	    devi->num_btns= nButtons;
4421ab64890Smrg	    devi->btn_acts= _XkbTypedCalloc(nButtons,XkbAction);
4431ab64890Smrg	    if (!devi->btn_acts) {
4441ab64890Smrg		_XkbFree(devi);
4451ab64890Smrg		return NULL;
4461ab64890Smrg	    }
4471ab64890Smrg	}
4481ab64890Smrg	devi->dflt_kbd_fb= XkbXINone;
4491ab64890Smrg	devi->dflt_led_fb= XkbXINone;
4501ab64890Smrg	devi->num_leds= 0;
4511ab64890Smrg	devi->sz_leds= 0;
4521ab64890Smrg	devi->leds= NULL;
4531ab64890Smrg	if (szLeds>0) {
4541ab64890Smrg	    devi->sz_leds= szLeds;
4551ab64890Smrg	    devi->leds= _XkbTypedCalloc(szLeds,XkbDeviceLedInfoRec);
4561ab64890Smrg	    if (!devi->leds) {
4571ab64890Smrg		if (devi->btn_acts)
4581ab64890Smrg		    _XkbFree(devi->btn_acts);
4591ab64890Smrg		_XkbFree(devi);
4601ab64890Smrg		return NULL;
4611ab64890Smrg	    }
4621ab64890Smrg	}
4631ab64890Smrg    }
4641ab64890Smrg    return devi;
4651ab64890Smrg}
4661ab64890Smrg
4671ab64890Smrg
46861b2299dSmrgvoid
4691ab64890SmrgXkbFreeDeviceInfo(XkbDeviceInfoPtr devi,unsigned which,Bool freeDevI)
4701ab64890Smrg{
4711ab64890Smrg    if (devi) {
4721ab64890Smrg	if (freeDevI) {
4731ab64890Smrg	    which= XkbXI_AllDeviceFeaturesMask;
4741ab64890Smrg	    if (devi->name) {
4751ab64890Smrg		_XkbFree(devi->name);
4761ab64890Smrg		devi->name= NULL;
4771ab64890Smrg	    }
4781ab64890Smrg	}
4791ab64890Smrg	if ((which&XkbXI_ButtonActionsMask)&&(devi->btn_acts)) {
4801ab64890Smrg	    _XkbFree(devi->btn_acts);
4811ab64890Smrg	    devi->num_btns= 0;
4821ab64890Smrg	    devi->btn_acts= NULL;
4831ab64890Smrg	}
4841ab64890Smrg	if ((which&XkbXI_IndicatorsMask)&&(devi->leds)) {
4851ab64890Smrg	    register int i;
4861ab64890Smrg	    if ((which&XkbXI_IndicatorsMask)==XkbXI_IndicatorsMask) {
4871ab64890Smrg		_XkbFree(devi->leds);
4881ab64890Smrg		devi->sz_leds= devi->num_leds= 0;
4891ab64890Smrg		devi->leds= NULL;
4901ab64890Smrg	    }
4911ab64890Smrg	    else {
4921ab64890Smrg		XkbDeviceLedInfoPtr	devli;
4931ab64890Smrg		for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
4941ab64890Smrg		    if (which&XkbXI_IndicatorMapsMask)
4951ab64890Smrg			 bzero((char *)&devli->maps[0],sizeof(devli->maps));
4961ab64890Smrg		    else bzero((char *)&devli->names[0],sizeof(devli->names));
4971ab64890Smrg		}
4981ab64890Smrg	    }
4991ab64890Smrg	}
5001ab64890Smrg	if (freeDevI)
5011ab64890Smrg	    _XkbFree(devi);
5021ab64890Smrg    }
5031ab64890Smrg    return;
5041ab64890Smrg}
505