XKBMAlloc.c revision 6747b715
105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#elif defined(HAVE_CONFIG_H) 3005b261ecSmrg#include <config.h> 3105b261ecSmrg#endif 3205b261ecSmrg 3305b261ecSmrg#include <stdio.h> 3405b261ecSmrg#include <X11/X.h> 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg#include <X11/keysym.h> 3905b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg 4205b261ecSmrg/***====================================================================***/ 4305b261ecSmrg 4405b261ecSmrgStatus 4505b261ecSmrgXkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) 4605b261ecSmrg{ 4705b261ecSmrgregister int i; 4805b261ecSmrgXkbClientMapPtr map; 4905b261ecSmrg 5005b261ecSmrg if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) 5105b261ecSmrg return BadValue; 5205b261ecSmrg if ((which&XkbKeySymsMask)&& 5305b261ecSmrg ((!XkbIsLegalKeycode(xkb->min_key_code))|| 5405b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 5505b261ecSmrg (xkb->max_key_code<xkb->min_key_code))) { 564642e01fSmrg DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n", 5705b261ecSmrg xkb->min_key_code,xkb->max_key_code); 5805b261ecSmrg return BadValue; 5905b261ecSmrg } 6005b261ecSmrg 6105b261ecSmrg if (xkb->map==NULL) { 626747b715Smrg map= calloc(1, sizeof(XkbClientMapRec)); 6305b261ecSmrg if (map==NULL) 6405b261ecSmrg return BadAlloc; 6505b261ecSmrg xkb->map= map; 6605b261ecSmrg } 6705b261ecSmrg else map= xkb->map; 6805b261ecSmrg 6905b261ecSmrg if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { 7005b261ecSmrg if (map->types==NULL) { 716747b715Smrg map->types= calloc(nTotalTypes, sizeof(XkbKeyTypeRec)); 7205b261ecSmrg if (map->types==NULL) 7305b261ecSmrg return BadAlloc; 7405b261ecSmrg map->num_types= 0; 7505b261ecSmrg map->size_types= nTotalTypes; 7605b261ecSmrg } 7705b261ecSmrg else if (map->size_types<nTotalTypes) { 7805b261ecSmrg XkbKeyTypeRec *prev_types = map->types; 7905b261ecSmrg 806747b715Smrg map->types= realloc(map->types,nTotalTypes * sizeof(XkbKeyTypeRec)); 8105b261ecSmrg if (map->types==NULL) { 826747b715Smrg free(prev_types); 8305b261ecSmrg map->num_types= map->size_types= 0; 8405b261ecSmrg return BadAlloc; 8505b261ecSmrg } 8605b261ecSmrg map->size_types= nTotalTypes; 876747b715Smrg memset(&map->types[map->num_types], 0, 8805b261ecSmrg ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); 8905b261ecSmrg } 9005b261ecSmrg } 9105b261ecSmrg if (which&XkbKeySymsMask) { 9205b261ecSmrg int nKeys= XkbNumKeys(xkb); 9305b261ecSmrg if (map->syms==NULL) { 9405b261ecSmrg map->size_syms= (nKeys*15)/10; 956747b715Smrg map->syms= calloc(map->size_syms, sizeof(KeySym)); 9605b261ecSmrg if (!map->syms) { 9705b261ecSmrg map->size_syms= 0; 9805b261ecSmrg return BadAlloc; 9905b261ecSmrg } 10005b261ecSmrg map->num_syms= 1; 10105b261ecSmrg map->syms[0]= NoSymbol; 10205b261ecSmrg } 10305b261ecSmrg if (map->key_sym_map==NULL) { 10405b261ecSmrg i= xkb->max_key_code+1; 1056747b715Smrg map->key_sym_map= calloc(i, sizeof(XkbSymMapRec)); 10605b261ecSmrg if (map->key_sym_map==NULL) 10705b261ecSmrg return BadAlloc; 10805b261ecSmrg } 10905b261ecSmrg } 11005b261ecSmrg if (which&XkbModifierMapMask) { 11105b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 11205b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 11305b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 11405b261ecSmrg return BadMatch; 11505b261ecSmrg if (map->modmap==NULL) { 11605b261ecSmrg i= xkb->max_key_code+1; 1176747b715Smrg map->modmap= calloc(i, sizeof(unsigned char)); 11805b261ecSmrg if (map->modmap==NULL) 11905b261ecSmrg return BadAlloc; 12005b261ecSmrg } 12105b261ecSmrg } 12205b261ecSmrg return Success; 12305b261ecSmrg} 12405b261ecSmrg 12505b261ecSmrgStatus 12605b261ecSmrgXkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) 12705b261ecSmrg{ 12805b261ecSmrgregister int i; 12905b261ecSmrgXkbServerMapPtr map; 13005b261ecSmrg 13105b261ecSmrg if (xkb==NULL) 13205b261ecSmrg return BadMatch; 13305b261ecSmrg if (xkb->server==NULL) { 1346747b715Smrg map= calloc(1, sizeof(XkbServerMapRec)); 13505b261ecSmrg if (map==NULL) 13605b261ecSmrg return BadAlloc; 13705b261ecSmrg for (i=0;i<XkbNumVirtualMods;i++) { 13805b261ecSmrg map->vmods[i]= XkbNoModifierMask; 13905b261ecSmrg } 14005b261ecSmrg xkb->server= map; 14105b261ecSmrg } 14205b261ecSmrg else map= xkb->server; 14305b261ecSmrg if (which&XkbExplicitComponentsMask) { 14405b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 14505b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 14605b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 14705b261ecSmrg return BadMatch; 14805b261ecSmrg if (map->explicit==NULL) { 14905b261ecSmrg i= xkb->max_key_code+1; 1506747b715Smrg map->explicit= calloc(i, sizeof(unsigned char)); 15105b261ecSmrg if (map->explicit==NULL) 15205b261ecSmrg return BadAlloc; 15305b261ecSmrg } 15405b261ecSmrg } 15505b261ecSmrg if (which&XkbKeyActionsMask) { 15605b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 15705b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 15805b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 15905b261ecSmrg return BadMatch; 16005b261ecSmrg if (nNewActions<1) 16105b261ecSmrg nNewActions= 1; 16205b261ecSmrg if (map->acts==NULL) { 1636747b715Smrg map->acts= calloc((nNewActions+1), sizeof(XkbAction)); 16405b261ecSmrg if (map->acts==NULL) 16505b261ecSmrg return BadAlloc; 16605b261ecSmrg map->num_acts= 1; 16705b261ecSmrg map->size_acts= nNewActions+1; 16805b261ecSmrg } 16905b261ecSmrg else if ((map->size_acts-map->num_acts)<nNewActions) { 17005b261ecSmrg unsigned need; 17105b261ecSmrg XkbAction *prev_acts = map->acts; 17205b261ecSmrg need= map->num_acts+nNewActions; 1736747b715Smrg map->acts= realloc(map->acts,need * sizeof(XkbAction)); 17405b261ecSmrg if (map->acts==NULL) { 1756747b715Smrg free(prev_acts); 17605b261ecSmrg map->num_acts= map->size_acts= 0; 17705b261ecSmrg return BadAlloc; 17805b261ecSmrg } 17905b261ecSmrg map->size_acts= need; 1806747b715Smrg memset(&map->acts[map->num_acts], 0, 18105b261ecSmrg ((map->size_acts-map->num_acts)*sizeof(XkbAction))); 18205b261ecSmrg } 18305b261ecSmrg if (map->key_acts==NULL) { 18405b261ecSmrg i= xkb->max_key_code+1; 1856747b715Smrg map->key_acts= calloc(i, sizeof(unsigned short)); 18605b261ecSmrg if (map->key_acts==NULL) 18705b261ecSmrg return BadAlloc; 18805b261ecSmrg } 18905b261ecSmrg } 19005b261ecSmrg if (which&XkbKeyBehaviorsMask) { 19105b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 19205b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 19305b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 19405b261ecSmrg return BadMatch; 19505b261ecSmrg if (map->behaviors==NULL) { 19605b261ecSmrg i= xkb->max_key_code+1; 1976747b715Smrg map->behaviors= calloc(i, sizeof(XkbBehavior)); 19805b261ecSmrg if (map->behaviors==NULL) 19905b261ecSmrg return BadAlloc; 20005b261ecSmrg } 20105b261ecSmrg } 20205b261ecSmrg if (which&XkbVirtualModMapMask) { 20305b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 20405b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 20505b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 20605b261ecSmrg return BadMatch; 20705b261ecSmrg if (map->vmodmap==NULL) { 20805b261ecSmrg i= xkb->max_key_code+1; 2096747b715Smrg map->vmodmap= calloc(i, sizeof(unsigned short)); 21005b261ecSmrg if (map->vmodmap==NULL) 21105b261ecSmrg return BadAlloc; 21205b261ecSmrg } 21305b261ecSmrg } 21405b261ecSmrg return Success; 21505b261ecSmrg} 21605b261ecSmrg 21705b261ecSmrg/***====================================================================***/ 21805b261ecSmrg 21905b261ecSmrgstatic Status 22005b261ecSmrgXkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) 22105b261ecSmrg{ 22205b261ecSmrg if ((!from)||(!into)) 22305b261ecSmrg return BadMatch; 2246747b715Smrg free(into->map); 2256747b715Smrg into->map = NULL; 2266747b715Smrg free(into->preserve); 2276747b715Smrg into->preserve = NULL; 2286747b715Smrg free(into->level_names); 2296747b715Smrg into->level_names = NULL; 23005b261ecSmrg *into= *from; 23105b261ecSmrg if ((from->map)&&(into->map_count>0)) { 2326747b715Smrg into->map= calloc(into->map_count, sizeof(XkbKTMapEntryRec)); 23305b261ecSmrg if (!into->map) 23405b261ecSmrg return BadAlloc; 23505b261ecSmrg memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); 23605b261ecSmrg } 23705b261ecSmrg if ((from->preserve)&&(into->map_count>0)) { 2386747b715Smrg into->preserve= calloc(into->map_count, sizeof(XkbModsRec)); 23905b261ecSmrg if (!into->preserve) 24005b261ecSmrg return BadAlloc; 24105b261ecSmrg memcpy(into->preserve,from->preserve, 24205b261ecSmrg into->map_count*sizeof(XkbModsRec)); 24305b261ecSmrg } 24405b261ecSmrg if ((from->level_names)&&(into->num_levels>0)) { 2456747b715Smrg into->level_names= calloc(into->num_levels, sizeof(Atom)); 24605b261ecSmrg if (!into->level_names) 24705b261ecSmrg return BadAlloc; 24805b261ecSmrg memcpy(into->level_names,from->level_names, 24905b261ecSmrg into->num_levels*sizeof(Atom)); 25005b261ecSmrg } 25105b261ecSmrg return Success; 25205b261ecSmrg} 25305b261ecSmrg 25405b261ecSmrgStatus 25505b261ecSmrgXkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) 25605b261ecSmrg{ 25705b261ecSmrgregister int i,rtrn; 25805b261ecSmrg 25905b261ecSmrg if ((!from)||(!into)||(num_types<0)) 26005b261ecSmrg return BadMatch; 26105b261ecSmrg for (i=0;i<num_types;i++) { 26205b261ecSmrg if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) 26305b261ecSmrg return rtrn; 26405b261ecSmrg } 26505b261ecSmrg return Success; 26605b261ecSmrg} 26705b261ecSmrg 26805b261ecSmrgStatus 26905b261ecSmrgXkbResizeKeyType( XkbDescPtr xkb, 27005b261ecSmrg int type_ndx, 27105b261ecSmrg int map_count, 27205b261ecSmrg Bool want_preserve, 27305b261ecSmrg int new_num_lvls) 27405b261ecSmrg{ 27505b261ecSmrgXkbKeyTypePtr type; 27605b261ecSmrgKeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; 27705b261ecSmrg 27805b261ecSmrg if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| 27905b261ecSmrg (new_num_lvls<1)) 28005b261ecSmrg return BadValue; 28105b261ecSmrg switch (type_ndx) { 28205b261ecSmrg case XkbOneLevelIndex: 28305b261ecSmrg if (new_num_lvls!=1) 28405b261ecSmrg return BadMatch; 28505b261ecSmrg break; 28605b261ecSmrg case XkbTwoLevelIndex: 28705b261ecSmrg case XkbAlphabeticIndex: 28805b261ecSmrg case XkbKeypadIndex: 28905b261ecSmrg if (new_num_lvls!=2) 29005b261ecSmrg return BadMatch; 29105b261ecSmrg break; 29205b261ecSmrg } 29305b261ecSmrg type= &xkb->map->types[type_ndx]; 29405b261ecSmrg if (map_count==0) { 29505b261ecSmrg if (type->map!=NULL) 2966747b715Smrg free(type->map); 29705b261ecSmrg type->map= NULL; 29805b261ecSmrg if (type->preserve!=NULL) 2996747b715Smrg free(type->preserve); 30005b261ecSmrg type->preserve= NULL; 30105b261ecSmrg type->map_count= 0; 30205b261ecSmrg } 30305b261ecSmrg else { 30405b261ecSmrg XkbKTMapEntryRec *prev_map = type->map; 30505b261ecSmrg 30605b261ecSmrg if ((map_count>type->map_count)||(type->map==NULL)) 3076747b715Smrg type->map = realloc(type->map,map_count * sizeof(XkbKTMapEntryRec)); 30805b261ecSmrg if (!type->map) { 3096747b715Smrg free(prev_map); 31005b261ecSmrg return BadAlloc; 31105b261ecSmrg } 31205b261ecSmrg if (want_preserve) { 31305b261ecSmrg XkbModsRec *prev_preserve = type->preserve; 31405b261ecSmrg 31505b261ecSmrg if ((map_count>type->map_count)||(type->preserve==NULL)) { 3166747b715Smrg type->preserve = realloc(type->preserve, 3176747b715Smrg map_count * sizeof(XkbModsRec)); 31805b261ecSmrg } 31905b261ecSmrg if (!type->preserve) { 3206747b715Smrg free(prev_preserve); 32105b261ecSmrg return BadAlloc; 32205b261ecSmrg } 32305b261ecSmrg } 32405b261ecSmrg else if (type->preserve!=NULL) { 3256747b715Smrg free(type->preserve); 32605b261ecSmrg type->preserve= NULL; 32705b261ecSmrg } 32805b261ecSmrg type->map_count= map_count; 32905b261ecSmrg } 33005b261ecSmrg 33105b261ecSmrg if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { 33205b261ecSmrg Atom * prev_level_names = type->level_names; 33305b261ecSmrg 3346747b715Smrg type->level_names = realloc(type->level_names, 3356747b715Smrg new_num_lvls * sizeof(Atom)); 33605b261ecSmrg if (!type->level_names) { 3376747b715Smrg free(prev_level_names); 33805b261ecSmrg return BadAlloc; 33905b261ecSmrg } 34005b261ecSmrg } 34105b261ecSmrg /* 34205b261ecSmrg * Here's the theory: 34305b261ecSmrg * If the width of the type changed, we might have to resize the symbol 34405b261ecSmrg * maps for any keys that use the type for one or more groups. This is 34505b261ecSmrg * expensive, so we'll try to cull out any keys that are obviously okay: 34605b261ecSmrg * In any case: 34705b261ecSmrg * - keys that have a group width <= the old width are okay (because 34805b261ecSmrg * they could not possibly have been associated with the old type) 34905b261ecSmrg * If the key type increased in size: 35005b261ecSmrg * - keys that already have a group width >= to the new width are okay 35105b261ecSmrg * + keys that have a group width >= the old width but < the new width 35205b261ecSmrg * might have to be enlarged. 35305b261ecSmrg * If the key type decreased in size: 35405b261ecSmrg * - keys that have a group width > the old width don't have to be 35505b261ecSmrg * resized (because they must have some other wider type associated 35605b261ecSmrg * with some group). 35705b261ecSmrg * + keys that have a group width == the old width might have to be 35805b261ecSmrg * shrunk. 35905b261ecSmrg * The possibilities marked with '+' require us to examine the key types 36005b261ecSmrg * associated with each group for the key. 36105b261ecSmrg */ 3626747b715Smrg memset(matchingKeys, 0, XkbMaxKeyCount*sizeof(KeyCode)); 36305b261ecSmrg nMatchingKeys= 0; 36405b261ecSmrg if (new_num_lvls>type->num_levels) { 36505b261ecSmrg int nTotal; 36605b261ecSmrg KeySym * newSyms; 36705b261ecSmrg int width,match,nResize; 36805b261ecSmrg register int i,g,nSyms; 36905b261ecSmrg 37005b261ecSmrg nResize= 0; 37105b261ecSmrg for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 37205b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 37305b261ecSmrg if (width<type->num_levels) 37405b261ecSmrg continue; 37505b261ecSmrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 37605b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 37705b261ecSmrg matchingKeys[nMatchingKeys++]= i; 37805b261ecSmrg match= 1; 37905b261ecSmrg } 38005b261ecSmrg } 38105b261ecSmrg if ((!match)||(width>=new_num_lvls)) 38205b261ecSmrg nTotal+= XkbKeyNumSyms(xkb,i); 38305b261ecSmrg else { 38405b261ecSmrg nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 38505b261ecSmrg nResize++; 38605b261ecSmrg } 38705b261ecSmrg } 38805b261ecSmrg if (nResize>0) { 38905b261ecSmrg int nextMatch; 39005b261ecSmrg xkb->map->size_syms= (nTotal*15)/10; 3916747b715Smrg newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 39205b261ecSmrg if (newSyms==NULL) 39305b261ecSmrg return BadAlloc; 39405b261ecSmrg nextMatch= 0; 39505b261ecSmrg nSyms= 1; 39605b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 39705b261ecSmrg if (matchingKeys[nextMatch]==i) { 39805b261ecSmrg KeySym *pOld; 39905b261ecSmrg nextMatch++; 40005b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 40105b261ecSmrg pOld= XkbKeySymsPtr(xkb,i); 40205b261ecSmrg for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 40305b261ecSmrg memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], 40405b261ecSmrg width*sizeof(KeySym)); 40505b261ecSmrg } 40605b261ecSmrg xkb->map->key_sym_map[i].offset= nSyms; 40705b261ecSmrg nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 40805b261ecSmrg } 40905b261ecSmrg else { 41005b261ecSmrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), 41105b261ecSmrg XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); 41205b261ecSmrg xkb->map->key_sym_map[i].offset= nSyms; 41305b261ecSmrg nSyms+= XkbKeyNumSyms(xkb,i); 41405b261ecSmrg } 41505b261ecSmrg } 41605b261ecSmrg type->num_levels= new_num_lvls; 4176747b715Smrg free(xkb->map->syms); 41805b261ecSmrg xkb->map->syms= newSyms; 41905b261ecSmrg xkb->map->num_syms= nSyms; 42005b261ecSmrg return Success; 42105b261ecSmrg } 42205b261ecSmrg } 42305b261ecSmrg else if (new_num_lvls<type->num_levels) { 42405b261ecSmrg int width,match; 42505b261ecSmrg register int g,i; 42605b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 42705b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 42805b261ecSmrg if (width<type->num_levels) 42905b261ecSmrg continue; 43005b261ecSmrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 43105b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 43205b261ecSmrg matchingKeys[nMatchingKeys++]= i; 43305b261ecSmrg match= 1; 43405b261ecSmrg } 43505b261ecSmrg } 43605b261ecSmrg } 43705b261ecSmrg } 43805b261ecSmrg if (nMatchingKeys>0) { 43905b261ecSmrg int key,firstClear; 44005b261ecSmrg register int i,g; 44105b261ecSmrg if (new_num_lvls>type->num_levels) 44205b261ecSmrg firstClear= type->num_levels; 44305b261ecSmrg else firstClear= new_num_lvls; 44405b261ecSmrg for (i=0;i<nMatchingKeys;i++) { 44505b261ecSmrg KeySym * pSyms; 44605b261ecSmrg int width,nClear; 44705b261ecSmrg 44805b261ecSmrg key= matchingKeys[i]; 44905b261ecSmrg width= XkbKeyGroupsWidth(xkb,key); 45005b261ecSmrg nClear= width-firstClear; 45105b261ecSmrg pSyms= XkbKeySymsPtr(xkb,key); 45205b261ecSmrg for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { 45305b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { 45405b261ecSmrg if (nClear>0) 4556747b715Smrg memset(&pSyms[g*width+firstClear], 0, nClear*sizeof(KeySym)); 45605b261ecSmrg } 45705b261ecSmrg } 45805b261ecSmrg } 45905b261ecSmrg } 46005b261ecSmrg type->num_levels= new_num_lvls; 46105b261ecSmrg return Success; 46205b261ecSmrg} 46305b261ecSmrg 46405b261ecSmrgKeySym * 46505b261ecSmrgXkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) 46605b261ecSmrg{ 46705b261ecSmrgregister int i,nSyms,nKeySyms; 46805b261ecSmrgunsigned nOldSyms; 46905b261ecSmrgKeySym *newSyms; 47005b261ecSmrg 47105b261ecSmrg if (needed==0) { 47205b261ecSmrg xkb->map->key_sym_map[key].offset= 0; 47305b261ecSmrg return xkb->map->syms; 47405b261ecSmrg } 47505b261ecSmrg nOldSyms= XkbKeyNumSyms(xkb,key); 47605b261ecSmrg if (nOldSyms>=(unsigned)needed) { 47705b261ecSmrg return XkbKeySymsPtr(xkb,key); 47805b261ecSmrg } 47905b261ecSmrg if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { 48005b261ecSmrg if (nOldSyms>0) { 48105b261ecSmrg memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), 48205b261ecSmrg nOldSyms*sizeof(KeySym)); 48305b261ecSmrg } 48405b261ecSmrg if ((needed-nOldSyms)>0) { 4856747b715Smrg memset(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb, key)], 4866747b715Smrg 0, (needed-nOldSyms)*sizeof(KeySym)); 48705b261ecSmrg } 48805b261ecSmrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 48905b261ecSmrg xkb->map->num_syms+= needed; 49005b261ecSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 49105b261ecSmrg } 49205b261ecSmrg xkb->map->size_syms+= (needed>32?needed:32); 4936747b715Smrg newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 49405b261ecSmrg if (newSyms==NULL) 49505b261ecSmrg return NULL; 49605b261ecSmrg newSyms[0]= NoSymbol; 49705b261ecSmrg nSyms = 1; 49805b261ecSmrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 49905b261ecSmrg int nCopy; 50005b261ecSmrg 50105b261ecSmrg nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); 50205b261ecSmrg if ((nKeySyms==0)&&(i!=key)) 50305b261ecSmrg continue; 50405b261ecSmrg if (i==key) 50505b261ecSmrg nKeySyms= needed; 50605b261ecSmrg if (nCopy!=0) 50705b261ecSmrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); 50805b261ecSmrg if (nKeySyms>nCopy) 5096747b715Smrg memset(&newSyms[nSyms+nCopy], 0, (nKeySyms-nCopy)*sizeof(KeySym)); 51005b261ecSmrg xkb->map->key_sym_map[i].offset = nSyms; 51105b261ecSmrg nSyms+= nKeySyms; 51205b261ecSmrg } 5136747b715Smrg free(xkb->map->syms); 51405b261ecSmrg xkb->map->syms = newSyms; 51505b261ecSmrg xkb->map->num_syms = nSyms; 51605b261ecSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 51705b261ecSmrg} 51805b261ecSmrg 51905b261ecSmrgstatic unsigned 52005b261ecSmrg_ExtendRange( unsigned int old_flags, 52105b261ecSmrg unsigned int flag, 52205b261ecSmrg KeyCode newKC, 52305b261ecSmrg KeyCode * old_min, 52405b261ecSmrg unsigned char * old_num) 52505b261ecSmrg{ 52605b261ecSmrg if ((old_flags&flag)==0) { 52705b261ecSmrg old_flags|= flag; 52805b261ecSmrg *old_min= newKC; 52905b261ecSmrg *old_num= 1; 53005b261ecSmrg } 53105b261ecSmrg else { 53205b261ecSmrg int last= (*old_min)+(*old_num)-1; 53305b261ecSmrg if (newKC<*old_min) { 53405b261ecSmrg *old_min= newKC; 53505b261ecSmrg *old_num= (last-newKC)+1; 53605b261ecSmrg } 53705b261ecSmrg else if (newKC>last) { 53805b261ecSmrg *old_num= (newKC-(*old_min))+1; 53905b261ecSmrg } 54005b261ecSmrg } 54105b261ecSmrg return old_flags; 54205b261ecSmrg} 54305b261ecSmrg 54405b261ecSmrgStatus 54505b261ecSmrgXkbChangeKeycodeRange( XkbDescPtr xkb, 54605b261ecSmrg int minKC, 54705b261ecSmrg int maxKC, 54805b261ecSmrg XkbChangesPtr changes) 54905b261ecSmrg{ 55005b261ecSmrgint tmp; 55105b261ecSmrg 55205b261ecSmrg if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) 55305b261ecSmrg return BadValue; 55405b261ecSmrg if (minKC>maxKC) 55505b261ecSmrg return BadMatch; 55605b261ecSmrg if (minKC<xkb->min_key_code) { 55705b261ecSmrg if (changes) 55805b261ecSmrg changes->map.min_key_code= minKC; 55905b261ecSmrg tmp= xkb->min_key_code-minKC; 56005b261ecSmrg if (xkb->map) { 56105b261ecSmrg if (xkb->map->key_sym_map) { 5626747b715Smrg memset((char *)&xkb->map->key_sym_map[minKC], 0, 56305b261ecSmrg tmp*sizeof(XkbSymMapRec)); 56405b261ecSmrg if (changes) { 56505b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 56605b261ecSmrg XkbKeySymsMask,minKC, 56705b261ecSmrg &changes->map.first_key_sym, 56805b261ecSmrg &changes->map.num_key_syms); 56905b261ecSmrg } 57005b261ecSmrg } 57105b261ecSmrg if (xkb->map->modmap) { 5726747b715Smrg memset((char *)&xkb->map->modmap[minKC], 0, tmp); 57305b261ecSmrg if (changes) { 57405b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 57505b261ecSmrg XkbModifierMapMask,minKC, 57605b261ecSmrg &changes->map.first_modmap_key, 57705b261ecSmrg &changes->map.num_modmap_keys); 57805b261ecSmrg } 57905b261ecSmrg } 58005b261ecSmrg } 58105b261ecSmrg if (xkb->server) { 58205b261ecSmrg if (xkb->server->behaviors) { 5836747b715Smrg memset((char *)&xkb->server->behaviors[minKC], 0, 58405b261ecSmrg tmp*sizeof(XkbBehavior)); 58505b261ecSmrg if (changes) { 58605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 58705b261ecSmrg XkbKeyBehaviorsMask,minKC, 58805b261ecSmrg &changes->map.first_key_behavior, 58905b261ecSmrg &changes->map.num_key_behaviors); 59005b261ecSmrg } 59105b261ecSmrg } 59205b261ecSmrg if (xkb->server->key_acts) { 5936747b715Smrg memset((char *)&xkb->server->key_acts[minKC], 0, 59405b261ecSmrg tmp*sizeof(unsigned short)); 59505b261ecSmrg if (changes) { 59605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 59705b261ecSmrg XkbKeyActionsMask,minKC, 59805b261ecSmrg &changes->map.first_key_act, 59905b261ecSmrg &changes->map.num_key_acts); 60005b261ecSmrg } 60105b261ecSmrg } 60205b261ecSmrg if (xkb->server->vmodmap) { 6036747b715Smrg memset((char *)&xkb->server->vmodmap[minKC], 0, 60405b261ecSmrg tmp*sizeof(unsigned short)); 60505b261ecSmrg if (changes) { 60605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 60705b261ecSmrg XkbVirtualModMapMask,minKC, 60805b261ecSmrg &changes->map.first_modmap_key, 60905b261ecSmrg &changes->map.num_vmodmap_keys); 61005b261ecSmrg } 61105b261ecSmrg } 61205b261ecSmrg } 61305b261ecSmrg if ((xkb->names)&&(xkb->names->keys)) { 6146747b715Smrg memset((char *)&xkb->names->keys[minKC], 0, tmp*sizeof(XkbKeyNameRec)); 61505b261ecSmrg if (changes) { 61605b261ecSmrg changes->names.changed= _ExtendRange(changes->names.changed, 61705b261ecSmrg XkbKeyNamesMask,minKC, 61805b261ecSmrg &changes->names.first_key, 61905b261ecSmrg &changes->names.num_keys); 62005b261ecSmrg } 62105b261ecSmrg } 62205b261ecSmrg xkb->min_key_code= minKC; 62305b261ecSmrg } 62405b261ecSmrg if (maxKC>xkb->max_key_code) { 62505b261ecSmrg if (changes) 62605b261ecSmrg changes->map.max_key_code= maxKC; 62705b261ecSmrg tmp= maxKC-xkb->max_key_code; 62805b261ecSmrg if (xkb->map) { 62905b261ecSmrg if (xkb->map->key_sym_map) { 63005b261ecSmrg XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 63105b261ecSmrg 6326747b715Smrg xkb->map->key_sym_map = realloc(xkb->map->key_sym_map, 6336747b715Smrg (maxKC+1) * sizeof(XkbSymMapRec)); 63405b261ecSmrg if (!xkb->map->key_sym_map) { 6356747b715Smrg free(prev_key_sym_map); 63605b261ecSmrg return BadAlloc; 63705b261ecSmrg } 6386747b715Smrg memset((char *)&xkb->map->key_sym_map[xkb->max_key_code], 0, 63905b261ecSmrg tmp*sizeof(XkbSymMapRec)); 64005b261ecSmrg if (changes) { 64105b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 64205b261ecSmrg XkbKeySymsMask,maxKC, 64305b261ecSmrg &changes->map.first_key_sym, 64405b261ecSmrg &changes->map.num_key_syms); 64505b261ecSmrg } 64605b261ecSmrg } 64705b261ecSmrg if (xkb->map->modmap) { 64805b261ecSmrg unsigned char *prev_modmap = xkb->map->modmap; 64905b261ecSmrg 6506747b715Smrg xkb->map->modmap = realloc(xkb->map->modmap, 6516747b715Smrg (maxKC+1) * sizeof(unsigned char)); 65205b261ecSmrg if (!xkb->map->modmap) { 6536747b715Smrg free(prev_modmap); 65405b261ecSmrg return BadAlloc; 65505b261ecSmrg } 6566747b715Smrg memset((char *)&xkb->map->modmap[xkb->max_key_code], 0, tmp); 65705b261ecSmrg if (changes) { 65805b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 65905b261ecSmrg XkbModifierMapMask,maxKC, 66005b261ecSmrg &changes->map.first_modmap_key, 66105b261ecSmrg &changes->map.num_modmap_keys); 66205b261ecSmrg } 66305b261ecSmrg } 66405b261ecSmrg } 66505b261ecSmrg if (xkb->server) { 66605b261ecSmrg if (xkb->server->behaviors) { 66705b261ecSmrg XkbBehavior *prev_behaviors = xkb->server->behaviors; 66805b261ecSmrg 6696747b715Smrg xkb->server->behaviors = realloc(xkb->server->behaviors, 6706747b715Smrg (maxKC+1) * sizeof(XkbBehavior)); 67105b261ecSmrg if (!xkb->server->behaviors) { 6726747b715Smrg free(prev_behaviors); 67305b261ecSmrg return BadAlloc; 67405b261ecSmrg } 6756747b715Smrg memset((char *)&xkb->server->behaviors[xkb->max_key_code], 0, 67605b261ecSmrg tmp*sizeof(XkbBehavior)); 67705b261ecSmrg if (changes) { 67805b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 67905b261ecSmrg XkbKeyBehaviorsMask,maxKC, 68005b261ecSmrg &changes->map.first_key_behavior, 68105b261ecSmrg &changes->map.num_key_behaviors); 68205b261ecSmrg } 68305b261ecSmrg } 68405b261ecSmrg if (xkb->server->key_acts) { 68505b261ecSmrg unsigned short *prev_key_acts = xkb->server->key_acts; 68605b261ecSmrg 6876747b715Smrg xkb->server->key_acts= realloc(xkb->server->key_acts, 6886747b715Smrg (maxKC+1) * sizeof(unsigned short)); 68905b261ecSmrg if (!xkb->server->key_acts) { 6906747b715Smrg free(prev_key_acts); 69105b261ecSmrg return BadAlloc; 69205b261ecSmrg } 6936747b715Smrg memset((char *)&xkb->server->key_acts[xkb->max_key_code], 0, 69405b261ecSmrg tmp*sizeof(unsigned short)); 69505b261ecSmrg if (changes) { 69605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 69705b261ecSmrg XkbKeyActionsMask,maxKC, 69805b261ecSmrg &changes->map.first_key_act, 69905b261ecSmrg &changes->map.num_key_acts); 70005b261ecSmrg } 70105b261ecSmrg } 70205b261ecSmrg if (xkb->server->vmodmap) { 70305b261ecSmrg unsigned short *prev_vmodmap = xkb->server->vmodmap; 70405b261ecSmrg 7056747b715Smrg xkb->server->vmodmap= realloc(xkb->server->vmodmap, 7066747b715Smrg (maxKC+1) * sizeof(unsigned short)); 70705b261ecSmrg if (!xkb->server->vmodmap) { 7086747b715Smrg free(prev_vmodmap); 70905b261ecSmrg return BadAlloc; 71005b261ecSmrg } 7116747b715Smrg memset((char *)&xkb->server->vmodmap[xkb->max_key_code], 0, 71205b261ecSmrg tmp*sizeof(unsigned short)); 71305b261ecSmrg if (changes) { 71405b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 71505b261ecSmrg XkbVirtualModMapMask,maxKC, 71605b261ecSmrg &changes->map.first_modmap_key, 71705b261ecSmrg &changes->map.num_vmodmap_keys); 71805b261ecSmrg } 71905b261ecSmrg } 72005b261ecSmrg } 72105b261ecSmrg if ((xkb->names)&&(xkb->names->keys)) { 72205b261ecSmrg XkbKeyNameRec *prev_keys = xkb->names->keys; 72305b261ecSmrg 7246747b715Smrg xkb->names->keys = realloc(xkb->names->keys, 7256747b715Smrg (maxKC+1) * sizeof(XkbKeyNameRec)); 72605b261ecSmrg if (!xkb->names->keys) { 7276747b715Smrg free(prev_keys); 72805b261ecSmrg return BadAlloc; 72905b261ecSmrg } 7306747b715Smrg memset((char *)&xkb->names->keys[xkb->max_key_code], 0, 73105b261ecSmrg tmp*sizeof(XkbKeyNameRec)); 73205b261ecSmrg if (changes) { 73305b261ecSmrg changes->names.changed= _ExtendRange(changes->names.changed, 73405b261ecSmrg XkbKeyNamesMask,maxKC, 73505b261ecSmrg &changes->names.first_key, 73605b261ecSmrg &changes->names.num_keys); 73705b261ecSmrg } 73805b261ecSmrg } 73905b261ecSmrg xkb->max_key_code= maxKC; 74005b261ecSmrg } 74105b261ecSmrg return Success; 74205b261ecSmrg} 74305b261ecSmrg 74405b261ecSmrgXkbAction * 74505b261ecSmrgXkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) 74605b261ecSmrg{ 74705b261ecSmrgregister int i,nActs; 74805b261ecSmrgXkbAction *newActs; 74905b261ecSmrg 75005b261ecSmrg if (needed==0) { 75105b261ecSmrg xkb->server->key_acts[key]= 0; 75205b261ecSmrg return NULL; 75305b261ecSmrg } 75405b261ecSmrg if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) 75505b261ecSmrg return XkbKeyActionsPtr(xkb,key); 75605b261ecSmrg if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { 75705b261ecSmrg xkb->server->key_acts[key]= xkb->server->num_acts; 75805b261ecSmrg xkb->server->num_acts+= needed; 75905b261ecSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 76005b261ecSmrg } 76105b261ecSmrg xkb->server->size_acts= xkb->server->num_acts+needed+8; 7626747b715Smrg newActs = calloc(xkb->server->size_acts, sizeof(XkbAction)); 76305b261ecSmrg if (newActs==NULL) 76405b261ecSmrg return NULL; 76505b261ecSmrg newActs[0].type = XkbSA_NoAction; 76605b261ecSmrg nActs = 1; 76705b261ecSmrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 76805b261ecSmrg int nKeyActs,nCopy; 76905b261ecSmrg 77005b261ecSmrg if ((xkb->server->key_acts[i]==0)&&(i!=key)) 77105b261ecSmrg continue; 77205b261ecSmrg 77305b261ecSmrg nCopy= nKeyActs= XkbKeyNumActions(xkb,i); 77405b261ecSmrg if (i==key) { 77505b261ecSmrg nKeyActs= needed; 77605b261ecSmrg if (needed<nCopy) 77705b261ecSmrg nCopy= needed; 77805b261ecSmrg } 77905b261ecSmrg 78005b261ecSmrg if (nCopy>0) 78105b261ecSmrg memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), 78205b261ecSmrg nCopy*sizeof(XkbAction)); 78305b261ecSmrg if (nCopy<nKeyActs) 7846747b715Smrg memset(&newActs[nActs+nCopy], 0, (nKeyActs-nCopy)*sizeof(XkbAction)); 78505b261ecSmrg xkb->server->key_acts[i]= nActs; 78605b261ecSmrg nActs+= nKeyActs; 78705b261ecSmrg } 7886747b715Smrg free(xkb->server->acts); 78905b261ecSmrg xkb->server->acts = newActs; 79005b261ecSmrg xkb->server->num_acts= nActs; 79105b261ecSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 79205b261ecSmrg} 79305b261ecSmrg 79405b261ecSmrgvoid 79505b261ecSmrgXkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 79605b261ecSmrg{ 79705b261ecSmrgXkbClientMapPtr map; 79805b261ecSmrg 79905b261ecSmrg if ((xkb==NULL)||(xkb->map==NULL)) 80005b261ecSmrg return; 80105b261ecSmrg if (freeMap) 80205b261ecSmrg what= XkbAllClientInfoMask; 80305b261ecSmrg map= xkb->map; 80405b261ecSmrg if (what&XkbKeyTypesMask) { 80505b261ecSmrg if (map->types!=NULL) { 80605b261ecSmrg if (map->num_types>0) { 80705b261ecSmrg register int i; 80805b261ecSmrg XkbKeyTypePtr type; 80905b261ecSmrg for (i=0,type=map->types;i<map->num_types;i++,type++) { 81005b261ecSmrg if (type->map!=NULL) { 8116747b715Smrg free(type->map); 81205b261ecSmrg type->map= NULL; 81305b261ecSmrg } 81405b261ecSmrg if (type->preserve!=NULL) { 8156747b715Smrg free(type->preserve); 81605b261ecSmrg type->preserve= NULL; 81705b261ecSmrg } 81805b261ecSmrg type->map_count= 0; 81905b261ecSmrg if (type->level_names!=NULL) { 8206747b715Smrg free(type->level_names); 82105b261ecSmrg type->level_names= NULL; 82205b261ecSmrg } 82305b261ecSmrg } 82405b261ecSmrg } 8256747b715Smrg free(map->types); 82605b261ecSmrg map->num_types= map->size_types= 0; 82705b261ecSmrg map->types= NULL; 82805b261ecSmrg } 82905b261ecSmrg } 83005b261ecSmrg if (what&XkbKeySymsMask) { 83105b261ecSmrg if (map->key_sym_map!=NULL) { 8326747b715Smrg free(map->key_sym_map); 83305b261ecSmrg map->key_sym_map= NULL; 83405b261ecSmrg } 83505b261ecSmrg if (map->syms!=NULL) { 8366747b715Smrg free(map->syms); 83705b261ecSmrg map->size_syms= map->num_syms= 0; 83805b261ecSmrg map->syms= NULL; 83905b261ecSmrg } 84005b261ecSmrg } 84105b261ecSmrg if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { 8426747b715Smrg free(map->modmap); 84305b261ecSmrg map->modmap= NULL; 84405b261ecSmrg } 84505b261ecSmrg if (freeMap) { 8466747b715Smrg free(xkb->map); 84705b261ecSmrg xkb->map= NULL; 84805b261ecSmrg } 84905b261ecSmrg return; 85005b261ecSmrg} 85105b261ecSmrg 85205b261ecSmrgvoid 85305b261ecSmrgXkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 85405b261ecSmrg{ 85505b261ecSmrgXkbServerMapPtr map; 85605b261ecSmrg 85705b261ecSmrg if ((xkb==NULL)||(xkb->server==NULL)) 85805b261ecSmrg return; 85905b261ecSmrg if (freeMap) 86005b261ecSmrg what= XkbAllServerInfoMask; 86105b261ecSmrg map= xkb->server; 86205b261ecSmrg if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { 8636747b715Smrg free(map->explicit); 86405b261ecSmrg map->explicit= NULL; 86505b261ecSmrg } 86605b261ecSmrg if (what&XkbKeyActionsMask) { 86705b261ecSmrg if (map->key_acts!=NULL) { 8686747b715Smrg free(map->key_acts); 86905b261ecSmrg map->key_acts= NULL; 87005b261ecSmrg } 87105b261ecSmrg if (map->acts!=NULL) { 8726747b715Smrg free(map->acts); 87305b261ecSmrg map->num_acts= map->size_acts= 0; 87405b261ecSmrg map->acts= NULL; 87505b261ecSmrg } 87605b261ecSmrg } 87705b261ecSmrg if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { 8786747b715Smrg free(map->behaviors); 87905b261ecSmrg map->behaviors= NULL; 88005b261ecSmrg } 88105b261ecSmrg if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { 8826747b715Smrg free(map->vmodmap); 88305b261ecSmrg map->vmodmap= NULL; 88405b261ecSmrg } 88505b261ecSmrg 88605b261ecSmrg if (freeMap) { 8876747b715Smrg free(xkb->server); 88805b261ecSmrg xkb->server= NULL; 88905b261ecSmrg } 89005b261ecSmrg return; 89105b261ecSmrg} 892