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