XKBMAlloc.c revision eb411b4b
1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#elif defined(HAVE_CONFIG_H) 30#include <config.h> 31#endif 32 33 34#include <stdio.h> 35#include "Xlibint.h" 36#include <X11/extensions/XKBproto.h> 37#include <X11/keysym.h> 38#include "XKBlibint.h" 39 40 41/***====================================================================***/ 42 43Status 44XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) 45{ 46register int i; 47XkbClientMapPtr map; 48 49 if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) 50 return BadValue; 51 if ((which&XkbKeySymsMask)&& 52 ((!XkbIsLegalKeycode(xkb->min_key_code))|| 53 (!XkbIsLegalKeycode(xkb->max_key_code))|| 54 (xkb->max_key_code<xkb->min_key_code))) { 55#ifdef DEBUG 56fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n", 57 xkb->min_key_code,xkb->max_key_code); 58#endif 59 return BadValue; 60 } 61 62 if (xkb->map==NULL) { 63 map= _XkbTypedCalloc(1,XkbClientMapRec); 64 if (map==NULL) 65 return BadAlloc; 66 xkb->map= map; 67 } 68 else map= xkb->map; 69 70 if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { 71 if (map->types==NULL) { 72 map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); 73 if (map->types==NULL) 74 return BadAlloc; 75 map->num_types= 0; 76 map->size_types= nTotalTypes; 77 } 78 else if (map->size_types<nTotalTypes) { 79 XkbKeyTypeRec *prev_types = map->types; 80 81 map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); 82 if (map->types==NULL) { 83 _XkbFree(prev_types); 84 map->num_types= map->size_types= 0; 85 return BadAlloc; 86 } 87 map->size_types= nTotalTypes; 88 bzero(&map->types[map->num_types], 89 ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); 90 } 91 } 92 if (which&XkbKeySymsMask) { 93 int nKeys= XkbNumKeys(xkb); 94 if (map->syms==NULL) { 95 map->size_syms= (nKeys*15)/10; 96 map->syms= _XkbTypedCalloc(map->size_syms,KeySym); 97 if (!map->syms) { 98 map->size_syms= 0; 99 return BadAlloc; 100 } 101 map->num_syms= 1; 102 map->syms[0]= NoSymbol; 103 } 104 if (map->key_sym_map==NULL) { 105 i= xkb->max_key_code+1; 106 map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); 107 if (map->key_sym_map==NULL) 108 return BadAlloc; 109 } 110 } 111 if (which&XkbModifierMapMask) { 112 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 113 (!XkbIsLegalKeycode(xkb->max_key_code))|| 114 (xkb->max_key_code<xkb->min_key_code)) 115 return BadMatch; 116 if (map->modmap==NULL) { 117 i= xkb->max_key_code+1; 118 map->modmap= _XkbTypedCalloc(i,unsigned char); 119 if (map->modmap==NULL) 120 return BadAlloc; 121 } 122 } 123 return Success; 124} 125 126Status 127XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) 128{ 129register int i; 130XkbServerMapPtr map; 131 132 if (xkb==NULL) 133 return BadMatch; 134 if (xkb->server==NULL) { 135 map= _XkbTypedCalloc(1,XkbServerMapRec); 136 if (map==NULL) 137 return BadAlloc; 138 for (i=0;i<XkbNumVirtualMods;i++) { 139 map->vmods[i]= XkbNoModifierMask; 140 } 141 xkb->server= map; 142 } 143 else map= xkb->server; 144 if (which&XkbExplicitComponentsMask) { 145 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 146 (!XkbIsLegalKeycode(xkb->max_key_code))|| 147 (xkb->max_key_code<xkb->min_key_code)) 148 return BadMatch; 149 if (map->explicit==NULL) { 150 i= xkb->max_key_code+1; 151 map->explicit= _XkbTypedCalloc(i,unsigned char); 152 if (map->explicit==NULL) 153 return BadAlloc; 154 } 155 } 156 if (which&XkbKeyActionsMask) { 157 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 158 (!XkbIsLegalKeycode(xkb->max_key_code))|| 159 (xkb->max_key_code<xkb->min_key_code)) 160 return BadMatch; 161 if (nNewActions<1) 162 nNewActions= 1; 163 if (map->acts==NULL) { 164 map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction); 165 if (map->acts==NULL) 166 return BadAlloc; 167 map->num_acts= 1; 168 map->size_acts= nNewActions+1; 169 } 170 else if ((map->size_acts-map->num_acts)<nNewActions) { 171 unsigned need; 172 XkbAction *prev_acts = map->acts; 173 need= map->num_acts+nNewActions; 174 map->acts= _XkbTypedRealloc(map->acts,need,XkbAction); 175 if (map->acts==NULL) { 176 _XkbFree(prev_acts); 177 map->num_acts= map->size_acts= 0; 178 return BadAlloc; 179 } 180 map->size_acts= need; 181 bzero(&map->acts[map->num_acts], 182 ((map->size_acts-map->num_acts)*sizeof(XkbAction))); 183 } 184 if (map->key_acts==NULL) { 185 i= xkb->max_key_code+1; 186 map->key_acts= _XkbTypedCalloc(i,unsigned short); 187 if (map->key_acts==NULL) 188 return BadAlloc; 189 } 190 } 191 if (which&XkbKeyBehaviorsMask) { 192 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 193 (!XkbIsLegalKeycode(xkb->max_key_code))|| 194 (xkb->max_key_code<xkb->min_key_code)) 195 return BadMatch; 196 if (map->behaviors==NULL) { 197 i= xkb->max_key_code+1; 198 map->behaviors= _XkbTypedCalloc(i,XkbBehavior); 199 if (map->behaviors==NULL) 200 return BadAlloc; 201 } 202 } 203 if (which&XkbVirtualModMapMask) { 204 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 205 (!XkbIsLegalKeycode(xkb->max_key_code))|| 206 (xkb->max_key_code<xkb->min_key_code)) 207 return BadMatch; 208 if (map->vmodmap==NULL) { 209 i= xkb->max_key_code+1; 210 map->vmodmap= _XkbTypedCalloc(i,unsigned short); 211 if (map->vmodmap==NULL) 212 return BadAlloc; 213 } 214 } 215 return Success; 216} 217 218/***====================================================================***/ 219 220Status 221XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) 222{ 223 if ((!from)||(!into)) 224 return BadMatch; 225 if (into->map) { 226 _XkbFree(into->map); 227 into->map= NULL; 228 } 229 if (into->preserve) { 230 _XkbFree(into->preserve); 231 into->preserve= NULL; 232 } 233 if (into->level_names) { 234 _XkbFree(into->level_names); 235 into->level_names= NULL; 236 } 237 *into= *from; 238 if ((from->map)&&(into->map_count>0)) { 239 into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec); 240 if (!into->map) 241 return BadAlloc; 242 memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); 243 } 244 if ((from->preserve)&&(into->map_count>0)) { 245 into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec); 246 if (!into->preserve) 247 return BadAlloc; 248 memcpy(into->preserve,from->preserve, 249 into->map_count*sizeof(XkbModsRec)); 250 } 251 if ((from->level_names)&&(into->num_levels>0)) { 252 into->level_names= _XkbTypedCalloc(into->num_levels,Atom); 253 if (!into->level_names) 254 return BadAlloc; 255 memcpy(into->level_names,from->level_names, 256 into->num_levels*sizeof(Atom)); 257 } 258 return Success; 259} 260 261Status 262XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) 263{ 264register int i,rtrn; 265 266 if ((!from)||(!into)||(num_types<0)) 267 return BadMatch; 268 for (i=0;i<num_types;i++) { 269 if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) 270 return rtrn; 271 } 272 return Success; 273} 274 275XkbKeyTypePtr 276XkbAddKeyType( XkbDescPtr xkb, 277 Atom name, 278 int map_count, 279 Bool want_preserve, 280 int num_lvls) 281{ 282register int i; 283unsigned tmp; 284XkbKeyTypePtr type; 285XkbClientMapPtr map; 286 287 if ((!xkb)||(num_lvls<1)) 288 return NULL; 289 map= xkb->map; 290 if ((map)&&(map->types)) { 291 for (i=0;i<map->num_types;i++) { 292 if (map->types[i].name==name) { 293 Status status; 294 status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); 295 return (status==Success?&map->types[i]:NULL); 296 } 297 } 298 } 299 if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) { 300 tmp= XkbNumRequiredTypes+1; 301 if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success) 302 return NULL; 303 if (!map) 304 map = xkb->map; 305 tmp= 0; 306 if (map->num_types<=XkbKeypadIndex) 307 tmp|= XkbKeypadMask; 308 if (map->num_types<=XkbAlphabeticIndex) 309 tmp|= XkbAlphabeticMask; 310 if (map->num_types<=XkbTwoLevelIndex) 311 tmp|= XkbTwoLevelMask; 312 if (map->num_types<=XkbOneLevelIndex) 313 tmp|= XkbOneLevelMask; 314 if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) { 315 for (i=0;i<map->num_types;i++) { 316 Status status; 317 if (map->types[i].name!=name) 318 continue; 319 status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); 320 return (status==Success?&map->types[i]:NULL); 321 } 322 } 323 } 324 if ((map->num_types<=map->size_types)&& 325 (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) { 326 return NULL; 327 } 328 type= &map->types[map->num_types]; 329 map->num_types++; 330 bzero((char *)type,sizeof(XkbKeyTypeRec)); 331 type->num_levels= num_lvls; 332 type->map_count= map_count; 333 type->name= name; 334 if (map_count>0) { 335 type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec); 336 if (!type->map) { 337 map->num_types--; 338 return NULL; 339 } 340 if (want_preserve) { 341 type->preserve= _XkbTypedCalloc(map_count,XkbModsRec); 342 if (!type->preserve) { 343 _XkbFree(type->map); 344 map->num_types--; 345 return NULL; 346 } 347 } 348 } 349 return type; 350} 351 352Status 353XkbResizeKeyType( XkbDescPtr xkb, 354 int type_ndx, 355 int map_count, 356 Bool want_preserve, 357 int new_num_lvls) 358{ 359XkbKeyTypePtr type; 360KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; 361 362 if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| 363 (new_num_lvls<1)) 364 return BadValue; 365 switch (type_ndx) { 366 case XkbOneLevelIndex: 367 if (new_num_lvls!=1) 368 return BadMatch; 369 break; 370 case XkbTwoLevelIndex: 371 case XkbAlphabeticIndex: 372 case XkbKeypadIndex: 373 if (new_num_lvls!=2) 374 return BadMatch; 375 break; 376 } 377 type= &xkb->map->types[type_ndx]; 378 if (map_count==0) { 379 if (type->map!=NULL) 380 _XkbFree(type->map); 381 type->map= NULL; 382 if (type->preserve!=NULL) 383 _XkbFree(type->preserve); 384 type->preserve= NULL; 385 type->map_count= 0; 386 } 387 else { 388 XkbKTMapEntryRec *prev_map = type->map; 389 390 if ((map_count>type->map_count)||(type->map==NULL)) 391 type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec); 392 if (!type->map) { 393 if (prev_map) 394 _XkbFree(prev_map); 395 return BadAlloc; 396 } 397 if (want_preserve) { 398 XkbModsRec *prev_preserve = type->preserve; 399 400 if ((map_count>type->map_count)||(type->preserve==NULL)) { 401 type->preserve= _XkbTypedRealloc(type->preserve,map_count, 402 XkbModsRec); 403 } 404 if (!type->preserve) { 405 if (prev_preserve) 406 _XkbFree(prev_preserve); 407 return BadAlloc; 408 } 409 } 410 else if (type->preserve!=NULL) { 411 _XkbFree(type->preserve); 412 type->preserve= NULL; 413 } 414 type->map_count= map_count; 415 } 416 417 if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { 418 Atom * prev_level_names = type->level_names; 419 420 type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom); 421 if (!type->level_names) { 422 if (prev_level_names) 423 _XkbFree(prev_level_names); 424 return BadAlloc; 425 } 426 } 427 /* 428 * Here's the theory: 429 * If the width of the type changed, we might have to resize the symbol 430 * maps for any keys that use the type for one or more groups. This is 431 * expensive, so we'll try to cull out any keys that are obviously okay: 432 * In any case: 433 * - keys that have a group width <= the old width are okay (because 434 * they could not possibly have been associated with the old type) 435 * If the key type increased in size: 436 * - keys that already have a group width >= to the new width are okay 437 * + keys that have a group width >= the old width but < the new width 438 * might have to be enlarged. 439 * If the key type decreased in size: 440 * - keys that have a group width > the old width don't have to be 441 * resized (because they must have some other wider type associated 442 * with some group). 443 * + keys that have a group width == the old width might have to be 444 * shrunk. 445 * The possibilities marked with '+' require us to examine the key types 446 * associated with each group for the key. 447 */ 448 bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode)); 449 nMatchingKeys= 0; 450 if (new_num_lvls>type->num_levels) { 451 int nTotal; 452 KeySym * newSyms; 453 int width,match,nResize; 454 register int i,g,nSyms; 455 456 nResize= 0; 457 for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 458 width= XkbKeyGroupsWidth(xkb,i); 459 if (width<type->num_levels) 460 continue; 461 for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 462 if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 463 matchingKeys[nMatchingKeys++]= i; 464 match= 1; 465 } 466 } 467 if ((!match)||(width>=new_num_lvls)) 468 nTotal+= XkbKeyNumSyms(xkb,i); 469 else { 470 nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 471 nResize++; 472 } 473 } 474 if (nResize>0) { 475 int nextMatch; 476 xkb->map->size_syms= (nTotal*12)/10; 477 newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 478 if (newSyms==NULL) 479 return BadAlloc; 480 nextMatch= 0; 481 nSyms= 1; 482 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 483 if (matchingKeys[nextMatch]==i) { 484 KeySym *pOld; 485 nextMatch++; 486 width= XkbKeyGroupsWidth(xkb,i); 487 pOld= XkbKeySymsPtr(xkb,i); 488 for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 489 memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], 490 width*sizeof(KeySym)); 491 } 492 xkb->map->key_sym_map[i].offset= nSyms; 493 nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 494 } 495 else { 496 memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), 497 XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); 498 xkb->map->key_sym_map[i].offset= nSyms; 499 nSyms+= XkbKeyNumSyms(xkb,i); 500 } 501 } 502 type->num_levels= new_num_lvls; 503 _XkbFree(xkb->map->syms); 504 xkb->map->syms= newSyms; 505 xkb->map->num_syms= nSyms; 506 return Success; 507 } 508 } 509 else if (new_num_lvls<type->num_levels) { 510 int width,match; 511 register int g,i; 512 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 513 width= XkbKeyGroupsWidth(xkb,i); 514 if (width<type->num_levels) 515 continue; 516 for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 517 if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 518 matchingKeys[nMatchingKeys++]= i; 519 match= 1; 520 } 521 } 522 } 523 } 524 if (nMatchingKeys>0) { 525 int key,firstClear; 526 register int i,g; 527 if (new_num_lvls>type->num_levels) 528 firstClear= type->num_levels; 529 else firstClear= new_num_lvls; 530 for (i=0;i<nMatchingKeys;i++) { 531 KeySym * pSyms; 532 int width,nClear; 533 534 key= matchingKeys[i]; 535 width= XkbKeyGroupsWidth(xkb,key); 536 nClear= width-firstClear; 537 pSyms= XkbKeySymsPtr(xkb,key); 538 for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { 539 if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { 540 if (nClear>0) 541 bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym)); 542 } 543 } 544 } 545 } 546 type->num_levels= new_num_lvls; 547 return Success; 548} 549 550KeySym * 551XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) 552{ 553register int i,nSyms,nKeySyms; 554unsigned nOldSyms; 555KeySym *newSyms; 556 557 if (needed==0) { 558 xkb->map->key_sym_map[key].offset= 0; 559 return xkb->map->syms; 560 } 561 nOldSyms= XkbKeyNumSyms(xkb,key); 562 if (nOldSyms>=(unsigned)needed) { 563 return XkbKeySymsPtr(xkb,key); 564 } 565 if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { 566 if (nOldSyms>0) { 567 memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), 568 nOldSyms*sizeof(KeySym)); 569 } 570 if ((needed-nOldSyms)>0) { 571 bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)], 572 (needed-nOldSyms)*sizeof(KeySym)); 573 } 574 xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 575 xkb->map->num_syms+= needed; 576 return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 577 } 578 xkb->map->size_syms+= (needed>32?needed:32); 579 newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); 580 if (newSyms==NULL) 581 return NULL; 582 newSyms[0]= NoSymbol; 583 nSyms = 1; 584 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 585 int nCopy; 586 587 nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); 588 if ((nKeySyms==0)&&(i!=key)) 589 continue; 590 if (i==key) 591 nKeySyms= needed; 592 if (nCopy!=0) 593 memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); 594 if (nKeySyms>nCopy) 595 bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym)); 596 xkb->map->key_sym_map[i].offset = nSyms; 597 nSyms+= nKeySyms; 598 } 599 _XkbFree(xkb->map->syms); 600 xkb->map->syms = newSyms; 601 xkb->map->num_syms = nSyms; 602 return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 603} 604 605static unsigned 606_ExtendRange( unsigned int old_flags, 607 unsigned int flag, 608 KeyCode newKC, 609 KeyCode * old_min, 610 unsigned char * old_num) 611{ 612 if ((old_flags&flag)==0) { 613 old_flags|= flag; 614 *old_min= newKC; 615 *old_num= 1; 616 } 617 else { 618 int last= (*old_min)+(*old_num)-1; 619 if (newKC<*old_min) { 620 *old_min= newKC; 621 *old_num= (last-newKC)+1; 622 } 623 else if (newKC>last) { 624 *old_num= (newKC-(*old_min))+1; 625 } 626 } 627 return old_flags; 628} 629 630Status 631XkbChangeKeycodeRange( XkbDescPtr xkb, 632 int minKC, 633 int maxKC, 634 XkbChangesPtr changes) 635{ 636int tmp; 637 638 if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) 639 return BadValue; 640 if (minKC>maxKC) 641 return BadMatch; 642 if (minKC<xkb->min_key_code) { 643 if (changes) 644 changes->map.min_key_code= minKC; 645 tmp= xkb->min_key_code-minKC; 646 if (xkb->map) { 647 if (xkb->map->key_sym_map) { 648 bzero((char *)&xkb->map->key_sym_map[minKC], 649 tmp*sizeof(XkbSymMapRec)); 650 if (changes) { 651 changes->map.changed= _ExtendRange(changes->map.changed, 652 XkbKeySymsMask,minKC, 653 &changes->map.first_key_sym, 654 &changes->map.num_key_syms); 655 } 656 } 657 if (xkb->map->modmap) { 658 bzero((char *)&xkb->map->modmap[minKC],tmp); 659 if (changes) { 660 changes->map.changed= _ExtendRange(changes->map.changed, 661 XkbModifierMapMask,minKC, 662 &changes->map.first_modmap_key, 663 &changes->map.num_modmap_keys); 664 } 665 } 666 } 667 if (xkb->server) { 668 if (xkb->server->behaviors) { 669 bzero((char *)&xkb->server->behaviors[minKC], 670 tmp*sizeof(XkbBehavior)); 671 if (changes) { 672 changes->map.changed= _ExtendRange(changes->map.changed, 673 XkbKeyBehaviorsMask,minKC, 674 &changes->map.first_key_behavior, 675 &changes->map.num_key_behaviors); 676 } 677 } 678 if (xkb->server->key_acts) { 679 bzero((char *)&xkb->server->key_acts[minKC], 680 tmp*sizeof(unsigned short)); 681 if (changes) { 682 changes->map.changed= _ExtendRange(changes->map.changed, 683 XkbKeyActionsMask,minKC, 684 &changes->map.first_key_act, 685 &changes->map.num_key_acts); 686 } 687 } 688 if (xkb->server->vmodmap) { 689 bzero((char *)&xkb->server->vmodmap[minKC], 690 tmp*sizeof(unsigned short)); 691 if (changes) { 692 changes->map.changed= _ExtendRange(changes->map.changed, 693 XkbVirtualModMapMask,minKC, 694 &changes->map.first_modmap_key, 695 &changes->map.num_vmodmap_keys); 696 } 697 } 698 } 699 if ((xkb->names)&&(xkb->names->keys)) { 700 bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec)); 701 if (changes) { 702 changes->names.changed= _ExtendRange(changes->names.changed, 703 XkbKeyNamesMask,minKC, 704 &changes->names.first_key, 705 &changes->names.num_keys); 706 } 707 } 708 xkb->min_key_code= minKC; 709 } 710 if (maxKC>xkb->max_key_code) { 711 if (changes) 712 changes->map.max_key_code= maxKC; 713 tmp= maxKC-xkb->max_key_code; 714 if (xkb->map) { 715 if (xkb->map->key_sym_map) { 716 XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 717 718 xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map, 719 (maxKC+1),XkbSymMapRec); 720 if (!xkb->map->key_sym_map) { 721 _XkbFree(prev_key_sym_map); 722 return BadAlloc; 723 } 724 bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], 725 tmp*sizeof(XkbSymMapRec)); 726 if (changes) { 727 changes->map.changed= _ExtendRange(changes->map.changed, 728 XkbKeySymsMask,maxKC, 729 &changes->map.first_key_sym, 730 &changes->map.num_key_syms); 731 } 732 } 733 if (xkb->map->modmap) { 734 unsigned char *prev_modmap = xkb->map->modmap; 735 736 xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap, 737 (maxKC+1),unsigned char); 738 if (!xkb->map->modmap) { 739 _XkbFree(prev_modmap); 740 return BadAlloc; 741 } 742 bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); 743 if (changes) { 744 changes->map.changed= _ExtendRange(changes->map.changed, 745 XkbModifierMapMask,maxKC, 746 &changes->map.first_modmap_key, 747 &changes->map.num_modmap_keys); 748 } 749 } 750 } 751 if (xkb->server) { 752 if (xkb->server->behaviors) { 753 XkbBehavior *prev_behaviors = xkb->server->behaviors; 754 755 xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors, 756 (maxKC+1),XkbBehavior); 757 if (!xkb->server->behaviors) { 758 _XkbFree(prev_behaviors); 759 return BadAlloc; 760 } 761 bzero((char *)&xkb->server->behaviors[xkb->max_key_code], 762 tmp*sizeof(XkbBehavior)); 763 if (changes) { 764 changes->map.changed= _ExtendRange(changes->map.changed, 765 XkbKeyBehaviorsMask,maxKC, 766 &changes->map.first_key_behavior, 767 &changes->map.num_key_behaviors); 768 } 769 } 770 if (xkb->server->key_acts) { 771 unsigned short *prev_key_acts = xkb->server->key_acts; 772 773 xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts, 774 (maxKC+1),unsigned short); 775 if (!xkb->server->key_acts) { 776 _XkbFree(prev_key_acts); 777 return BadAlloc; 778 } 779 bzero((char *)&xkb->server->key_acts[xkb->max_key_code], 780 tmp*sizeof(unsigned short)); 781 if (changes) { 782 changes->map.changed= _ExtendRange(changes->map.changed, 783 XkbKeyActionsMask,maxKC, 784 &changes->map.first_key_act, 785 &changes->map.num_key_acts); 786 } 787 } 788 if (xkb->server->vmodmap) { 789 unsigned short *prev_vmodmap = xkb->server->vmodmap; 790 791 xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap, 792 (maxKC+1),unsigned short); 793 if (!xkb->server->vmodmap) { 794 _XkbFree(prev_vmodmap); 795 return BadAlloc; 796 } 797 bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], 798 tmp*sizeof(unsigned short)); 799 if (changes) { 800 changes->map.changed= _ExtendRange(changes->map.changed, 801 XkbVirtualModMapMask,maxKC, 802 &changes->map.first_modmap_key, 803 &changes->map.num_vmodmap_keys); 804 } 805 } 806 } 807 if ((xkb->names)&&(xkb->names->keys)) { 808 XkbKeyNameRec *prev_keys = xkb->names->keys; 809 810 xkb->names->keys= _XkbTypedRealloc(xkb->names->keys, 811 (maxKC+1),XkbKeyNameRec); 812 if (!xkb->names->keys) { 813 _XkbFree(prev_keys); 814 return BadAlloc; 815 } 816 bzero((char *)&xkb->names->keys[xkb->max_key_code], 817 tmp*sizeof(XkbKeyNameRec)); 818 if (changes) { 819 changes->names.changed= _ExtendRange(changes->names.changed, 820 XkbKeyNamesMask,maxKC, 821 &changes->names.first_key, 822 &changes->names.num_keys); 823 } 824 } 825 xkb->max_key_code= maxKC; 826 } 827 return Success; 828} 829 830XkbAction * 831XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) 832{ 833register int i,nActs; 834XkbAction *newActs; 835 836 if (needed==0) { 837 xkb->server->key_acts[key]= 0; 838 return NULL; 839 } 840 if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) 841 return XkbKeyActionsPtr(xkb,key); 842 if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { 843 xkb->server->key_acts[key]= xkb->server->num_acts; 844 xkb->server->num_acts+= needed; 845 return &xkb->server->acts[xkb->server->key_acts[key]]; 846 } 847 xkb->server->size_acts= xkb->server->num_acts+needed+8; 848 newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction); 849 if (newActs==NULL) 850 return NULL; 851 newActs[0].type = XkbSA_NoAction; 852 nActs = 1; 853 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 854 int nKeyActs,nCopy; 855 856 if ((xkb->server->key_acts[i]==0)&&(i!=key)) 857 continue; 858 859 nCopy= nKeyActs= XkbKeyNumActions(xkb,i); 860 if (i==key) { 861 nKeyActs= needed; 862 if (needed<nCopy) 863 nCopy= needed; 864 } 865 866 if (nCopy>0) 867 memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), 868 nCopy*sizeof(XkbAction)); 869 if (nCopy<nKeyActs) 870 bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction)); 871 xkb->server->key_acts[i]= nActs; 872 nActs+= nKeyActs; 873 } 874 _XkbFree(xkb->server->acts); 875 xkb->server->acts = newActs; 876 xkb->server->num_acts= nActs; 877 return &xkb->server->acts[xkb->server->key_acts[key]]; 878} 879 880void 881XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 882{ 883XkbClientMapPtr map; 884 885 if ((xkb==NULL)||(xkb->map==NULL)) 886 return; 887 if (freeMap) 888 what= XkbAllClientInfoMask; 889 map= xkb->map; 890 if (what&XkbKeyTypesMask) { 891 if (map->types!=NULL) { 892 if (map->num_types>0) { 893 register int i; 894 XkbKeyTypePtr type; 895 for (i=0,type=map->types;i<map->num_types;i++,type++) { 896 if (type->map!=NULL) { 897 _XkbFree(type->map); 898 type->map= NULL; 899 } 900 if (type->preserve!=NULL) { 901 _XkbFree(type->preserve); 902 type->preserve= NULL; 903 } 904 type->map_count= 0; 905 if (type->level_names!=NULL) { 906 _XkbFree(type->level_names); 907 type->level_names= NULL; 908 } 909 } 910 } 911 _XkbFree(map->types); 912 map->num_types= map->size_types= 0; 913 map->types= NULL; 914 } 915 } 916 if (what&XkbKeySymsMask) { 917 if (map->key_sym_map!=NULL) { 918 _XkbFree(map->key_sym_map); 919 map->key_sym_map= NULL; 920 } 921 if (map->syms!=NULL) { 922 _XkbFree(map->syms); 923 map->size_syms= map->num_syms= 0; 924 map->syms= NULL; 925 } 926 } 927 if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { 928 _XkbFree(map->modmap); 929 map->modmap= NULL; 930 } 931 if (freeMap) { 932 _XkbFree(xkb->map); 933 xkb->map= NULL; 934 } 935 return; 936} 937 938void 939XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 940{ 941XkbServerMapPtr map; 942 943 if ((xkb==NULL)||(xkb->server==NULL)) 944 return; 945 if (freeMap) 946 what= XkbAllServerInfoMask; 947 map= xkb->server; 948 if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { 949 _XkbFree(map->explicit); 950 map->explicit= NULL; 951 } 952 if (what&XkbKeyActionsMask) { 953 if (map->key_acts!=NULL) { 954 _XkbFree(map->key_acts); 955 map->key_acts= NULL; 956 } 957 if (map->acts!=NULL) { 958 _XkbFree(map->acts); 959 map->num_acts= map->size_acts= 0; 960 map->acts= NULL; 961 } 962 } 963 if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { 964 _XkbFree(map->behaviors); 965 map->behaviors= NULL; 966 } 967 if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { 968 _XkbFree(map->vmodmap); 969 map->vmodmap= NULL; 970 } 971 972 if (freeMap) { 973 _XkbFree(xkb->server); 974 xkb->server= NULL; 975 } 976 return; 977} 978