XKBAlloc.c revision 07fb9b8f
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" 355afda2e6Smrg#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); 29907fb9b8fSmrg if ((which & XkbGeometryMask) && (xkb->geom != NULL)) { 300818534a1Smrg XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); 30107fb9b8fSmrg xkb->geom = NULL; 30207fb9b8fSmrg } 303818534a1Smrg if (which & XkbControlsMask) 304818534a1Smrg XkbFreeControls(xkb, XkbAllControlsMask, True); 3051ab64890Smrg if (freeAll) 306818534a1Smrg _XkbFree(xkb); 3071ab64890Smrg return; 3081ab64890Smrg} 3091ab64890Smrg 3101ab64890Smrg/***====================================================================***/ 3111ab64890Smrg 3121ab64890SmrgXkbDeviceLedInfoPtr 313818534a1SmrgXkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 3141ab64890Smrg{ 315818534a1Smrg XkbDeviceLedInfoPtr devli; 316818534a1Smrg register int i; 317818534a1Smrg 318818534a1Smrg if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 319818534a1Smrg return NULL; 320818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 321818534a1Smrg if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 322818534a1Smrg return devli; 3231ab64890Smrg } 324818534a1Smrg if (devi->num_leds >= devi->sz_leds) { 325818534a1Smrg if (devi->sz_leds > 0) 326818534a1Smrg devi->sz_leds *= 2; 327818534a1Smrg else 328818534a1Smrg devi->sz_leds = 1; 329258a0ebeSmrg _XkbResizeArray(devi->leds, devi->num_leds, devi->sz_leds, 330258a0ebeSmrg XkbDeviceLedInfoRec); 331818534a1Smrg if (!devi->leds) { 332818534a1Smrg devi->sz_leds = devi->num_leds = 0; 333818534a1Smrg return NULL; 334818534a1Smrg } 335818534a1Smrg i = devi->num_leds; 336818534a1Smrg for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 337818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 338818534a1Smrg devli->led_class = XkbXINone; 339818534a1Smrg devli->led_id = XkbXINone; 340818534a1Smrg } 3411ab64890Smrg } 342818534a1Smrg devli = &devi->leds[devi->num_leds++]; 343818534a1Smrg bzero(devli, sizeof(XkbDeviceLedInfoRec)); 344818534a1Smrg devli->led_class = ledClass; 345818534a1Smrg devli->led_id = ledId; 3461ab64890Smrg return devli; 3471ab64890Smrg} 3481ab64890Smrg 3491ab64890SmrgStatus 350818534a1SmrgXkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 3511ab64890Smrg{ 352818534a1Smrg if ((!devi) || (newTotal > 255)) 353818534a1Smrg return BadValue; 354818534a1Smrg if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 355818534a1Smrg return Success; 356818534a1Smrg if (newTotal == 0) { 357818534a1Smrg if (devi->btn_acts != NULL) { 358818534a1Smrg _XkbFree(devi->btn_acts); 359818534a1Smrg devi->btn_acts = NULL; 360818534a1Smrg } 361818534a1Smrg devi->num_btns = 0; 362818534a1Smrg return Success; 3631ab64890Smrg } 364258a0ebeSmrg _XkbResizeArray(devi->btn_acts, devi->num_btns, newTotal, XkbAction); 365818534a1Smrg if (devi->btn_acts == NULL) { 366818534a1Smrg devi->num_btns = 0; 367818534a1Smrg return BadAlloc; 3681ab64890Smrg } 369818534a1Smrg if (newTotal > devi->num_btns) { 370818534a1Smrg XkbAction *act; 371818534a1Smrg 372818534a1Smrg act = &devi->btn_acts[devi->num_btns]; 373818534a1Smrg bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 3741ab64890Smrg } 375818534a1Smrg devi->num_btns = newTotal; 3761ab64890Smrg return Success; 3771ab64890Smrg} 3781ab64890Smrg 3791ab64890Smrg/*ARGSUSED*/ 3801ab64890SmrgXkbDeviceInfoPtr 381818534a1SmrgXkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 3821ab64890Smrg{ 383818534a1Smrg XkbDeviceInfoPtr devi; 384818534a1Smrg 385818534a1Smrg devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 386818534a1Smrg if (devi != NULL) { 387818534a1Smrg devi->device_spec = deviceSpec; 388818534a1Smrg devi->has_own_state = False; 389818534a1Smrg devi->num_btns = 0; 390818534a1Smrg devi->btn_acts = NULL; 391818534a1Smrg if (nButtons > 0) { 392818534a1Smrg devi->num_btns = nButtons; 393818534a1Smrg devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 394818534a1Smrg if (!devi->btn_acts) { 395818534a1Smrg _XkbFree(devi); 396818534a1Smrg return NULL; 397818534a1Smrg } 398818534a1Smrg } 399818534a1Smrg devi->dflt_kbd_fb = XkbXINone; 400818534a1Smrg devi->dflt_led_fb = XkbXINone; 401818534a1Smrg devi->num_leds = 0; 402818534a1Smrg devi->sz_leds = 0; 403818534a1Smrg devi->leds = NULL; 404818534a1Smrg if (szLeds > 0) { 405818534a1Smrg devi->sz_leds = szLeds; 406818534a1Smrg devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 407818534a1Smrg if (!devi->leds) { 4080f8248bfSmrg _XkbFree(devi->btn_acts); 409818534a1Smrg _XkbFree(devi); 410818534a1Smrg return NULL; 411818534a1Smrg } 412818534a1Smrg } 4131ab64890Smrg } 4141ab64890Smrg return devi; 4151ab64890Smrg} 4161ab64890Smrg 4171ab64890Smrg 41861b2299dSmrgvoid 419818534a1SmrgXkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 4201ab64890Smrg{ 4211ab64890Smrg if (devi) { 422818534a1Smrg if (freeDevI) { 423818534a1Smrg which = XkbXI_AllDeviceFeaturesMask; 424818534a1Smrg if (devi->name) { 425818534a1Smrg _XkbFree(devi->name); 426818534a1Smrg devi->name = NULL; 427818534a1Smrg } 428818534a1Smrg } 429818534a1Smrg if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 430818534a1Smrg _XkbFree(devi->btn_acts); 431818534a1Smrg devi->num_btns = 0; 432818534a1Smrg devi->btn_acts = NULL; 433818534a1Smrg } 434818534a1Smrg if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 435818534a1Smrg register int i; 436818534a1Smrg 437818534a1Smrg if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 438818534a1Smrg _XkbFree(devi->leds); 439818534a1Smrg devi->sz_leds = devi->num_leds = 0; 440818534a1Smrg devi->leds = NULL; 441818534a1Smrg } 442818534a1Smrg else { 443818534a1Smrg XkbDeviceLedInfoPtr devli; 444818534a1Smrg 445818534a1Smrg for (i = 0, devli = devi->leds; i < devi->num_leds; 446818534a1Smrg i++, devli++) { 447818534a1Smrg if (which & XkbXI_IndicatorMapsMask) 448818534a1Smrg bzero((char *) &devli->maps[0], sizeof(devli->maps)); 449818534a1Smrg else 450818534a1Smrg bzero((char *) &devli->names[0], sizeof(devli->names)); 451818534a1Smrg } 452818534a1Smrg } 453818534a1Smrg } 454818534a1Smrg if (freeDevI) 455818534a1Smrg _XkbFree(devi); 4561ab64890Smrg } 4571ab64890Smrg return; 4581ab64890Smrg} 459