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