XKBMAlloc.c revision f2d49d05
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) { 72f2d49d05Smrg map->num_types = map->size_types = 0; 73818534a1Smrg } 74f2d49d05Smrg if ((map->types == NULL) || (map->size_types < nTotalTypes)) { 75f2d49d05Smrg _XkbResizeArray(map->types, map->size_types, nTotalTypes, 76f2d49d05Smrg XkbKeyTypeRec); 77818534a1Smrg 78818534a1Smrg if (map->types == NULL) { 79818534a1Smrg map->num_types = map->size_types = 0; 80818534a1Smrg return BadAlloc; 81818534a1Smrg } 82818534a1Smrg map->size_types = nTotalTypes; 83818534a1Smrg } 84818534a1Smrg } 85818534a1Smrg if (which & XkbKeySymsMask) { 86818534a1Smrg int nKeys = XkbNumKeys(xkb); 87818534a1Smrg 88818534a1Smrg if (map->syms == NULL) { 89818534a1Smrg map->size_syms = (nKeys * 15) / 10; 90818534a1Smrg map->syms = _XkbTypedCalloc(map->size_syms, KeySym); 91818534a1Smrg if (!map->syms) { 92818534a1Smrg map->size_syms = 0; 93818534a1Smrg return BadAlloc; 94818534a1Smrg } 95818534a1Smrg map->num_syms = 1; 96818534a1Smrg map->syms[0] = NoSymbol; 97818534a1Smrg } 98818534a1Smrg if (map->key_sym_map == NULL) { 99818534a1Smrg i = xkb->max_key_code + 1; 100818534a1Smrg map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec); 101818534a1Smrg if (map->key_sym_map == NULL) 102818534a1Smrg return BadAlloc; 103818534a1Smrg } 104818534a1Smrg } 105818534a1Smrg if (which & XkbModifierMapMask) { 106818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 107818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 108818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 109818534a1Smrg return BadMatch; 110818534a1Smrg if (map->modmap == NULL) { 111818534a1Smrg i = xkb->max_key_code + 1; 112818534a1Smrg map->modmap = _XkbTypedCalloc(i, unsigned char); 113818534a1Smrg if (map->modmap == NULL) 114818534a1Smrg return BadAlloc; 115818534a1Smrg } 1161ab64890Smrg } 1171ab64890Smrg return Success; 1181ab64890Smrg} 1191ab64890Smrg 1201ab64890SmrgStatus 121818534a1SmrgXkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) 1221ab64890Smrg{ 123818534a1Smrg register int i; 124818534a1Smrg XkbServerMapPtr map; 125818534a1Smrg 126818534a1Smrg if (xkb == NULL) 127818534a1Smrg return BadMatch; 128818534a1Smrg if (xkb->server == NULL) { 129818534a1Smrg map = _XkbTypedCalloc(1, XkbServerMapRec); 130818534a1Smrg if (map == NULL) 131818534a1Smrg return BadAlloc; 132818534a1Smrg for (i = 0; i < XkbNumVirtualMods; i++) { 133818534a1Smrg map->vmods[i] = XkbNoModifierMask; 134818534a1Smrg } 135818534a1Smrg xkb->server = map; 136818534a1Smrg } 137818534a1Smrg else 138818534a1Smrg map = xkb->server; 139818534a1Smrg if (which & XkbExplicitComponentsMask) { 140818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 141818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 142818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 143818534a1Smrg return BadMatch; 144818534a1Smrg if (map->explicit == NULL) { 145818534a1Smrg i = xkb->max_key_code + 1; 146818534a1Smrg map->explicit = _XkbTypedCalloc(i, unsigned char); 147818534a1Smrg if (map->explicit == NULL) 148818534a1Smrg return BadAlloc; 149818534a1Smrg } 150818534a1Smrg } 151818534a1Smrg if (which & XkbKeyActionsMask) { 152818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 153818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 154818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 155818534a1Smrg return BadMatch; 156818534a1Smrg if (nNewActions < 1) 157818534a1Smrg nNewActions = 1; 158818534a1Smrg if (map->acts == NULL) { 159818534a1Smrg map->num_acts = 1; 160f2d49d05Smrg map->size_acts = 0; 161818534a1Smrg } 162f2d49d05Smrg if ((map->acts == NULL) || 163f2d49d05Smrg ((map->size_acts - map->num_acts) < nNewActions)) { 164818534a1Smrg unsigned need; 165818534a1Smrg 166818534a1Smrg need = map->num_acts + nNewActions; 167f2d49d05Smrg _XkbResizeArray(map->acts, map->size_acts, need, XkbAction); 168818534a1Smrg if (map->acts == NULL) { 169818534a1Smrg map->num_acts = map->size_acts = 0; 170818534a1Smrg return BadAlloc; 171818534a1Smrg } 172818534a1Smrg map->size_acts = need; 173818534a1Smrg } 174818534a1Smrg if (map->key_acts == NULL) { 175818534a1Smrg i = xkb->max_key_code + 1; 176818534a1Smrg map->key_acts = _XkbTypedCalloc(i, unsigned short); 177818534a1Smrg if (map->key_acts == NULL) 178818534a1Smrg return BadAlloc; 179818534a1Smrg } 180818534a1Smrg } 181818534a1Smrg if (which & XkbKeyBehaviorsMask) { 182818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 183818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 184818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 185818534a1Smrg return BadMatch; 186818534a1Smrg if (map->behaviors == NULL) { 187818534a1Smrg i = xkb->max_key_code + 1; 188818534a1Smrg map->behaviors = _XkbTypedCalloc(i, XkbBehavior); 189818534a1Smrg if (map->behaviors == NULL) 190818534a1Smrg return BadAlloc; 191818534a1Smrg } 192818534a1Smrg } 193818534a1Smrg if (which & XkbVirtualModMapMask) { 194818534a1Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 195818534a1Smrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 196818534a1Smrg (xkb->max_key_code < xkb->min_key_code)) 197818534a1Smrg return BadMatch; 198818534a1Smrg if (map->vmodmap == NULL) { 199818534a1Smrg i = xkb->max_key_code + 1; 200818534a1Smrg map->vmodmap = _XkbTypedCalloc(i, unsigned short); 201818534a1Smrg if (map->vmodmap == NULL) 202818534a1Smrg return BadAlloc; 203818534a1Smrg } 2041ab64890Smrg } 2051ab64890Smrg return Success; 2061ab64890Smrg} 2071ab64890Smrg 2081ab64890Smrg/***====================================================================***/ 2091ab64890Smrg 2101ab64890SmrgStatus 211818534a1SmrgXkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) 2121ab64890Smrg{ 213818534a1Smrg if ((!from) || (!into)) 214818534a1Smrg return BadMatch; 215cf2acddeSmrg 216cf2acddeSmrg _XkbFree(into->map); 217cf2acddeSmrg into->map = NULL; 218cf2acddeSmrg 219cf2acddeSmrg _XkbFree(into->preserve); 220cf2acddeSmrg into->preserve = NULL; 221cf2acddeSmrg 222cf2acddeSmrg _XkbFree(into->level_names); 223cf2acddeSmrg into->level_names = NULL; 224cf2acddeSmrg 225818534a1Smrg *into = *from; 226818534a1Smrg if ((from->map) && (into->map_count > 0)) { 227818534a1Smrg into->map = _XkbTypedCalloc(into->map_count, XkbKTMapEntryRec); 228818534a1Smrg if (!into->map) 229818534a1Smrg return BadAlloc; 230818534a1Smrg memcpy(into->map, from->map, 231818534a1Smrg into->map_count * sizeof(XkbKTMapEntryRec)); 232818534a1Smrg } 233818534a1Smrg if ((from->preserve) && (into->map_count > 0)) { 234818534a1Smrg into->preserve = _XkbTypedCalloc(into->map_count, XkbModsRec); 235818534a1Smrg if (!into->preserve) 236818534a1Smrg return BadAlloc; 237818534a1Smrg memcpy(into->preserve, from->preserve, 238818534a1Smrg into->map_count * sizeof(XkbModsRec)); 239818534a1Smrg } 240818534a1Smrg if ((from->level_names) && (into->num_levels > 0)) { 241818534a1Smrg into->level_names = _XkbTypedCalloc(into->num_levels, Atom); 242818534a1Smrg if (!into->level_names) 243818534a1Smrg return BadAlloc; 244818534a1Smrg memcpy(into->level_names, from->level_names, 245818534a1Smrg into->num_levels * sizeof(Atom)); 2461ab64890Smrg } 2471ab64890Smrg return Success; 2481ab64890Smrg} 2491ab64890Smrg 2501ab64890SmrgStatus 251818534a1SmrgXkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) 2521ab64890Smrg{ 253818534a1Smrg register int i, rtrn; 2541ab64890Smrg 255818534a1Smrg if ((!from) || (!into) || (num_types < 0)) 256818534a1Smrg return BadMatch; 257818534a1Smrg for (i = 0; i < num_types; i++) { 258818534a1Smrg if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) 259818534a1Smrg return rtrn; 2601ab64890Smrg } 2611ab64890Smrg return Success; 2621ab64890Smrg} 2631ab64890Smrg 2641ab64890SmrgXkbKeyTypePtr 265818534a1SmrgXkbAddKeyType(XkbDescPtr xkb, 266818534a1Smrg Atom name, 267818534a1Smrg int map_count, 268818534a1Smrg Bool want_preserve, 269818534a1Smrg int num_lvls) 2701ab64890Smrg{ 271818534a1Smrg register int i; 272818534a1Smrg unsigned tmp; 273818534a1Smrg XkbKeyTypePtr type; 274818534a1Smrg XkbClientMapPtr map; 275818534a1Smrg 276818534a1Smrg if ((!xkb) || (num_lvls < 1)) 277818534a1Smrg return NULL; 278818534a1Smrg map = xkb->map; 279818534a1Smrg if ((map) && (map->types)) { 280818534a1Smrg for (i = 0; i < map->num_types; i++) { 281818534a1Smrg if (map->types[i].name == name) { 282818534a1Smrg Status status = 283818534a1Smrg XkbResizeKeyType(xkb, i, map_count, want_preserve, 284818534a1Smrg num_lvls); 285818534a1Smrg return (status == Success ? &map->types[i] : NULL); 286818534a1Smrg } 287818534a1Smrg } 288818534a1Smrg } 289cf2acddeSmrg if ((!map) || (!map->types) || (map->num_types < XkbNumRequiredTypes)) { 290818534a1Smrg tmp = XkbNumRequiredTypes + 1; 291818534a1Smrg if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success) 292818534a1Smrg return NULL; 2931ab64890Smrg if (!map) 2941ab64890Smrg map = xkb->map; 295818534a1Smrg tmp = 0; 296818534a1Smrg if (map->num_types <= XkbKeypadIndex) 297818534a1Smrg tmp |= XkbKeypadMask; 298818534a1Smrg if (map->num_types <= XkbAlphabeticIndex) 299818534a1Smrg tmp |= XkbAlphabeticMask; 300818534a1Smrg if (map->num_types <= XkbTwoLevelIndex) 301818534a1Smrg tmp |= XkbTwoLevelMask; 302818534a1Smrg if (map->num_types <= XkbOneLevelIndex) 303818534a1Smrg tmp |= XkbOneLevelMask; 304818534a1Smrg if (XkbInitCanonicalKeyTypes(xkb, tmp, XkbNoModifier) == Success) { 305818534a1Smrg for (i = 0; i < map->num_types; i++) { 306818534a1Smrg Status status; 307818534a1Smrg 308818534a1Smrg if (map->types[i].name != name) 309818534a1Smrg continue; 310818534a1Smrg status = XkbResizeKeyType(xkb, i, map_count, want_preserve, 311818534a1Smrg num_lvls); 312818534a1Smrg return (status == Success ? &map->types[i] : NULL); 313818534a1Smrg } 314818534a1Smrg } 315818534a1Smrg } 316818534a1Smrg if ((map->num_types <= map->size_types) && 317818534a1Smrg (XkbAllocClientMap(xkb, XkbKeyTypesMask, map->num_types + 1) != 318818534a1Smrg Success)) { 319818534a1Smrg return NULL; 320818534a1Smrg } 321818534a1Smrg type = &map->types[map->num_types]; 3221ab64890Smrg map->num_types++; 323818534a1Smrg bzero((char *) type, sizeof(XkbKeyTypeRec)); 324818534a1Smrg type->num_levels = num_lvls; 325818534a1Smrg type->map_count = map_count; 326818534a1Smrg type->name = name; 327818534a1Smrg if (map_count > 0) { 328818534a1Smrg type->map = _XkbTypedCalloc(map_count, XkbKTMapEntryRec); 329818534a1Smrg if (!type->map) { 330818534a1Smrg map->num_types--; 331818534a1Smrg return NULL; 332818534a1Smrg } 333818534a1Smrg if (want_preserve) { 334818534a1Smrg type->preserve = _XkbTypedCalloc(map_count, XkbModsRec); 335818534a1Smrg if (!type->preserve) { 336818534a1Smrg _XkbFree(type->map); 337818534a1Smrg map->num_types--; 338818534a1Smrg return NULL; 339818534a1Smrg } 340818534a1Smrg } 3411ab64890Smrg } 3421ab64890Smrg return type; 3431ab64890Smrg} 3441ab64890Smrg 3451ab64890SmrgStatus 346818534a1SmrgXkbResizeKeyType(XkbDescPtr xkb, 347818534a1Smrg int type_ndx, 348818534a1Smrg int map_count, 349818534a1Smrg Bool want_preserve, 350818534a1Smrg int new_num_lvls) 3511ab64890Smrg{ 352818534a1Smrg XkbKeyTypePtr type; 353818534a1Smrg KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; 3541ab64890Smrg 355818534a1Smrg if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) 356818534a1Smrg || (new_num_lvls < 1)) 357818534a1Smrg return BadValue; 3581ab64890Smrg switch (type_ndx) { 359818534a1Smrg case XkbOneLevelIndex: 360818534a1Smrg if (new_num_lvls != 1) 361818534a1Smrg return BadMatch; 362818534a1Smrg break; 363818534a1Smrg case XkbTwoLevelIndex: 364818534a1Smrg case XkbAlphabeticIndex: 365818534a1Smrg case XkbKeypadIndex: 366818534a1Smrg if (new_num_lvls != 2) 367818534a1Smrg return BadMatch; 368818534a1Smrg break; 369818534a1Smrg } 370818534a1Smrg type = &xkb->map->types[type_ndx]; 371818534a1Smrg if (map_count == 0) { 372cf2acddeSmrg _XkbFree(type->map); 373818534a1Smrg type->map = NULL; 374cf2acddeSmrg _XkbFree(type->preserve); 375818534a1Smrg type->preserve = NULL; 376818534a1Smrg type->map_count = 0; 3771ab64890Smrg } 3781ab64890Smrg else { 379818534a1Smrg if ((map_count > type->map_count) || (type->map == NULL)) 380f2d49d05Smrg _XkbResizeArray(type->map, type->map_count, map_count, 381f2d49d05Smrg XkbKTMapEntryRec); 382818534a1Smrg if (!type->map) { 383818534a1Smrg return BadAlloc; 384818534a1Smrg } 385818534a1Smrg if (want_preserve) { 386818534a1Smrg if ((map_count > type->map_count) || (type->preserve == NULL)) { 387f2d49d05Smrg _XkbResizeArray(type->preserve, type->map_count, map_count, 388f2d49d05Smrg XkbModsRec); 389818534a1Smrg } 390818534a1Smrg if (!type->preserve) { 391818534a1Smrg return BadAlloc; 392818534a1Smrg } 393818534a1Smrg } 394cf2acddeSmrg else { 395818534a1Smrg _XkbFree(type->preserve); 396818534a1Smrg type->preserve = NULL; 397818534a1Smrg } 398818534a1Smrg type->map_count = map_count; 399818534a1Smrg } 400818534a1Smrg 401818534a1Smrg if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { 402f2d49d05Smrg _XkbResizeArray(type->level_names, type->num_levels, new_num_lvls, Atom); 403818534a1Smrg if (!type->level_names) { 404818534a1Smrg return BadAlloc; 405818534a1Smrg } 4061ab64890Smrg } 4071ab64890Smrg /* 4081ab64890Smrg * Here's the theory: 4091ab64890Smrg * If the width of the type changed, we might have to resize the symbol 4101ab64890Smrg * maps for any keys that use the type for one or more groups. This is 4111ab64890Smrg * expensive, so we'll try to cull out any keys that are obviously okay: 4121ab64890Smrg * In any case: 4131ab64890Smrg * - keys that have a group width <= the old width are okay (because 4141ab64890Smrg * they could not possibly have been associated with the old type) 4151ab64890Smrg * If the key type increased in size: 4161ab64890Smrg * - keys that already have a group width >= to the new width are okay 4171ab64890Smrg * + keys that have a group width >= the old width but < the new width 4181ab64890Smrg * might have to be enlarged. 4191ab64890Smrg * If the key type decreased in size: 4201ab64890Smrg * - keys that have a group width > the old width don't have to be 42161b2299dSmrg * resized (because they must have some other wider type associated 4221ab64890Smrg * with some group). 4231ab64890Smrg * + keys that have a group width == the old width might have to be 4241ab64890Smrg * shrunk. 4251ab64890Smrg * The possibilities marked with '+' require us to examine the key types 4261ab64890Smrg * associated with each group for the key. 4271ab64890Smrg */ 428818534a1Smrg bzero(matchingKeys, XkbMaxKeyCount * sizeof(KeyCode)); 429818534a1Smrg nMatchingKeys = 0; 430818534a1Smrg if (new_num_lvls > type->num_levels) { 431818534a1Smrg int nTotal; 432818534a1Smrg KeySym *newSyms; 433818534a1Smrg int width, match, nResize; 434818534a1Smrg register int i, g, nSyms; 435818534a1Smrg 436818534a1Smrg nResize = 0; 437818534a1Smrg for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 438818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 439818534a1Smrg if (width < type->num_levels) 440818534a1Smrg continue; 441818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 442818534a1Smrg (g >= 0) && (!match); g--) { 443818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 444818534a1Smrg matchingKeys[nMatchingKeys++] = i; 445818534a1Smrg match = 1; 446818534a1Smrg } 447818534a1Smrg } 448818534a1Smrg if ((!match) || (width >= new_num_lvls)) 449818534a1Smrg nTotal += XkbKeyNumSyms(xkb, i); 450818534a1Smrg else { 451818534a1Smrg nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; 452818534a1Smrg nResize++; 453818534a1Smrg } 454818534a1Smrg } 455818534a1Smrg if (nResize > 0) { 456818534a1Smrg int nextMatch; 457818534a1Smrg 458818534a1Smrg xkb->map->size_syms = (nTotal * 12) / 10; 459818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 460818534a1Smrg if (newSyms == NULL) 461818534a1Smrg return BadAlloc; 462818534a1Smrg nextMatch = 0; 463818534a1Smrg nSyms = 1; 464818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 465818534a1Smrg if (matchingKeys[nextMatch] == i) { 466818534a1Smrg KeySym *pOld; 467818534a1Smrg 468818534a1Smrg nextMatch++; 469818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 470818534a1Smrg pOld = XkbKeySymsPtr(xkb, i); 471818534a1Smrg for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { 472818534a1Smrg memcpy(&newSyms[nSyms + (new_num_lvls * g)], 473818534a1Smrg &pOld[width * g], width * sizeof(KeySym)); 474818534a1Smrg } 475818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 476818534a1Smrg nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; 477818534a1Smrg } 478818534a1Smrg else { 479818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 480818534a1Smrg XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); 481818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 482818534a1Smrg nSyms += XkbKeyNumSyms(xkb, i); 483818534a1Smrg } 484818534a1Smrg } 485818534a1Smrg type->num_levels = new_num_lvls; 486818534a1Smrg _XkbFree(xkb->map->syms); 487818534a1Smrg xkb->map->syms = newSyms; 488818534a1Smrg xkb->map->num_syms = nSyms; 489818534a1Smrg return Success; 490818534a1Smrg } 491818534a1Smrg } 492818534a1Smrg else if (new_num_lvls < type->num_levels) { 493818534a1Smrg int width, match; 494818534a1Smrg register int g, i; 495818534a1Smrg 496818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 497818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 498818534a1Smrg if (width < type->num_levels) 499818534a1Smrg continue; 500818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 501818534a1Smrg (g >= 0) && (!match); g--) { 502818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 503818534a1Smrg matchingKeys[nMatchingKeys++] = i; 504818534a1Smrg match = 1; 505818534a1Smrg } 506818534a1Smrg } 507818534a1Smrg } 508818534a1Smrg } 509818534a1Smrg if (nMatchingKeys > 0) { 510818534a1Smrg int key, firstClear; 511818534a1Smrg register int i, g; 512818534a1Smrg 513818534a1Smrg if (new_num_lvls > type->num_levels) 514818534a1Smrg firstClear = type->num_levels; 515818534a1Smrg else 516818534a1Smrg firstClear = new_num_lvls; 517818534a1Smrg for (i = 0; i < nMatchingKeys; i++) { 518818534a1Smrg KeySym *pSyms; 519818534a1Smrg int width, nClear; 520818534a1Smrg 521818534a1Smrg key = matchingKeys[i]; 522818534a1Smrg width = XkbKeyGroupsWidth(xkb, key); 523818534a1Smrg nClear = width - firstClear; 524818534a1Smrg pSyms = XkbKeySymsPtr(xkb, key); 525818534a1Smrg for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { 526818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { 527818534a1Smrg if (nClear > 0) 528818534a1Smrg bzero(&pSyms[g * width + firstClear], 529818534a1Smrg nClear * sizeof(KeySym)); 530818534a1Smrg } 531818534a1Smrg } 532818534a1Smrg } 533818534a1Smrg } 534818534a1Smrg type->num_levels = new_num_lvls; 5351ab64890Smrg return Success; 5361ab64890Smrg} 5371ab64890Smrg 5381ab64890SmrgKeySym * 539818534a1SmrgXkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) 5401ab64890Smrg{ 541818534a1Smrg register int i, nSyms, nKeySyms; 542818534a1Smrg unsigned nOldSyms; 543818534a1Smrg KeySym *newSyms; 544818534a1Smrg 545818534a1Smrg if (needed == 0) { 546818534a1Smrg xkb->map->key_sym_map[key].offset = 0; 547818534a1Smrg return xkb->map->syms; 548818534a1Smrg } 549818534a1Smrg nOldSyms = XkbKeyNumSyms(xkb, key); 550818534a1Smrg if (nOldSyms >= (unsigned) needed) { 551818534a1Smrg return XkbKeySymsPtr(xkb, key); 552818534a1Smrg } 553818534a1Smrg if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { 554818534a1Smrg if (nOldSyms > 0) { 555818534a1Smrg memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), 556818534a1Smrg nOldSyms * sizeof(KeySym)); 557818534a1Smrg } 558818534a1Smrg if ((needed - nOldSyms) > 0) { 559818534a1Smrg bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], 560818534a1Smrg (needed - nOldSyms) * sizeof(KeySym)); 561818534a1Smrg } 562818534a1Smrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 563818534a1Smrg xkb->map->num_syms += needed; 564818534a1Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 565818534a1Smrg } 566818534a1Smrg xkb->map->size_syms += (needed > 32 ? needed : 32); 567818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 568818534a1Smrg if (newSyms == NULL) 569818534a1Smrg return NULL; 570818534a1Smrg newSyms[0] = NoSymbol; 5711ab64890Smrg nSyms = 1; 572818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 573818534a1Smrg int nCopy; 574818534a1Smrg 575818534a1Smrg nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); 576818534a1Smrg if ((nKeySyms == 0) && (i != key)) 577818534a1Smrg continue; 578818534a1Smrg if (i == key) 579818534a1Smrg nKeySyms = needed; 580818534a1Smrg if (nCopy != 0) 581818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 582818534a1Smrg nCopy * sizeof(KeySym)); 583818534a1Smrg if (nKeySyms > nCopy) 584818534a1Smrg bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); 585818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 586818534a1Smrg nSyms += nKeySyms; 5871ab64890Smrg } 5881ab64890Smrg _XkbFree(xkb->map->syms); 5891ab64890Smrg xkb->map->syms = newSyms; 5901ab64890Smrg xkb->map->num_syms = nSyms; 5911ab64890Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 5921ab64890Smrg} 5931ab64890Smrg 5941ab64890Smrgstatic unsigned 595818534a1Smrg_ExtendRange(unsigned int old_flags, 596818534a1Smrg unsigned int flag, 597818534a1Smrg KeyCode newKC, 598818534a1Smrg KeyCode *old_min, 599818534a1Smrg unsigned char *old_num) 6001ab64890Smrg{ 601818534a1Smrg if ((old_flags & flag) == 0) { 602818534a1Smrg old_flags |= flag; 603818534a1Smrg *old_min = newKC; 604818534a1Smrg *old_num = 1; 6051ab64890Smrg } 6061ab64890Smrg else { 607818534a1Smrg int last = (*old_min) + (*old_num) - 1; 608818534a1Smrg 609818534a1Smrg if (newKC < *old_min) { 610818534a1Smrg *old_min = newKC; 611818534a1Smrg *old_num = (last - newKC) + 1; 612818534a1Smrg } 613818534a1Smrg else if (newKC > last) { 614818534a1Smrg *old_num = (newKC - (*old_min)) + 1; 615818534a1Smrg } 6161ab64890Smrg } 6171ab64890Smrg return old_flags; 6181ab64890Smrg} 6191ab64890Smrg 6201ab64890SmrgStatus 621818534a1SmrgXkbChangeKeycodeRange(XkbDescPtr xkb, 622818534a1Smrg int minKC, 623818534a1Smrg int maxKC, 624818534a1Smrg XkbChangesPtr changes) 6251ab64890Smrg{ 626818534a1Smrg int tmp; 627818534a1Smrg 628818534a1Smrg if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) 629818534a1Smrg return BadValue; 630818534a1Smrg if (minKC > maxKC) 631818534a1Smrg return BadMatch; 632818534a1Smrg if (minKC < xkb->min_key_code) { 633818534a1Smrg if (changes) 634818534a1Smrg changes->map.min_key_code = minKC; 635818534a1Smrg tmp = xkb->min_key_code - minKC; 636818534a1Smrg if (xkb->map) { 637818534a1Smrg if (xkb->map->key_sym_map) { 638818534a1Smrg bzero((char *) &xkb->map->key_sym_map[minKC], 639818534a1Smrg tmp * sizeof(XkbSymMapRec)); 640818534a1Smrg if (changes) { 641818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 642818534a1Smrg XkbKeySymsMask, minKC, 643818534a1Smrg &changes->map.first_key_sym, 644818534a1Smrg &changes->map.num_key_syms); 645818534a1Smrg } 646818534a1Smrg } 647818534a1Smrg if (xkb->map->modmap) { 648818534a1Smrg bzero((char *) &xkb->map->modmap[minKC], tmp); 649818534a1Smrg if (changes) { 650818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 651818534a1Smrg XkbModifierMapMask, minKC, 652818534a1Smrg &changes->map.first_modmap_key, 653818534a1Smrg &changes->map.num_modmap_keys); 654818534a1Smrg } 655818534a1Smrg } 656818534a1Smrg } 657818534a1Smrg if (xkb->server) { 658818534a1Smrg if (xkb->server->behaviors) { 659818534a1Smrg bzero((char *) &xkb->server->behaviors[minKC], 660818534a1Smrg tmp * sizeof(XkbBehavior)); 661818534a1Smrg if (changes) { 662818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 663818534a1Smrg XkbKeyBehaviorsMask, minKC, 664818534a1Smrg &changes->map.first_key_behavior, 665818534a1Smrg &changes->map.num_key_behaviors); 666818534a1Smrg } 667818534a1Smrg } 668818534a1Smrg if (xkb->server->key_acts) { 669818534a1Smrg bzero((char *) &xkb->server->key_acts[minKC], 670818534a1Smrg tmp * sizeof(unsigned short)); 671818534a1Smrg if (changes) { 672818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 673818534a1Smrg XkbKeyActionsMask, minKC, 674818534a1Smrg &changes->map.first_key_act, 675818534a1Smrg &changes->map.num_key_acts); 676818534a1Smrg } 677818534a1Smrg } 678818534a1Smrg if (xkb->server->vmodmap) { 679818534a1Smrg bzero((char *) &xkb->server->vmodmap[minKC], 680818534a1Smrg tmp * sizeof(unsigned short)); 681818534a1Smrg if (changes) { 682818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 683818534a1Smrg XkbVirtualModMapMask, minKC, 684818534a1Smrg &changes->map.first_modmap_key, 685818534a1Smrg &changes->map.num_vmodmap_keys); 686818534a1Smrg } 687818534a1Smrg } 688818534a1Smrg } 689818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 690818534a1Smrg bzero((char *) &xkb->names->keys[minKC], 691818534a1Smrg tmp * sizeof(XkbKeyNameRec)); 692818534a1Smrg if (changes) { 693818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 694818534a1Smrg XkbKeyNamesMask, minKC, 695818534a1Smrg &changes->names.first_key, 696818534a1Smrg &changes->names.num_keys); 697818534a1Smrg } 698818534a1Smrg } 699818534a1Smrg xkb->min_key_code = minKC; 700818534a1Smrg } 701818534a1Smrg if (maxKC > xkb->max_key_code) { 702818534a1Smrg if (changes) 703818534a1Smrg changes->map.max_key_code = maxKC; 704818534a1Smrg tmp = maxKC - xkb->max_key_code; 705818534a1Smrg if (xkb->map) { 706818534a1Smrg if (xkb->map->key_sym_map) { 707f2d49d05Smrg _XkbResizeArray(xkb->map->key_sym_map, xkb->max_key_code + 1, 708f2d49d05Smrg (maxKC + 1), XkbSymMapRec); 709818534a1Smrg if (!xkb->map->key_sym_map) { 710818534a1Smrg return BadAlloc; 711818534a1Smrg } 712818534a1Smrg if (changes) { 713818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 714818534a1Smrg XkbKeySymsMask, maxKC, 715818534a1Smrg &changes->map.first_key_sym, 716818534a1Smrg &changes->map.num_key_syms); 717818534a1Smrg } 718818534a1Smrg } 719818534a1Smrg if (xkb->map->modmap) { 720f2d49d05Smrg _XkbResizeArray(xkb->map->modmap, xkb->max_key_code + 1, 721f2d49d05Smrg (maxKC + 1), unsigned char); 722818534a1Smrg if (!xkb->map->modmap) { 723818534a1Smrg return BadAlloc; 724818534a1Smrg } 725818534a1Smrg if (changes) { 726818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 727818534a1Smrg XkbModifierMapMask, maxKC, 728818534a1Smrg &changes->map.first_modmap_key, 729818534a1Smrg &changes->map.num_modmap_keys); 730818534a1Smrg } 731818534a1Smrg } 732818534a1Smrg } 733818534a1Smrg if (xkb->server) { 734818534a1Smrg if (xkb->server->behaviors) { 735f2d49d05Smrg _XkbResizeArray(xkb->server->behaviors, xkb->max_key_code + 1, 736f2d49d05Smrg (maxKC + 1), XkbBehavior); 737818534a1Smrg if (!xkb->server->behaviors) { 738818534a1Smrg return BadAlloc; 739818534a1Smrg } 740818534a1Smrg if (changes) { 741818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 742818534a1Smrg XkbKeyBehaviorsMask, maxKC, 743818534a1Smrg &changes->map.first_key_behavior, 744818534a1Smrg &changes->map.num_key_behaviors); 745818534a1Smrg } 746818534a1Smrg } 747818534a1Smrg if (xkb->server->key_acts) { 748f2d49d05Smrg _XkbResizeArray(xkb->server->key_acts, xkb->max_key_code + 1, 749f2d49d05Smrg (maxKC + 1), unsigned short); 750818534a1Smrg if (!xkb->server->key_acts) { 751818534a1Smrg return BadAlloc; 752818534a1Smrg } 753818534a1Smrg if (changes) { 754818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 755818534a1Smrg XkbKeyActionsMask, maxKC, 756818534a1Smrg &changes->map.first_key_act, 757818534a1Smrg &changes->map.num_key_acts); 758818534a1Smrg } 759818534a1Smrg } 760818534a1Smrg if (xkb->server->vmodmap) { 761f2d49d05Smrg _XkbResizeArray(xkb->server->vmodmap, xkb->max_key_code + 1, 762f2d49d05Smrg (maxKC + 1), unsigned short); 763818534a1Smrg if (!xkb->server->vmodmap) { 764818534a1Smrg return BadAlloc; 765818534a1Smrg } 766818534a1Smrg if (changes) { 767818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 768818534a1Smrg XkbVirtualModMapMask, maxKC, 769818534a1Smrg &changes->map.first_modmap_key, 770818534a1Smrg &changes->map.num_vmodmap_keys); 771818534a1Smrg } 772818534a1Smrg } 773818534a1Smrg } 774818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 775f2d49d05Smrg _XkbResizeArray(xkb->names->keys, xkb->max_key_code + 1, 776f2d49d05Smrg (maxKC + 1), XkbKeyNameRec); 777818534a1Smrg if (!xkb->names->keys) { 778818534a1Smrg return BadAlloc; 779818534a1Smrg } 780818534a1Smrg if (changes) { 781818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 782818534a1Smrg XkbKeyNamesMask, maxKC, 783818534a1Smrg &changes->names.first_key, 784818534a1Smrg &changes->names.num_keys); 785818534a1Smrg } 786818534a1Smrg } 787818534a1Smrg xkb->max_key_code = maxKC; 7881ab64890Smrg } 7891ab64890Smrg return Success; 7901ab64890Smrg} 7911ab64890Smrg 7921ab64890SmrgXkbAction * 793818534a1SmrgXkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) 7941ab64890Smrg{ 795818534a1Smrg register int i, nActs; 796818534a1Smrg XkbAction *newActs; 797818534a1Smrg 798818534a1Smrg if (needed == 0) { 799818534a1Smrg xkb->server->key_acts[key] = 0; 800818534a1Smrg return NULL; 801818534a1Smrg } 802818534a1Smrg if (XkbKeyHasActions(xkb, key) && 803818534a1Smrg (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) 804818534a1Smrg return XkbKeyActionsPtr(xkb, key); 805818534a1Smrg if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { 806818534a1Smrg xkb->server->key_acts[key] = xkb->server->num_acts; 807818534a1Smrg xkb->server->num_acts += needed; 808818534a1Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 809818534a1Smrg } 810818534a1Smrg xkb->server->size_acts = xkb->server->num_acts + needed + 8; 811818534a1Smrg newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); 812818534a1Smrg if (newActs == NULL) 813818534a1Smrg return NULL; 8141ab64890Smrg newActs[0].type = XkbSA_NoAction; 8151ab64890Smrg nActs = 1; 816818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 817818534a1Smrg int nKeyActs, nCopy; 818818534a1Smrg 819818534a1Smrg if ((xkb->server->key_acts[i] == 0) && (i != key)) 820818534a1Smrg continue; 821818534a1Smrg 822818534a1Smrg nCopy = nKeyActs = XkbKeyNumActions(xkb, i); 823818534a1Smrg if (i == key) { 824818534a1Smrg nKeyActs = needed; 825818534a1Smrg if (needed < nCopy) 826818534a1Smrg nCopy = needed; 827818534a1Smrg } 828818534a1Smrg 829818534a1Smrg if (nCopy > 0) 830818534a1Smrg memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), 831818534a1Smrg nCopy * sizeof(XkbAction)); 832818534a1Smrg if (nCopy < nKeyActs) 833818534a1Smrg bzero(&newActs[nActs + nCopy], 834818534a1Smrg (nKeyActs - nCopy) * sizeof(XkbAction)); 835818534a1Smrg xkb->server->key_acts[i] = nActs; 836818534a1Smrg nActs += nKeyActs; 8371ab64890Smrg } 8381ab64890Smrg _XkbFree(xkb->server->acts); 8391ab64890Smrg xkb->server->acts = newActs; 840818534a1Smrg xkb->server->num_acts = nActs; 8411ab64890Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 8421ab64890Smrg} 8431ab64890Smrg 8441ab64890Smrgvoid 845818534a1SmrgXkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 8461ab64890Smrg{ 847818534a1Smrg XkbClientMapPtr map; 8481ab64890Smrg 849818534a1Smrg if ((xkb == NULL) || (xkb->map == NULL)) 850818534a1Smrg return; 8511ab64890Smrg if (freeMap) 852818534a1Smrg what = XkbAllClientInfoMask; 853818534a1Smrg map = xkb->map; 854818534a1Smrg if (what & XkbKeyTypesMask) { 855818534a1Smrg if (map->types != NULL) { 856818534a1Smrg if (map->num_types > 0) { 857818534a1Smrg register int i; 858818534a1Smrg XkbKeyTypePtr type; 859818534a1Smrg 860818534a1Smrg for (i = 0, type = map->types; i < map->num_types; i++, type++) { 861cf2acddeSmrg _XkbFree(type->map); 862cf2acddeSmrg type->map = NULL; 863cf2acddeSmrg 864cf2acddeSmrg _XkbFree(type->preserve); 865cf2acddeSmrg type->preserve = NULL; 866cf2acddeSmrg 867818534a1Smrg type->map_count = 0; 868cf2acddeSmrg 869cf2acddeSmrg _XkbFree(type->level_names); 870cf2acddeSmrg type->level_names = NULL; 871818534a1Smrg } 872818534a1Smrg } 873818534a1Smrg _XkbFree(map->types); 874818534a1Smrg map->num_types = map->size_types = 0; 875818534a1Smrg map->types = NULL; 876818534a1Smrg } 877818534a1Smrg } 878818534a1Smrg if (what & XkbKeySymsMask) { 879cf2acddeSmrg _XkbFree(map->key_sym_map); 880cf2acddeSmrg map->key_sym_map = NULL; 881cf2acddeSmrg 882cf2acddeSmrg _XkbFree(map->syms); 883cf2acddeSmrg map->size_syms = map->num_syms = 0; 884cf2acddeSmrg map->syms = NULL; 885818534a1Smrg } 886cf2acddeSmrg if (what & XkbModifierMapMask) { 887818534a1Smrg _XkbFree(map->modmap); 888818534a1Smrg map->modmap = NULL; 8891ab64890Smrg } 8901ab64890Smrg if (freeMap) { 891818534a1Smrg _XkbFree(xkb->map); 892818534a1Smrg xkb->map = NULL; 8931ab64890Smrg } 8941ab64890Smrg return; 8951ab64890Smrg} 8961ab64890Smrg 8971ab64890Smrgvoid 898818534a1SmrgXkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 8991ab64890Smrg{ 900818534a1Smrg XkbServerMapPtr map; 9011ab64890Smrg 902818534a1Smrg if ((xkb == NULL) || (xkb->server == NULL)) 903818534a1Smrg return; 9041ab64890Smrg if (freeMap) 905818534a1Smrg what = XkbAllServerInfoMask; 906818534a1Smrg map = xkb->server; 907cf2acddeSmrg if (what & XkbExplicitComponentsMask) { 908818534a1Smrg _XkbFree(map->explicit); 909818534a1Smrg map->explicit = NULL; 910818534a1Smrg } 911818534a1Smrg if (what & XkbKeyActionsMask) { 912cf2acddeSmrg _XkbFree(map->key_acts); 913818534a1Smrg map->key_acts = NULL; 914cf2acddeSmrg 915cf2acddeSmrg _XkbFree(map->acts); 916818534a1Smrg map->num_acts = map->size_acts = 0; 917818534a1Smrg map->acts = NULL; 918818534a1Smrg } 919cf2acddeSmrg if (what & XkbKeyBehaviorsMask) { 920818534a1Smrg _XkbFree(map->behaviors); 921818534a1Smrg map->behaviors = NULL; 922818534a1Smrg } 923cf2acddeSmrg if (what & XkbVirtualModMapMask) { 924818534a1Smrg _XkbFree(map->vmodmap); 925818534a1Smrg map->vmodmap = NULL; 9261ab64890Smrg } 9271ab64890Smrg 9281ab64890Smrg if (freeMap) { 929818534a1Smrg _XkbFree(xkb->server); 930818534a1Smrg xkb->server = NULL; 9311ab64890Smrg } 9321ab64890Smrg return; 9331ab64890Smrg} 934