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