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