XKBAlloc.c revision 0f8248bf
11ab64890Smrg/************************************************************ 21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 31ab64890Smrg 41ab64890SmrgPermission to use, copy, modify, and distribute this 51ab64890Smrgsoftware and its documentation for any purpose and without 61ab64890Smrgfee is hereby granted, provided that the above copyright 71ab64890Smrgnotice appear in all copies and that both that copyright 81ab64890Smrgnotice and this permission notice appear in supporting 961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1061b2299dSmrgused in advertising or publicity pertaining to distribution 111ab64890Smrgof the software without specific prior written permission. 1261b2299dSmrgSilicon Graphics makes no representation about the suitability 131ab64890Smrgof this software for any purpose. It is provided "as is" 141ab64890Smrgwithout any express or implied warranty. 151ab64890Smrg 1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 241ab64890Smrg 251ab64890Smrg********************************************************/ 261ab64890Smrg 27818534a1Smrg#ifdef HAVE_CONFIG_H 281ab64890Smrg#include <config.h> 291ab64890Smrg#endif 301ab64890Smrg 311ab64890Smrg 321ab64890Smrg#include <stdio.h> 331ab64890Smrg#include "Xlibint.h" 341ab64890Smrg#include "XKBlibint.h" 351ab64890Smrg#include <X11/extensions/XKBgeom.h> 361ab64890Smrg#include <X11/extensions/XKBproto.h> 371ab64890Smrg#include "XKBlibint.h" 381ab64890Smrg 391ab64890Smrg 401ab64890Smrg/***===================================================================***/ 411ab64890Smrg 421ab64890Smrg/*ARGSUSED*/ 431ab64890SmrgStatus 44818534a1SmrgXkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI) 451ab64890Smrg{ 46818534a1Smrg XkbCompatMapPtr compat; 47818534a1Smrg XkbSymInterpretRec *prev_interpret; 481ab64890Smrg 491ab64890Smrg if (!xkb) 50818534a1Smrg return BadMatch; 511ab64890Smrg if (xkb->compat) { 52818534a1Smrg if (xkb->compat->size_si >= nSI) 53818534a1Smrg return Success; 54818534a1Smrg compat = xkb->compat; 55818534a1Smrg compat->size_si = nSI; 56818534a1Smrg if (compat->sym_interpret == NULL) 57818534a1Smrg compat->num_si = 0; 58818534a1Smrg prev_interpret = compat->sym_interpret; 59818534a1Smrg compat->sym_interpret = _XkbTypedRealloc(compat->sym_interpret, 60818534a1Smrg nSI, XkbSymInterpretRec); 61818534a1Smrg if (compat->sym_interpret == NULL) { 62818534a1Smrg _XkbFree(prev_interpret); 63818534a1Smrg compat->size_si = compat->num_si = 0; 64818534a1Smrg return BadAlloc; 65818534a1Smrg } 66818534a1Smrg if (compat->num_si != 0) { 67818534a1Smrg _XkbClearElems(compat->sym_interpret, compat->num_si, 68818534a1Smrg compat->size_si - 1, XkbSymInterpretRec); 69818534a1Smrg } 70818534a1Smrg return Success; 711ab64890Smrg } 72818534a1Smrg compat = _XkbTypedCalloc(1, XkbCompatMapRec); 73818534a1Smrg if (compat == NULL) 74818534a1Smrg return BadAlloc; 75818534a1Smrg if (nSI > 0) { 76818534a1Smrg compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec); 77818534a1Smrg if (!compat->sym_interpret) { 78818534a1Smrg _XkbFree(compat); 79818534a1Smrg return BadAlloc; 80818534a1Smrg } 811ab64890Smrg } 82818534a1Smrg compat->size_si = nSI; 83818534a1Smrg compat->num_si = 0; 84818534a1Smrg bzero((char *) &compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 85818534a1Smrg xkb->compat = compat; 861ab64890Smrg return Success; 871ab64890Smrg} 881ab64890Smrg 891ab64890Smrg 901ab64890Smrgvoid 91818534a1SmrgXkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) 921ab64890Smrg{ 93818534a1Smrg register XkbCompatMapPtr compat; 941ab64890Smrg 95818534a1Smrg if ((xkb == NULL) || (xkb->compat == NULL)) 96818534a1Smrg return; 97818534a1Smrg compat = xkb->compat; 981ab64890Smrg if (freeMap) 99818534a1Smrg which = XkbAllCompatMask; 100818534a1Smrg if (which & XkbGroupCompatMask) 101818534a1Smrg bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 102818534a1Smrg if (which & XkbSymInterpMask) { 103818534a1Smrg if ((compat->sym_interpret) && (compat->size_si > 0)) 104818534a1Smrg _XkbFree(compat->sym_interpret); 105818534a1Smrg compat->size_si = compat->num_si = 0; 106818534a1Smrg compat->sym_interpret = NULL; 1071ab64890Smrg } 1081ab64890Smrg if (freeMap) { 109818534a1Smrg _XkbFree(compat); 110818534a1Smrg xkb->compat = NULL; 1111ab64890Smrg } 1121ab64890Smrg return; 1131ab64890Smrg} 1141ab64890Smrg 1151ab64890Smrg/***===================================================================***/ 1161ab64890Smrg 1171ab64890SmrgStatus 118818534a1SmrgXkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) 1191ab64890Smrg{ 120818534a1Smrg XkbNamesPtr names; 121818534a1Smrg 122818534a1Smrg if (xkb == NULL) 123818534a1Smrg return BadMatch; 124818534a1Smrg if (xkb->names == NULL) { 125818534a1Smrg xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 126818534a1Smrg if (xkb->names == NULL) 127818534a1Smrg return BadAlloc; 1281ab64890Smrg } 129818534a1Smrg names = xkb->names; 130818534a1Smrg if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && 131818534a1Smrg (xkb->map->types != NULL)) { 132818534a1Smrg register int i; 133818534a1Smrg XkbKeyTypePtr type = xkb->map->types; 134818534a1Smrg 135818534a1Smrg for (i = 0; i < xkb->map->num_types; i++, type++) { 136818534a1Smrg if (type->level_names == NULL) { 137818534a1Smrg type->level_names = _XkbTypedCalloc(type->num_levels, Atom); 138818534a1Smrg if (type->level_names == NULL) 139818534a1Smrg return BadAlloc; 140818534a1Smrg } 141818534a1Smrg } 1421ab64890Smrg } 143818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { 144818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 145818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 146818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 147818534a1Smrg return BadValue; 148818534a1Smrg names->keys = _XkbTypedCalloc((xkb->max_key_code + 1), XkbKeyNameRec); 149818534a1Smrg if (names->keys == NULL) 150818534a1Smrg return BadAlloc; 1511ab64890Smrg } 152818534a1Smrg if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { 153818534a1Smrg if (names->key_aliases == NULL) { 154818534a1Smrg names->key_aliases = _XkbTypedCalloc(nTotalAliases, XkbKeyAliasRec); 155818534a1Smrg } 156818534a1Smrg else if (nTotalAliases > names->num_key_aliases) { 157818534a1Smrg XkbKeyAliasRec *prev_aliases = names->key_aliases; 158818534a1Smrg 159818534a1Smrg names->key_aliases = _XkbTypedRealloc(names->key_aliases, 160818534a1Smrg nTotalAliases, 161818534a1Smrg XkbKeyAliasRec); 162818534a1Smrg if (names->key_aliases != NULL) { 163818534a1Smrg _XkbClearElems(names->key_aliases, names->num_key_aliases, 164818534a1Smrg nTotalAliases - 1, XkbKeyAliasRec); 165818534a1Smrg } 166818534a1Smrg else { 167818534a1Smrg _XkbFree(prev_aliases); 168818534a1Smrg } 169818534a1Smrg } 170818534a1Smrg if (names->key_aliases == NULL) { 171818534a1Smrg names->num_key_aliases = 0; 172818534a1Smrg return BadAlloc; 173818534a1Smrg } 174818534a1Smrg names->num_key_aliases = nTotalAliases; 1751ab64890Smrg } 176818534a1Smrg if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { 177818534a1Smrg if (names->radio_groups == NULL) { 178818534a1Smrg names->radio_groups = _XkbTypedCalloc(nTotalRG, Atom); 179818534a1Smrg } 180818534a1Smrg else if (nTotalRG > names->num_rg) { 181818534a1Smrg Atom *prev_radio_groups = names->radio_groups; 182818534a1Smrg 183818534a1Smrg names->radio_groups = 184818534a1Smrg _XkbTypedRealloc(names->radio_groups, nTotalRG, Atom); 185818534a1Smrg if (names->radio_groups != NULL) { 186818534a1Smrg _XkbClearElems(names->radio_groups, names->num_rg, nTotalRG - 1, 187818534a1Smrg Atom); 188818534a1Smrg } 189818534a1Smrg else { 190818534a1Smrg _XkbFree(prev_radio_groups); 191818534a1Smrg } 192818534a1Smrg } 193818534a1Smrg if (names->radio_groups == NULL) 194818534a1Smrg return BadAlloc; 195818534a1Smrg names->num_rg = nTotalRG; 1961ab64890Smrg } 1971ab64890Smrg return Success; 1981ab64890Smrg} 1991ab64890Smrg 2001ab64890Smrgvoid 201818534a1SmrgXkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) 2021ab64890Smrg{ 203818534a1Smrg XkbNamesPtr names; 2041ab64890Smrg 205818534a1Smrg if ((xkb == NULL) || (xkb->names == NULL)) 206818534a1Smrg return; 207818534a1Smrg names = xkb->names; 2081ab64890Smrg if (freeMap) 209818534a1Smrg which = XkbAllNamesMask; 210818534a1Smrg if (which & XkbKTLevelNamesMask) { 211818534a1Smrg XkbClientMapPtr map = xkb->map; 212818534a1Smrg 213818534a1Smrg if ((map != NULL) && (map->types != NULL)) { 214818534a1Smrg register int i; 215818534a1Smrg register XkbKeyTypePtr type; 216818534a1Smrg 217818534a1Smrg type = map->types; 218818534a1Smrg for (i = 0; i < map->num_types; i++, type++) { 219818534a1Smrg if (type->level_names != NULL) { 220818534a1Smrg _XkbFree(type->level_names); 221818534a1Smrg type->level_names = NULL; 222818534a1Smrg } 223818534a1Smrg } 224818534a1Smrg } 2251ab64890Smrg } 226818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 227818534a1Smrg _XkbFree(names->keys); 228818534a1Smrg names->keys = NULL; 229818534a1Smrg names->num_keys = 0; 2301ab64890Smrg } 231818534a1Smrg if ((which & XkbKeyAliasesMask) && (names->key_aliases)) { 232818534a1Smrg _XkbFree(names->key_aliases); 233818534a1Smrg names->key_aliases = NULL; 234818534a1Smrg names->num_key_aliases = 0; 2351ab64890Smrg } 236818534a1Smrg if ((which & XkbRGNamesMask) && (names->radio_groups)) { 237818534a1Smrg _XkbFree(names->radio_groups); 238818534a1Smrg names->radio_groups = NULL; 239818534a1Smrg names->num_rg = 0; 2401ab64890Smrg } 2411ab64890Smrg if (freeMap) { 242818534a1Smrg _XkbFree(names); 243818534a1Smrg xkb->names = NULL; 2441ab64890Smrg } 2451ab64890Smrg return; 2461ab64890Smrg} 2471ab64890Smrg 2481ab64890Smrg/***===================================================================***/ 2491ab64890Smrg 2501ab64890Smrg/*ARGSUSED*/ 2511ab64890SmrgStatus 252818534a1SmrgXkbAllocControls(XkbDescPtr xkb, unsigned which) 2531ab64890Smrg{ 254818534a1Smrg if (xkb == NULL) 255818534a1Smrg return BadMatch; 2561ab64890Smrg 257818534a1Smrg if (xkb->ctrls == NULL) { 258818534a1Smrg xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); 259818534a1Smrg if (!xkb->ctrls) 260818534a1Smrg return BadAlloc; 2611ab64890Smrg } 2621ab64890Smrg return Success; 2631ab64890Smrg} 2641ab64890Smrg 2651ab64890Smrg/*ARGSUSED*/ 2661ab64890Smrgvoid 267818534a1SmrgXkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 2681ab64890Smrg{ 269818534a1Smrg if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 270818534a1Smrg _XkbFree(xkb->ctrls); 271818534a1Smrg xkb->ctrls = NULL; 2721ab64890Smrg } 2731ab64890Smrg return; 2741ab64890Smrg} 2751ab64890Smrg 2761ab64890Smrg/***===================================================================***/ 2771ab64890Smrg 27861b2299dSmrgStatus 2791ab64890SmrgXkbAllocIndicatorMaps(XkbDescPtr xkb) 2801ab64890Smrg{ 281818534a1Smrg if (xkb == NULL) 282818534a1Smrg return BadMatch; 283818534a1Smrg if (xkb->indicators == NULL) { 284818534a1Smrg xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); 285818534a1Smrg if (!xkb->indicators) 286818534a1Smrg return BadAlloc; 2871ab64890Smrg } 2881ab64890Smrg return Success; 2891ab64890Smrg} 2901ab64890Smrg 2911ab64890Smrgvoid 2921ab64890SmrgXkbFreeIndicatorMaps(XkbDescPtr xkb) 2931ab64890Smrg{ 294818534a1Smrg if ((xkb != NULL) && (xkb->indicators != NULL)) { 295818534a1Smrg _XkbFree(xkb->indicators); 296818534a1Smrg xkb->indicators = NULL; 2971ab64890Smrg } 2981ab64890Smrg return; 2991ab64890Smrg} 3001ab64890Smrg 3011ab64890Smrg/***====================================================================***/ 3021ab64890Smrg 303818534a1SmrgXkbDescRec * 3041ab64890SmrgXkbAllocKeyboard(void) 3051ab64890Smrg{ 306818534a1Smrg XkbDescRec *xkb; 3071ab64890Smrg 308818534a1Smrg xkb = _XkbTypedCalloc(1, XkbDescRec); 3091ab64890Smrg if (xkb) 310818534a1Smrg xkb->device_spec = XkbUseCoreKbd; 3111ab64890Smrg return xkb; 3121ab64890Smrg} 3131ab64890Smrg 3141ab64890Smrgvoid 315818534a1SmrgXkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) 3161ab64890Smrg{ 317818534a1Smrg if (xkb == NULL) 318818534a1Smrg return; 3191ab64890Smrg if (freeAll) 320818534a1Smrg which = XkbAllComponentsMask; 321818534a1Smrg if (which & XkbClientMapMask) 322818534a1Smrg XkbFreeClientMap(xkb, XkbAllClientInfoMask, True); 323818534a1Smrg if (which & XkbServerMapMask) 324818534a1Smrg XkbFreeServerMap(xkb, XkbAllServerInfoMask, True); 325818534a1Smrg if (which & XkbCompatMapMask) 326818534a1Smrg XkbFreeCompatMap(xkb, XkbAllCompatMask, True); 327818534a1Smrg if (which & XkbIndicatorMapMask) 328818534a1Smrg XkbFreeIndicatorMaps(xkb); 329818534a1Smrg if (which & XkbNamesMask) 330818534a1Smrg XkbFreeNames(xkb, XkbAllNamesMask, True); 331818534a1Smrg if ((which & XkbGeometryMask) && (xkb->geom != NULL)) 332818534a1Smrg XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); 333818534a1Smrg if (which & XkbControlsMask) 334818534a1Smrg XkbFreeControls(xkb, XkbAllControlsMask, True); 3351ab64890Smrg if (freeAll) 336818534a1Smrg _XkbFree(xkb); 3371ab64890Smrg return; 3381ab64890Smrg} 3391ab64890Smrg 3401ab64890Smrg/***====================================================================***/ 3411ab64890Smrg 3421ab64890SmrgXkbDeviceLedInfoPtr 343818534a1SmrgXkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 3441ab64890Smrg{ 345818534a1Smrg XkbDeviceLedInfoPtr devli; 346818534a1Smrg register int i; 347818534a1Smrg 348818534a1Smrg if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 349818534a1Smrg return NULL; 350818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 351818534a1Smrg if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 352818534a1Smrg return devli; 3531ab64890Smrg } 354818534a1Smrg if (devi->num_leds >= devi->sz_leds) { 355818534a1Smrg XkbDeviceLedInfoRec *prev_leds = devi->leds; 356818534a1Smrg 357818534a1Smrg if (devi->sz_leds > 0) 358818534a1Smrg devi->sz_leds *= 2; 359818534a1Smrg else 360818534a1Smrg devi->sz_leds = 1; 361818534a1Smrg devi->leds = _XkbTypedRealloc(devi->leds, devi->sz_leds, 362818534a1Smrg XkbDeviceLedInfoRec); 363818534a1Smrg if (!devi->leds) { 364818534a1Smrg _XkbFree(prev_leds); 365818534a1Smrg devi->sz_leds = devi->num_leds = 0; 366818534a1Smrg return NULL; 367818534a1Smrg } 368818534a1Smrg i = devi->num_leds; 369818534a1Smrg for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 370818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 371818534a1Smrg devli->led_class = XkbXINone; 372818534a1Smrg devli->led_id = XkbXINone; 373818534a1Smrg } 3741ab64890Smrg } 375818534a1Smrg devli = &devi->leds[devi->num_leds++]; 376818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 377818534a1Smrg devli->led_class = ledClass; 378818534a1Smrg devli->led_id = ledId; 3791ab64890Smrg return devli; 3801ab64890Smrg} 3811ab64890Smrg 3821ab64890SmrgStatus 383818534a1SmrgXkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 3841ab64890Smrg{ 3851ab64890Smrg XkbAction *prev_btn_acts; 3861ab64890Smrg 387818534a1Smrg if ((!devi) || (newTotal > 255)) 388818534a1Smrg return BadValue; 389818534a1Smrg if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 390818534a1Smrg return Success; 391818534a1Smrg if (newTotal == 0) { 392818534a1Smrg if (devi->btn_acts != NULL) { 393818534a1Smrg _XkbFree(devi->btn_acts); 394818534a1Smrg devi->btn_acts = NULL; 395818534a1Smrg } 396818534a1Smrg devi->num_btns = 0; 397818534a1Smrg return Success; 3981ab64890Smrg } 3991ab64890Smrg prev_btn_acts = devi->btn_acts; 400818534a1Smrg devi->btn_acts = _XkbTypedRealloc(devi->btn_acts, newTotal, XkbAction); 401818534a1Smrg if (devi->btn_acts == NULL) { 402818534a1Smrg _XkbFree(prev_btn_acts); 403818534a1Smrg devi->num_btns = 0; 404818534a1Smrg return BadAlloc; 4051ab64890Smrg } 406818534a1Smrg if (newTotal > devi->num_btns) { 407818534a1Smrg XkbAction *act; 408818534a1Smrg 409818534a1Smrg act = &devi->btn_acts[devi->num_btns]; 410818534a1Smrg bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 4111ab64890Smrg } 412818534a1Smrg devi->num_btns = newTotal; 4131ab64890Smrg return Success; 4141ab64890Smrg} 4151ab64890Smrg 4161ab64890Smrg/*ARGSUSED*/ 4171ab64890SmrgXkbDeviceInfoPtr 418818534a1SmrgXkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 4191ab64890Smrg{ 420818534a1Smrg XkbDeviceInfoPtr devi; 421818534a1Smrg 422818534a1Smrg devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 423818534a1Smrg if (devi != NULL) { 424818534a1Smrg devi->device_spec = deviceSpec; 425818534a1Smrg devi->has_own_state = False; 426818534a1Smrg devi->num_btns = 0; 427818534a1Smrg devi->btn_acts = NULL; 428818534a1Smrg if (nButtons > 0) { 429818534a1Smrg devi->num_btns = nButtons; 430818534a1Smrg devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 431818534a1Smrg if (!devi->btn_acts) { 432818534a1Smrg _XkbFree(devi); 433818534a1Smrg return NULL; 434818534a1Smrg } 435818534a1Smrg } 436818534a1Smrg devi->dflt_kbd_fb = XkbXINone; 437818534a1Smrg devi->dflt_led_fb = XkbXINone; 438818534a1Smrg devi->num_leds = 0; 439818534a1Smrg devi->sz_leds = 0; 440818534a1Smrg devi->leds = NULL; 441818534a1Smrg if (szLeds > 0) { 442818534a1Smrg devi->sz_leds = szLeds; 443818534a1Smrg devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 444818534a1Smrg if (!devi->leds) { 4450f8248bfSmrg _XkbFree(devi->btn_acts); 446818534a1Smrg _XkbFree(devi); 447818534a1Smrg return NULL; 448818534a1Smrg } 449818534a1Smrg } 4501ab64890Smrg } 4511ab64890Smrg return devi; 4521ab64890Smrg} 4531ab64890Smrg 4541ab64890Smrg 45561b2299dSmrgvoid 456818534a1SmrgXkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 4571ab64890Smrg{ 4581ab64890Smrg if (devi) { 459818534a1Smrg if (freeDevI) { 460818534a1Smrg which = XkbXI_AllDeviceFeaturesMask; 461818534a1Smrg if (devi->name) { 462818534a1Smrg _XkbFree(devi->name); 463818534a1Smrg devi->name = NULL; 464818534a1Smrg } 465818534a1Smrg } 466818534a1Smrg if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 467818534a1Smrg _XkbFree(devi->btn_acts); 468818534a1Smrg devi->num_btns = 0; 469818534a1Smrg devi->btn_acts = NULL; 470818534a1Smrg } 471818534a1Smrg if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 472818534a1Smrg register int i; 473818534a1Smrg 474818534a1Smrg if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 475818534a1Smrg _XkbFree(devi->leds); 476818534a1Smrg devi->sz_leds = devi->num_leds = 0; 477818534a1Smrg devi->leds = NULL; 478818534a1Smrg } 479818534a1Smrg else { 480818534a1Smrg XkbDeviceLedInfoPtr devli; 481818534a1Smrg 482818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; 483818534a1Smrg i++, devli++) { 484818534a1Smrg if (which & XkbXI_IndicatorMapsMask) 485818534a1Smrg bzero((char *) &devli->maps[0], sizeof(devli->maps)); 486818534a1Smrg else 487818534a1Smrg bzero((char *) &devli->names[0], sizeof(devli->names)); 488818534a1Smrg } 489818534a1Smrg } 490818534a1Smrg } 491818534a1Smrg if (freeDevI) 492818534a1Smrg _XkbFree(devi); 4931ab64890Smrg } 4941ab64890Smrg return; 4951ab64890Smrg} 496