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); 439d5e6aabbSmrg if (width < type->num_levels || width >= new_num_lvls) { 440d5e6aabbSmrg nTotal += XkbKeyNumSyms(xkb,i); 441818534a1Smrg continue; 442d5e6aabbSmrg } 443818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 444818534a1Smrg (g >= 0) && (!match); g--) { 445818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 446818534a1Smrg matchingKeys[nMatchingKeys++] = i; 447818534a1Smrg match = 1; 448818534a1Smrg } 449818534a1Smrg } 450d5e6aabbSmrg if (!match) 451818534a1Smrg nTotal += XkbKeyNumSyms(xkb, i); 452818534a1Smrg else { 453818534a1Smrg nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; 454818534a1Smrg nResize++; 455818534a1Smrg } 456818534a1Smrg } 457818534a1Smrg if (nResize > 0) { 458818534a1Smrg int nextMatch; 459818534a1Smrg 460d5e6aabbSmrg xkb->map->size_syms = (nTotal * 15) / 10; 461818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 462818534a1Smrg if (newSyms == NULL) 463818534a1Smrg return BadAlloc; 464818534a1Smrg nextMatch = 0; 465818534a1Smrg nSyms = 1; 466818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 467818534a1Smrg if (matchingKeys[nextMatch] == i) { 468818534a1Smrg KeySym *pOld; 469818534a1Smrg 470818534a1Smrg nextMatch++; 471818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 472818534a1Smrg pOld = XkbKeySymsPtr(xkb, i); 473818534a1Smrg for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { 474818534a1Smrg memcpy(&newSyms[nSyms + (new_num_lvls * g)], 475818534a1Smrg &pOld[width * g], width * sizeof(KeySym)); 476818534a1Smrg } 477818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 478818534a1Smrg nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; 479818534a1Smrg } 480818534a1Smrg else { 481818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 482818534a1Smrg XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); 483818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 484818534a1Smrg nSyms += XkbKeyNumSyms(xkb, i); 485818534a1Smrg } 486818534a1Smrg } 487818534a1Smrg type->num_levels = new_num_lvls; 488818534a1Smrg _XkbFree(xkb->map->syms); 489818534a1Smrg xkb->map->syms = newSyms; 490818534a1Smrg xkb->map->num_syms = nSyms; 491818534a1Smrg return Success; 492818534a1Smrg } 493818534a1Smrg } 494818534a1Smrg else if (new_num_lvls < type->num_levels) { 495818534a1Smrg int width, match; 496818534a1Smrg register int g, i; 497818534a1Smrg 498818534a1Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 499818534a1Smrg width = XkbKeyGroupsWidth(xkb, i); 500818534a1Smrg if (width < type->num_levels) 501818534a1Smrg continue; 502818534a1Smrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 503818534a1Smrg (g >= 0) && (!match); g--) { 504818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 505818534a1Smrg matchingKeys[nMatchingKeys++] = i; 506818534a1Smrg match = 1; 507818534a1Smrg } 508818534a1Smrg } 509818534a1Smrg } 510818534a1Smrg } 511818534a1Smrg if (nMatchingKeys > 0) { 512818534a1Smrg int key, firstClear; 513818534a1Smrg register int i, g; 514818534a1Smrg 515818534a1Smrg if (new_num_lvls > type->num_levels) 516818534a1Smrg firstClear = type->num_levels; 517818534a1Smrg else 518818534a1Smrg firstClear = new_num_lvls; 519818534a1Smrg for (i = 0; i < nMatchingKeys; i++) { 520818534a1Smrg KeySym *pSyms; 521818534a1Smrg int width, nClear; 522818534a1Smrg 523818534a1Smrg key = matchingKeys[i]; 524818534a1Smrg width = XkbKeyGroupsWidth(xkb, key); 525818534a1Smrg nClear = width - firstClear; 526818534a1Smrg pSyms = XkbKeySymsPtr(xkb, key); 527818534a1Smrg for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { 528818534a1Smrg if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { 529818534a1Smrg if (nClear > 0) 530818534a1Smrg bzero(&pSyms[g * width + firstClear], 531818534a1Smrg nClear * sizeof(KeySym)); 532818534a1Smrg } 533818534a1Smrg } 534818534a1Smrg } 535818534a1Smrg } 536818534a1Smrg type->num_levels = new_num_lvls; 5371ab64890Smrg return Success; 5381ab64890Smrg} 5391ab64890Smrg 5401ab64890SmrgKeySym * 541818534a1SmrgXkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) 5421ab64890Smrg{ 543818534a1Smrg register int i, nSyms, nKeySyms; 544818534a1Smrg unsigned nOldSyms; 545818534a1Smrg KeySym *newSyms; 546818534a1Smrg 547818534a1Smrg if (needed == 0) { 548818534a1Smrg xkb->map->key_sym_map[key].offset = 0; 549818534a1Smrg return xkb->map->syms; 550818534a1Smrg } 551818534a1Smrg nOldSyms = XkbKeyNumSyms(xkb, key); 552818534a1Smrg if (nOldSyms >= (unsigned) needed) { 553818534a1Smrg return XkbKeySymsPtr(xkb, key); 554818534a1Smrg } 555818534a1Smrg if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { 556818534a1Smrg if (nOldSyms > 0) { 557818534a1Smrg memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), 558818534a1Smrg nOldSyms * sizeof(KeySym)); 559818534a1Smrg } 560818534a1Smrg if ((needed - nOldSyms) > 0) { 561818534a1Smrg bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], 562818534a1Smrg (needed - nOldSyms) * sizeof(KeySym)); 563818534a1Smrg } 564818534a1Smrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 565818534a1Smrg xkb->map->num_syms += needed; 566818534a1Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 567818534a1Smrg } 568818534a1Smrg xkb->map->size_syms += (needed > 32 ? needed : 32); 569818534a1Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); 570818534a1Smrg if (newSyms == NULL) 571818534a1Smrg return NULL; 572818534a1Smrg newSyms[0] = NoSymbol; 5731ab64890Smrg nSyms = 1; 574818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 575818534a1Smrg int nCopy; 576818534a1Smrg 577818534a1Smrg nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); 578818534a1Smrg if ((nKeySyms == 0) && (i != key)) 579818534a1Smrg continue; 580818534a1Smrg if (i == key) 581818534a1Smrg nKeySyms = needed; 582818534a1Smrg if (nCopy != 0) 583818534a1Smrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 584818534a1Smrg nCopy * sizeof(KeySym)); 585818534a1Smrg if (nKeySyms > nCopy) 586818534a1Smrg bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); 587818534a1Smrg xkb->map->key_sym_map[i].offset = nSyms; 588818534a1Smrg nSyms += nKeySyms; 5891ab64890Smrg } 5901ab64890Smrg _XkbFree(xkb->map->syms); 5911ab64890Smrg xkb->map->syms = newSyms; 5921ab64890Smrg xkb->map->num_syms = nSyms; 5931ab64890Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 5941ab64890Smrg} 5951ab64890Smrg 5961ab64890Smrgstatic unsigned 597818534a1Smrg_ExtendRange(unsigned int old_flags, 598818534a1Smrg unsigned int flag, 599818534a1Smrg KeyCode newKC, 600818534a1Smrg KeyCode *old_min, 601818534a1Smrg unsigned char *old_num) 6021ab64890Smrg{ 603818534a1Smrg if ((old_flags & flag) == 0) { 604818534a1Smrg old_flags |= flag; 605818534a1Smrg *old_min = newKC; 606818534a1Smrg *old_num = 1; 6071ab64890Smrg } 6081ab64890Smrg else { 609818534a1Smrg int last = (*old_min) + (*old_num) - 1; 610818534a1Smrg 611818534a1Smrg if (newKC < *old_min) { 612818534a1Smrg *old_min = newKC; 613818534a1Smrg *old_num = (last - newKC) + 1; 614818534a1Smrg } 615818534a1Smrg else if (newKC > last) { 616818534a1Smrg *old_num = (newKC - (*old_min)) + 1; 617818534a1Smrg } 6181ab64890Smrg } 6191ab64890Smrg return old_flags; 6201ab64890Smrg} 6211ab64890Smrg 6221ab64890SmrgStatus 623818534a1SmrgXkbChangeKeycodeRange(XkbDescPtr xkb, 624818534a1Smrg int minKC, 625818534a1Smrg int maxKC, 626818534a1Smrg XkbChangesPtr changes) 6271ab64890Smrg{ 628818534a1Smrg int tmp; 629818534a1Smrg 630818534a1Smrg if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) 631818534a1Smrg return BadValue; 632818534a1Smrg if (minKC > maxKC) 633818534a1Smrg return BadMatch; 634818534a1Smrg if (minKC < xkb->min_key_code) { 635818534a1Smrg if (changes) 636818534a1Smrg changes->map.min_key_code = minKC; 637818534a1Smrg tmp = xkb->min_key_code - minKC; 638818534a1Smrg if (xkb->map) { 639818534a1Smrg if (xkb->map->key_sym_map) { 640818534a1Smrg bzero((char *) &xkb->map->key_sym_map[minKC], 641818534a1Smrg tmp * sizeof(XkbSymMapRec)); 642818534a1Smrg if (changes) { 643818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 644818534a1Smrg XkbKeySymsMask, minKC, 645818534a1Smrg &changes->map.first_key_sym, 646818534a1Smrg &changes->map.num_key_syms); 647818534a1Smrg } 648818534a1Smrg } 649818534a1Smrg if (xkb->map->modmap) { 650818534a1Smrg bzero((char *) &xkb->map->modmap[minKC], tmp); 651818534a1Smrg if (changes) { 652818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 653818534a1Smrg XkbModifierMapMask, minKC, 654818534a1Smrg &changes->map.first_modmap_key, 655818534a1Smrg &changes->map.num_modmap_keys); 656818534a1Smrg } 657818534a1Smrg } 658818534a1Smrg } 659818534a1Smrg if (xkb->server) { 660818534a1Smrg if (xkb->server->behaviors) { 661818534a1Smrg bzero((char *) &xkb->server->behaviors[minKC], 662818534a1Smrg tmp * sizeof(XkbBehavior)); 663818534a1Smrg if (changes) { 664818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 665818534a1Smrg XkbKeyBehaviorsMask, minKC, 666818534a1Smrg &changes->map.first_key_behavior, 667818534a1Smrg &changes->map.num_key_behaviors); 668818534a1Smrg } 669818534a1Smrg } 670818534a1Smrg if (xkb->server->key_acts) { 671818534a1Smrg bzero((char *) &xkb->server->key_acts[minKC], 672818534a1Smrg tmp * sizeof(unsigned short)); 673818534a1Smrg if (changes) { 674818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 675818534a1Smrg XkbKeyActionsMask, minKC, 676818534a1Smrg &changes->map.first_key_act, 677818534a1Smrg &changes->map.num_key_acts); 678818534a1Smrg } 679818534a1Smrg } 680818534a1Smrg if (xkb->server->vmodmap) { 681818534a1Smrg bzero((char *) &xkb->server->vmodmap[minKC], 682818534a1Smrg tmp * sizeof(unsigned short)); 683818534a1Smrg if (changes) { 684818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 685818534a1Smrg XkbVirtualModMapMask, minKC, 6860ef0e59aSmrg &changes->map.first_vmodmap_key, 687818534a1Smrg &changes->map.num_vmodmap_keys); 688818534a1Smrg } 689818534a1Smrg } 690818534a1Smrg } 691818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 692818534a1Smrg bzero((char *) &xkb->names->keys[minKC], 693818534a1Smrg tmp * sizeof(XkbKeyNameRec)); 694818534a1Smrg if (changes) { 695818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 696818534a1Smrg XkbKeyNamesMask, minKC, 697818534a1Smrg &changes->names.first_key, 698818534a1Smrg &changes->names.num_keys); 699818534a1Smrg } 700818534a1Smrg } 701818534a1Smrg xkb->min_key_code = minKC; 702818534a1Smrg } 703818534a1Smrg if (maxKC > xkb->max_key_code) { 704818534a1Smrg if (changes) 705818534a1Smrg changes->map.max_key_code = maxKC; 706818534a1Smrg tmp = maxKC - xkb->max_key_code; 707818534a1Smrg if (xkb->map) { 708818534a1Smrg if (xkb->map->key_sym_map) { 709f2d49d05Smrg _XkbResizeArray(xkb->map->key_sym_map, xkb->max_key_code + 1, 710f2d49d05Smrg (maxKC + 1), XkbSymMapRec); 711818534a1Smrg if (!xkb->map->key_sym_map) { 712818534a1Smrg return BadAlloc; 713818534a1Smrg } 714818534a1Smrg if (changes) { 715818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 716818534a1Smrg XkbKeySymsMask, maxKC, 717818534a1Smrg &changes->map.first_key_sym, 718818534a1Smrg &changes->map.num_key_syms); 719818534a1Smrg } 720818534a1Smrg } 721818534a1Smrg if (xkb->map->modmap) { 722f2d49d05Smrg _XkbResizeArray(xkb->map->modmap, xkb->max_key_code + 1, 723f2d49d05Smrg (maxKC + 1), unsigned char); 724818534a1Smrg if (!xkb->map->modmap) { 725818534a1Smrg return BadAlloc; 726818534a1Smrg } 727818534a1Smrg if (changes) { 728818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 729818534a1Smrg XkbModifierMapMask, maxKC, 730818534a1Smrg &changes->map.first_modmap_key, 731818534a1Smrg &changes->map.num_modmap_keys); 732818534a1Smrg } 733818534a1Smrg } 734818534a1Smrg } 735818534a1Smrg if (xkb->server) { 736818534a1Smrg if (xkb->server->behaviors) { 737f2d49d05Smrg _XkbResizeArray(xkb->server->behaviors, xkb->max_key_code + 1, 738f2d49d05Smrg (maxKC + 1), XkbBehavior); 739818534a1Smrg if (!xkb->server->behaviors) { 740818534a1Smrg return BadAlloc; 741818534a1Smrg } 742818534a1Smrg if (changes) { 743818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 744818534a1Smrg XkbKeyBehaviorsMask, maxKC, 745818534a1Smrg &changes->map.first_key_behavior, 746818534a1Smrg &changes->map.num_key_behaviors); 747818534a1Smrg } 748818534a1Smrg } 749818534a1Smrg if (xkb->server->key_acts) { 750f2d49d05Smrg _XkbResizeArray(xkb->server->key_acts, xkb->max_key_code + 1, 751f2d49d05Smrg (maxKC + 1), unsigned short); 752818534a1Smrg if (!xkb->server->key_acts) { 753818534a1Smrg return BadAlloc; 754818534a1Smrg } 755818534a1Smrg if (changes) { 756818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 757818534a1Smrg XkbKeyActionsMask, maxKC, 758818534a1Smrg &changes->map.first_key_act, 759818534a1Smrg &changes->map.num_key_acts); 760818534a1Smrg } 761818534a1Smrg } 762818534a1Smrg if (xkb->server->vmodmap) { 763f2d49d05Smrg _XkbResizeArray(xkb->server->vmodmap, xkb->max_key_code + 1, 764f2d49d05Smrg (maxKC + 1), unsigned short); 765818534a1Smrg if (!xkb->server->vmodmap) { 766818534a1Smrg return BadAlloc; 767818534a1Smrg } 768818534a1Smrg if (changes) { 769818534a1Smrg changes->map.changed = _ExtendRange(changes->map.changed, 770818534a1Smrg XkbVirtualModMapMask, maxKC, 7710ef0e59aSmrg &changes->map.first_vmodmap_key, 772818534a1Smrg &changes->map.num_vmodmap_keys); 773818534a1Smrg } 774818534a1Smrg } 775818534a1Smrg } 776818534a1Smrg if ((xkb->names) && (xkb->names->keys)) { 777f2d49d05Smrg _XkbResizeArray(xkb->names->keys, xkb->max_key_code + 1, 778f2d49d05Smrg (maxKC + 1), XkbKeyNameRec); 779818534a1Smrg if (!xkb->names->keys) { 780818534a1Smrg return BadAlloc; 781818534a1Smrg } 782818534a1Smrg if (changes) { 783818534a1Smrg changes->names.changed = _ExtendRange(changes->names.changed, 784818534a1Smrg XkbKeyNamesMask, maxKC, 785818534a1Smrg &changes->names.first_key, 786818534a1Smrg &changes->names.num_keys); 787818534a1Smrg } 788818534a1Smrg } 789818534a1Smrg xkb->max_key_code = maxKC; 7901ab64890Smrg } 7911ab64890Smrg return Success; 7921ab64890Smrg} 7931ab64890Smrg 7941ab64890SmrgXkbAction * 795818534a1SmrgXkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) 7961ab64890Smrg{ 797818534a1Smrg register int i, nActs; 798818534a1Smrg XkbAction *newActs; 799818534a1Smrg 8006e467124Smrg if (needed <= 0) { 801818534a1Smrg xkb->server->key_acts[key] = 0; 802818534a1Smrg return NULL; 803818534a1Smrg } 804818534a1Smrg if (XkbKeyHasActions(xkb, key) && 805818534a1Smrg (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) 806818534a1Smrg return XkbKeyActionsPtr(xkb, key); 807818534a1Smrg if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { 808818534a1Smrg xkb->server->key_acts[key] = xkb->server->num_acts; 809818534a1Smrg xkb->server->num_acts += needed; 810818534a1Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 811818534a1Smrg } 812818534a1Smrg xkb->server->size_acts = xkb->server->num_acts + needed + 8; 813818534a1Smrg newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); 814818534a1Smrg if (newActs == NULL) 815818534a1Smrg return NULL; 8161ab64890Smrg newActs[0].type = XkbSA_NoAction; 8171ab64890Smrg nActs = 1; 818818534a1Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 819818534a1Smrg int nKeyActs, nCopy; 820818534a1Smrg 821818534a1Smrg if ((xkb->server->key_acts[i] == 0) && (i != key)) 822818534a1Smrg continue; 823818534a1Smrg 824818534a1Smrg nCopy = nKeyActs = XkbKeyNumActions(xkb, i); 825818534a1Smrg if (i == key) { 826818534a1Smrg nKeyActs = needed; 827818534a1Smrg if (needed < nCopy) 828818534a1Smrg nCopy = needed; 829818534a1Smrg } 830818534a1Smrg 831818534a1Smrg if (nCopy > 0) 832818534a1Smrg memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), 833818534a1Smrg nCopy * sizeof(XkbAction)); 834818534a1Smrg if (nCopy < nKeyActs) 835818534a1Smrg bzero(&newActs[nActs + nCopy], 836818534a1Smrg (nKeyActs - nCopy) * sizeof(XkbAction)); 837818534a1Smrg xkb->server->key_acts[i] = nActs; 838818534a1Smrg nActs += nKeyActs; 8391ab64890Smrg } 8401ab64890Smrg _XkbFree(xkb->server->acts); 8411ab64890Smrg xkb->server->acts = newActs; 842818534a1Smrg xkb->server->num_acts = nActs; 8431ab64890Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 8441ab64890Smrg} 8451ab64890Smrg 8461ab64890Smrgvoid 847818534a1SmrgXkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 8481ab64890Smrg{ 849818534a1Smrg XkbClientMapPtr map; 8501ab64890Smrg 851818534a1Smrg if ((xkb == NULL) || (xkb->map == NULL)) 852818534a1Smrg return; 8531ab64890Smrg if (freeMap) 854818534a1Smrg what = XkbAllClientInfoMask; 855818534a1Smrg map = xkb->map; 856818534a1Smrg if (what & XkbKeyTypesMask) { 857818534a1Smrg if (map->types != NULL) { 858818534a1Smrg if (map->num_types > 0) { 859818534a1Smrg register int i; 860818534a1Smrg XkbKeyTypePtr type; 861818534a1Smrg 862818534a1Smrg for (i = 0, type = map->types; i < map->num_types; i++, type++) { 863cf2acddeSmrg _XkbFree(type->map); 864cf2acddeSmrg type->map = NULL; 865cf2acddeSmrg 866cf2acddeSmrg _XkbFree(type->preserve); 867cf2acddeSmrg type->preserve = NULL; 868cf2acddeSmrg 869818534a1Smrg type->map_count = 0; 870cf2acddeSmrg 871cf2acddeSmrg _XkbFree(type->level_names); 872cf2acddeSmrg type->level_names = NULL; 873818534a1Smrg } 874818534a1Smrg } 875818534a1Smrg _XkbFree(map->types); 876818534a1Smrg map->num_types = map->size_types = 0; 877818534a1Smrg map->types = NULL; 878818534a1Smrg } 879818534a1Smrg } 880818534a1Smrg if (what & XkbKeySymsMask) { 881cf2acddeSmrg _XkbFree(map->key_sym_map); 882cf2acddeSmrg map->key_sym_map = NULL; 883cf2acddeSmrg 884cf2acddeSmrg _XkbFree(map->syms); 885cf2acddeSmrg map->size_syms = map->num_syms = 0; 886cf2acddeSmrg map->syms = NULL; 887818534a1Smrg } 888cf2acddeSmrg if (what & XkbModifierMapMask) { 889818534a1Smrg _XkbFree(map->modmap); 890818534a1Smrg map->modmap = NULL; 8911ab64890Smrg } 8921ab64890Smrg if (freeMap) { 893818534a1Smrg _XkbFree(xkb->map); 894818534a1Smrg xkb->map = NULL; 8951ab64890Smrg } 8961ab64890Smrg return; 8971ab64890Smrg} 8981ab64890Smrg 8991ab64890Smrgvoid 900818534a1SmrgXkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 9011ab64890Smrg{ 902818534a1Smrg XkbServerMapPtr map; 9031ab64890Smrg 904818534a1Smrg if ((xkb == NULL) || (xkb->server == NULL)) 905818534a1Smrg return; 9061ab64890Smrg if (freeMap) 907818534a1Smrg what = XkbAllServerInfoMask; 908818534a1Smrg map = xkb->server; 909cf2acddeSmrg if (what & XkbExplicitComponentsMask) { 910818534a1Smrg _XkbFree(map->explicit); 911818534a1Smrg map->explicit = NULL; 912818534a1Smrg } 913818534a1Smrg if (what & XkbKeyActionsMask) { 914cf2acddeSmrg _XkbFree(map->key_acts); 915818534a1Smrg map->key_acts = NULL; 916cf2acddeSmrg 917cf2acddeSmrg _XkbFree(map->acts); 918818534a1Smrg map->num_acts = map->size_acts = 0; 919818534a1Smrg map->acts = NULL; 920818534a1Smrg } 921cf2acddeSmrg if (what & XkbKeyBehaviorsMask) { 922818534a1Smrg _XkbFree(map->behaviors); 923818534a1Smrg map->behaviors = NULL; 924818534a1Smrg } 925cf2acddeSmrg if (what & XkbVirtualModMapMask) { 926818534a1Smrg _XkbFree(map->vmodmap); 927818534a1Smrg map->vmodmap = NULL; 9281ab64890Smrg } 9291ab64890Smrg 9301ab64890Smrg if (freeMap) { 931818534a1Smrg _XkbFree(xkb->server); 932818534a1Smrg xkb->server = NULL; 9331ab64890Smrg } 9341ab64890Smrg return; 9351ab64890Smrg} 936