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 free(type->map); 296 type->map= NULL; 297 free(type->preserve); 298 type->preserve= NULL; 299 type->map_count= 0; 300 } 301 else { 302 XkbKTMapEntryRec *prev_map = type->map; 303 304 if ((map_count>type->map_count)||(type->map==NULL)) 305 type->map = realloc(type->map,map_count * sizeof(XkbKTMapEntryRec)); 306 if (!type->map) { 307 free(prev_map); 308 return BadAlloc; 309 } 310 if (want_preserve) { 311 XkbModsRec *prev_preserve = type->preserve; 312 313 if ((map_count>type->map_count)||(type->preserve==NULL)) { 314 type->preserve = realloc(type->preserve, 315 map_count * sizeof(XkbModsRec)); 316 } 317 if (!type->preserve) { 318 free(prev_preserve); 319 return BadAlloc; 320 } 321 } 322 else { 323 free(type->preserve); 324 type->preserve = NULL; 325 } 326 type->map_count= map_count; 327 } 328 329 if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { 330 Atom * prev_level_names = type->level_names; 331 332 type->level_names = realloc(type->level_names, 333 new_num_lvls * sizeof(Atom)); 334 if (!type->level_names) { 335 free(prev_level_names); 336 return BadAlloc; 337 } 338 } 339 /* 340 * Here's the theory: 341 * If the width of the type changed, we might have to resize the symbol 342 * maps for any keys that use the type for one or more groups. This is 343 * expensive, so we'll try to cull out any keys that are obviously okay: 344 * In any case: 345 * - keys that have a group width <= the old width are okay (because 346 * they could not possibly have been associated with the old type) 347 * If the key type increased in size: 348 * - keys that already have a group width >= to the new width are okay 349 * + keys that have a group width >= the old width but < the new width 350 * might have to be enlarged. 351 * If the key type decreased in size: 352 * - keys that have a group width > the old width don't have to be 353 * resized (because they must have some other wider type associated 354 * with some group). 355 * + keys that have a group width == the old width might have to be 356 * shrunk. 357 * The possibilities marked with '+' require us to examine the key types 358 * associated with each group for the key. 359 */ 360 memset(matchingKeys, 0, XkbMaxKeyCount*sizeof(KeyCode)); 361 nMatchingKeys= 0; 362 if (new_num_lvls>type->num_levels) { 363 int nTotal; 364 KeySym * newSyms; 365 int width,match,nResize; 366 register int i,g,nSyms; 367 368 nResize= 0; 369 for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 370 width= XkbKeyGroupsWidth(xkb,i); 371 if (width<type->num_levels) 372 continue; 373 for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 374 if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 375 matchingKeys[nMatchingKeys++]= i; 376 match= 1; 377 } 378 } 379 if ((!match)||(width>=new_num_lvls)) 380 nTotal+= XkbKeyNumSyms(xkb,i); 381 else { 382 nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 383 nResize++; 384 } 385 } 386 if (nResize>0) { 387 int nextMatch; 388 xkb->map->size_syms= (nTotal*15)/10; 389 newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 390 if (newSyms==NULL) 391 return BadAlloc; 392 nextMatch= 0; 393 nSyms= 1; 394 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 395 if (matchingKeys[nextMatch]==i) { 396 KeySym *pOld; 397 nextMatch++; 398 width= XkbKeyGroupsWidth(xkb,i); 399 pOld= XkbKeySymsPtr(xkb,i); 400 for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 401 memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], 402 width*sizeof(KeySym)); 403 } 404 xkb->map->key_sym_map[i].offset= nSyms; 405 nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; 406 } 407 else { 408 memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), 409 XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); 410 xkb->map->key_sym_map[i].offset= nSyms; 411 nSyms+= XkbKeyNumSyms(xkb,i); 412 } 413 } 414 type->num_levels= new_num_lvls; 415 free(xkb->map->syms); 416 xkb->map->syms= newSyms; 417 xkb->map->num_syms= nSyms; 418 return Success; 419 } 420 } 421 else if (new_num_lvls<type->num_levels) { 422 int width,match; 423 register int g,i; 424 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 425 width= XkbKeyGroupsWidth(xkb,i); 426 if (width<type->num_levels) 427 continue; 428 for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { 429 if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { 430 matchingKeys[nMatchingKeys++]= i; 431 match= 1; 432 } 433 } 434 } 435 } 436 if (nMatchingKeys>0) { 437 int key,firstClear; 438 register int i,g; 439 if (new_num_lvls>type->num_levels) 440 firstClear= type->num_levels; 441 else firstClear= new_num_lvls; 442 for (i=0;i<nMatchingKeys;i++) { 443 KeySym * pSyms; 444 int width,nClear; 445 446 key= matchingKeys[i]; 447 width= XkbKeyGroupsWidth(xkb,key); 448 nClear= width-firstClear; 449 pSyms= XkbKeySymsPtr(xkb,key); 450 for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { 451 if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { 452 if (nClear>0) 453 memset(&pSyms[g*width+firstClear], 0, nClear*sizeof(KeySym)); 454 } 455 } 456 } 457 } 458 type->num_levels= new_num_lvls; 459 return Success; 460} 461 462KeySym * 463XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) 464{ 465register int i,nSyms,nKeySyms; 466unsigned nOldSyms; 467KeySym *newSyms; 468 469 if (needed==0) { 470 xkb->map->key_sym_map[key].offset= 0; 471 return xkb->map->syms; 472 } 473 nOldSyms= XkbKeyNumSyms(xkb,key); 474 if (nOldSyms>=(unsigned)needed) { 475 return XkbKeySymsPtr(xkb,key); 476 } 477 if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { 478 if (nOldSyms>0) { 479 memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), 480 nOldSyms*sizeof(KeySym)); 481 } 482 if ((needed-nOldSyms)>0) { 483 memset(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb, key)], 484 0, (needed-nOldSyms)*sizeof(KeySym)); 485 } 486 xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 487 xkb->map->num_syms+= needed; 488 return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 489 } 490 xkb->map->size_syms+= (needed>32?needed:32); 491 newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 492 if (newSyms==NULL) 493 return NULL; 494 newSyms[0]= NoSymbol; 495 nSyms = 1; 496 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 497 int nCopy; 498 499 nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); 500 if ((nKeySyms==0)&&(i!=key)) 501 continue; 502 if (i==key) 503 nKeySyms= needed; 504 if (nCopy!=0) 505 memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); 506 if (nKeySyms>nCopy) 507 memset(&newSyms[nSyms+nCopy], 0, (nKeySyms-nCopy)*sizeof(KeySym)); 508 xkb->map->key_sym_map[i].offset = nSyms; 509 nSyms+= nKeySyms; 510 } 511 free(xkb->map->syms); 512 xkb->map->syms = newSyms; 513 xkb->map->num_syms = nSyms; 514 return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 515} 516 517static unsigned 518_ExtendRange( unsigned int old_flags, 519 unsigned int flag, 520 KeyCode newKC, 521 KeyCode * old_min, 522 unsigned char * old_num) 523{ 524 if ((old_flags&flag)==0) { 525 old_flags|= flag; 526 *old_min= newKC; 527 *old_num= 1; 528 } 529 else { 530 int last= (*old_min)+(*old_num)-1; 531 if (newKC<*old_min) { 532 *old_min= newKC; 533 *old_num= (last-newKC)+1; 534 } 535 else if (newKC>last) { 536 *old_num= (newKC-(*old_min))+1; 537 } 538 } 539 return old_flags; 540} 541 542Status 543XkbChangeKeycodeRange( XkbDescPtr xkb, 544 int minKC, 545 int maxKC, 546 XkbChangesPtr changes) 547{ 548int tmp; 549 550 if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) 551 return BadValue; 552 if (minKC>maxKC) 553 return BadMatch; 554 if (minKC<xkb->min_key_code) { 555 if (changes) 556 changes->map.min_key_code= minKC; 557 tmp= xkb->min_key_code-minKC; 558 if (xkb->map) { 559 if (xkb->map->key_sym_map) { 560 memset((char *)&xkb->map->key_sym_map[minKC], 0, 561 tmp*sizeof(XkbSymMapRec)); 562 if (changes) { 563 changes->map.changed= _ExtendRange(changes->map.changed, 564 XkbKeySymsMask,minKC, 565 &changes->map.first_key_sym, 566 &changes->map.num_key_syms); 567 } 568 } 569 if (xkb->map->modmap) { 570 memset((char *)&xkb->map->modmap[minKC], 0, tmp); 571 if (changes) { 572 changes->map.changed= _ExtendRange(changes->map.changed, 573 XkbModifierMapMask,minKC, 574 &changes->map.first_modmap_key, 575 &changes->map.num_modmap_keys); 576 } 577 } 578 } 579 if (xkb->server) { 580 if (xkb->server->behaviors) { 581 memset((char *)&xkb->server->behaviors[minKC], 0, 582 tmp*sizeof(XkbBehavior)); 583 if (changes) { 584 changes->map.changed= _ExtendRange(changes->map.changed, 585 XkbKeyBehaviorsMask,minKC, 586 &changes->map.first_key_behavior, 587 &changes->map.num_key_behaviors); 588 } 589 } 590 if (xkb->server->key_acts) { 591 memset((char *)&xkb->server->key_acts[minKC], 0, 592 tmp*sizeof(unsigned short)); 593 if (changes) { 594 changes->map.changed= _ExtendRange(changes->map.changed, 595 XkbKeyActionsMask,minKC, 596 &changes->map.first_key_act, 597 &changes->map.num_key_acts); 598 } 599 } 600 if (xkb->server->vmodmap) { 601 memset((char *)&xkb->server->vmodmap[minKC], 0, 602 tmp*sizeof(unsigned short)); 603 if (changes) { 604 changes->map.changed= _ExtendRange(changes->map.changed, 605 XkbVirtualModMapMask,minKC, 606 &changes->map.first_modmap_key, 607 &changes->map.num_vmodmap_keys); 608 } 609 } 610 } 611 if ((xkb->names)&&(xkb->names->keys)) { 612 memset((char *)&xkb->names->keys[minKC], 0, tmp*sizeof(XkbKeyNameRec)); 613 if (changes) { 614 changes->names.changed= _ExtendRange(changes->names.changed, 615 XkbKeyNamesMask,minKC, 616 &changes->names.first_key, 617 &changes->names.num_keys); 618 } 619 } 620 xkb->min_key_code= minKC; 621 } 622 if (maxKC>xkb->max_key_code) { 623 if (changes) 624 changes->map.max_key_code= maxKC; 625 tmp= maxKC-xkb->max_key_code; 626 if (xkb->map) { 627 if (xkb->map->key_sym_map) { 628 XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; 629 630 xkb->map->key_sym_map = realloc(xkb->map->key_sym_map, 631 (maxKC+1) * sizeof(XkbSymMapRec)); 632 if (!xkb->map->key_sym_map) { 633 free(prev_key_sym_map); 634 return BadAlloc; 635 } 636 memset((char *)&xkb->map->key_sym_map[xkb->max_key_code], 0, 637 tmp*sizeof(XkbSymMapRec)); 638 if (changes) { 639 changes->map.changed= _ExtendRange(changes->map.changed, 640 XkbKeySymsMask,maxKC, 641 &changes->map.first_key_sym, 642 &changes->map.num_key_syms); 643 } 644 } 645 if (xkb->map->modmap) { 646 unsigned char *prev_modmap = xkb->map->modmap; 647 648 xkb->map->modmap = realloc(xkb->map->modmap, 649 (maxKC+1) * sizeof(unsigned char)); 650 if (!xkb->map->modmap) { 651 free(prev_modmap); 652 return BadAlloc; 653 } 654 memset((char *)&xkb->map->modmap[xkb->max_key_code], 0, tmp); 655 if (changes) { 656 changes->map.changed= _ExtendRange(changes->map.changed, 657 XkbModifierMapMask,maxKC, 658 &changes->map.first_modmap_key, 659 &changes->map.num_modmap_keys); 660 } 661 } 662 } 663 if (xkb->server) { 664 if (xkb->server->behaviors) { 665 XkbBehavior *prev_behaviors = xkb->server->behaviors; 666 667 xkb->server->behaviors = realloc(xkb->server->behaviors, 668 (maxKC+1) * sizeof(XkbBehavior)); 669 if (!xkb->server->behaviors) { 670 free(prev_behaviors); 671 return BadAlloc; 672 } 673 memset((char *)&xkb->server->behaviors[xkb->max_key_code], 0, 674 tmp*sizeof(XkbBehavior)); 675 if (changes) { 676 changes->map.changed= _ExtendRange(changes->map.changed, 677 XkbKeyBehaviorsMask,maxKC, 678 &changes->map.first_key_behavior, 679 &changes->map.num_key_behaviors); 680 } 681 } 682 if (xkb->server->key_acts) { 683 unsigned short *prev_key_acts = xkb->server->key_acts; 684 685 xkb->server->key_acts= realloc(xkb->server->key_acts, 686 (maxKC+1) * sizeof(unsigned short)); 687 if (!xkb->server->key_acts) { 688 free(prev_key_acts); 689 return BadAlloc; 690 } 691 memset((char *)&xkb->server->key_acts[xkb->max_key_code], 0, 692 tmp*sizeof(unsigned short)); 693 if (changes) { 694 changes->map.changed= _ExtendRange(changes->map.changed, 695 XkbKeyActionsMask,maxKC, 696 &changes->map.first_key_act, 697 &changes->map.num_key_acts); 698 } 699 } 700 if (xkb->server->vmodmap) { 701 unsigned short *prev_vmodmap = xkb->server->vmodmap; 702 703 xkb->server->vmodmap= realloc(xkb->server->vmodmap, 704 (maxKC+1) * sizeof(unsigned short)); 705 if (!xkb->server->vmodmap) { 706 free(prev_vmodmap); 707 return BadAlloc; 708 } 709 memset((char *)&xkb->server->vmodmap[xkb->max_key_code], 0, 710 tmp*sizeof(unsigned short)); 711 if (changes) { 712 changes->map.changed= _ExtendRange(changes->map.changed, 713 XkbVirtualModMapMask,maxKC, 714 &changes->map.first_modmap_key, 715 &changes->map.num_vmodmap_keys); 716 } 717 } 718 } 719 if ((xkb->names)&&(xkb->names->keys)) { 720 XkbKeyNameRec *prev_keys = xkb->names->keys; 721 722 xkb->names->keys = realloc(xkb->names->keys, 723 (maxKC+1) * sizeof(XkbKeyNameRec)); 724 if (!xkb->names->keys) { 725 free(prev_keys); 726 return BadAlloc; 727 } 728 memset((char *)&xkb->names->keys[xkb->max_key_code], 0, 729 tmp*sizeof(XkbKeyNameRec)); 730 if (changes) { 731 changes->names.changed= _ExtendRange(changes->names.changed, 732 XkbKeyNamesMask,maxKC, 733 &changes->names.first_key, 734 &changes->names.num_keys); 735 } 736 } 737 xkb->max_key_code= maxKC; 738 } 739 return Success; 740} 741 742XkbAction * 743XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) 744{ 745register int i,nActs; 746XkbAction *newActs; 747 748 if (needed==0) { 749 xkb->server->key_acts[key]= 0; 750 return NULL; 751 } 752 if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) 753 return XkbKeyActionsPtr(xkb,key); 754 if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { 755 xkb->server->key_acts[key]= xkb->server->num_acts; 756 xkb->server->num_acts+= needed; 757 return &xkb->server->acts[xkb->server->key_acts[key]]; 758 } 759 xkb->server->size_acts= xkb->server->num_acts+needed+8; 760 newActs = calloc(xkb->server->size_acts, sizeof(XkbAction)); 761 if (newActs==NULL) 762 return NULL; 763 newActs[0].type = XkbSA_NoAction; 764 nActs = 1; 765 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 766 int nKeyActs,nCopy; 767 768 if ((xkb->server->key_acts[i]==0)&&(i!=key)) 769 continue; 770 771 nCopy= nKeyActs= XkbKeyNumActions(xkb,i); 772 if (i==key) { 773 nKeyActs= needed; 774 if (needed<nCopy) 775 nCopy= needed; 776 } 777 778 if (nCopy>0) 779 memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), 780 nCopy*sizeof(XkbAction)); 781 if (nCopy<nKeyActs) 782 memset(&newActs[nActs+nCopy], 0, (nKeyActs-nCopy)*sizeof(XkbAction)); 783 xkb->server->key_acts[i]= nActs; 784 nActs+= nKeyActs; 785 } 786 free(xkb->server->acts); 787 xkb->server->acts = newActs; 788 xkb->server->num_acts= nActs; 789 return &xkb->server->acts[xkb->server->key_acts[key]]; 790} 791 792void 793XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 794{ 795XkbClientMapPtr map; 796 797 if ((xkb==NULL)||(xkb->map==NULL)) 798 return; 799 if (freeMap) 800 what= XkbAllClientInfoMask; 801 map= xkb->map; 802 if (what&XkbKeyTypesMask) { 803 if (map->types!=NULL) { 804 if (map->num_types>0) { 805 register int i; 806 XkbKeyTypePtr type; 807 for (i=0,type=map->types;i<map->num_types;i++,type++) { 808 free(type->map); 809 type->map = NULL; 810 free(type->preserve); 811 type->preserve = NULL; 812 type->map_count= 0; 813 free(type->level_names); 814 type->level_names = NULL; 815 } 816 } 817 free(map->types); 818 map->num_types= map->size_types= 0; 819 map->types= NULL; 820 } 821 } 822 if (what&XkbKeySymsMask) { 823 free(map->key_sym_map); 824 map->key_sym_map = NULL; 825 if (map->syms!=NULL) { 826 free(map->syms); 827 map->size_syms= map->num_syms= 0; 828 map->syms= NULL; 829 } 830 } 831 if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { 832 free(map->modmap); 833 map->modmap= NULL; 834 } 835 if (freeMap) { 836 free(xkb->map); 837 xkb->map= NULL; 838 } 839 return; 840} 841 842void 843XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) 844{ 845XkbServerMapPtr map; 846 847 if ((xkb==NULL)||(xkb->server==NULL)) 848 return; 849 if (freeMap) 850 what= XkbAllServerInfoMask; 851 map= xkb->server; 852 if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { 853 free(map->explicit); 854 map->explicit= NULL; 855 } 856 if (what&XkbKeyActionsMask) { 857 free(map->key_acts); 858 map->key_acts = NULL; 859 if (map->acts!=NULL) { 860 free(map->acts); 861 map->num_acts= map->size_acts= 0; 862 map->acts= NULL; 863 } 864 } 865 if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { 866 free(map->behaviors); 867 map->behaviors= NULL; 868 } 869 if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { 870 free(map->vmodmap); 871 map->vmodmap= NULL; 872 } 873 874 if (freeMap) { 875 free(xkb->server); 876 xkb->server= NULL; 877 } 878 return; 879} 880