XKBAlloc.c revision 258a0ebe
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; 471ab64890Smrg 481ab64890Smrg if (!xkb) 49818534a1Smrg return BadMatch; 501ab64890Smrg if (xkb->compat) { 51818534a1Smrg if (xkb->compat->size_si >= nSI) 52818534a1Smrg return Success; 53818534a1Smrg compat = xkb->compat; 54818534a1Smrg compat->size_si = nSI; 55818534a1Smrg if (compat->sym_interpret == NULL) 56818534a1Smrg compat->num_si = 0; 57258a0ebeSmrg _XkbResizeArray(compat->sym_interpret, compat->num_si, 58258a0ebeSmrg nSI, XkbSymInterpretRec); 59818534a1Smrg if (compat->sym_interpret == NULL) { 60818534a1Smrg compat->size_si = compat->num_si = 0; 61818534a1Smrg return BadAlloc; 62818534a1Smrg } 63818534a1Smrg return Success; 641ab64890Smrg } 65818534a1Smrg compat = _XkbTypedCalloc(1, XkbCompatMapRec); 66818534a1Smrg if (compat == NULL) 67818534a1Smrg return BadAlloc; 68818534a1Smrg if (nSI > 0) { 69818534a1Smrg compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec); 70818534a1Smrg if (!compat->sym_interpret) { 71818534a1Smrg _XkbFree(compat); 72818534a1Smrg return BadAlloc; 73818534a1Smrg } 741ab64890Smrg } 75818534a1Smrg compat->size_si = nSI; 76818534a1Smrg compat->num_si = 0; 77818534a1Smrg bzero((char *) &compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 78818534a1Smrg xkb->compat = compat; 791ab64890Smrg return Success; 801ab64890Smrg} 811ab64890Smrg 821ab64890Smrg 831ab64890Smrgvoid 84818534a1SmrgXkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) 851ab64890Smrg{ 86818534a1Smrg register XkbCompatMapPtr compat; 871ab64890Smrg 88818534a1Smrg if ((xkb == NULL) || (xkb->compat == NULL)) 89818534a1Smrg return; 90818534a1Smrg compat = xkb->compat; 911ab64890Smrg if (freeMap) 92818534a1Smrg which = XkbAllCompatMask; 93818534a1Smrg if (which & XkbGroupCompatMask) 94818534a1Smrg bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 95818534a1Smrg if (which & XkbSymInterpMask) { 96818534a1Smrg if ((compat->sym_interpret) && (compat->size_si > 0)) 97818534a1Smrg _XkbFree(compat->sym_interpret); 98818534a1Smrg compat->size_si = compat->num_si = 0; 99818534a1Smrg compat->sym_interpret = NULL; 1001ab64890Smrg } 1011ab64890Smrg if (freeMap) { 102818534a1Smrg _XkbFree(compat); 103818534a1Smrg xkb->compat = NULL; 1041ab64890Smrg } 1051ab64890Smrg return; 1061ab64890Smrg} 1071ab64890Smrg 1081ab64890Smrg/***===================================================================***/ 1091ab64890Smrg 1101ab64890SmrgStatus 111818534a1SmrgXkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) 1121ab64890Smrg{ 113818534a1Smrg XkbNamesPtr names; 114818534a1Smrg 115818534a1Smrg if (xkb == NULL) 116818534a1Smrg return BadMatch; 117818534a1Smrg if (xkb->names == NULL) { 118818534a1Smrg xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 119818534a1Smrg if (xkb->names == NULL) 120818534a1Smrg return BadAlloc; 1211ab64890Smrg } 122818534a1Smrg names = xkb->names; 123818534a1Smrg if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && 124818534a1Smrg (xkb->map->types != NULL)) { 125818534a1Smrg register int i; 126818534a1Smrg XkbKeyTypePtr type = xkb->map->types; 127818534a1Smrg 128818534a1Smrg for (i = 0; i < xkb->map->num_types; i++, type++) { 129818534a1Smrg if (type->level_names == NULL) { 130818534a1Smrg type->level_names = _XkbTypedCalloc(type->num_levels, Atom); 131818534a1Smrg if (type->level_names == NULL) 132818534a1Smrg return BadAlloc; 133818534a1Smrg } 134818534a1Smrg } 1351ab64890Smrg } 136818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { 137818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 138818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 139818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 140818534a1Smrg return BadValue; 141818534a1Smrg names->keys = _XkbTypedCalloc((xkb->max_key_code + 1), XkbKeyNameRec); 142818534a1Smrg if (names->keys == NULL) 143818534a1Smrg return BadAlloc; 1441ab64890Smrg } 145818534a1Smrg if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { 146258a0ebeSmrg if ((names->key_aliases == NULL) || 147258a0ebeSmrg (nTotalAliases > names->num_key_aliases)) { 148258a0ebeSmrg _XkbResizeArray(names->key_aliases, names->num_key_aliases, 149258a0ebeSmrg nTotalAliases, XkbKeyAliasRec); 150818534a1Smrg } 151818534a1Smrg if (names->key_aliases == NULL) { 152818534a1Smrg names->num_key_aliases = 0; 153818534a1Smrg return BadAlloc; 154818534a1Smrg } 155818534a1Smrg names->num_key_aliases = nTotalAliases; 1561ab64890Smrg } 157818534a1Smrg if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { 158258a0ebeSmrg if ((names->radio_groups == NULL) || (nTotalRG > names->num_rg)) { 159258a0ebeSmrg _XkbResizeArray(names->radio_groups, names->num_rg, nTotalRG, Atom); 160818534a1Smrg } 161258a0ebeSmrg if (names->radio_groups == NULL) { 162258a0ebeSmrg names->num_rg = 0; 163818534a1Smrg return BadAlloc; 164258a0ebeSmrg } 165818534a1Smrg names->num_rg = nTotalRG; 1661ab64890Smrg } 1671ab64890Smrg return Success; 1681ab64890Smrg} 1691ab64890Smrg 1701ab64890Smrgvoid 171818534a1SmrgXkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) 1721ab64890Smrg{ 173818534a1Smrg XkbNamesPtr names; 1741ab64890Smrg 175818534a1Smrg if ((xkb == NULL) || (xkb->names == NULL)) 176818534a1Smrg return; 177818534a1Smrg names = xkb->names; 1781ab64890Smrg if (freeMap) 179818534a1Smrg which = XkbAllNamesMask; 180818534a1Smrg if (which & XkbKTLevelNamesMask) { 181818534a1Smrg XkbClientMapPtr map = xkb->map; 182818534a1Smrg 183818534a1Smrg if ((map != NULL) && (map->types != NULL)) { 184818534a1Smrg register int i; 185818534a1Smrg register XkbKeyTypePtr type; 186818534a1Smrg 187818534a1Smrg type = map->types; 188818534a1Smrg for (i = 0; i < map->num_types; i++, type++) { 189818534a1Smrg _XkbFree(type->level_names); 190818534a1Smrg type->level_names = NULL; 191818534a1Smrg } 192818534a1Smrg } 1931ab64890Smrg } 1943233502eSmrg if (which & XkbKeyNamesMask) { 195818534a1Smrg _XkbFree(names->keys); 196818534a1Smrg names->keys = NULL; 197818534a1Smrg names->num_keys = 0; 1981ab64890Smrg } 1993233502eSmrg if (which & XkbKeyAliasesMask) { 200818534a1Smrg _XkbFree(names->key_aliases); 201818534a1Smrg names->key_aliases = NULL; 202818534a1Smrg names->num_key_aliases = 0; 2031ab64890Smrg } 2043233502eSmrg if (which & XkbRGNamesMask) { 205818534a1Smrg _XkbFree(names->radio_groups); 206818534a1Smrg names->radio_groups = NULL; 207818534a1Smrg names->num_rg = 0; 2081ab64890Smrg } 2091ab64890Smrg if (freeMap) { 210818534a1Smrg _XkbFree(names); 211818534a1Smrg xkb->names = NULL; 2121ab64890Smrg } 2131ab64890Smrg return; 2141ab64890Smrg} 2151ab64890Smrg 2161ab64890Smrg/***===================================================================***/ 2171ab64890Smrg 2181ab64890Smrg/*ARGSUSED*/ 2191ab64890SmrgStatus 220818534a1SmrgXkbAllocControls(XkbDescPtr xkb, unsigned which) 2211ab64890Smrg{ 222818534a1Smrg if (xkb == NULL) 223818534a1Smrg return BadMatch; 2241ab64890Smrg 225818534a1Smrg if (xkb->ctrls == NULL) { 226818534a1Smrg xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); 227818534a1Smrg if (!xkb->ctrls) 228818534a1Smrg return BadAlloc; 2291ab64890Smrg } 2301ab64890Smrg return Success; 2311ab64890Smrg} 2321ab64890Smrg 2331ab64890Smrg/*ARGSUSED*/ 2341ab64890Smrgvoid 235818534a1SmrgXkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 2361ab64890Smrg{ 237818534a1Smrg if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 238818534a1Smrg _XkbFree(xkb->ctrls); 239818534a1Smrg xkb->ctrls = NULL; 2401ab64890Smrg } 2411ab64890Smrg return; 2421ab64890Smrg} 2431ab64890Smrg 2441ab64890Smrg/***===================================================================***/ 2451ab64890Smrg 24661b2299dSmrgStatus 2471ab64890SmrgXkbAllocIndicatorMaps(XkbDescPtr xkb) 2481ab64890Smrg{ 249818534a1Smrg if (xkb == NULL) 250818534a1Smrg return BadMatch; 251818534a1Smrg if (xkb->indicators == NULL) { 252818534a1Smrg xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); 253818534a1Smrg if (!xkb->indicators) 254818534a1Smrg return BadAlloc; 2551ab64890Smrg } 2561ab64890Smrg return Success; 2571ab64890Smrg} 2581ab64890Smrg 2591ab64890Smrgvoid 2601ab64890SmrgXkbFreeIndicatorMaps(XkbDescPtr xkb) 2611ab64890Smrg{ 262818534a1Smrg if ((xkb != NULL) && (xkb->indicators != NULL)) { 263818534a1Smrg _XkbFree(xkb->indicators); 264818534a1Smrg xkb->indicators = NULL; 2651ab64890Smrg } 2661ab64890Smrg return; 2671ab64890Smrg} 2681ab64890Smrg 2691ab64890Smrg/***====================================================================***/ 2701ab64890Smrg 271818534a1SmrgXkbDescRec * 2721ab64890SmrgXkbAllocKeyboard(void) 2731ab64890Smrg{ 274818534a1Smrg XkbDescRec *xkb; 2751ab64890Smrg 276818534a1Smrg xkb = _XkbTypedCalloc(1, XkbDescRec); 2771ab64890Smrg if (xkb) 278818534a1Smrg xkb->device_spec = XkbUseCoreKbd; 2791ab64890Smrg return xkb; 2801ab64890Smrg} 2811ab64890Smrg 2821ab64890Smrgvoid 283818534a1SmrgXkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) 2841ab64890Smrg{ 285818534a1Smrg if (xkb == NULL) 286818534a1Smrg return; 2871ab64890Smrg if (freeAll) 288818534a1Smrg which = XkbAllComponentsMask; 289818534a1Smrg if (which & XkbClientMapMask) 290818534a1Smrg XkbFreeClientMap(xkb, XkbAllClientInfoMask, True); 291818534a1Smrg if (which & XkbServerMapMask) 292818534a1Smrg XkbFreeServerMap(xkb, XkbAllServerInfoMask, True); 293818534a1Smrg if (which & XkbCompatMapMask) 294818534a1Smrg XkbFreeCompatMap(xkb, XkbAllCompatMask, True); 295818534a1Smrg if (which & XkbIndicatorMapMask) 296818534a1Smrg XkbFreeIndicatorMaps(xkb); 297818534a1Smrg if (which & XkbNamesMask) 298818534a1Smrg XkbFreeNames(xkb, XkbAllNamesMask, True); 299818534a1Smrg if ((which & XkbGeometryMask) && (xkb->geom != NULL)) 300818534a1Smrg XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); 301818534a1Smrg if (which & XkbControlsMask) 302818534a1Smrg XkbFreeControls(xkb, XkbAllControlsMask, True); 3031ab64890Smrg if (freeAll) 304818534a1Smrg _XkbFree(xkb); 3051ab64890Smrg return; 3061ab64890Smrg} 3071ab64890Smrg 3081ab64890Smrg/***====================================================================***/ 3091ab64890Smrg 3101ab64890SmrgXkbDeviceLedInfoPtr 311818534a1SmrgXkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 3121ab64890Smrg{ 313818534a1Smrg XkbDeviceLedInfoPtr devli; 314818534a1Smrg register int i; 315818534a1Smrg 316818534a1Smrg if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 317818534a1Smrg return NULL; 318818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 319818534a1Smrg if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 320818534a1Smrg return devli; 3211ab64890Smrg } 322818534a1Smrg if (devi->num_leds >= devi->sz_leds) { 323818534a1Smrg if (devi->sz_leds > 0) 324818534a1Smrg devi->sz_leds *= 2; 325818534a1Smrg else 326818534a1Smrg devi->sz_leds = 1; 327258a0ebeSmrg _XkbResizeArray(devi->leds, devi->num_leds, devi->sz_leds, 328258a0ebeSmrg XkbDeviceLedInfoRec); 329818534a1Smrg if (!devi->leds) { 330818534a1Smrg devi->sz_leds = devi->num_leds = 0; 331818534a1Smrg return NULL; 332818534a1Smrg } 333818534a1Smrg i = devi->num_leds; 334818534a1Smrg for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 335818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 336818534a1Smrg devli->led_class = XkbXINone; 337818534a1Smrg devli->led_id = XkbXINone; 338818534a1Smrg } 3391ab64890Smrg } 340818534a1Smrg devli = &devi->leds[devi->num_leds++]; 341818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 342818534a1Smrg devli->led_class = ledClass; 343818534a1Smrg devli->led_id = ledId; 3441ab64890Smrg return devli; 3451ab64890Smrg} 3461ab64890Smrg 3471ab64890SmrgStatus 348818534a1SmrgXkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 3491ab64890Smrg{ 350818534a1Smrg if ((!devi) || (newTotal > 255)) 351818534a1Smrg return BadValue; 352818534a1Smrg if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 353818534a1Smrg return Success; 354818534a1Smrg if (newTotal == 0) { 355818534a1Smrg if (devi->btn_acts != NULL) { 356818534a1Smrg _XkbFree(devi->btn_acts); 357818534a1Smrg devi->btn_acts = NULL; 358818534a1Smrg } 359818534a1Smrg devi->num_btns = 0; 360818534a1Smrg return Success; 3611ab64890Smrg } 362258a0ebeSmrg _XkbResizeArray(devi->btn_acts, devi->num_btns, newTotal, XkbAction); 363818534a1Smrg if (devi->btn_acts == NULL) { 364818534a1Smrg devi->num_btns = 0; 365818534a1Smrg return BadAlloc; 3661ab64890Smrg } 367818534a1Smrg if (newTotal > devi->num_btns) { 368818534a1Smrg XkbAction *act; 369818534a1Smrg 370818534a1Smrg act = &devi->btn_acts[devi->num_btns]; 371818534a1Smrg bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 3721ab64890Smrg } 373818534a1Smrg devi->num_btns = newTotal; 3741ab64890Smrg return Success; 3751ab64890Smrg} 3761ab64890Smrg 3771ab64890Smrg/*ARGSUSED*/ 3781ab64890SmrgXkbDeviceInfoPtr 379818534a1SmrgXkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 3801ab64890Smrg{ 381818534a1Smrg XkbDeviceInfoPtr devi; 382818534a1Smrg 383818534a1Smrg devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 384818534a1Smrg if (devi != NULL) { 385818534a1Smrg devi->device_spec = deviceSpec; 386818534a1Smrg devi->has_own_state = False; 387818534a1Smrg devi->num_btns = 0; 388818534a1Smrg devi->btn_acts = NULL; 389818534a1Smrg if (nButtons > 0) { 390818534a1Smrg devi->num_btns = nButtons; 391818534a1Smrg devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 392818534a1Smrg if (!devi->btn_acts) { 393818534a1Smrg _XkbFree(devi); 394818534a1Smrg return NULL; 395818534a1Smrg } 396818534a1Smrg } 397818534a1Smrg devi->dflt_kbd_fb = XkbXINone; 398818534a1Smrg devi->dflt_led_fb = XkbXINone; 399818534a1Smrg devi->num_leds = 0; 400818534a1Smrg devi->sz_leds = 0; 401818534a1Smrg devi->leds = NULL; 402818534a1Smrg if (szLeds > 0) { 403818534a1Smrg devi->sz_leds = szLeds; 404818534a1Smrg devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 405818534a1Smrg if (!devi->leds) { 4060f8248bfSmrg _XkbFree(devi->btn_acts); 407818534a1Smrg _XkbFree(devi); 408818534a1Smrg return NULL; 409818534a1Smrg } 410818534a1Smrg } 4111ab64890Smrg } 4121ab64890Smrg return devi; 4131ab64890Smrg} 4141ab64890Smrg 4151ab64890Smrg 41661b2299dSmrgvoid 417818534a1SmrgXkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 4181ab64890Smrg{ 4191ab64890Smrg if (devi) { 420818534a1Smrg if (freeDevI) { 421818534a1Smrg which = XkbXI_AllDeviceFeaturesMask; 422818534a1Smrg if (devi->name) { 423818534a1Smrg _XkbFree(devi->name); 424818534a1Smrg devi->name = NULL; 425818534a1Smrg } 426818534a1Smrg } 427818534a1Smrg if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 428818534a1Smrg _XkbFree(devi->btn_acts); 429818534a1Smrg devi->num_btns = 0; 430818534a1Smrg devi->btn_acts = NULL; 431818534a1Smrg } 432818534a1Smrg if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 433818534a1Smrg register int i; 434818534a1Smrg 435818534a1Smrg if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 436818534a1Smrg _XkbFree(devi->leds); 437818534a1Smrg devi->sz_leds = devi->num_leds = 0; 438818534a1Smrg devi->leds = NULL; 439818534a1Smrg } 440818534a1Smrg else { 441818534a1Smrg XkbDeviceLedInfoPtr devli; 442818534a1Smrg 443818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; 444818534a1Smrg i++, devli++) { 445818534a1Smrg if (which & XkbXI_IndicatorMapsMask) 446818534a1Smrg bzero((char *) &devli->maps[0], sizeof(devli->maps)); 447818534a1Smrg else 448818534a1Smrg bzero((char *) &devli->names[0], sizeof(devli->names)); 449818534a1Smrg } 450818534a1Smrg } 451818534a1Smrg } 452818534a1Smrg if (freeDevI) 453818534a1Smrg _XkbFree(devi); 4541ab64890Smrg } 4551ab64890Smrg return; 4561ab64890Smrg} 457