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