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