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