XKBMAlloc.c revision 4642e01f
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#define NEED_EVENTS 3605b261ecSmrg#define NEED_REPLIES 3705b261ecSmrg#include <X11/Xproto.h> 3805b261ecSmrg#include "misc.h" 3905b261ecSmrg#include "inputstr.h" 4005b261ecSmrg#include <X11/keysym.h> 4105b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 4205b261ecSmrg#include <xkbsrv.h> 4305b261ecSmrg 4405b261ecSmrg/***====================================================================***/ 4505b261ecSmrg 4605b261ecSmrgStatus 4705b261ecSmrgXkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) 4805b261ecSmrg{ 4905b261ecSmrgregister int i; 5005b261ecSmrgXkbClientMapPtr map; 5105b261ecSmrg 5205b261ecSmrg if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) 5305b261ecSmrg return BadValue; 5405b261ecSmrg if ((which&XkbKeySymsMask)&& 5505b261ecSmrg ((!XkbIsLegalKeycode(xkb->min_key_code))|| 5605b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 5705b261ecSmrg (xkb->max_key_code<xkb->min_key_code))) { 584642e01fSmrg DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n", 5905b261ecSmrg xkb->min_key_code,xkb->max_key_code); 6005b261ecSmrg return BadValue; 6105b261ecSmrg } 6205b261ecSmrg 6305b261ecSmrg if (xkb->map==NULL) { 6405b261ecSmrg map= _XkbTypedCalloc(1,XkbClientMapRec); 6505b261ecSmrg if (map==NULL) 6605b261ecSmrg return BadAlloc; 6705b261ecSmrg xkb->map= map; 6805b261ecSmrg } 6905b261ecSmrg else map= xkb->map; 7005b261ecSmrg 7105b261ecSmrg if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { 7205b261ecSmrg if (map->types==NULL) { 7305b261ecSmrg map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); 7405b261ecSmrg if (map->types==NULL) 7505b261ecSmrg return BadAlloc; 7605b261ecSmrg map->num_types= 0; 7705b261ecSmrg map->size_types= nTotalTypes; 7805b261ecSmrg } 7905b261ecSmrg else if (map->size_types<nTotalTypes) { 8005b261ecSmrg XkbKeyTypeRec *prev_types = map->types; 8105b261ecSmrg 8205b261ecSmrg map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); 8305b261ecSmrg if (map->types==NULL) { 8405b261ecSmrg _XkbFree(prev_types); 8505b261ecSmrg map->num_types= map->size_types= 0; 8605b261ecSmrg return BadAlloc; 8705b261ecSmrg } 8805b261ecSmrg map->size_types= nTotalTypes; 8905b261ecSmrg bzero(&map->types[map->num_types], 9005b261ecSmrg ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); 9105b261ecSmrg } 9205b261ecSmrg } 9305b261ecSmrg if (which&XkbKeySymsMask) { 9405b261ecSmrg int nKeys= XkbNumKeys(xkb); 9505b261ecSmrg if (map->syms==NULL) { 9605b261ecSmrg map->size_syms= (nKeys*15)/10; 9705b261ecSmrg map->syms= _XkbTypedCalloc(map->size_syms,KeySym); 9805b261ecSmrg if (!map->syms) { 9905b261ecSmrg map->size_syms= 0; 10005b261ecSmrg return BadAlloc; 10105b261ecSmrg } 10205b261ecSmrg map->num_syms= 1; 10305b261ecSmrg map->syms[0]= NoSymbol; 10405b261ecSmrg } 10505b261ecSmrg if (map->key_sym_map==NULL) { 10605b261ecSmrg i= xkb->max_key_code+1; 10705b261ecSmrg map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); 10805b261ecSmrg if (map->key_sym_map==NULL) 10905b261ecSmrg return BadAlloc; 11005b261ecSmrg } 11105b261ecSmrg } 11205b261ecSmrg if (which&XkbModifierMapMask) { 11305b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 11405b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 11505b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 11605b261ecSmrg return BadMatch; 11705b261ecSmrg if (map->modmap==NULL) { 11805b261ecSmrg i= xkb->max_key_code+1; 11905b261ecSmrg map->modmap= _XkbTypedCalloc(i,unsigned char); 12005b261ecSmrg if (map->modmap==NULL) 12105b261ecSmrg return BadAlloc; 12205b261ecSmrg } 12305b261ecSmrg } 12405b261ecSmrg return Success; 12505b261ecSmrg} 12605b261ecSmrg 12705b261ecSmrgStatus 12805b261ecSmrgXkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) 12905b261ecSmrg{ 13005b261ecSmrgregister int i; 13105b261ecSmrgXkbServerMapPtr map; 13205b261ecSmrg 13305b261ecSmrg if (xkb==NULL) 13405b261ecSmrg return BadMatch; 13505b261ecSmrg if (xkb->server==NULL) { 13605b261ecSmrg map= _XkbTypedCalloc(1,XkbServerMapRec); 13705b261ecSmrg if (map==NULL) 13805b261ecSmrg return BadAlloc; 13905b261ecSmrg for (i=0;i<XkbNumVirtualMods;i++) { 14005b261ecSmrg map->vmods[i]= XkbNoModifierMask; 14105b261ecSmrg } 14205b261ecSmrg xkb->server= map; 14305b261ecSmrg } 14405b261ecSmrg else map= xkb->server; 14505b261ecSmrg if (which&XkbExplicitComponentsMask) { 14605b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 14705b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 14805b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 14905b261ecSmrg return BadMatch; 15005b261ecSmrg if (map->explicit==NULL) { 15105b261ecSmrg i= xkb->max_key_code+1; 15205b261ecSmrg map->explicit= _XkbTypedCalloc(i,unsigned char); 15305b261ecSmrg if (map->explicit==NULL) 15405b261ecSmrg return BadAlloc; 15505b261ecSmrg } 15605b261ecSmrg } 15705b261ecSmrg if (which&XkbKeyActionsMask) { 15805b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 15905b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 16005b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 16105b261ecSmrg return BadMatch; 16205b261ecSmrg if (nNewActions<1) 16305b261ecSmrg nNewActions= 1; 16405b261ecSmrg if (map->acts==NULL) { 16505b261ecSmrg map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction); 16605b261ecSmrg if (map->acts==NULL) 16705b261ecSmrg return BadAlloc; 16805b261ecSmrg map->num_acts= 1; 16905b261ecSmrg map->size_acts= nNewActions+1; 17005b261ecSmrg } 17105b261ecSmrg else if ((map->size_acts-map->num_acts)<nNewActions) { 17205b261ecSmrg unsigned need; 17305b261ecSmrg XkbAction *prev_acts = map->acts; 17405b261ecSmrg need= map->num_acts+nNewActions; 17505b261ecSmrg map->acts= _XkbTypedRealloc(map->acts,need,XkbAction); 17605b261ecSmrg if (map->acts==NULL) { 17705b261ecSmrg _XkbFree(prev_acts); 17805b261ecSmrg map->num_acts= map->size_acts= 0; 17905b261ecSmrg return BadAlloc; 18005b261ecSmrg } 18105b261ecSmrg map->size_acts= need; 18205b261ecSmrg bzero(&map->acts[map->num_acts], 18305b261ecSmrg ((map->size_acts-map->num_acts)*sizeof(XkbAction))); 18405b261ecSmrg } 18505b261ecSmrg if (map->key_acts==NULL) { 18605b261ecSmrg i= xkb->max_key_code+1; 18705b261ecSmrg map->key_acts= _XkbTypedCalloc(i,unsigned short); 18805b261ecSmrg if (map->key_acts==NULL) 18905b261ecSmrg return BadAlloc; 19005b261ecSmrg } 19105b261ecSmrg } 19205b261ecSmrg if (which&XkbKeyBehaviorsMask) { 19305b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 19405b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 19505b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 19605b261ecSmrg return BadMatch; 19705b261ecSmrg if (map->behaviors==NULL) { 19805b261ecSmrg i= xkb->max_key_code+1; 19905b261ecSmrg map->behaviors= _XkbTypedCalloc(i,XkbBehavior); 20005b261ecSmrg if (map->behaviors==NULL) 20105b261ecSmrg return BadAlloc; 20205b261ecSmrg } 20305b261ecSmrg } 20405b261ecSmrg if (which&XkbVirtualModMapMask) { 20505b261ecSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 20605b261ecSmrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 20705b261ecSmrg (xkb->max_key_code<xkb->min_key_code)) 20805b261ecSmrg return BadMatch; 20905b261ecSmrg if (map->vmodmap==NULL) { 21005b261ecSmrg i= xkb->max_key_code+1; 21105b261ecSmrg map->vmodmap= _XkbTypedCalloc(i,unsigned short); 21205b261ecSmrg if (map->vmodmap==NULL) 21305b261ecSmrg return BadAlloc; 21405b261ecSmrg } 21505b261ecSmrg } 21605b261ecSmrg return Success; 21705b261ecSmrg} 21805b261ecSmrg 21905b261ecSmrg/***====================================================================***/ 22005b261ecSmrg 22105b261ecSmrgstatic Status 22205b261ecSmrgXkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) 22305b261ecSmrg{ 22405b261ecSmrg if ((!from)||(!into)) 22505b261ecSmrg return BadMatch; 22605b261ecSmrg if (into->map) { 22705b261ecSmrg _XkbFree(into->map); 22805b261ecSmrg into->map= NULL; 22905b261ecSmrg } 23005b261ecSmrg if (into->preserve) { 23105b261ecSmrg _XkbFree(into->preserve); 23205b261ecSmrg into->preserve= NULL; 23305b261ecSmrg } 23405b261ecSmrg if (into->level_names) { 23505b261ecSmrg _XkbFree(into->level_names); 23605b261ecSmrg into->level_names= NULL; 23705b261ecSmrg } 23805b261ecSmrg *into= *from; 23905b261ecSmrg if ((from->map)&&(into->map_count>0)) { 24005b261ecSmrg into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec); 24105b261ecSmrg if (!into->map) 24205b261ecSmrg return BadAlloc; 24305b261ecSmrg memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); 24405b261ecSmrg } 24505b261ecSmrg if ((from->preserve)&&(into->map_count>0)) { 24605b261ecSmrg into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec); 24705b261ecSmrg if (!into->preserve) 24805b261ecSmrg return BadAlloc; 24905b261ecSmrg memcpy(into->preserve,from->preserve, 25005b261ecSmrg into->map_count*sizeof(XkbModsRec)); 25105b261ecSmrg } 25205b261ecSmrg if ((from->level_names)&&(into->num_levels>0)) { 25305b261ecSmrg into->level_names= _XkbTypedCalloc(into->num_levels,Atom); 25405b261ecSmrg if (!into->level_names) 25505b261ecSmrg return BadAlloc; 25605b261ecSmrg memcpy(into->level_names,from->level_names, 25705b261ecSmrg into->num_levels*sizeof(Atom)); 25805b261ecSmrg } 25905b261ecSmrg return Success; 26005b261ecSmrg} 26105b261ecSmrg 26205b261ecSmrgStatus 26305b261ecSmrgXkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) 26405b261ecSmrg{ 26505b261ecSmrgregister int i,rtrn; 26605b261ecSmrg 26705b261ecSmrg if ((!from)||(!into)||(num_types<0)) 26805b261ecSmrg return BadMatch; 26905b261ecSmrg for (i=0;i<num_types;i++) { 27005b261ecSmrg if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) 27105b261ecSmrg return rtrn; 27205b261ecSmrg } 27305b261ecSmrg return Success; 27405b261ecSmrg} 27505b261ecSmrg 27605b261ecSmrgStatus 27705b261ecSmrgXkbResizeKeyType( XkbDescPtr xkb, 27805b261ecSmrg int type_ndx, 27905b261ecSmrg int map_count, 28005b261ecSmrg Bool want_preserve, 28105b261ecSmrg int new_num_lvls) 28205b261ecSmrg{ 28305b261ecSmrgXkbKeyTypePtr type; 28405b261ecSmrgKeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; 28505b261ecSmrg 28605b261ecSmrg if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| 28705b261ecSmrg (new_num_lvls<1)) 28805b261ecSmrg return BadValue; 28905b261ecSmrg switch (type_ndx) { 29005b261ecSmrg case XkbOneLevelIndex: 29105b261ecSmrg if (new_num_lvls!=1) 29205b261ecSmrg return BadMatch; 29305b261ecSmrg break; 29405b261ecSmrg case XkbTwoLevelIndex: 29505b261ecSmrg case XkbAlphabeticIndex: 29605b261ecSmrg case XkbKeypadIndex: 29705b261ecSmrg if (new_num_lvls!=2) 29805b261ecSmrg return BadMatch; 29905b261ecSmrg break; 30005b261ecSmrg } 30105b261ecSmrg type= &xkb->map->types[type_ndx]; 30205b261ecSmrg if (map_count==0) { 30305b261ecSmrg if (type->map!=NULL) 30405b261ecSmrg _XkbFree(type->map); 30505b261ecSmrg type->map= NULL; 30605b261ecSmrg if (type->preserve!=NULL) 30705b261ecSmrg _XkbFree(type->preserve); 30805b261ecSmrg type->preserve= NULL; 30905b261ecSmrg type->map_count= 0; 31005b261ecSmrg } 31105b261ecSmrg else { 31205b261ecSmrg XkbKTMapEntryRec *prev_map = type->map; 31305b261ecSmrg 31405b261ecSmrg if ((map_count>type->map_count)||(type->map==NULL)) 31505b261ecSmrg type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec); 31605b261ecSmrg if (!type->map) { 31705b261ecSmrg if (prev_map) 31805b261ecSmrg _XkbFree(prev_map); 31905b261ecSmrg return BadAlloc; 32005b261ecSmrg } 32105b261ecSmrg if (want_preserve) { 32205b261ecSmrg XkbModsRec *prev_preserve = type->preserve; 32305b261ecSmrg 32405b261ecSmrg if ((map_count>type->map_count)||(type->preserve==NULL)) { 32505b261ecSmrg type->preserve= _XkbTypedRealloc(type->preserve,map_count, 32605b261ecSmrg XkbModsRec); 32705b261ecSmrg } 32805b261ecSmrg if (!type->preserve) { 32905b261ecSmrg if (prev_preserve) 33005b261ecSmrg _XkbFree(prev_preserve); 33105b261ecSmrg return BadAlloc; 33205b261ecSmrg } 33305b261ecSmrg } 33405b261ecSmrg else if (type->preserve!=NULL) { 33505b261ecSmrg _XkbFree(type->preserve); 33605b261ecSmrg type->preserve= NULL; 33705b261ecSmrg } 33805b261ecSmrg type->map_count= map_count; 33905b261ecSmrg } 34005b261ecSmrg 34105b261ecSmrg if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { 34205b261ecSmrg Atom * prev_level_names = type->level_names; 34305b261ecSmrg 34405b261ecSmrg type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom); 34505b261ecSmrg if (!type->level_names) { 34605b261ecSmrg if (prev_level_names) 34705b261ecSmrg _XkbFree(prev_level_names); 34805b261ecSmrg return BadAlloc; 34905b261ecSmrg } 35005b261ecSmrg } 35105b261ecSmrg /* 35205b261ecSmrg * Here's the theory: 35305b261ecSmrg * If the width of the type changed, we might have to resize the symbol 35405b261ecSmrg * maps for any keys that use the type for one or more groups. This is 35505b261ecSmrg * expensive, so we'll try to cull out any keys that are obviously okay: 35605b261ecSmrg * In any case: 35705b261ecSmrg * - keys that have a group width <= the old width are okay (because 35805b261ecSmrg * they could not possibly have been associated with the old type) 35905b261ecSmrg * If the key type increased in size: 36005b261ecSmrg * - keys that already have a group width >= to the new width are okay 36105b261ecSmrg * + keys that have a group width >= the old width but < the new width 36205b261ecSmrg * might have to be enlarged. 36305b261ecSmrg * If the key type decreased in size: 36405b261ecSmrg * - keys that have a group width > the old width don't have to be 36505b261ecSmrg * resized (because they must have some other wider type associated 36605b261ecSmrg * with some group). 36705b261ecSmrg * + keys that have a group width == the old width might have to be 36805b261ecSmrg * shrunk. 36905b261ecSmrg * The possibilities marked with '+' require us to examine the key types 37005b261ecSmrg * associated with each group for the key. 37105b261ecSmrg */ 37205b261ecSmrg bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode)); 37305b261ecSmrg nMatchingKeys= 0; 37405b261ecSmrg if (new_num_lvls>type->num_levels) { 37505b261ecSmrg int nTotal; 37605b261ecSmrg KeySym * newSyms; 37705b261ecSmrg int width,match,nResize; 37805b261ecSmrg register int i,g,nSyms; 37905b261ecSmrg 38005b261ecSmrg nResize= 0; 38105b261ecSmrg for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 38205b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 38305b261ecSmrg if (width<type->num_levels) 38405b261ecSmrg continue; 38505b261ecSmrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 38605b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 38705b261ecSmrg matchingKeys[nMatchingKeys++]= i; 38805b261ecSmrg match= 1; 38905b261ecSmrg } 39005b261ecSmrg } 39105b261ecSmrg if ((!match)||(width>=new_num_lvls)) 39205b261ecSmrg nTotal+= XkbKeyNumSyms(xkb,i); 39305b261ecSmrg else { 39405b261ecSmrg nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 39505b261ecSmrg nResize++; 39605b261ecSmrg } 39705b261ecSmrg } 39805b261ecSmrg if (nResize>0) { 39905b261ecSmrg int nextMatch; 40005b261ecSmrg xkb->map->size_syms= (nTotal*15)/10; 40105b261ecSmrg newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 40205b261ecSmrg if (newSyms==NULL) 40305b261ecSmrg return BadAlloc; 40405b261ecSmrg nextMatch= 0; 40505b261ecSmrg nSyms= 1; 40605b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 40705b261ecSmrg if (matchingKeys[nextMatch]==i) { 40805b261ecSmrg KeySym *pOld; 40905b261ecSmrg nextMatch++; 41005b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 41105b261ecSmrg pOld= XkbKeySymsPtr(xkb,i); 41205b261ecSmrg for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 41305b261ecSmrg memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], 41405b261ecSmrg width*sizeof(KeySym)); 41505b261ecSmrg } 41605b261ecSmrg xkb->map->key_sym_map[i].offset= nSyms; 41705b261ecSmrg nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 41805b261ecSmrg } 41905b261ecSmrg else { 42005b261ecSmrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), 42105b261ecSmrg XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); 42205b261ecSmrg xkb->map->key_sym_map[i].offset= nSyms; 42305b261ecSmrg nSyms+= XkbKeyNumSyms(xkb,i); 42405b261ecSmrg } 42505b261ecSmrg } 42605b261ecSmrg type->num_levels= new_num_lvls; 42705b261ecSmrg _XkbFree(xkb->map->syms); 42805b261ecSmrg xkb->map->syms= newSyms; 42905b261ecSmrg xkb->map->num_syms= nSyms; 43005b261ecSmrg return Success; 43105b261ecSmrg } 43205b261ecSmrg } 43305b261ecSmrg else if (new_num_lvls<type->num_levels) { 43405b261ecSmrg int width,match; 43505b261ecSmrg register int g,i; 43605b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 43705b261ecSmrg width= XkbKeyGroupsWidth(xkb,i); 43805b261ecSmrg if (width<type->num_levels) 43905b261ecSmrg continue; 44005b261ecSmrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 44105b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 44205b261ecSmrg matchingKeys[nMatchingKeys++]= i; 44305b261ecSmrg match= 1; 44405b261ecSmrg } 44505b261ecSmrg } 44605b261ecSmrg } 44705b261ecSmrg } 44805b261ecSmrg if (nMatchingKeys>0) { 44905b261ecSmrg int key,firstClear; 45005b261ecSmrg register int i,g; 45105b261ecSmrg if (new_num_lvls>type->num_levels) 45205b261ecSmrg firstClear= type->num_levels; 45305b261ecSmrg else firstClear= new_num_lvls; 45405b261ecSmrg for (i=0;i<nMatchingKeys;i++) { 45505b261ecSmrg KeySym * pSyms; 45605b261ecSmrg int width,nClear; 45705b261ecSmrg 45805b261ecSmrg key= matchingKeys[i]; 45905b261ecSmrg width= XkbKeyGroupsWidth(xkb,key); 46005b261ecSmrg nClear= width-firstClear; 46105b261ecSmrg pSyms= XkbKeySymsPtr(xkb,key); 46205b261ecSmrg for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { 46305b261ecSmrg if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { 46405b261ecSmrg if (nClear>0) 46505b261ecSmrg bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym)); 46605b261ecSmrg } 46705b261ecSmrg } 46805b261ecSmrg } 46905b261ecSmrg } 47005b261ecSmrg type->num_levels= new_num_lvls; 47105b261ecSmrg return Success; 47205b261ecSmrg} 47305b261ecSmrg 47405b261ecSmrgKeySym * 47505b261ecSmrgXkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) 47605b261ecSmrg{ 47705b261ecSmrgregister int i,nSyms,nKeySyms; 47805b261ecSmrgunsigned nOldSyms; 47905b261ecSmrgKeySym *newSyms; 48005b261ecSmrg 48105b261ecSmrg if (needed==0) { 48205b261ecSmrg xkb->map->key_sym_map[key].offset= 0; 48305b261ecSmrg return xkb->map->syms; 48405b261ecSmrg } 48505b261ecSmrg nOldSyms= XkbKeyNumSyms(xkb,key); 48605b261ecSmrg if (nOldSyms>=(unsigned)needed) { 48705b261ecSmrg return XkbKeySymsPtr(xkb,key); 48805b261ecSmrg } 48905b261ecSmrg if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { 49005b261ecSmrg if (nOldSyms>0) { 49105b261ecSmrg memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), 49205b261ecSmrg nOldSyms*sizeof(KeySym)); 49305b261ecSmrg } 49405b261ecSmrg if ((needed-nOldSyms)>0) { 49505b261ecSmrg bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)], 49605b261ecSmrg (needed-nOldSyms)*sizeof(KeySym)); 49705b261ecSmrg } 49805b261ecSmrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 49905b261ecSmrg xkb->map->num_syms+= needed; 50005b261ecSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 50105b261ecSmrg } 50205b261ecSmrg xkb->map->size_syms+= (needed>32?needed:32); 50305b261ecSmrg newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 50405b261ecSmrg if (newSyms==NULL) 50505b261ecSmrg return NULL; 50605b261ecSmrg newSyms[0]= NoSymbol; 50705b261ecSmrg nSyms = 1; 50805b261ecSmrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 50905b261ecSmrg int nCopy; 51005b261ecSmrg 51105b261ecSmrg nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); 51205b261ecSmrg if ((nKeySyms==0)&&(i!=key)) 51305b261ecSmrg continue; 51405b261ecSmrg if (i==key) 51505b261ecSmrg nKeySyms= needed; 51605b261ecSmrg if (nCopy!=0) 51705b261ecSmrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); 51805b261ecSmrg if (nKeySyms>nCopy) 51905b261ecSmrg bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym)); 52005b261ecSmrg xkb->map->key_sym_map[i].offset = nSyms; 52105b261ecSmrg nSyms+= nKeySyms; 52205b261ecSmrg } 52305b261ecSmrg _XkbFree(xkb->map->syms); 52405b261ecSmrg xkb->map->syms = newSyms; 52505b261ecSmrg xkb->map->num_syms = nSyms; 52605b261ecSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 52705b261ecSmrg} 52805b261ecSmrg 52905b261ecSmrgstatic unsigned 53005b261ecSmrg_ExtendRange( unsigned int old_flags, 53105b261ecSmrg unsigned int flag, 53205b261ecSmrg KeyCode newKC, 53305b261ecSmrg KeyCode * old_min, 53405b261ecSmrg unsigned char * old_num) 53505b261ecSmrg{ 53605b261ecSmrg if ((old_flags&flag)==0) { 53705b261ecSmrg old_flags|= flag; 53805b261ecSmrg *old_min= newKC; 53905b261ecSmrg *old_num= 1; 54005b261ecSmrg } 54105b261ecSmrg else { 54205b261ecSmrg int last= (*old_min)+(*old_num)-1; 54305b261ecSmrg if (newKC<*old_min) { 54405b261ecSmrg *old_min= newKC; 54505b261ecSmrg *old_num= (last-newKC)+1; 54605b261ecSmrg } 54705b261ecSmrg else if (newKC>last) { 54805b261ecSmrg *old_num= (newKC-(*old_min))+1; 54905b261ecSmrg } 55005b261ecSmrg } 55105b261ecSmrg return old_flags; 55205b261ecSmrg} 55305b261ecSmrg 55405b261ecSmrgStatus 55505b261ecSmrgXkbChangeKeycodeRange( XkbDescPtr xkb, 55605b261ecSmrg int minKC, 55705b261ecSmrg int maxKC, 55805b261ecSmrg XkbChangesPtr changes) 55905b261ecSmrg{ 56005b261ecSmrgint tmp; 56105b261ecSmrg 56205b261ecSmrg if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) 56305b261ecSmrg return BadValue; 56405b261ecSmrg if (minKC>maxKC) 56505b261ecSmrg return BadMatch; 56605b261ecSmrg if (minKC<xkb->min_key_code) { 56705b261ecSmrg if (changes) 56805b261ecSmrg changes->map.min_key_code= minKC; 56905b261ecSmrg tmp= xkb->min_key_code-minKC; 57005b261ecSmrg if (xkb->map) { 57105b261ecSmrg if (xkb->map->key_sym_map) { 57205b261ecSmrg bzero((char *)&xkb->map->key_sym_map[minKC], 57305b261ecSmrg tmp*sizeof(XkbSymMapRec)); 57405b261ecSmrg if (changes) { 57505b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 57605b261ecSmrg XkbKeySymsMask,minKC, 57705b261ecSmrg &changes->map.first_key_sym, 57805b261ecSmrg &changes->map.num_key_syms); 57905b261ecSmrg } 58005b261ecSmrg } 58105b261ecSmrg if (xkb->map->modmap) { 58205b261ecSmrg bzero((char *)&xkb->map->modmap[minKC],tmp); 58305b261ecSmrg if (changes) { 58405b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 58505b261ecSmrg XkbModifierMapMask,minKC, 58605b261ecSmrg &changes->map.first_modmap_key, 58705b261ecSmrg &changes->map.num_modmap_keys); 58805b261ecSmrg } 58905b261ecSmrg } 59005b261ecSmrg } 59105b261ecSmrg if (xkb->server) { 59205b261ecSmrg if (xkb->server->behaviors) { 59305b261ecSmrg bzero((char *)&xkb->server->behaviors[minKC], 59405b261ecSmrg tmp*sizeof(XkbBehavior)); 59505b261ecSmrg if (changes) { 59605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 59705b261ecSmrg XkbKeyBehaviorsMask,minKC, 59805b261ecSmrg &changes->map.first_key_behavior, 59905b261ecSmrg &changes->map.num_key_behaviors); 60005b261ecSmrg } 60105b261ecSmrg } 60205b261ecSmrg if (xkb->server->key_acts) { 60305b261ecSmrg bzero((char *)&xkb->server->key_acts[minKC], 60405b261ecSmrg tmp*sizeof(unsigned short)); 60505b261ecSmrg if (changes) { 60605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 60705b261ecSmrg XkbKeyActionsMask,minKC, 60805b261ecSmrg &changes->map.first_key_act, 60905b261ecSmrg &changes->map.num_key_acts); 61005b261ecSmrg } 61105b261ecSmrg } 61205b261ecSmrg if (xkb->server->vmodmap) { 61305b261ecSmrg bzero((char *)&xkb->server->vmodmap[minKC], 61405b261ecSmrg tmp*sizeof(unsigned short)); 61505b261ecSmrg if (changes) { 61605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 61705b261ecSmrg XkbVirtualModMapMask,minKC, 61805b261ecSmrg &changes->map.first_modmap_key, 61905b261ecSmrg &changes->map.num_vmodmap_keys); 62005b261ecSmrg } 62105b261ecSmrg } 62205b261ecSmrg } 62305b261ecSmrg if ((xkb->names)&&(xkb->names->keys)) { 62405b261ecSmrg bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec)); 62505b261ecSmrg if (changes) { 62605b261ecSmrg changes->names.changed= _ExtendRange(changes->names.changed, 62705b261ecSmrg XkbKeyNamesMask,minKC, 62805b261ecSmrg &changes->names.first_key, 62905b261ecSmrg &changes->names.num_keys); 63005b261ecSmrg } 63105b261ecSmrg } 63205b261ecSmrg xkb->min_key_code= minKC; 63305b261ecSmrg } 63405b261ecSmrg if (maxKC>xkb->max_key_code) { 63505b261ecSmrg if (changes) 63605b261ecSmrg changes->map.max_key_code= maxKC; 63705b261ecSmrg tmp= maxKC-xkb->max_key_code; 63805b261ecSmrg if (xkb->map) { 63905b261ecSmrg if (xkb->map->key_sym_map) { 64005b261ecSmrg XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 64105b261ecSmrg 64205b261ecSmrg xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map, 64305b261ecSmrg (maxKC+1),XkbSymMapRec); 64405b261ecSmrg if (!xkb->map->key_sym_map) { 64505b261ecSmrg _XkbFree(prev_key_sym_map); 64605b261ecSmrg return BadAlloc; 64705b261ecSmrg } 64805b261ecSmrg bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], 64905b261ecSmrg tmp*sizeof(XkbSymMapRec)); 65005b261ecSmrg if (changes) { 65105b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 65205b261ecSmrg XkbKeySymsMask,maxKC, 65305b261ecSmrg &changes->map.first_key_sym, 65405b261ecSmrg &changes->map.num_key_syms); 65505b261ecSmrg } 65605b261ecSmrg } 65705b261ecSmrg if (xkb->map->modmap) { 65805b261ecSmrg unsigned char *prev_modmap = xkb->map->modmap; 65905b261ecSmrg 66005b261ecSmrg xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap, 66105b261ecSmrg (maxKC+1),unsigned char); 66205b261ecSmrg if (!xkb->map->modmap) { 66305b261ecSmrg _XkbFree(prev_modmap); 66405b261ecSmrg return BadAlloc; 66505b261ecSmrg } 66605b261ecSmrg bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); 66705b261ecSmrg if (changes) { 66805b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 66905b261ecSmrg XkbModifierMapMask,maxKC, 67005b261ecSmrg &changes->map.first_modmap_key, 67105b261ecSmrg &changes->map.num_modmap_keys); 67205b261ecSmrg } 67305b261ecSmrg } 67405b261ecSmrg } 67505b261ecSmrg if (xkb->server) { 67605b261ecSmrg if (xkb->server->behaviors) { 67705b261ecSmrg XkbBehavior *prev_behaviors = xkb->server->behaviors; 67805b261ecSmrg 67905b261ecSmrg xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors, 68005b261ecSmrg (maxKC+1),XkbBehavior); 68105b261ecSmrg if (!xkb->server->behaviors) { 68205b261ecSmrg _XkbFree(prev_behaviors); 68305b261ecSmrg return BadAlloc; 68405b261ecSmrg } 68505b261ecSmrg bzero((char *)&xkb->server->behaviors[xkb->max_key_code], 68605b261ecSmrg tmp*sizeof(XkbBehavior)); 68705b261ecSmrg if (changes) { 68805b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 68905b261ecSmrg XkbKeyBehaviorsMask,maxKC, 69005b261ecSmrg &changes->map.first_key_behavior, 69105b261ecSmrg &changes->map.num_key_behaviors); 69205b261ecSmrg } 69305b261ecSmrg } 69405b261ecSmrg if (xkb->server->key_acts) { 69505b261ecSmrg unsigned short *prev_key_acts = xkb->server->key_acts; 69605b261ecSmrg 69705b261ecSmrg xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts, 69805b261ecSmrg (maxKC+1),unsigned short); 69905b261ecSmrg if (!xkb->server->key_acts) { 70005b261ecSmrg _XkbFree(prev_key_acts); 70105b261ecSmrg return BadAlloc; 70205b261ecSmrg } 70305b261ecSmrg bzero((char *)&xkb->server->key_acts[xkb->max_key_code], 70405b261ecSmrg tmp*sizeof(unsigned short)); 70505b261ecSmrg if (changes) { 70605b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 70705b261ecSmrg XkbKeyActionsMask,maxKC, 70805b261ecSmrg &changes->map.first_key_act, 70905b261ecSmrg &changes->map.num_key_acts); 71005b261ecSmrg } 71105b261ecSmrg } 71205b261ecSmrg if (xkb->server->vmodmap) { 71305b261ecSmrg unsigned short *prev_vmodmap = xkb->server->vmodmap; 71405b261ecSmrg 71505b261ecSmrg xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap, 71605b261ecSmrg (maxKC+1),unsigned short); 71705b261ecSmrg if (!xkb->server->vmodmap) { 71805b261ecSmrg _XkbFree(prev_vmodmap); 71905b261ecSmrg return BadAlloc; 72005b261ecSmrg } 72105b261ecSmrg bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], 72205b261ecSmrg tmp*sizeof(unsigned short)); 72305b261ecSmrg if (changes) { 72405b261ecSmrg changes->map.changed= _ExtendRange(changes->map.changed, 72505b261ecSmrg XkbVirtualModMapMask,maxKC, 72605b261ecSmrg &changes->map.first_modmap_key, 72705b261ecSmrg &changes->map.num_vmodmap_keys); 72805b261ecSmrg } 72905b261ecSmrg } 73005b261ecSmrg } 73105b261ecSmrg if ((xkb->names)&&(xkb->names->keys)) { 73205b261ecSmrg XkbKeyNameRec *prev_keys = xkb->names->keys; 73305b261ecSmrg 73405b261ecSmrg xkb->names->keys= _XkbTypedRealloc(xkb->names->keys, 73505b261ecSmrg (maxKC+1),XkbKeyNameRec); 73605b261ecSmrg if (!xkb->names->keys) { 73705b261ecSmrg _XkbFree(prev_keys); 73805b261ecSmrg return BadAlloc; 73905b261ecSmrg } 74005b261ecSmrg bzero((char *)&xkb->names->keys[xkb->max_key_code], 74105b261ecSmrg tmp*sizeof(XkbKeyNameRec)); 74205b261ecSmrg if (changes) { 74305b261ecSmrg changes->names.changed= _ExtendRange(changes->names.changed, 74405b261ecSmrg XkbKeyNamesMask,maxKC, 74505b261ecSmrg &changes->names.first_key, 74605b261ecSmrg &changes->names.num_keys); 74705b261ecSmrg } 74805b261ecSmrg } 74905b261ecSmrg xkb->max_key_code= maxKC; 75005b261ecSmrg } 75105b261ecSmrg return Success; 75205b261ecSmrg} 75305b261ecSmrg 75405b261ecSmrgXkbAction * 75505b261ecSmrgXkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) 75605b261ecSmrg{ 75705b261ecSmrgregister int i,nActs; 75805b261ecSmrgXkbAction *newActs; 75905b261ecSmrg 76005b261ecSmrg if (needed==0) { 76105b261ecSmrg xkb->server->key_acts[key]= 0; 76205b261ecSmrg return NULL; 76305b261ecSmrg } 76405b261ecSmrg if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) 76505b261ecSmrg return XkbKeyActionsPtr(xkb,key); 76605b261ecSmrg if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { 76705b261ecSmrg xkb->server->key_acts[key]= xkb->server->num_acts; 76805b261ecSmrg xkb->server->num_acts+= needed; 76905b261ecSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 77005b261ecSmrg } 77105b261ecSmrg xkb->server->size_acts= xkb->server->num_acts+needed+8; 77205b261ecSmrg newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction); 77305b261ecSmrg if (newActs==NULL) 77405b261ecSmrg return NULL; 77505b261ecSmrg newActs[0].type = XkbSA_NoAction; 77605b261ecSmrg nActs = 1; 77705b261ecSmrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 77805b261ecSmrg int nKeyActs,nCopy; 77905b261ecSmrg 78005b261ecSmrg if ((xkb->server->key_acts[i]==0)&&(i!=key)) 78105b261ecSmrg continue; 78205b261ecSmrg 78305b261ecSmrg nCopy= nKeyActs= XkbKeyNumActions(xkb,i); 78405b261ecSmrg if (i==key) { 78505b261ecSmrg nKeyActs= needed; 78605b261ecSmrg if (needed<nCopy) 78705b261ecSmrg nCopy= needed; 78805b261ecSmrg } 78905b261ecSmrg 79005b261ecSmrg if (nCopy>0) 79105b261ecSmrg memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), 79205b261ecSmrg nCopy*sizeof(XkbAction)); 79305b261ecSmrg if (nCopy<nKeyActs) 79405b261ecSmrg bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction)); 79505b261ecSmrg xkb->server->key_acts[i]= nActs; 79605b261ecSmrg nActs+= nKeyActs; 79705b261ecSmrg } 79805b261ecSmrg _XkbFree(xkb->server->acts); 79905b261ecSmrg xkb->server->acts = newActs; 80005b261ecSmrg xkb->server->num_acts= nActs; 80105b261ecSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 80205b261ecSmrg} 80305b261ecSmrg 80405b261ecSmrgvoid 80505b261ecSmrgXkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 80605b261ecSmrg{ 80705b261ecSmrgXkbClientMapPtr map; 80805b261ecSmrg 80905b261ecSmrg if ((xkb==NULL)||(xkb->map==NULL)) 81005b261ecSmrg return; 81105b261ecSmrg if (freeMap) 81205b261ecSmrg what= XkbAllClientInfoMask; 81305b261ecSmrg map= xkb->map; 81405b261ecSmrg if (what&XkbKeyTypesMask) { 81505b261ecSmrg if (map->types!=NULL) { 81605b261ecSmrg if (map->num_types>0) { 81705b261ecSmrg register int i; 81805b261ecSmrg XkbKeyTypePtr type; 81905b261ecSmrg for (i=0,type=map->types;i<map->num_types;i++,type++) { 82005b261ecSmrg if (type->map!=NULL) { 82105b261ecSmrg _XkbFree(type->map); 82205b261ecSmrg type->map= NULL; 82305b261ecSmrg } 82405b261ecSmrg if (type->preserve!=NULL) { 82505b261ecSmrg _XkbFree(type->preserve); 82605b261ecSmrg type->preserve= NULL; 82705b261ecSmrg } 82805b261ecSmrg type->map_count= 0; 82905b261ecSmrg if (type->level_names!=NULL) { 83005b261ecSmrg _XkbFree(type->level_names); 83105b261ecSmrg type->level_names= NULL; 83205b261ecSmrg } 83305b261ecSmrg } 83405b261ecSmrg } 83505b261ecSmrg _XkbFree(map->types); 83605b261ecSmrg map->num_types= map->size_types= 0; 83705b261ecSmrg map->types= NULL; 83805b261ecSmrg } 83905b261ecSmrg } 84005b261ecSmrg if (what&XkbKeySymsMask) { 84105b261ecSmrg if (map->key_sym_map!=NULL) { 84205b261ecSmrg _XkbFree(map->key_sym_map); 84305b261ecSmrg map->key_sym_map= NULL; 84405b261ecSmrg } 84505b261ecSmrg if (map->syms!=NULL) { 84605b261ecSmrg _XkbFree(map->syms); 84705b261ecSmrg map->size_syms= map->num_syms= 0; 84805b261ecSmrg map->syms= NULL; 84905b261ecSmrg } 85005b261ecSmrg } 85105b261ecSmrg if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { 85205b261ecSmrg _XkbFree(map->modmap); 85305b261ecSmrg map->modmap= NULL; 85405b261ecSmrg } 85505b261ecSmrg if (freeMap) { 85605b261ecSmrg _XkbFree(xkb->map); 85705b261ecSmrg xkb->map= NULL; 85805b261ecSmrg } 85905b261ecSmrg return; 86005b261ecSmrg} 86105b261ecSmrg 86205b261ecSmrgvoid 86305b261ecSmrgXkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 86405b261ecSmrg{ 86505b261ecSmrgXkbServerMapPtr map; 86605b261ecSmrg 86705b261ecSmrg if ((xkb==NULL)||(xkb->server==NULL)) 86805b261ecSmrg return; 86905b261ecSmrg if (freeMap) 87005b261ecSmrg what= XkbAllServerInfoMask; 87105b261ecSmrg map= xkb->server; 87205b261ecSmrg if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { 87305b261ecSmrg _XkbFree(map->explicit); 87405b261ecSmrg map->explicit= NULL; 87505b261ecSmrg } 87605b261ecSmrg if (what&XkbKeyActionsMask) { 87705b261ecSmrg if (map->key_acts!=NULL) { 87805b261ecSmrg _XkbFree(map->key_acts); 87905b261ecSmrg map->key_acts= NULL; 88005b261ecSmrg } 88105b261ecSmrg if (map->acts!=NULL) { 88205b261ecSmrg _XkbFree(map->acts); 88305b261ecSmrg map->num_acts= map->size_acts= 0; 88405b261ecSmrg map->acts= NULL; 88505b261ecSmrg } 88605b261ecSmrg } 88705b261ecSmrg if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { 88805b261ecSmrg _XkbFree(map->behaviors); 88905b261ecSmrg map->behaviors= NULL; 89005b261ecSmrg } 89105b261ecSmrg if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { 89205b261ecSmrg _XkbFree(map->vmodmap); 89305b261ecSmrg map->vmodmap= NULL; 89405b261ecSmrg } 89505b261ecSmrg 89605b261ecSmrg if (freeMap) { 89705b261ecSmrg _XkbFree(xkb->server); 89805b261ecSmrg xkb->server= NULL; 89905b261ecSmrg } 90005b261ecSmrg return; 90105b261ecSmrg} 902