XKBMAlloc.c revision cf2acdde
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 <X11/extensions/XKBproto.h> 351ab64890Smrg#include <X11/keysym.h> 361ab64890Smrg#include "XKBlibint.h" 371ab64890Smrg 381ab64890Smrg 391ab64890Smrg/***====================================================================***/ 401ab64890Smrg 411ab64890SmrgStatus 42818534a1SmrgXkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) 431ab64890Smrg{ 44818534a1Smrg register int i; 45818534a1Smrg XkbClientMapPtr map; 46818534a1Smrg 47818534a1Smrg if ((xkb == NULL) || 48818534a1Smrg ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes))) 49818534a1Smrg return BadValue; 50818534a1Smrg if ((which & XkbKeySymsMask) && 51818534a1Smrg ((!XkbIsLegalKeycode(xkb->min_key_code)) || 52818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 53818534a1Smrg (xkb->max_key_code < xkb->min_key_code))) { 541ab64890Smrg#ifdef DEBUG 55818534a1Smrg fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n", 56818534a1Smrg xkb->min_key_code, xkb->max_key_code); 571ab64890Smrg#endif 58818534a1Smrg return BadValue; 59818534a1Smrg } 60818534a1Smrg 61818534a1Smrg if (xkb->map == NULL) { 62818534a1Smrg map = _XkbTypedCalloc(1, XkbClientMapRec); 63818534a1Smrg if (map == NULL) 64818534a1Smrg return BadAlloc; 65818534a1Smrg xkb->map = map; 66818534a1Smrg } 67818534a1Smrg else 68818534a1Smrg map = xkb->map; 69818534a1Smrg 70818534a1Smrg if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) { 71818534a1Smrg if (map->types == NULL) { 72818534a1Smrg map->types = _XkbTypedCalloc(nTotalTypes, XkbKeyTypeRec); 73818534a1Smrg if (map->types == NULL) 74818534a1Smrg return BadAlloc; 75818534a1Smrg map->num_types = 0; 76818534a1Smrg map->size_types = nTotalTypes; 77818534a1Smrg } 78818534a1Smrg else if (map->size_types < nTotalTypes) { 79818534a1Smrg XkbKeyTypeRec *prev_types = map->types; 80818534a1Smrg 81818534a1Smrg map->types = 82818534a1Smrg _XkbTypedRealloc(map->types, nTotalTypes, XkbKeyTypeRec); 83818534a1Smrg if (map->types == NULL) { 84818534a1Smrg _XkbFree(prev_types); 85818534a1Smrg map->num_types = map->size_types = 0; 86818534a1Smrg return BadAlloc; 87818534a1Smrg } 88818534a1Smrg map->size_types = nTotalTypes; 89818534a1Smrg bzero(&map->types[map->num_types], 90818534a1Smrg ((map->size_types - map->num_types) * sizeof(XkbKeyTypeRec))); 91818534a1Smrg } 92818534a1Smrg } 93818534a1Smrg if (which & XkbKeySymsMask) { 94818534a1Smrg int nKeys = XkbNumKeys(xkb); 95818534a1Smrg 96818534a1Smrg if (map->syms == NULL) { 97818534a1Smrg map->size_syms = (nKeys * 15) / 10; 98818534a1Smrg map->syms = _XkbTypedCalloc(map->size_syms, KeySym); 99818534a1Smrg if (!map->syms) { 100818534a1Smrg map->size_syms = 0; 101818534a1Smrg return BadAlloc; 102818534a1Smrg } 103818534a1Smrg map->num_syms = 1; 104818534a1Smrg map->syms[0] = NoSymbol; 105818534a1Smrg } 106818534a1Smrg if (map->key_sym_map == NULL) { 107818534a1Smrg i = xkb->max_key_code + 1; 108818534a1Smrg map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec); 109818534a1Smrg if (map->key_sym_map == NULL) 110818534a1Smrg return BadAlloc; 111818534a1Smrg } 112818534a1Smrg } 113818534a1Smrg if (which & XkbModifierMapMask) { 114818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 115818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 116818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 117818534a1Smrg return BadMatch; 118818534a1Smrg if (map->modmap == NULL) { 119818534a1Smrg i = xkb->max_key_code + 1; 120818534a1Smrg map->modmap = _XkbTypedCalloc(i, unsigned char); 121818534a1Smrg if (map->modmap == NULL) 122818534a1Smrg return BadAlloc; 123818534a1Smrg } 1241ab64890Smrg } 1251ab64890Smrg return Success; 1261ab64890Smrg} 1271ab64890Smrg 1281ab64890SmrgStatus 129818534a1SmrgXkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) 1301ab64890Smrg{ 131818534a1Smrg register int i; 132818534a1Smrg XkbServerMapPtr map; 133818534a1Smrg 134818534a1Smrg if (xkb == NULL) 135818534a1Smrg return BadMatch; 136818534a1Smrg if (xkb->server == NULL) { 137818534a1Smrg map = _XkbTypedCalloc(1, XkbServerMapRec); 138818534a1Smrg if (map == NULL) 139818534a1Smrg return BadAlloc; 140818534a1Smrg for (i = 0; i < XkbNumVirtualMods; i++) { 141818534a1Smrg map->vmods[i] = XkbNoModifierMask; 142818534a1Smrg } 143818534a1Smrg xkb->server = map; 144818534a1Smrg } 145818534a1Smrg else 146818534a1Smrg map = xkb->server; 147818534a1Smrg if (which & XkbExplicitComponentsMask) { 148818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 149818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 150818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 151818534a1Smrg return BadMatch; 152818534a1Smrg if (map->explicit == NULL) { 153818534a1Smrg i = xkb->max_key_code + 1; 154818534a1Smrg map->explicit = _XkbTypedCalloc(i, unsigned char); 155818534a1Smrg if (map->explicit == NULL) 156818534a1Smrg return BadAlloc; 157818534a1Smrg } 158818534a1Smrg } 159818534a1Smrg if (which & XkbKeyActionsMask) { 160818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 161818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 162818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 163818534a1Smrg return BadMatch; 164818534a1Smrg if (nNewActions < 1) 165818534a1Smrg nNewActions = 1; 166818534a1Smrg if (map->acts == NULL) { 167818534a1Smrg map->acts = _XkbTypedCalloc((nNewActions + 1), XkbAction); 168818534a1Smrg if (map->acts == NULL) 169818534a1Smrg return BadAlloc; 170818534a1Smrg map->num_acts = 1; 171818534a1Smrg map->size_acts = nNewActions + 1; 172818534a1Smrg } 173818534a1Smrg else if ((map->size_acts - map->num_acts) < nNewActions) { 174818534a1Smrg unsigned need; 175818534a1Smrg XkbAction *prev_acts = map->acts; 176818534a1Smrg 177818534a1Smrg need = map->num_acts + nNewActions; 178818534a1Smrg map->acts = _XkbTypedRealloc(map->acts, need, XkbAction); 179818534a1Smrg if (map->acts == NULL) { 180818534a1Smrg _XkbFree(prev_acts); 181818534a1Smrg map->num_acts = map->size_acts = 0; 182818534a1Smrg return BadAlloc; 183818534a1Smrg } 184818534a1Smrg map->size_acts = need; 185818534a1Smrg bzero(&map->acts[map->num_acts], 186818534a1Smrg ((map->size_acts - map->num_acts) * sizeof(XkbAction))); 187818534a1Smrg } 188818534a1Smrg if (map->key_acts == NULL) { 189818534a1Smrg i = xkb->max_key_code + 1; 190818534a1Smrg map->key_acts = _XkbTypedCalloc(i, unsigned short); 191818534a1Smrg if (map->key_acts == NULL) 192818534a1Smrg return BadAlloc; 193818534a1Smrg } 194818534a1Smrg } 195818534a1Smrg if (which & XkbKeyBehaviorsMask) { 196818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 197818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 198818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 199818534a1Smrg return BadMatch; 200818534a1Smrg if (map->behaviors == NULL) { 201818534a1Smrg i = xkb->max_key_code + 1; 202818534a1Smrg map->behaviors = _XkbTypedCalloc(i, XkbBehavior); 203818534a1Smrg if (map->behaviors == NULL) 204818534a1Smrg return BadAlloc; 205818534a1Smrg } 206818534a1Smrg } 207818534a1Smrg if (which & XkbVirtualModMapMask) { 208818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 209818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 210818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 211818534a1Smrg return BadMatch; 212818534a1Smrg if (map->vmodmap == NULL) { 213818534a1Smrg i = xkb->max_key_code + 1; 214818534a1Smrg map->vmodmap = _XkbTypedCalloc(i, unsigned short); 215818534a1Smrg if (map->vmodmap == NULL) 216818534a1Smrg return BadAlloc; 217818534a1Smrg } 2181ab64890Smrg } 2191ab64890Smrg return Success; 2201ab64890Smrg} 2211ab64890Smrg 2221ab64890Smrg/***====================================================================***/ 2231ab64890Smrg 2241ab64890SmrgStatus 225818534a1SmrgXkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) 2261ab64890Smrg{ 227818534a1Smrg if ((!from) || (!into)) 228818534a1Smrg return BadMatch; 229cf2acddeSmrg 230cf2acddeSmrg _XkbFree(into->map); 231cf2acddeSmrg into->map = NULL; 232cf2acddeSmrg 233cf2acddeSmrg _XkbFree(into->preserve); 234cf2acddeSmrg into->preserve = NULL; 235cf2acddeSmrg 236cf2acddeSmrg _XkbFree(into->level_names); 237cf2acddeSmrg into->level_names = NULL; 238cf2acddeSmrg 239818534a1Smrg *into = *from; 240818534a1Smrg if ((from->map) && (into->map_count > 0)) { 241818534a1Smrg into->map = _XkbTypedCalloc(into->map_count, XkbKTMapEntryRec); 242818534a1Smrg if (!into->map) 243818534a1Smrg return BadAlloc; 244818534a1Smrg memcpy(into->map, from->map, 245818534a1Smrg into->map_count * sizeof(XkbKTMapEntryRec)); 246818534a1Smrg } 247818534a1Smrg if ((from->preserve) && (into->map_count > 0)) { 248818534a1Smrg into->preserve = _XkbTypedCalloc(into->map_count, XkbModsRec); 249818534a1Smrg if (!into->preserve) 250818534a1Smrg return BadAlloc; 251818534a1Smrg memcpy(into->preserve, from->preserve, 252818534a1Smrg into->map_count * sizeof(XkbModsRec)); 253818534a1Smrg } 254818534a1Smrg if ((from->level_names) && (into->num_levels > 0)) { 255818534a1Smrg into->level_names = _XkbTypedCalloc(into->num_levels, Atom); 256818534a1Smrg if (!into->level_names) 257818534a1Smrg return BadAlloc; 258818534a1Smrg memcpy(into->level_names, from->level_names, 259818534a1Smrg into->num_levels * sizeof(Atom)); 2601ab64890Smrg } 2611ab64890Smrg return Success; 2621ab64890Smrg} 2631ab64890Smrg 2641ab64890SmrgStatus 265818534a1SmrgXkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) 2661ab64890Smrg{ 267818534a1Smrg register int i, rtrn; 2681ab64890Smrg 269818534a1Smrg if ((!from) || (!into) || (num_types < 0)) 270818534a1Smrg return BadMatch; 271818534a1Smrg for (i = 0; i < num_types; i++) { 272818534a1Smrg if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) 273818534a1Smrg return rtrn; 2741ab64890Smrg } 2751ab64890Smrg return Success; 2761ab64890Smrg} 2771ab64890Smrg 2781ab64890SmrgXkbKeyTypePtr 279818534a1SmrgXkbAddKeyType(XkbDescPtr xkb, 280818534a1Smrg Atom name, 281818534a1Smrg int map_count, 282818534a1Smrg Bool want_preserve, 283818534a1Smrg int num_lvls) 2841ab64890Smrg{ 285818534a1Smrg register int i; 286818534a1Smrg unsigned tmp; 287818534a1Smrg XkbKeyTypePtr type; 288818534a1Smrg XkbClientMapPtr map; 289818534a1Smrg 290818534a1Smrg if ((!xkb) || (num_lvls < 1)) 291818534a1Smrg return NULL; 292818534a1Smrg map = xkb->map; 293818534a1Smrg if ((map) && (map->types)) { 294818534a1Smrg for (i = 0; i < map->num_types; i++) { 295818534a1Smrg if (map->types[i].name == name) { 296818534a1Smrg Status status = 297818534a1Smrg XkbResizeKeyType(xkb, i, map_count, want_preserve, 298818534a1Smrg num_lvls); 299818534a1Smrg return (status == Success ? &map->types[i] : NULL); 300818534a1Smrg } 301818534a1Smrg } 302818534a1Smrg } 303cf2acddeSmrg if ((!map) || (!map->types) || (map->num_types < XkbNumRequiredTypes)) { 304818534a1Smrg tmp = XkbNumRequiredTypes + 1; 305818534a1Smrg if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success) 306818534a1Smrg return NULL; 3071ab64890Smrg if (!map) 3081ab64890Smrg map = xkb->map; 309818534a1Smrg tmp = 0; 310818534a1Smrg if (map->num_types <= XkbKeypadIndex) 311818534a1Smrg tmp |= XkbKeypadMask; 312818534a1Smrg if (map->num_types <= XkbAlphabeticIndex) 313818534a1Smrg tmp |= XkbAlphabeticMask; 314818534a1Smrg if (map->num_types <= XkbTwoLevelIndex) 315818534a1Smrg tmp |= XkbTwoLevelMask; 316818534a1Smrg if (map->num_types <= XkbOneLevelIndex) 317818534a1Smrg tmp |= XkbOneLevelMask; 318818534a1Smrg if (XkbInitCanonicalKeyTypes(xkb, tmp, XkbNoModifier) == Success) { 319818534a1Smrg for (i = 0; i < map->num_types; i++) { 320818534a1Smrg Status status; 321818534a1Smrg 322818534a1Smrg if (map->types[i].name != name) 323818534a1Smrg continue; 324818534a1Smrg status = XkbResizeKeyType(xkb, i, map_count, want_preserve, 325818534a1Smrg num_lvls); 326818534a1Smrg return (status == Success ? &map->types[i] : NULL); 327818534a1Smrg } 328818534a1Smrg } 329818534a1Smrg } 330818534a1Smrg if ((map->num_types <= map->size_types) && 331818534a1Smrg (XkbAllocClientMap(xkb, XkbKeyTypesMask, map->num_types + 1) != 332818534a1Smrg Success)) { 333818534a1Smrg return NULL; 334818534a1Smrg } 335818534a1Smrg type = &map->types[map->num_types]; 3361ab64890Smrg map->num_types++; 337818534a1Smrg bzero((char *) type, sizeof(XkbKeyTypeRec)); 338818534a1Smrg type->num_levels = num_lvls; 339818534a1Smrg type->map_count = map_count; 340818534a1Smrg type->name = name; 341818534a1Smrg if (map_count > 0) { 342818534a1Smrg type->map = _XkbTypedCalloc(map_count, XkbKTMapEntryRec); 343818534a1Smrg if (!type->map) { 344818534a1Smrg map->num_types--; 345818534a1Smrg return NULL; 346818534a1Smrg } 347818534a1Smrg if (want_preserve) { 348818534a1Smrg type->preserve = _XkbTypedCalloc(map_count, XkbModsRec); 349818534a1Smrg if (!type->preserve) { 350818534a1Smrg _XkbFree(type->map); 351818534a1Smrg map->num_types--; 352818534a1Smrg return NULL; 353818534a1Smrg } 354818534a1Smrg } 3551ab64890Smrg } 3561ab64890Smrg return type; 3571ab64890Smrg} 3581ab64890Smrg 3591ab64890SmrgStatus 360818534a1SmrgXkbResizeKeyType(XkbDescPtr xkb, 361818534a1Smrg int type_ndx, 362818534a1Smrg int map_count, 363818534a1Smrg Bool want_preserve, 364818534a1Smrg int new_num_lvls) 3651ab64890Smrg{ 366818534a1Smrg XkbKeyTypePtr type; 367818534a1Smrg KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; 3681ab64890Smrg 369818534a1Smrg if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) 370818534a1Smrg || (new_num_lvls < 1)) 371818534a1Smrg return BadValue; 3721ab64890Smrg switch (type_ndx) { 373818534a1Smrg case XkbOneLevelIndex: 374818534a1Smrg if (new_num_lvls != 1) 375818534a1Smrg return BadMatch; 376818534a1Smrg break; 377818534a1Smrg case XkbTwoLevelIndex: 378818534a1Smrg case XkbAlphabeticIndex: 379818534a1Smrg case XkbKeypadIndex: 380818534a1Smrg if (new_num_lvls != 2) 381818534a1Smrg return BadMatch; 382818534a1Smrg break; 383818534a1Smrg } 384818534a1Smrg type = &xkb->map->types[type_ndx]; 385818534a1Smrg if (map_count == 0) { 386cf2acddeSmrg _XkbFree(type->map); 387818534a1Smrg type->map = NULL; 388cf2acddeSmrg _XkbFree(type->preserve); 389818534a1Smrg type->preserve = NULL; 390818534a1Smrg type->map_count = 0; 3911ab64890Smrg } 3921ab64890Smrg else { 393818534a1Smrg XkbKTMapEntryRec *prev_map = type->map; 394818534a1Smrg 395818534a1Smrg if ((map_count > type->map_count) || (type->map == NULL)) 396818534a1Smrg type->map = 397818534a1Smrg _XkbTypedRealloc(type->map, map_count, XkbKTMapEntryRec); 398818534a1Smrg if (!type->map) { 399cf2acddeSmrg _XkbFree(prev_map); 400818534a1Smrg return BadAlloc; 401818534a1Smrg } 402818534a1Smrg if (want_preserve) { 403818534a1Smrg XkbModsRec *prev_preserve = type->preserve; 404818534a1Smrg 405818534a1Smrg if ((map_count > type->map_count) || (type->preserve == NULL)) { 406818534a1Smrg type->preserve = _XkbTypedRealloc(type->preserve, map_count, 407818534a1Smrg XkbModsRec); 408818534a1Smrg } 409818534a1Smrg if (!type->preserve) { 410cf2acddeSmrg _XkbFree(prev_preserve); 411818534a1Smrg return BadAlloc; 412818534a1Smrg } 413818534a1Smrg } 414cf2acddeSmrg else { 415818534a1Smrg _XkbFree(type->preserve); 416818534a1Smrg type->preserve = NULL; 417818534a1Smrg } 418818534a1Smrg type->map_count = map_count; 419818534a1Smrg } 420818534a1Smrg 421818534a1Smrg if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { 422818534a1Smrg Atom *prev_level_names = type->level_names; 423818534a1Smrg 424818534a1Smrg type->level_names = 425818534a1Smrg _XkbTypedRealloc(type->level_names, new_num_lvls, Atom); 426818534a1Smrg if (!type->level_names) { 427cf2acddeSmrg _XkbFree(prev_level_names); 428818534a1Smrg return BadAlloc; 429818534a1Smrg } 4301ab64890Smrg } 4311ab64890Smrg /* 4321ab64890Smrg * Here's the theory: 4331ab64890Smrg * If the width of the type changed, we might have to resize the symbol 4341ab64890Smrg * maps for any keys that use the type for one or more groups. This is 4351ab64890Smrg * expensive, so we'll try to cull out any keys that are obviously okay: 4361ab64890Smrg * In any case: 4371ab64890Smrg * - keys that have a group width <= the old width are okay (because 4381ab64890Smrg * they could not possibly have been associated with the old type) 4391ab64890Smrg * If the key type increased in size: 4401ab64890Smrg * - keys that already have a group width >= to the new width are okay 4411ab64890Smrg * + keys that have a group width >= the old width but < the new width 4421ab64890Smrg * might have to be enlarged. 4431ab64890Smrg * If the key type decreased in size: 4441ab64890Smrg * - keys that have a group width > the old width don't have to be 44561b2299dSmrg * resized (because they must have some other wider type associated 4461ab64890Smrg * with some group). 4471ab64890Smrg * + keys that have a group width == the old width might have to be 4481ab64890Smrg * shrunk. 4491ab64890Smrg * The possibilities marked with '+' require us to examine the key types 4501ab64890Smrg * associated with each group for the key. 4511ab64890Smrg */ 452818534a1Smrg bzero(matchingKeys, XkbMaxKeyCount * sizeof(KeyCode)); 453818534a1Smrg nMatchingKeys = 0; 454818534a1Smrg if (new_num_lvls > type->num_levels) { 455818534a1Smrg int nTotal; 456818534a1Smrg KeySym *newSyms; 457818534a1Smrg int width, match, nResize; 458818534a1Smrg register int i, g, nSyms; 459818534a1Smrg 460818534a1Smrg nResize = 0; 461818534a1Smrg for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 462818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 463818534a1Smrg if (width < type->num_levels) 464818534a1Smrg continue; 465818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 466818534a1Smrg (g >= 0) && (!match); g--) { 467818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 468818534a1Smrg matchingKeys[nMatchingKeys++] = i; 469818534a1Smrg match = 1; 470818534a1Smrg } 471818534a1Smrg } 472818534a1Smrg if ((!match) || (width >= new_num_lvls)) 473818534a1Smrg nTotal += XkbKeyNumSyms(xkb, i); 474818534a1Smrg else { 475818534a1Smrg nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; 476818534a1Smrg nResize++; 477818534a1Smrg } 478818534a1Smrg } 479818534a1Smrg if (nResize > 0) { 480818534a1Smrg int nextMatch; 481818534a1Smrg 482818534a1Smrg xkb->map->size_syms = (nTotal * 12) / 10; 483818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 484818534a1Smrg if (newSyms == NULL) 485818534a1Smrg return BadAlloc; 486818534a1Smrg nextMatch = 0; 487818534a1Smrg nSyms = 1; 488818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 489818534a1Smrg if (matchingKeys[nextMatch] == i) { 490818534a1Smrg KeySym *pOld; 491818534a1Smrg 492818534a1Smrg nextMatch++; 493818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 494818534a1Smrg pOld = XkbKeySymsPtr(xkb, i); 495818534a1Smrg for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { 496818534a1Smrg memcpy(&newSyms[nSyms + (new_num_lvls * g)], 497818534a1Smrg &pOld[width * g], width * sizeof(KeySym)); 498818534a1Smrg } 499818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 500818534a1Smrg nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; 501818534a1Smrg } 502818534a1Smrg else { 503818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 504818534a1Smrg XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); 505818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 506818534a1Smrg nSyms += XkbKeyNumSyms(xkb, i); 507818534a1Smrg } 508818534a1Smrg } 509818534a1Smrg type->num_levels = new_num_lvls; 510818534a1Smrg _XkbFree(xkb->map->syms); 511818534a1Smrg xkb->map->syms = newSyms; 512818534a1Smrg xkb->map->num_syms = nSyms; 513818534a1Smrg return Success; 514818534a1Smrg } 515818534a1Smrg } 516818534a1Smrg else if (new_num_lvls < type->num_levels) { 517818534a1Smrg int width, match; 518818534a1Smrg register int g, i; 519818534a1Smrg 520818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 521818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 522818534a1Smrg if (width < type->num_levels) 523818534a1Smrg continue; 524818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 525818534a1Smrg (g >= 0) && (!match); g--) { 526818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 527818534a1Smrg matchingKeys[nMatchingKeys++] = i; 528818534a1Smrg match = 1; 529818534a1Smrg } 530818534a1Smrg } 531818534a1Smrg } 532818534a1Smrg } 533818534a1Smrg if (nMatchingKeys > 0) { 534818534a1Smrg int key, firstClear; 535818534a1Smrg register int i, g; 536818534a1Smrg 537818534a1Smrg if (new_num_lvls > type->num_levels) 538818534a1Smrg firstClear = type->num_levels; 539818534a1Smrg else 540818534a1Smrg firstClear = new_num_lvls; 541818534a1Smrg for (i = 0; i < nMatchingKeys; i++) { 542818534a1Smrg KeySym *pSyms; 543818534a1Smrg int width, nClear; 544818534a1Smrg 545818534a1Smrg key = matchingKeys[i]; 546818534a1Smrg width = XkbKeyGroupsWidth(xkb, key); 547818534a1Smrg nClear = width - firstClear; 548818534a1Smrg pSyms = XkbKeySymsPtr(xkb, key); 549818534a1Smrg for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { 550818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { 551818534a1Smrg if (nClear > 0) 552818534a1Smrg bzero(&pSyms[g * width + firstClear], 553818534a1Smrg nClear * sizeof(KeySym)); 554818534a1Smrg } 555818534a1Smrg } 556818534a1Smrg } 557818534a1Smrg } 558818534a1Smrg type->num_levels = new_num_lvls; 5591ab64890Smrg return Success; 5601ab64890Smrg} 5611ab64890Smrg 5621ab64890SmrgKeySym * 563818534a1SmrgXkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) 5641ab64890Smrg{ 565818534a1Smrg register int i, nSyms, nKeySyms; 566818534a1Smrg unsigned nOldSyms; 567818534a1Smrg KeySym *newSyms; 568818534a1Smrg 569818534a1Smrg if (needed == 0) { 570818534a1Smrg xkb->map->key_sym_map[key].offset = 0; 571818534a1Smrg return xkb->map->syms; 572818534a1Smrg } 573818534a1Smrg nOldSyms = XkbKeyNumSyms(xkb, key); 574818534a1Smrg if (nOldSyms >= (unsigned) needed) { 575818534a1Smrg return XkbKeySymsPtr(xkb, key); 576818534a1Smrg } 577818534a1Smrg if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { 578818534a1Smrg if (nOldSyms > 0) { 579818534a1Smrg memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), 580818534a1Smrg nOldSyms * sizeof(KeySym)); 581818534a1Smrg } 582818534a1Smrg if ((needed - nOldSyms) > 0) { 583818534a1Smrg bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], 584818534a1Smrg (needed - nOldSyms) * sizeof(KeySym)); 585818534a1Smrg } 586818534a1Smrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 587818534a1Smrg xkb->map->num_syms += needed; 588818534a1Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 589818534a1Smrg } 590818534a1Smrg xkb->map->size_syms += (needed > 32 ? needed : 32); 591818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 592818534a1Smrg if (newSyms == NULL) 593818534a1Smrg return NULL; 594818534a1Smrg newSyms[0] = NoSymbol; 5951ab64890Smrg nSyms = 1; 596818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 597818534a1Smrg int nCopy; 598818534a1Smrg 599818534a1Smrg nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); 600818534a1Smrg if ((nKeySyms == 0) && (i != key)) 601818534a1Smrg continue; 602818534a1Smrg if (i == key) 603818534a1Smrg nKeySyms = needed; 604818534a1Smrg if (nCopy != 0) 605818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 606818534a1Smrg nCopy * sizeof(KeySym)); 607818534a1Smrg if (nKeySyms > nCopy) 608818534a1Smrg bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); 609818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 610818534a1Smrg nSyms += nKeySyms; 6111ab64890Smrg } 6121ab64890Smrg _XkbFree(xkb->map->syms); 6131ab64890Smrg xkb->map->syms = newSyms; 6141ab64890Smrg xkb->map->num_syms = nSyms; 6151ab64890Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 6161ab64890Smrg} 6171ab64890Smrg 6181ab64890Smrgstatic unsigned 619818534a1Smrg_ExtendRange(unsigned int old_flags, 620818534a1Smrg unsigned int flag, 621818534a1Smrg KeyCode newKC, 622818534a1Smrg KeyCode *old_min, 623818534a1Smrg unsigned char *old_num) 6241ab64890Smrg{ 625818534a1Smrg if ((old_flags & flag) == 0) { 626818534a1Smrg old_flags |= flag; 627818534a1Smrg *old_min = newKC; 628818534a1Smrg *old_num = 1; 6291ab64890Smrg } 6301ab64890Smrg else { 631818534a1Smrg int last = (*old_min) + (*old_num) - 1; 632818534a1Smrg 633818534a1Smrg if (newKC < *old_min) { 634818534a1Smrg *old_min = newKC; 635818534a1Smrg *old_num = (last - newKC) + 1; 636818534a1Smrg } 637818534a1Smrg else if (newKC > last) { 638818534a1Smrg *old_num = (newKC - (*old_min)) + 1; 639818534a1Smrg } 6401ab64890Smrg } 6411ab64890Smrg return old_flags; 6421ab64890Smrg} 6431ab64890Smrg 6441ab64890SmrgStatus 645818534a1SmrgXkbChangeKeycodeRange(XkbDescPtr xkb, 646818534a1Smrg int minKC, 647818534a1Smrg int maxKC, 648818534a1Smrg XkbChangesPtr changes) 6491ab64890Smrg{ 650818534a1Smrg int tmp; 651818534a1Smrg 652818534a1Smrg if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) 653818534a1Smrg return BadValue; 654818534a1Smrg if (minKC > maxKC) 655818534a1Smrg return BadMatch; 656818534a1Smrg if (minKC < xkb->min_key_code) { 657818534a1Smrg if (changes) 658818534a1Smrg changes->map.min_key_code = minKC; 659818534a1Smrg tmp = xkb->min_key_code - minKC; 660818534a1Smrg if (xkb->map) { 661818534a1Smrg if (xkb->map->key_sym_map) { 662818534a1Smrg bzero((char *) &xkb->map->key_sym_map[minKC], 663818534a1Smrg tmp * sizeof(XkbSymMapRec)); 664818534a1Smrg if (changes) { 665818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 666818534a1Smrg XkbKeySymsMask, minKC, 667818534a1Smrg &changes->map.first_key_sym, 668818534a1Smrg &changes->map.num_key_syms); 669818534a1Smrg } 670818534a1Smrg } 671818534a1Smrg if (xkb->map->modmap) { 672818534a1Smrg bzero((char *) &xkb->map->modmap[minKC], tmp); 673818534a1Smrg if (changes) { 674818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 675818534a1Smrg XkbModifierMapMask, minKC, 676818534a1Smrg &changes->map.first_modmap_key, 677818534a1Smrg &changes->map.num_modmap_keys); 678818534a1Smrg } 679818534a1Smrg } 680818534a1Smrg } 681818534a1Smrg if (xkb->server) { 682818534a1Smrg if (xkb->server->behaviors) { 683818534a1Smrg bzero((char *) &xkb->server->behaviors[minKC], 684818534a1Smrg tmp * sizeof(XkbBehavior)); 685818534a1Smrg if (changes) { 686818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 687818534a1Smrg XkbKeyBehaviorsMask, minKC, 688818534a1Smrg &changes->map.first_key_behavior, 689818534a1Smrg &changes->map.num_key_behaviors); 690818534a1Smrg } 691818534a1Smrg } 692818534a1Smrg if (xkb->server->key_acts) { 693818534a1Smrg bzero((char *) &xkb->server->key_acts[minKC], 694818534a1Smrg tmp * sizeof(unsigned short)); 695818534a1Smrg if (changes) { 696818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 697818534a1Smrg XkbKeyActionsMask, minKC, 698818534a1Smrg &changes->map.first_key_act, 699818534a1Smrg &changes->map.num_key_acts); 700818534a1Smrg } 701818534a1Smrg } 702818534a1Smrg if (xkb->server->vmodmap) { 703818534a1Smrg bzero((char *) &xkb->server->vmodmap[minKC], 704818534a1Smrg tmp * sizeof(unsigned short)); 705818534a1Smrg if (changes) { 706818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 707818534a1Smrg XkbVirtualModMapMask, minKC, 708818534a1Smrg &changes->map.first_modmap_key, 709818534a1Smrg &changes->map.num_vmodmap_keys); 710818534a1Smrg } 711818534a1Smrg } 712818534a1Smrg } 713818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 714818534a1Smrg bzero((char *) &xkb->names->keys[minKC], 715818534a1Smrg tmp * sizeof(XkbKeyNameRec)); 716818534a1Smrg if (changes) { 717818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 718818534a1Smrg XkbKeyNamesMask, minKC, 719818534a1Smrg &changes->names.first_key, 720818534a1Smrg &changes->names.num_keys); 721818534a1Smrg } 722818534a1Smrg } 723818534a1Smrg xkb->min_key_code = minKC; 724818534a1Smrg } 725818534a1Smrg if (maxKC > xkb->max_key_code) { 726818534a1Smrg if (changes) 727818534a1Smrg changes->map.max_key_code = maxKC; 728818534a1Smrg tmp = maxKC - xkb->max_key_code; 729818534a1Smrg if (xkb->map) { 730818534a1Smrg if (xkb->map->key_sym_map) { 731818534a1Smrg XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 732818534a1Smrg 733818534a1Smrg xkb->map->key_sym_map = _XkbTypedRealloc(xkb->map->key_sym_map, 734818534a1Smrg (maxKC + 1), XkbSymMapRec); 735818534a1Smrg if (!xkb->map->key_sym_map) { 736818534a1Smrg _XkbFree(prev_key_sym_map); 737818534a1Smrg return BadAlloc; 738818534a1Smrg } 739818534a1Smrg bzero((char *) &xkb->map->key_sym_map[xkb->max_key_code], 740818534a1Smrg tmp * sizeof(XkbSymMapRec)); 741818534a1Smrg if (changes) { 742818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 743818534a1Smrg XkbKeySymsMask, maxKC, 744818534a1Smrg &changes->map.first_key_sym, 745818534a1Smrg &changes->map.num_key_syms); 746818534a1Smrg } 747818534a1Smrg } 748818534a1Smrg if (xkb->map->modmap) { 749818534a1Smrg unsigned char *prev_modmap = xkb->map->modmap; 750818534a1Smrg 751818534a1Smrg xkb->map->modmap = _XkbTypedRealloc(xkb->map->modmap, 752818534a1Smrg (maxKC + 1), unsigned char); 753818534a1Smrg if (!xkb->map->modmap) { 754818534a1Smrg _XkbFree(prev_modmap); 755818534a1Smrg return BadAlloc; 756818534a1Smrg } 757818534a1Smrg bzero((char *) &xkb->map->modmap[xkb->max_key_code], tmp); 758818534a1Smrg if (changes) { 759818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 760818534a1Smrg XkbModifierMapMask, maxKC, 761818534a1Smrg &changes->map.first_modmap_key, 762818534a1Smrg &changes->map.num_modmap_keys); 763818534a1Smrg } 764818534a1Smrg } 765818534a1Smrg } 766818534a1Smrg if (xkb->server) { 767818534a1Smrg if (xkb->server->behaviors) { 768818534a1Smrg XkbBehavior *prev_behaviors = xkb->server->behaviors; 769818534a1Smrg 770818534a1Smrg xkb->server->behaviors = 771818534a1Smrg _XkbTypedRealloc(xkb->server->behaviors, (maxKC + 1), 772818534a1Smrg XkbBehavior); 773818534a1Smrg if (!xkb->server->behaviors) { 774818534a1Smrg _XkbFree(prev_behaviors); 775818534a1Smrg return BadAlloc; 776818534a1Smrg } 777818534a1Smrg bzero((char *) &xkb->server->behaviors[xkb->max_key_code], 778818534a1Smrg tmp * sizeof(XkbBehavior)); 779818534a1Smrg if (changes) { 780818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 781818534a1Smrg XkbKeyBehaviorsMask, maxKC, 782818534a1Smrg &changes->map.first_key_behavior, 783818534a1Smrg &changes->map.num_key_behaviors); 784818534a1Smrg } 785818534a1Smrg } 786818534a1Smrg if (xkb->server->key_acts) { 787818534a1Smrg unsigned short *prev_key_acts = xkb->server->key_acts; 788818534a1Smrg 789818534a1Smrg xkb->server->key_acts = _XkbTypedRealloc(xkb->server->key_acts, 790818534a1Smrg (maxKC + 1), unsigned short); 791818534a1Smrg if (!xkb->server->key_acts) { 792818534a1Smrg _XkbFree(prev_key_acts); 793818534a1Smrg return BadAlloc; 794818534a1Smrg } 795818534a1Smrg bzero((char *) &xkb->server->key_acts[xkb->max_key_code], 796818534a1Smrg tmp * sizeof(unsigned short)); 797818534a1Smrg if (changes) { 798818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 799818534a1Smrg XkbKeyActionsMask, maxKC, 800818534a1Smrg &changes->map.first_key_act, 801818534a1Smrg &changes->map.num_key_acts); 802818534a1Smrg } 803818534a1Smrg } 804818534a1Smrg if (xkb->server->vmodmap) { 805818534a1Smrg unsigned short *prev_vmodmap = xkb->server->vmodmap; 806818534a1Smrg 807818534a1Smrg xkb->server->vmodmap = _XkbTypedRealloc(xkb->server->vmodmap, 808818534a1Smrg (maxKC + 1), unsigned short); 809818534a1Smrg if (!xkb->server->vmodmap) { 810818534a1Smrg _XkbFree(prev_vmodmap); 811818534a1Smrg return BadAlloc; 812818534a1Smrg } 813818534a1Smrg bzero((char *) &xkb->server->vmodmap[xkb->max_key_code], 814818534a1Smrg tmp * sizeof(unsigned short)); 815818534a1Smrg if (changes) { 816818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 817818534a1Smrg XkbVirtualModMapMask, maxKC, 818818534a1Smrg &changes->map.first_modmap_key, 819818534a1Smrg &changes->map.num_vmodmap_keys); 820818534a1Smrg } 821818534a1Smrg } 822818534a1Smrg } 823818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 824818534a1Smrg XkbKeyNameRec *prev_keys = xkb->names->keys; 825818534a1Smrg 826818534a1Smrg xkb->names->keys = _XkbTypedRealloc(xkb->names->keys, 827818534a1Smrg (maxKC + 1), XkbKeyNameRec); 828818534a1Smrg if (!xkb->names->keys) { 829818534a1Smrg _XkbFree(prev_keys); 830818534a1Smrg return BadAlloc; 831818534a1Smrg } 832818534a1Smrg bzero((char *) &xkb->names->keys[xkb->max_key_code], 833818534a1Smrg tmp * sizeof(XkbKeyNameRec)); 834818534a1Smrg if (changes) { 835818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 836818534a1Smrg XkbKeyNamesMask, maxKC, 837818534a1Smrg &changes->names.first_key, 838818534a1Smrg &changes->names.num_keys); 839818534a1Smrg } 840818534a1Smrg } 841818534a1Smrg xkb->max_key_code = maxKC; 8421ab64890Smrg } 8431ab64890Smrg return Success; 8441ab64890Smrg} 8451ab64890Smrg 8461ab64890SmrgXkbAction * 847818534a1SmrgXkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) 8481ab64890Smrg{ 849818534a1Smrg register int i, nActs; 850818534a1Smrg XkbAction *newActs; 851818534a1Smrg 852818534a1Smrg if (needed == 0) { 853818534a1Smrg xkb->server->key_acts[key] = 0; 854818534a1Smrg return NULL; 855818534a1Smrg } 856818534a1Smrg if (XkbKeyHasActions(xkb, key) && 857818534a1Smrg (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) 858818534a1Smrg return XkbKeyActionsPtr(xkb, key); 859818534a1Smrg if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { 860818534a1Smrg xkb->server->key_acts[key] = xkb->server->num_acts; 861818534a1Smrg xkb->server->num_acts += needed; 862818534a1Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 863818534a1Smrg } 864818534a1Smrg xkb->server->size_acts = xkb->server->num_acts + needed + 8; 865818534a1Smrg newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); 866818534a1Smrg if (newActs == NULL) 867818534a1Smrg return NULL; 8681ab64890Smrg newActs[0].type = XkbSA_NoAction; 8691ab64890Smrg nActs = 1; 870818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 871818534a1Smrg int nKeyActs, nCopy; 872818534a1Smrg 873818534a1Smrg if ((xkb->server->key_acts[i] == 0) && (i != key)) 874818534a1Smrg continue; 875818534a1Smrg 876818534a1Smrg nCopy = nKeyActs = XkbKeyNumActions(xkb, i); 877818534a1Smrg if (i == key) { 878818534a1Smrg nKeyActs = needed; 879818534a1Smrg if (needed < nCopy) 880818534a1Smrg nCopy = needed; 881818534a1Smrg } 882818534a1Smrg 883818534a1Smrg if (nCopy > 0) 884818534a1Smrg memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), 885818534a1Smrg nCopy * sizeof(XkbAction)); 886818534a1Smrg if (nCopy < nKeyActs) 887818534a1Smrg bzero(&newActs[nActs + nCopy], 888818534a1Smrg (nKeyActs - nCopy) * sizeof(XkbAction)); 889818534a1Smrg xkb->server->key_acts[i] = nActs; 890818534a1Smrg nActs += nKeyActs; 8911ab64890Smrg } 8921ab64890Smrg _XkbFree(xkb->server->acts); 8931ab64890Smrg xkb->server->acts = newActs; 894818534a1Smrg xkb->server->num_acts = nActs; 8951ab64890Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 8961ab64890Smrg} 8971ab64890Smrg 8981ab64890Smrgvoid 899818534a1SmrgXkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 9001ab64890Smrg{ 901818534a1Smrg XkbClientMapPtr map; 9021ab64890Smrg 903818534a1Smrg if ((xkb == NULL) || (xkb->map == NULL)) 904818534a1Smrg return; 9051ab64890Smrg if (freeMap) 906818534a1Smrg what = XkbAllClientInfoMask; 907818534a1Smrg map = xkb->map; 908818534a1Smrg if (what & XkbKeyTypesMask) { 909818534a1Smrg if (map->types != NULL) { 910818534a1Smrg if (map->num_types > 0) { 911818534a1Smrg register int i; 912818534a1Smrg XkbKeyTypePtr type; 913818534a1Smrg 914818534a1Smrg for (i = 0, type = map->types; i < map->num_types; i++, type++) { 915cf2acddeSmrg _XkbFree(type->map); 916cf2acddeSmrg type->map = NULL; 917cf2acddeSmrg 918cf2acddeSmrg _XkbFree(type->preserve); 919cf2acddeSmrg type->preserve = NULL; 920cf2acddeSmrg 921818534a1Smrg type->map_count = 0; 922cf2acddeSmrg 923cf2acddeSmrg _XkbFree(type->level_names); 924cf2acddeSmrg type->level_names = NULL; 925818534a1Smrg } 926818534a1Smrg } 927818534a1Smrg _XkbFree(map->types); 928818534a1Smrg map->num_types = map->size_types = 0; 929818534a1Smrg map->types = NULL; 930818534a1Smrg } 931818534a1Smrg } 932818534a1Smrg if (what & XkbKeySymsMask) { 933cf2acddeSmrg _XkbFree(map->key_sym_map); 934cf2acddeSmrg map->key_sym_map = NULL; 935cf2acddeSmrg 936cf2acddeSmrg _XkbFree(map->syms); 937cf2acddeSmrg map->size_syms = map->num_syms = 0; 938cf2acddeSmrg map->syms = NULL; 939818534a1Smrg } 940cf2acddeSmrg if (what & XkbModifierMapMask) { 941818534a1Smrg _XkbFree(map->modmap); 942818534a1Smrg map->modmap = NULL; 9431ab64890Smrg } 9441ab64890Smrg if (freeMap) { 945818534a1Smrg _XkbFree(xkb->map); 946818534a1Smrg xkb->map = NULL; 9471ab64890Smrg } 9481ab64890Smrg return; 9491ab64890Smrg} 9501ab64890Smrg 9511ab64890Smrgvoid 952818534a1SmrgXkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 9531ab64890Smrg{ 954818534a1Smrg XkbServerMapPtr map; 9551ab64890Smrg 956818534a1Smrg if ((xkb == NULL) || (xkb->server == NULL)) 957818534a1Smrg return; 9581ab64890Smrg if (freeMap) 959818534a1Smrg what = XkbAllServerInfoMask; 960818534a1Smrg map = xkb->server; 961cf2acddeSmrg if (what & XkbExplicitComponentsMask) { 962818534a1Smrg _XkbFree(map->explicit); 963818534a1Smrg map->explicit = NULL; 964818534a1Smrg } 965818534a1Smrg if (what & XkbKeyActionsMask) { 966cf2acddeSmrg _XkbFree(map->key_acts); 967818534a1Smrg map->key_acts = NULL; 968cf2acddeSmrg 969cf2acddeSmrg _XkbFree(map->acts); 970818534a1Smrg map->num_acts = map->size_acts = 0; 971818534a1Smrg map->acts = NULL; 972818534a1Smrg } 973cf2acddeSmrg if (what & XkbKeyBehaviorsMask) { 974818534a1Smrg _XkbFree(map->behaviors); 975818534a1Smrg map->behaviors = NULL; 976818534a1Smrg } 977cf2acddeSmrg if (what & XkbVirtualModMapMask) { 978818534a1Smrg _XkbFree(map->vmodmap); 979818534a1Smrg map->vmodmap = NULL; 9801ab64890Smrg } 9811ab64890Smrg 9821ab64890Smrg if (freeMap) { 983818534a1Smrg _XkbFree(xkb->server); 984818534a1Smrg xkb->server = NULL; 9851ab64890Smrg } 9861ab64890Smrg return; 9871ab64890Smrg} 988