XKBMAlloc.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBMAlloc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ 21ab64890Smrg/************************************************************ 31ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 41ab64890Smrg 51ab64890SmrgPermission to use, copy, modify, and distribute this 61ab64890Smrgsoftware and its documentation for any purpose and without 71ab64890Smrgfee is hereby granted, provided that the above copyright 81ab64890Smrgnotice appear in all copies and that both that copyright 91ab64890Smrgnotice and this permission notice appear in supporting 1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1161b2299dSmrgused in advertising or publicity pertaining to distribution 121ab64890Smrgof the software without specific prior written permission. 1361b2299dSmrgSilicon Graphics makes no representation about the suitability 141ab64890Smrgof this software for any purpose. It is provided "as is" 151ab64890Smrgwithout any express or implied warranty. 161ab64890Smrg 1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 251ab64890Smrg 261ab64890Smrg********************************************************/ 271ab64890Smrg/* $XFree86: xc/lib/X11/XKBMAlloc.c,v 3.11 2001/01/17 19:41:48 dawes Exp $ */ 281ab64890Smrg 291ab64890Smrg#ifdef HAVE_DIX_CONFIG_H 301ab64890Smrg#include <dix-config.h> 311ab64890Smrg#elif defined(HAVE_CONFIG_H) 321ab64890Smrg#include <config.h> 331ab64890Smrg#endif 341ab64890Smrg 351ab64890Smrg#ifndef XKB_IN_SERVER 361ab64890Smrg 371ab64890Smrg#include <stdio.h> 381ab64890Smrg#define NEED_REPLIES 391ab64890Smrg#define NEED_EVENTS 401ab64890Smrg#include "Xlibint.h" 411ab64890Smrg#include <X11/extensions/XKBproto.h> 421ab64890Smrg#include <X11/keysym.h> 431ab64890Smrg#include "XKBlibint.h" 441ab64890Smrg 4561b2299dSmrg#else 461ab64890Smrg 471ab64890Smrg#include <stdio.h> 481ab64890Smrg#include <X11/X.h> 491ab64890Smrg#define NEED_EVENTS 501ab64890Smrg#define NEED_REPLIES 511ab64890Smrg#include <X11/Xproto.h> 521ab64890Smrg#include "misc.h" 531ab64890Smrg#include "inputstr.h" 541ab64890Smrg#include <X11/keysym.h> 551ab64890Smrg#define XKBSRV_NEED_FILE_FUNCS 561ab64890Smrg#include <X11/extensions/XKBsrv.h> 571ab64890Smrg 581ab64890Smrg#endif /* XKB_IN_SERVER */ 591ab64890Smrg 601ab64890Smrg/***====================================================================***/ 611ab64890Smrg 621ab64890SmrgStatus 631ab64890SmrgXkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) 641ab64890Smrg{ 651ab64890Smrgregister int i; 661ab64890SmrgXkbClientMapPtr map; 671ab64890Smrg 681ab64890Smrg if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) 691ab64890Smrg return BadValue; 701ab64890Smrg if ((which&XkbKeySymsMask)&& 711ab64890Smrg ((!XkbIsLegalKeycode(xkb->min_key_code))|| 721ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 731ab64890Smrg (xkb->max_key_code<xkb->min_key_code))) { 741ab64890Smrg#ifdef DEBUG 751ab64890Smrgfprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n", 761ab64890Smrg xkb->min_key_code,xkb->max_key_code); 771ab64890Smrg#endif 781ab64890Smrg return BadValue; 791ab64890Smrg } 801ab64890Smrg 811ab64890Smrg if (xkb->map==NULL) { 821ab64890Smrg map= _XkbTypedCalloc(1,XkbClientMapRec); 831ab64890Smrg if (map==NULL) 841ab64890Smrg return BadAlloc; 851ab64890Smrg xkb->map= map; 861ab64890Smrg } 871ab64890Smrg else map= xkb->map; 881ab64890Smrg 891ab64890Smrg if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { 901ab64890Smrg if (map->types==NULL) { 911ab64890Smrg map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); 921ab64890Smrg if (map->types==NULL) 931ab64890Smrg return BadAlloc; 941ab64890Smrg map->num_types= 0; 951ab64890Smrg map->size_types= nTotalTypes; 961ab64890Smrg } 971ab64890Smrg else if (map->size_types<nTotalTypes) { 981ab64890Smrg XkbKeyTypeRec *prev_types = map->types; 991ab64890Smrg 1001ab64890Smrg map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); 1011ab64890Smrg if (map->types==NULL) { 1021ab64890Smrg _XkbFree(prev_types); 1031ab64890Smrg map->num_types= map->size_types= 0; 1041ab64890Smrg return BadAlloc; 1051ab64890Smrg } 1061ab64890Smrg map->size_types= nTotalTypes; 10761b2299dSmrg bzero(&map->types[map->num_types], 1081ab64890Smrg ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); 1091ab64890Smrg } 1101ab64890Smrg } 1111ab64890Smrg if (which&XkbKeySymsMask) { 1121ab64890Smrg int nKeys= XkbNumKeys(xkb); 1131ab64890Smrg if (map->syms==NULL) { 1141ab64890Smrg map->size_syms= (nKeys*15)/10; 1151ab64890Smrg map->syms= _XkbTypedCalloc(map->size_syms,KeySym); 1161ab64890Smrg if (!map->syms) { 1171ab64890Smrg map->size_syms= 0; 1181ab64890Smrg return BadAlloc; 1191ab64890Smrg } 1201ab64890Smrg map->num_syms= 1; 1211ab64890Smrg map->syms[0]= NoSymbol; 1221ab64890Smrg } 1231ab64890Smrg if (map->key_sym_map==NULL) { 1241ab64890Smrg i= xkb->max_key_code+1; 1251ab64890Smrg map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); 1261ab64890Smrg if (map->key_sym_map==NULL) 1271ab64890Smrg return BadAlloc; 1281ab64890Smrg } 1291ab64890Smrg } 1301ab64890Smrg if (which&XkbModifierMapMask) { 1311ab64890Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 1321ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 1331ab64890Smrg (xkb->max_key_code<xkb->min_key_code)) 1341ab64890Smrg return BadMatch; 1351ab64890Smrg if (map->modmap==NULL) { 1361ab64890Smrg i= xkb->max_key_code+1; 1371ab64890Smrg map->modmap= _XkbTypedCalloc(i,unsigned char); 1381ab64890Smrg if (map->modmap==NULL) 1391ab64890Smrg return BadAlloc; 1401ab64890Smrg } 1411ab64890Smrg } 1421ab64890Smrg return Success; 1431ab64890Smrg} 1441ab64890Smrg 1451ab64890SmrgStatus 1461ab64890SmrgXkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) 1471ab64890Smrg{ 1481ab64890Smrgregister int i; 1491ab64890SmrgXkbServerMapPtr map; 1501ab64890Smrg 1511ab64890Smrg if (xkb==NULL) 1521ab64890Smrg return BadMatch; 1531ab64890Smrg if (xkb->server==NULL) { 1541ab64890Smrg map= _XkbTypedCalloc(1,XkbServerMapRec); 1551ab64890Smrg if (map==NULL) 1561ab64890Smrg return BadAlloc; 1571ab64890Smrg for (i=0;i<XkbNumVirtualMods;i++) { 1581ab64890Smrg map->vmods[i]= XkbNoModifierMask; 1591ab64890Smrg } 1601ab64890Smrg xkb->server= map; 1611ab64890Smrg } 1621ab64890Smrg else map= xkb->server; 1631ab64890Smrg if (which&XkbExplicitComponentsMask) { 1641ab64890Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 1651ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 1661ab64890Smrg (xkb->max_key_code<xkb->min_key_code)) 1671ab64890Smrg return BadMatch; 1681ab64890Smrg if (map->explicit==NULL) { 1691ab64890Smrg i= xkb->max_key_code+1; 1701ab64890Smrg map->explicit= _XkbTypedCalloc(i,unsigned char); 1711ab64890Smrg if (map->explicit==NULL) 1721ab64890Smrg return BadAlloc; 1731ab64890Smrg } 1741ab64890Smrg } 1751ab64890Smrg if (which&XkbKeyActionsMask) { 1761ab64890Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 1771ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 1781ab64890Smrg (xkb->max_key_code<xkb->min_key_code)) 1791ab64890Smrg return BadMatch; 1801ab64890Smrg if (nNewActions<1) 1811ab64890Smrg nNewActions= 1; 1821ab64890Smrg if (map->acts==NULL) { 1831ab64890Smrg map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction); 1841ab64890Smrg if (map->acts==NULL) 1851ab64890Smrg return BadAlloc; 1861ab64890Smrg map->num_acts= 1; 1871ab64890Smrg map->size_acts= nNewActions+1; 1881ab64890Smrg } 1891ab64890Smrg else if ((map->size_acts-map->num_acts)<nNewActions) { 1901ab64890Smrg unsigned need; 1911ab64890Smrg XkbAction *prev_acts = map->acts; 1921ab64890Smrg need= map->num_acts+nNewActions; 1931ab64890Smrg map->acts= _XkbTypedRealloc(map->acts,need,XkbAction); 1941ab64890Smrg if (map->acts==NULL) { 1951ab64890Smrg _XkbFree(prev_acts); 1961ab64890Smrg map->num_acts= map->size_acts= 0; 1971ab64890Smrg return BadAlloc; 1981ab64890Smrg } 1991ab64890Smrg map->size_acts= need; 20061b2299dSmrg bzero(&map->acts[map->num_acts], 2011ab64890Smrg ((map->size_acts-map->num_acts)*sizeof(XkbAction))); 2021ab64890Smrg } 2031ab64890Smrg if (map->key_acts==NULL) { 2041ab64890Smrg i= xkb->max_key_code+1; 2051ab64890Smrg map->key_acts= _XkbTypedCalloc(i,unsigned short); 2061ab64890Smrg if (map->key_acts==NULL) 2071ab64890Smrg return BadAlloc; 2081ab64890Smrg } 2091ab64890Smrg } 2101ab64890Smrg if (which&XkbKeyBehaviorsMask) { 2111ab64890Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 2121ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 2131ab64890Smrg (xkb->max_key_code<xkb->min_key_code)) 2141ab64890Smrg return BadMatch; 2151ab64890Smrg if (map->behaviors==NULL) { 2161ab64890Smrg i= xkb->max_key_code+1; 2171ab64890Smrg map->behaviors= _XkbTypedCalloc(i,XkbBehavior); 2181ab64890Smrg if (map->behaviors==NULL) 2191ab64890Smrg return BadAlloc; 2201ab64890Smrg } 2211ab64890Smrg } 2221ab64890Smrg if (which&XkbVirtualModMapMask) { 2231ab64890Smrg if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 2241ab64890Smrg (!XkbIsLegalKeycode(xkb->max_key_code))|| 2251ab64890Smrg (xkb->max_key_code<xkb->min_key_code)) 2261ab64890Smrg return BadMatch; 2271ab64890Smrg if (map->vmodmap==NULL) { 2281ab64890Smrg i= xkb->max_key_code+1; 2291ab64890Smrg map->vmodmap= _XkbTypedCalloc(i,unsigned short); 2301ab64890Smrg if (map->vmodmap==NULL) 2311ab64890Smrg return BadAlloc; 2321ab64890Smrg } 2331ab64890Smrg } 2341ab64890Smrg return Success; 2351ab64890Smrg} 2361ab64890Smrg 2371ab64890Smrg/***====================================================================***/ 2381ab64890Smrg 2391ab64890SmrgStatus 2401ab64890SmrgXkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) 2411ab64890Smrg{ 2421ab64890Smrg if ((!from)||(!into)) 2431ab64890Smrg return BadMatch; 2441ab64890Smrg if (into->map) { 2451ab64890Smrg _XkbFree(into->map); 2461ab64890Smrg into->map= NULL; 2471ab64890Smrg } 2481ab64890Smrg if (into->preserve) { 2491ab64890Smrg _XkbFree(into->preserve); 2501ab64890Smrg into->preserve= NULL; 2511ab64890Smrg } 2521ab64890Smrg if (into->level_names) { 2531ab64890Smrg _XkbFree(into->level_names); 2541ab64890Smrg into->level_names= NULL; 2551ab64890Smrg } 2561ab64890Smrg *into= *from; 2571ab64890Smrg if ((from->map)&&(into->map_count>0)) { 2581ab64890Smrg into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec); 2591ab64890Smrg if (!into->map) 2601ab64890Smrg return BadAlloc; 2611ab64890Smrg memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); 2621ab64890Smrg } 2631ab64890Smrg if ((from->preserve)&&(into->map_count>0)) { 2641ab64890Smrg into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec); 2651ab64890Smrg if (!into->preserve) 2661ab64890Smrg return BadAlloc; 2671ab64890Smrg memcpy(into->preserve,from->preserve, 2681ab64890Smrg into->map_count*sizeof(XkbModsRec)); 2691ab64890Smrg } 2701ab64890Smrg if ((from->level_names)&&(into->num_levels>0)) { 2711ab64890Smrg into->level_names= _XkbTypedCalloc(into->num_levels,Atom); 2721ab64890Smrg if (!into->level_names) 2731ab64890Smrg return BadAlloc; 2741ab64890Smrg memcpy(into->level_names,from->level_names, 2751ab64890Smrg into->num_levels*sizeof(Atom)); 2761ab64890Smrg } 2771ab64890Smrg return Success; 2781ab64890Smrg} 2791ab64890Smrg 2801ab64890SmrgStatus 2811ab64890SmrgXkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) 2821ab64890Smrg{ 2831ab64890Smrgregister int i,rtrn; 2841ab64890Smrg 2851ab64890Smrg if ((!from)||(!into)||(num_types<0)) 2861ab64890Smrg return BadMatch; 2871ab64890Smrg for (i=0;i<num_types;i++) { 2881ab64890Smrg if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) 2891ab64890Smrg return rtrn; 2901ab64890Smrg } 2911ab64890Smrg return Success; 2921ab64890Smrg} 2931ab64890Smrg 2941ab64890SmrgXkbKeyTypePtr 2951ab64890SmrgXkbAddKeyType( XkbDescPtr xkb, 2961ab64890Smrg Atom name, 2971ab64890Smrg int map_count, 2981ab64890Smrg Bool want_preserve, 2991ab64890Smrg int num_lvls) 3001ab64890Smrg{ 3011ab64890Smrgregister int i; 3021ab64890Smrgunsigned tmp; 3031ab64890SmrgXkbKeyTypePtr type; 3041ab64890SmrgXkbClientMapPtr map; 3051ab64890Smrg 3061ab64890Smrg if ((!xkb)||(num_lvls<1)) 3071ab64890Smrg return NULL; 3081ab64890Smrg map= xkb->map; 3091ab64890Smrg if ((map)&&(map->types)) { 3101ab64890Smrg for (i=0;i<map->num_types;i++) { 3111ab64890Smrg if (map->types[i].name==name) { 3121ab64890Smrg Status status; 3131ab64890Smrg status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); 3141ab64890Smrg return (status==Success?&map->types[i]:NULL); 3151ab64890Smrg } 3161ab64890Smrg } 3171ab64890Smrg } 3181ab64890Smrg if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) { 3191ab64890Smrg tmp= XkbNumRequiredTypes+1; 3201ab64890Smrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success) 3211ab64890Smrg return NULL; 3221ab64890Smrg if (!map) 3231ab64890Smrg map = xkb->map; 3241ab64890Smrg tmp= 0; 3251ab64890Smrg if (map->num_types<=XkbKeypadIndex) 3261ab64890Smrg tmp|= XkbKeypadMask; 3271ab64890Smrg if (map->num_types<=XkbAlphabeticIndex) 3281ab64890Smrg tmp|= XkbAlphabeticMask; 3291ab64890Smrg if (map->num_types<=XkbTwoLevelIndex) 3301ab64890Smrg tmp|= XkbTwoLevelMask; 3311ab64890Smrg if (map->num_types<=XkbOneLevelIndex) 3321ab64890Smrg tmp|= XkbOneLevelMask; 3331ab64890Smrg if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) { 3341ab64890Smrg for (i=0;i<map->num_types;i++) { 3351ab64890Smrg Status status; 3361ab64890Smrg if (map->types[i].name!=name) 3371ab64890Smrg continue; 3381ab64890Smrg status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); 3391ab64890Smrg return (status==Success?&map->types[i]:NULL); 3401ab64890Smrg } 3411ab64890Smrg } 3421ab64890Smrg } 3431ab64890Smrg if ((map->num_types<=map->size_types)&& 3441ab64890Smrg (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) { 3451ab64890Smrg return NULL; 3461ab64890Smrg } 3471ab64890Smrg type= &map->types[map->num_types]; 3481ab64890Smrg map->num_types++; 3491ab64890Smrg bzero((char *)type,sizeof(XkbKeyTypeRec)); 3501ab64890Smrg type->num_levels= num_lvls; 3511ab64890Smrg type->map_count= map_count; 3521ab64890Smrg type->name= name; 3531ab64890Smrg if (map_count>0) { 3541ab64890Smrg type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec); 3551ab64890Smrg if (!type->map) { 3561ab64890Smrg map->num_types--; 3571ab64890Smrg return NULL; 3581ab64890Smrg } 3591ab64890Smrg if (want_preserve) { 3601ab64890Smrg type->preserve= _XkbTypedCalloc(map_count,XkbModsRec); 3611ab64890Smrg if (!type->preserve) { 3621ab64890Smrg _XkbFree(type->map); 3631ab64890Smrg map->num_types--; 3641ab64890Smrg return NULL; 3651ab64890Smrg } 3661ab64890Smrg } 3671ab64890Smrg } 3681ab64890Smrg return type; 3691ab64890Smrg} 3701ab64890Smrg 3711ab64890SmrgStatus 3721ab64890SmrgXkbResizeKeyType( XkbDescPtr xkb, 3731ab64890Smrg int type_ndx, 3741ab64890Smrg int map_count, 3751ab64890Smrg Bool want_preserve, 3761ab64890Smrg int new_num_lvls) 3771ab64890Smrg{ 3781ab64890SmrgXkbKeyTypePtr type; 3791ab64890SmrgKeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; 3801ab64890Smrg 3811ab64890Smrg if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| 3821ab64890Smrg (new_num_lvls<1)) 3831ab64890Smrg return BadValue; 3841ab64890Smrg switch (type_ndx) { 3851ab64890Smrg case XkbOneLevelIndex: 3861ab64890Smrg if (new_num_lvls!=1) 3871ab64890Smrg return BadMatch; 3881ab64890Smrg break; 3891ab64890Smrg case XkbTwoLevelIndex: 3901ab64890Smrg case XkbAlphabeticIndex: 3911ab64890Smrg case XkbKeypadIndex: 3921ab64890Smrg if (new_num_lvls!=2) 3931ab64890Smrg return BadMatch; 3941ab64890Smrg break; 3951ab64890Smrg } 3961ab64890Smrg type= &xkb->map->types[type_ndx]; 3971ab64890Smrg if (map_count==0) { 3981ab64890Smrg if (type->map!=NULL) 3991ab64890Smrg _XkbFree(type->map); 4001ab64890Smrg type->map= NULL; 4011ab64890Smrg if (type->preserve!=NULL) 4021ab64890Smrg _XkbFree(type->preserve); 4031ab64890Smrg type->preserve= NULL; 4041ab64890Smrg type->map_count= 0; 4051ab64890Smrg } 4061ab64890Smrg else { 4071ab64890Smrg XkbKTMapEntryRec *prev_map = type->map; 4081ab64890Smrg 4091ab64890Smrg if ((map_count>type->map_count)||(type->map==NULL)) 4101ab64890Smrg type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec); 4111ab64890Smrg if (!type->map) { 41261b2299dSmrg if (prev_map) 4131ab64890Smrg _XkbFree(prev_map); 4141ab64890Smrg return BadAlloc; 4151ab64890Smrg } 4161ab64890Smrg if (want_preserve) { 4171ab64890Smrg XkbModsRec *prev_preserve = type->preserve; 4181ab64890Smrg 4191ab64890Smrg if ((map_count>type->map_count)||(type->preserve==NULL)) { 4201ab64890Smrg type->preserve= _XkbTypedRealloc(type->preserve,map_count, 4211ab64890Smrg XkbModsRec); 4221ab64890Smrg } 4231ab64890Smrg if (!type->preserve) { 42461b2299dSmrg if (prev_preserve) 4251ab64890Smrg _XkbFree(prev_preserve); 4261ab64890Smrg return BadAlloc; 4271ab64890Smrg } 4281ab64890Smrg } 4291ab64890Smrg else if (type->preserve!=NULL) { 4301ab64890Smrg _XkbFree(type->preserve); 4311ab64890Smrg type->preserve= NULL; 4321ab64890Smrg } 4331ab64890Smrg type->map_count= map_count; 4341ab64890Smrg } 4351ab64890Smrg 4361ab64890Smrg if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { 4371ab64890Smrg Atom * prev_level_names = type->level_names; 4381ab64890Smrg 4391ab64890Smrg type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom); 4401ab64890Smrg if (!type->level_names) { 44161b2299dSmrg if (prev_level_names) 4421ab64890Smrg _XkbFree(prev_level_names); 4431ab64890Smrg return BadAlloc; 4441ab64890Smrg } 4451ab64890Smrg } 4461ab64890Smrg /* 4471ab64890Smrg * Here's the theory: 4481ab64890Smrg * If the width of the type changed, we might have to resize the symbol 4491ab64890Smrg * maps for any keys that use the type for one or more groups. This is 4501ab64890Smrg * expensive, so we'll try to cull out any keys that are obviously okay: 4511ab64890Smrg * In any case: 4521ab64890Smrg * - keys that have a group width <= the old width are okay (because 4531ab64890Smrg * they could not possibly have been associated with the old type) 4541ab64890Smrg * If the key type increased in size: 4551ab64890Smrg * - keys that already have a group width >= to the new width are okay 4561ab64890Smrg * + keys that have a group width >= the old width but < the new width 4571ab64890Smrg * might have to be enlarged. 4581ab64890Smrg * If the key type decreased in size: 4591ab64890Smrg * - keys that have a group width > the old width don't have to be 46061b2299dSmrg * resized (because they must have some other wider type associated 4611ab64890Smrg * with some group). 4621ab64890Smrg * + keys that have a group width == the old width might have to be 4631ab64890Smrg * shrunk. 4641ab64890Smrg * The possibilities marked with '+' require us to examine the key types 4651ab64890Smrg * associated with each group for the key. 4661ab64890Smrg */ 4671ab64890Smrg bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode)); 4681ab64890Smrg nMatchingKeys= 0; 4691ab64890Smrg if (new_num_lvls>type->num_levels) { 4701ab64890Smrg int nTotal; 4711ab64890Smrg KeySym * newSyms; 4721ab64890Smrg int width,match,nResize; 4731ab64890Smrg register int i,g,nSyms; 4741ab64890Smrg 4751ab64890Smrg nResize= 0; 4761ab64890Smrg for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 4771ab64890Smrg width= XkbKeyGroupsWidth(xkb,i); 4781ab64890Smrg if (width<type->num_levels) 4791ab64890Smrg continue; 4801ab64890Smrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 4811ab64890Smrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 4821ab64890Smrg matchingKeys[nMatchingKeys++]= i; 4831ab64890Smrg match= 1; 4841ab64890Smrg } 4851ab64890Smrg } 4861ab64890Smrg if ((!match)||(width>=new_num_lvls)) 4871ab64890Smrg nTotal+= XkbKeyNumSyms(xkb,i); 4881ab64890Smrg else { 4891ab64890Smrg nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 4901ab64890Smrg nResize++; 4911ab64890Smrg } 4921ab64890Smrg } 4931ab64890Smrg if (nResize>0) { 4941ab64890Smrg int nextMatch; 4951ab64890Smrg xkb->map->size_syms= (nTotal*12)/10; 4961ab64890Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 4971ab64890Smrg if (newSyms==NULL) 4981ab64890Smrg return BadAlloc; 4991ab64890Smrg nextMatch= 0; 5001ab64890Smrg nSyms= 1; 5011ab64890Smrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 5021ab64890Smrg if (matchingKeys[nextMatch]==i) { 5031ab64890Smrg KeySym *pOld; 5041ab64890Smrg nextMatch++; 5051ab64890Smrg width= XkbKeyGroupsWidth(xkb,i); 5061ab64890Smrg pOld= XkbKeySymsPtr(xkb,i); 5071ab64890Smrg for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 5081ab64890Smrg memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], 5091ab64890Smrg width*sizeof(KeySym)); 5101ab64890Smrg } 5111ab64890Smrg xkb->map->key_sym_map[i].offset= nSyms; 5121ab64890Smrg nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 5131ab64890Smrg } 5141ab64890Smrg else { 5151ab64890Smrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), 5161ab64890Smrg XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); 5171ab64890Smrg xkb->map->key_sym_map[i].offset= nSyms; 5181ab64890Smrg nSyms+= XkbKeyNumSyms(xkb,i); 5191ab64890Smrg } 5201ab64890Smrg } 5211ab64890Smrg type->num_levels= new_num_lvls; 5221ab64890Smrg _XkbFree(xkb->map->syms); 5231ab64890Smrg xkb->map->syms= newSyms; 5241ab64890Smrg xkb->map->num_syms= nSyms; 5251ab64890Smrg return Success; 5261ab64890Smrg } 5271ab64890Smrg } 5281ab64890Smrg else if (new_num_lvls<type->num_levels) { 5291ab64890Smrg int width,match; 5301ab64890Smrg register int g,i; 5311ab64890Smrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 5321ab64890Smrg width= XkbKeyGroupsWidth(xkb,i); 5331ab64890Smrg if (width<type->num_levels) 5341ab64890Smrg continue; 5351ab64890Smrg for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 5361ab64890Smrg if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 5371ab64890Smrg matchingKeys[nMatchingKeys++]= i; 5381ab64890Smrg match= 1; 5391ab64890Smrg } 5401ab64890Smrg } 5411ab64890Smrg } 5421ab64890Smrg } 5431ab64890Smrg if (nMatchingKeys>0) { 5441ab64890Smrg int key,firstClear; 5451ab64890Smrg register int i,g; 5461ab64890Smrg if (new_num_lvls>type->num_levels) 5471ab64890Smrg firstClear= type->num_levels; 5481ab64890Smrg else firstClear= new_num_lvls; 5491ab64890Smrg for (i=0;i<nMatchingKeys;i++) { 5501ab64890Smrg KeySym * pSyms; 5511ab64890Smrg int width,nClear; 5521ab64890Smrg 5531ab64890Smrg key= matchingKeys[i]; 5541ab64890Smrg width= XkbKeyGroupsWidth(xkb,key); 5551ab64890Smrg nClear= width-firstClear; 5561ab64890Smrg pSyms= XkbKeySymsPtr(xkb,key); 5571ab64890Smrg for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { 5581ab64890Smrg if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { 5591ab64890Smrg if (nClear>0) 5601ab64890Smrg bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym)); 5611ab64890Smrg } 5621ab64890Smrg } 5631ab64890Smrg } 5641ab64890Smrg } 5651ab64890Smrg type->num_levels= new_num_lvls; 5661ab64890Smrg return Success; 5671ab64890Smrg} 5681ab64890Smrg 5691ab64890SmrgKeySym * 5701ab64890SmrgXkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) 5711ab64890Smrg{ 5721ab64890Smrgregister int i,nSyms,nKeySyms; 5731ab64890Smrgunsigned nOldSyms; 5741ab64890SmrgKeySym *newSyms; 5751ab64890Smrg 5761ab64890Smrg if (needed==0) { 5771ab64890Smrg xkb->map->key_sym_map[key].offset= 0; 5781ab64890Smrg return xkb->map->syms; 5791ab64890Smrg } 5801ab64890Smrg nOldSyms= XkbKeyNumSyms(xkb,key); 5811ab64890Smrg if (nOldSyms>=(unsigned)needed) { 5821ab64890Smrg return XkbKeySymsPtr(xkb,key); 5831ab64890Smrg } 5841ab64890Smrg if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { 5851ab64890Smrg if (nOldSyms>0) { 5861ab64890Smrg memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), 5871ab64890Smrg nOldSyms*sizeof(KeySym)); 5881ab64890Smrg } 5891ab64890Smrg if ((needed-nOldSyms)>0) { 5901ab64890Smrg bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)], 5911ab64890Smrg (needed-nOldSyms)*sizeof(KeySym)); 5921ab64890Smrg } 5931ab64890Smrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 5941ab64890Smrg xkb->map->num_syms+= needed; 5951ab64890Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 5961ab64890Smrg } 5971ab64890Smrg xkb->map->size_syms+= (needed>32?needed:32); 5981ab64890Smrg newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 5991ab64890Smrg if (newSyms==NULL) 6001ab64890Smrg return NULL; 6011ab64890Smrg newSyms[0]= NoSymbol; 6021ab64890Smrg nSyms = 1; 6031ab64890Smrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 6041ab64890Smrg int nCopy; 6051ab64890Smrg 6061ab64890Smrg nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); 6071ab64890Smrg if ((nKeySyms==0)&&(i!=key)) 6081ab64890Smrg continue; 6091ab64890Smrg if (i==key) 6101ab64890Smrg nKeySyms= needed; 6111ab64890Smrg if (nCopy!=0) 6121ab64890Smrg memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); 6131ab64890Smrg if (nKeySyms>nCopy) 6141ab64890Smrg bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym)); 6151ab64890Smrg xkb->map->key_sym_map[i].offset = nSyms; 6161ab64890Smrg nSyms+= nKeySyms; 6171ab64890Smrg } 6181ab64890Smrg _XkbFree(xkb->map->syms); 6191ab64890Smrg xkb->map->syms = newSyms; 6201ab64890Smrg xkb->map->num_syms = nSyms; 6211ab64890Smrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 6221ab64890Smrg} 6231ab64890Smrg 6241ab64890Smrgstatic unsigned 6251ab64890Smrg_ExtendRange( unsigned int old_flags, 6261ab64890Smrg unsigned int flag, 6271ab64890Smrg KeyCode newKC, 6281ab64890Smrg KeyCode * old_min, 6291ab64890Smrg unsigned char * old_num) 6301ab64890Smrg{ 6311ab64890Smrg if ((old_flags&flag)==0) { 6321ab64890Smrg old_flags|= flag; 6331ab64890Smrg *old_min= newKC; 6341ab64890Smrg *old_num= 1; 6351ab64890Smrg } 6361ab64890Smrg else { 6371ab64890Smrg int last= (*old_min)+(*old_num)-1; 6381ab64890Smrg if (newKC<*old_min) { 6391ab64890Smrg *old_min= newKC; 6401ab64890Smrg *old_num= (last-newKC)+1; 6411ab64890Smrg } 6421ab64890Smrg else if (newKC>last) { 6431ab64890Smrg *old_num= (newKC-(*old_min))+1; 6441ab64890Smrg } 6451ab64890Smrg } 6461ab64890Smrg return old_flags; 6471ab64890Smrg} 6481ab64890Smrg 6491ab64890SmrgStatus 6501ab64890SmrgXkbChangeKeycodeRange( XkbDescPtr xkb, 6511ab64890Smrg int minKC, 6521ab64890Smrg int maxKC, 6531ab64890Smrg XkbChangesPtr changes) 6541ab64890Smrg{ 6551ab64890Smrgint tmp; 6561ab64890Smrg 6571ab64890Smrg if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) 6581ab64890Smrg return BadValue; 6591ab64890Smrg if (minKC>maxKC) 6601ab64890Smrg return BadMatch; 6611ab64890Smrg if (minKC<xkb->min_key_code) { 6621ab64890Smrg if (changes) 6631ab64890Smrg changes->map.min_key_code= minKC; 6641ab64890Smrg tmp= xkb->min_key_code-minKC; 6651ab64890Smrg if (xkb->map) { 6661ab64890Smrg if (xkb->map->key_sym_map) { 6671ab64890Smrg bzero((char *)&xkb->map->key_sym_map[minKC], 6681ab64890Smrg tmp*sizeof(XkbSymMapRec)); 6691ab64890Smrg if (changes) { 6701ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 6711ab64890Smrg XkbKeySymsMask,minKC, 6721ab64890Smrg &changes->map.first_key_sym, 6731ab64890Smrg &changes->map.num_key_syms); 6741ab64890Smrg } 6751ab64890Smrg } 6761ab64890Smrg if (xkb->map->modmap) { 6771ab64890Smrg bzero((char *)&xkb->map->modmap[minKC],tmp); 6781ab64890Smrg if (changes) { 6791ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 6801ab64890Smrg XkbModifierMapMask,minKC, 6811ab64890Smrg &changes->map.first_modmap_key, 6821ab64890Smrg &changes->map.num_modmap_keys); 6831ab64890Smrg } 6841ab64890Smrg } 6851ab64890Smrg } 6861ab64890Smrg if (xkb->server) { 6871ab64890Smrg if (xkb->server->behaviors) { 6881ab64890Smrg bzero((char *)&xkb->server->behaviors[minKC], 6891ab64890Smrg tmp*sizeof(XkbBehavior)); 6901ab64890Smrg if (changes) { 6911ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 6921ab64890Smrg XkbKeyBehaviorsMask,minKC, 6931ab64890Smrg &changes->map.first_key_behavior, 6941ab64890Smrg &changes->map.num_key_behaviors); 6951ab64890Smrg } 6961ab64890Smrg } 6971ab64890Smrg if (xkb->server->key_acts) { 6981ab64890Smrg bzero((char *)&xkb->server->key_acts[minKC], 6991ab64890Smrg tmp*sizeof(unsigned short)); 7001ab64890Smrg if (changes) { 7011ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 7021ab64890Smrg XkbKeyActionsMask,minKC, 7031ab64890Smrg &changes->map.first_key_act, 7041ab64890Smrg &changes->map.num_key_acts); 7051ab64890Smrg } 7061ab64890Smrg } 7071ab64890Smrg if (xkb->server->vmodmap) { 7081ab64890Smrg bzero((char *)&xkb->server->vmodmap[minKC], 7091ab64890Smrg tmp*sizeof(unsigned short)); 7101ab64890Smrg if (changes) { 7111ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 7121ab64890Smrg XkbVirtualModMapMask,minKC, 7131ab64890Smrg &changes->map.first_modmap_key, 7141ab64890Smrg &changes->map.num_vmodmap_keys); 7151ab64890Smrg } 7161ab64890Smrg } 7171ab64890Smrg } 7181ab64890Smrg if ((xkb->names)&&(xkb->names->keys)) { 7191ab64890Smrg bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec)); 7201ab64890Smrg if (changes) { 7211ab64890Smrg changes->names.changed= _ExtendRange(changes->names.changed, 7221ab64890Smrg XkbKeyNamesMask,minKC, 7231ab64890Smrg &changes->names.first_key, 7241ab64890Smrg &changes->names.num_keys); 7251ab64890Smrg } 7261ab64890Smrg } 7271ab64890Smrg xkb->min_key_code= minKC; 7281ab64890Smrg } 7291ab64890Smrg if (maxKC>xkb->max_key_code) { 7301ab64890Smrg if (changes) 7311ab64890Smrg changes->map.max_key_code= maxKC; 7321ab64890Smrg tmp= maxKC-xkb->max_key_code; 7331ab64890Smrg if (xkb->map) { 7341ab64890Smrg if (xkb->map->key_sym_map) { 7351ab64890Smrg XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 7361ab64890Smrg 7371ab64890Smrg xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map, 7381ab64890Smrg (maxKC+1),XkbSymMapRec); 7391ab64890Smrg if (!xkb->map->key_sym_map) { 7401ab64890Smrg _XkbFree(prev_key_sym_map); 7411ab64890Smrg return BadAlloc; 7421ab64890Smrg } 7431ab64890Smrg bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], 7441ab64890Smrg tmp*sizeof(XkbSymMapRec)); 7451ab64890Smrg if (changes) { 7461ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 7471ab64890Smrg XkbKeySymsMask,maxKC, 7481ab64890Smrg &changes->map.first_key_sym, 7491ab64890Smrg &changes->map.num_key_syms); 7501ab64890Smrg } 7511ab64890Smrg } 7521ab64890Smrg if (xkb->map->modmap) { 7531ab64890Smrg unsigned char *prev_modmap = xkb->map->modmap; 7541ab64890Smrg 7551ab64890Smrg xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap, 7561ab64890Smrg (maxKC+1),unsigned char); 7571ab64890Smrg if (!xkb->map->modmap) { 7581ab64890Smrg _XkbFree(prev_modmap); 7591ab64890Smrg return BadAlloc; 7601ab64890Smrg } 7611ab64890Smrg bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); 7621ab64890Smrg if (changes) { 7631ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 7641ab64890Smrg XkbModifierMapMask,maxKC, 7651ab64890Smrg &changes->map.first_modmap_key, 7661ab64890Smrg &changes->map.num_modmap_keys); 7671ab64890Smrg } 7681ab64890Smrg } 7691ab64890Smrg } 7701ab64890Smrg if (xkb->server) { 7711ab64890Smrg if (xkb->server->behaviors) { 7721ab64890Smrg XkbBehavior *prev_behaviors = xkb->server->behaviors; 7731ab64890Smrg 7741ab64890Smrg xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors, 7751ab64890Smrg (maxKC+1),XkbBehavior); 7761ab64890Smrg if (!xkb->server->behaviors) { 7771ab64890Smrg _XkbFree(prev_behaviors); 7781ab64890Smrg return BadAlloc; 7791ab64890Smrg } 7801ab64890Smrg bzero((char *)&xkb->server->behaviors[xkb->max_key_code], 7811ab64890Smrg tmp*sizeof(XkbBehavior)); 7821ab64890Smrg if (changes) { 7831ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 7841ab64890Smrg XkbKeyBehaviorsMask,maxKC, 7851ab64890Smrg &changes->map.first_key_behavior, 7861ab64890Smrg &changes->map.num_key_behaviors); 7871ab64890Smrg } 7881ab64890Smrg } 7891ab64890Smrg if (xkb->server->key_acts) { 7901ab64890Smrg unsigned short *prev_key_acts = xkb->server->key_acts; 7911ab64890Smrg 7921ab64890Smrg xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts, 7931ab64890Smrg (maxKC+1),unsigned short); 7941ab64890Smrg if (!xkb->server->key_acts) { 7951ab64890Smrg _XkbFree(prev_key_acts); 7961ab64890Smrg return BadAlloc; 7971ab64890Smrg } 7981ab64890Smrg bzero((char *)&xkb->server->key_acts[xkb->max_key_code], 7991ab64890Smrg tmp*sizeof(unsigned short)); 8001ab64890Smrg if (changes) { 8011ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 8021ab64890Smrg XkbKeyActionsMask,maxKC, 8031ab64890Smrg &changes->map.first_key_act, 8041ab64890Smrg &changes->map.num_key_acts); 8051ab64890Smrg } 8061ab64890Smrg } 8071ab64890Smrg if (xkb->server->vmodmap) { 8081ab64890Smrg unsigned short *prev_vmodmap = xkb->server->vmodmap; 8091ab64890Smrg 8101ab64890Smrg xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap, 8111ab64890Smrg (maxKC+1),unsigned short); 8121ab64890Smrg if (!xkb->server->vmodmap) { 8131ab64890Smrg _XkbFree(prev_vmodmap); 8141ab64890Smrg return BadAlloc; 8151ab64890Smrg } 8161ab64890Smrg bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], 8171ab64890Smrg tmp*sizeof(unsigned short)); 8181ab64890Smrg if (changes) { 8191ab64890Smrg changes->map.changed= _ExtendRange(changes->map.changed, 8201ab64890Smrg XkbVirtualModMapMask,maxKC, 8211ab64890Smrg &changes->map.first_modmap_key, 8221ab64890Smrg &changes->map.num_vmodmap_keys); 8231ab64890Smrg } 8241ab64890Smrg } 8251ab64890Smrg } 8261ab64890Smrg if ((xkb->names)&&(xkb->names->keys)) { 8271ab64890Smrg XkbKeyNameRec *prev_keys = xkb->names->keys; 8281ab64890Smrg 8291ab64890Smrg xkb->names->keys= _XkbTypedRealloc(xkb->names->keys, 8301ab64890Smrg (maxKC+1),XkbKeyNameRec); 8311ab64890Smrg if (!xkb->names->keys) { 8321ab64890Smrg _XkbFree(prev_keys); 8331ab64890Smrg return BadAlloc; 8341ab64890Smrg } 8351ab64890Smrg bzero((char *)&xkb->names->keys[xkb->max_key_code], 8361ab64890Smrg tmp*sizeof(XkbKeyNameRec)); 8371ab64890Smrg if (changes) { 8381ab64890Smrg changes->names.changed= _ExtendRange(changes->names.changed, 8391ab64890Smrg XkbKeyNamesMask,maxKC, 8401ab64890Smrg &changes->names.first_key, 8411ab64890Smrg &changes->names.num_keys); 8421ab64890Smrg } 8431ab64890Smrg } 8441ab64890Smrg xkb->max_key_code= maxKC; 8451ab64890Smrg } 8461ab64890Smrg return Success; 8471ab64890Smrg} 8481ab64890Smrg 8491ab64890SmrgXkbAction * 8501ab64890SmrgXkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) 8511ab64890Smrg{ 8521ab64890Smrgregister int i,nActs; 8531ab64890SmrgXkbAction *newActs; 8541ab64890Smrg 8551ab64890Smrg if (needed==0) { 8561ab64890Smrg xkb->server->key_acts[key]= 0; 8571ab64890Smrg return NULL; 8581ab64890Smrg } 8591ab64890Smrg if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) 8601ab64890Smrg return XkbKeyActionsPtr(xkb,key); 8611ab64890Smrg if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { 8621ab64890Smrg xkb->server->key_acts[key]= xkb->server->num_acts; 8631ab64890Smrg xkb->server->num_acts+= needed; 8641ab64890Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 8651ab64890Smrg } 8661ab64890Smrg xkb->server->size_acts= xkb->server->num_acts+needed+8; 8671ab64890Smrg newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction); 8681ab64890Smrg if (newActs==NULL) 8691ab64890Smrg return NULL; 8701ab64890Smrg newActs[0].type = XkbSA_NoAction; 8711ab64890Smrg nActs = 1; 8721ab64890Smrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 8731ab64890Smrg int nKeyActs,nCopy; 8741ab64890Smrg 8751ab64890Smrg if ((xkb->server->key_acts[i]==0)&&(i!=key)) 8761ab64890Smrg continue; 8771ab64890Smrg 8781ab64890Smrg nCopy= nKeyActs= XkbKeyNumActions(xkb,i); 8791ab64890Smrg if (i==key) { 8801ab64890Smrg nKeyActs= needed; 8811ab64890Smrg if (needed<nCopy) 8821ab64890Smrg nCopy= needed; 8831ab64890Smrg } 8841ab64890Smrg 8851ab64890Smrg if (nCopy>0) 8861ab64890Smrg memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), 8871ab64890Smrg nCopy*sizeof(XkbAction)); 8881ab64890Smrg if (nCopy<nKeyActs) 8891ab64890Smrg bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction)); 8901ab64890Smrg xkb->server->key_acts[i]= nActs; 8911ab64890Smrg nActs+= nKeyActs; 8921ab64890Smrg } 8931ab64890Smrg _XkbFree(xkb->server->acts); 8941ab64890Smrg xkb->server->acts = newActs; 8951ab64890Smrg xkb->server->num_acts= nActs; 8961ab64890Smrg return &xkb->server->acts[xkb->server->key_acts[key]]; 8971ab64890Smrg} 8981ab64890Smrg 8991ab64890Smrgvoid 9001ab64890SmrgXkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 9011ab64890Smrg{ 9021ab64890SmrgXkbClientMapPtr map; 9031ab64890Smrg 9041ab64890Smrg if ((xkb==NULL)||(xkb->map==NULL)) 9051ab64890Smrg return; 9061ab64890Smrg if (freeMap) 9071ab64890Smrg what= XkbAllClientInfoMask; 9081ab64890Smrg map= xkb->map; 9091ab64890Smrg if (what&XkbKeyTypesMask) { 9101ab64890Smrg if (map->types!=NULL) { 9111ab64890Smrg if (map->num_types>0) { 9121ab64890Smrg register int i; 9131ab64890Smrg XkbKeyTypePtr type; 9141ab64890Smrg for (i=0,type=map->types;i<map->num_types;i++,type++) { 9151ab64890Smrg if (type->map!=NULL) { 9161ab64890Smrg _XkbFree(type->map); 9171ab64890Smrg type->map= NULL; 9181ab64890Smrg } 9191ab64890Smrg if (type->preserve!=NULL) { 9201ab64890Smrg _XkbFree(type->preserve); 9211ab64890Smrg type->preserve= NULL; 9221ab64890Smrg } 9231ab64890Smrg type->map_count= 0; 9241ab64890Smrg if (type->level_names!=NULL) { 9251ab64890Smrg _XkbFree(type->level_names); 9261ab64890Smrg type->level_names= NULL; 9271ab64890Smrg } 9281ab64890Smrg } 9291ab64890Smrg } 9301ab64890Smrg _XkbFree(map->types); 9311ab64890Smrg map->num_types= map->size_types= 0; 9321ab64890Smrg map->types= NULL; 9331ab64890Smrg } 9341ab64890Smrg } 9351ab64890Smrg if (what&XkbKeySymsMask) { 9361ab64890Smrg if (map->key_sym_map!=NULL) { 9371ab64890Smrg _XkbFree(map->key_sym_map); 9381ab64890Smrg map->key_sym_map= NULL; 9391ab64890Smrg } 9401ab64890Smrg if (map->syms!=NULL) { 9411ab64890Smrg _XkbFree(map->syms); 9421ab64890Smrg map->size_syms= map->num_syms= 0; 9431ab64890Smrg map->syms= NULL; 9441ab64890Smrg } 9451ab64890Smrg } 9461ab64890Smrg if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { 9471ab64890Smrg _XkbFree(map->modmap); 9481ab64890Smrg map->modmap= NULL; 9491ab64890Smrg } 9501ab64890Smrg if (freeMap) { 9511ab64890Smrg _XkbFree(xkb->map); 9521ab64890Smrg xkb->map= NULL; 9531ab64890Smrg } 9541ab64890Smrg return; 9551ab64890Smrg} 9561ab64890Smrg 9571ab64890Smrgvoid 9581ab64890SmrgXkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 9591ab64890Smrg{ 9601ab64890SmrgXkbServerMapPtr map; 9611ab64890Smrg 9621ab64890Smrg if ((xkb==NULL)||(xkb->server==NULL)) 9631ab64890Smrg return; 9641ab64890Smrg if (freeMap) 9651ab64890Smrg what= XkbAllServerInfoMask; 9661ab64890Smrg map= xkb->server; 9671ab64890Smrg if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { 9681ab64890Smrg _XkbFree(map->explicit); 9691ab64890Smrg map->explicit= NULL; 9701ab64890Smrg } 9711ab64890Smrg if (what&XkbKeyActionsMask) { 9721ab64890Smrg if (map->key_acts!=NULL) { 9731ab64890Smrg _XkbFree(map->key_acts); 9741ab64890Smrg map->key_acts= NULL; 9751ab64890Smrg } 9761ab64890Smrg if (map->acts!=NULL) { 9771ab64890Smrg _XkbFree(map->acts); 9781ab64890Smrg map->num_acts= map->size_acts= 0; 9791ab64890Smrg map->acts= NULL; 9801ab64890Smrg } 9811ab64890Smrg } 9821ab64890Smrg if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { 9831ab64890Smrg _XkbFree(map->behaviors); 9841ab64890Smrg map->behaviors= NULL; 9851ab64890Smrg } 9861ab64890Smrg if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { 9871ab64890Smrg _XkbFree(map->vmodmap); 9881ab64890Smrg map->vmodmap= NULL; 9891ab64890Smrg } 9901ab64890Smrg 9911ab64890Smrg if (freeMap) { 9921ab64890Smrg _XkbFree(xkb->server); 9931ab64890Smrg xkb->server= NULL; 9941ab64890Smrg } 9951ab64890Smrg return; 9961ab64890Smrg} 997