XKBNames.c revision 0f8248bf
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#define NEED_MAP_READERS 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include "Xlibint.h" 32#include <X11/extensions/XKBproto.h> 33#include "XKBlibint.h" 34 35 36static Status 37_XkbReadAtoms(XkbReadBufferPtr buf, 38 Atom *atoms, 39 int maxAtoms, 40 CARD32 present) 41{ 42 register int i, bit; 43 44 for (i = 0, bit = 1; (i < maxAtoms) && (present); i++, bit <<= 1) { 45 if (present & bit) { 46 if (!_XkbReadBufferCopy32(buf, (long *) &atoms[i], 1)) 47 return BadLength; 48 present &= ~bit; 49 } 50 } 51 return Success; 52} 53 54Status 55_XkbReadGetNamesReply(Display *dpy, 56 xkbGetNamesReply *rep, 57 XkbDescPtr xkb, 58 int *nread_rtrn) 59{ 60 int i, len; 61 XkbReadBufferRec buf; 62 register XkbNamesPtr names; 63 64 if (xkb->device_spec == XkbUseCoreKbd) 65 xkb->device_spec = rep->deviceID; 66 67 if ((xkb->names == NULL) && 68 (XkbAllocNames(xkb, rep->which, 69 rep->nRadioGroups, rep->nKeyAliases) != Success)) { 70 return BadAlloc; 71 } 72 names = xkb->names; 73 if (rep->length == 0) 74 return Success; 75 76 if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) 77 return BadAlloc; 78 if (nread_rtrn) 79 *nread_rtrn = (int) rep->length * 4; 80 81 if ((rep->which & XkbKeycodesNameMask) && 82 (!_XkbReadBufferCopy32(&buf, (long *) &names->keycodes, 1))) 83 goto BAILOUT; 84 if ((rep->which & XkbGeometryNameMask) && 85 (!_XkbReadBufferCopy32(&buf, (long *) &names->geometry, 1))) 86 goto BAILOUT; 87 if ((rep->which & XkbSymbolsNameMask) && 88 (!_XkbReadBufferCopy32(&buf, (long *) &names->symbols, 1))) 89 goto BAILOUT; 90 if ((rep->which & XkbPhysSymbolsNameMask) && 91 (!_XkbReadBufferCopy32(&buf, (long *) &names->phys_symbols, 1))) 92 goto BAILOUT; 93 if ((rep->which & XkbTypesNameMask) && 94 (!_XkbReadBufferCopy32(&buf, (long *) &names->types, 1))) 95 goto BAILOUT; 96 if ((rep->which & XkbCompatNameMask) && 97 (!_XkbReadBufferCopy32(&buf, (long *) &names->compat, 1))) 98 goto BAILOUT; 99 100 if (rep->which & XkbKeyTypeNamesMask) { 101 XkbClientMapPtr map = xkb->map; 102 XkbKeyTypePtr type; 103 104 len = rep->nTypes * 4; 105 if (map != NULL) { 106 type = map->types; 107 for (i = 0; (i < map->num_types) && (i < rep->nTypes); i++, type++) { 108 if (!_XkbReadBufferCopy32(&buf, (long *) &type->name, 1)) 109 goto BAILOUT; 110 len -= 4; 111 } 112 } 113 if ((len > 0) && (!_XkbSkipReadBufferData(&buf, len))) 114 goto BAILOUT; 115 } 116 if (rep->which & XkbKTLevelNamesMask) { 117 CARD8 *nLevels; 118 XkbClientMapPtr map = xkb->map; 119 120 nLevels = 121 (CARD8 *) _XkbGetReadBufferPtr(&buf, XkbPaddedSize(rep->nTypes)); 122 if (nLevels == NULL) 123 goto BAILOUT; 124 if (map != NULL) { 125 XkbKeyTypePtr type = map->types; 126 127 for (i = 0; i < (int) rep->nTypes; i++, type++) { 128 if (i >= map->num_types) { 129 if (!_XkbSkipReadBufferData(&buf, nLevels[i] * 4)) 130 goto BAILOUT; 131 continue; 132 } 133 if ((nLevels[i] > 0) && (nLevels[i] != type->num_levels)) { 134 goto BAILOUT; 135 } 136 137 Xfree(type->level_names); 138 if (nLevels[i] == 0) { 139 type->level_names = NULL; 140 continue; 141 } 142 type->level_names = _XkbTypedCalloc(nLevels[i], Atom); 143 if (type->level_names != NULL) { 144 if (!_XkbReadBufferCopy32(&buf, (long *) type->level_names, 145 nLevels[i])) 146 goto BAILOUT; 147 } 148 else { 149 _XkbSkipReadBufferData(&buf, nLevels[i] * 4); 150 } 151 } 152 } 153 else { 154 for (i = 0; i < (int) rep->nTypes; i++) { 155 _XkbSkipReadBufferData(&buf, nLevels[i] * 4); 156 } 157 } 158 } 159 if (rep->which & XkbIndicatorNamesMask) { 160 if (_XkbReadAtoms(&buf, names->indicators, XkbNumIndicators, 161 rep->indicators) != Success) 162 goto BAILOUT; 163 } 164 if (rep->which & XkbVirtualModNamesMask) { 165 if (_XkbReadAtoms(&buf, names->vmods, XkbNumVirtualMods, 166 (CARD32) rep->virtualMods) != Success) 167 goto BAILOUT; 168 } 169 if (rep->which & XkbGroupNamesMask) { 170 if (_XkbReadAtoms(&buf, names->groups, XkbNumKbdGroups, 171 (CARD32) rep->groupNames) != Success) 172 goto BAILOUT; 173 } 174 if (rep->which & XkbKeyNamesMask) { 175 if (names->keys == NULL) { 176 int nKeys; 177 178 if (xkb->max_key_code == 0) { 179 xkb->min_key_code = rep->minKeyCode; 180 xkb->max_key_code = rep->maxKeyCode; 181 } 182 nKeys = xkb->max_key_code + 1; 183 names->keys = _XkbTypedCalloc(nKeys, XkbKeyNameRec); 184 } 185 if (((int) rep->firstKey + rep->nKeys) > xkb->max_key_code + 1) 186 goto BAILOUT; 187 if (names->keys != NULL) { 188 if (!_XkbCopyFromReadBuffer(&buf, 189 (char *) &names->keys[rep->firstKey], 190 rep->nKeys * XkbKeyNameLength)) 191 goto BAILOUT; 192 } 193 else 194 _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength); 195 } 196 if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) { 197 if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) != 198 Success) 199 goto BAILOUT; 200 if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases, 201 rep->nKeyAliases * XkbKeyNameLength * 2)) 202 goto BAILOUT; 203 } 204 if (rep->which & XkbRGNamesMask) { 205 if (rep->nRadioGroups > 0) { 206 Atom *rgNames; 207 208 if (names->radio_groups == NULL) 209 names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups, Atom); 210 else if (names->num_rg < rep->nRadioGroups) { 211 names->radio_groups = _XkbTypedRealloc(names->radio_groups, 212 rep->nRadioGroups, Atom); 213 } 214 rgNames = names->radio_groups; 215 if (!rgNames) { 216 goto BAILOUT; 217 } 218 if (!_XkbReadBufferCopy32 219 (&buf, (long *) rgNames, rep->nRadioGroups)) 220 goto BAILOUT; 221 names->num_rg = rep->nRadioGroups; 222 } 223 else if (names->num_rg > 0) { 224 names->num_rg = 0; 225 Xfree(names->radio_groups); 226 } 227 } 228 len = _XkbFreeReadBuffer(&buf); 229 if (len != 0) 230 return BadLength; 231 else 232 return Success; 233 BAILOUT: 234 _XkbFreeReadBuffer(&buf); 235 return BadLength; 236} 237 238Status 239XkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb) 240{ 241 register xkbGetNamesReq *req; 242 xkbGetNamesReply rep; 243 Status status; 244 XkbInfoPtr xkbi; 245 246 if ((dpy->flags & XlibDisplayNoXkb) || 247 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 248 return BadAccess; 249 LockDisplay(dpy); 250 xkbi = dpy->xkb_info; 251 if (!xkb->names) { 252 xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 253 if (!xkb->names) { 254 UnlockDisplay(dpy); 255 SyncHandle(); 256 return BadAlloc; 257 } 258 } 259 GetReq(kbGetNames, req); 260 req->reqType = xkbi->codes->major_opcode; 261 req->xkbReqType = X_kbGetNames; 262 req->deviceSpec = xkb->device_spec; 263 req->which = which; 264 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 265 UnlockDisplay(dpy); 266 SyncHandle(); 267 return BadImplementation; 268 } 269 270 status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL); 271 UnlockDisplay(dpy); 272 SyncHandle(); 273 return status; 274} 275 276/***====================================================================***/ 277 278static int 279_XkbCountBits(int nBitsMax, unsigned long mask) 280{ 281 register unsigned long y, nBits; 282 283 y = (mask >> 1) & 033333333333; 284 y = mask - y - ((y >> 1) & 033333333333); 285 nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); 286 287 /* nBitsMax really means max+1 */ 288 return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); 289} 290 291static CARD32 292_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 293{ 294 register unsigned int i, bit, nAtoms; 295 register CARD32 atomsPresent; 296 297 for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 298 if (atoms[i] != None) { 299 atomsPresent |= bit; 300 nAtoms++; 301 } 302 } 303 if (count) 304 *count = nAtoms; 305 return atomsPresent; 306} 307 308static void 309_XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms) 310{ 311 register unsigned int i, bit; 312 313 for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 314 if (mask & bit) 315 Data32(dpy, &atoms[i], 4); 316 } 317 return; 318} 319 320Bool 321XkbSetNames(Display *dpy, 322 unsigned int which, 323 unsigned int firstType, 324 unsigned int nTypes, 325 XkbDescPtr xkb) 326{ 327 register xkbSetNamesReq *req; 328 int nLvlNames = 0; 329 XkbInfoPtr xkbi; 330 XkbNamesPtr names; 331 unsigned firstLvlType, nLvlTypes; 332 int nVMods, nLEDs, nRG, nKA, nGroups; 333 int nKeys = 0, firstKey = 0, nAtoms; 334 CARD32 leds, vmods, groups; 335 336 if ((dpy->flags & XlibDisplayNoXkb) || 337 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 338 return False; 339 if ((!xkb) || (!xkb->names)) 340 return False; 341 firstLvlType = firstType; 342 nLvlTypes = nTypes; 343 if (nTypes < 1) 344 which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask); 345 else if (firstType <= XkbLastRequiredType) { 346 int adjust; 347 348 adjust = XkbLastRequiredType - firstType + 1; 349 firstType += adjust; 350 nTypes -= adjust; 351 if (nTypes < 1) 352 which &= ~XkbKeyTypeNamesMask; 353 } 354 names = xkb->names; 355 if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 356 register int i; 357 XkbKeyTypePtr type; 358 359 if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 360 (firstType + nTypes > xkb->map->num_types) || 361 (firstLvlType + nLvlTypes > xkb->map->num_types)) 362 return False; 363 if (which & XkbKTLevelNamesMask) { 364 type = &xkb->map->types[firstLvlType]; 365 for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 366 if (type->level_names != NULL) 367 nLvlNames += type->num_levels; 368 } 369 } 370 } 371 372 nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 373 LockDisplay(dpy); 374 xkbi = dpy->xkb_info; 375 GetReq(kbSetNames, req); 376 req->reqType = xkbi->codes->major_opcode; 377 req->xkbReqType = X_kbSetNames; 378 req->deviceSpec = xkb->device_spec; 379 req->firstType = firstType; 380 req->nTypes = nTypes; 381 req->firstKey = xkb->min_key_code; 382 req->nKeys = xkb->max_key_code - xkb->min_key_code + 1; 383 384 if (which & XkbKeycodesNameMask) 385 nAtoms++; 386 if (which & XkbGeometryNameMask) 387 nAtoms++; 388 if (which & XkbSymbolsNameMask) 389 nAtoms++; 390 if (which & XkbPhysSymbolsNameMask) 391 nAtoms++; 392 if (which & XkbTypesNameMask) 393 nAtoms++; 394 if (which & XkbCompatNameMask) 395 nAtoms++; 396 if (which & XkbKeyTypeNamesMask) 397 nAtoms += nTypes; 398 if (which & XkbKTLevelNamesMask) { 399 req->firstKTLevel = firstLvlType; 400 req->nKTLevels = nLvlTypes; 401 req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 402 nAtoms += nLvlNames; 403 } 404 else 405 req->firstKTLevel = req->nKTLevels = 0; 406 407 if (which & XkbIndicatorNamesMask) { 408 req->indicators = leds = 409 _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs); 410 if (nLEDs > 0) 411 nAtoms += nLEDs; 412 else 413 which &= ~XkbIndicatorNamesMask; 414 } 415 else 416 req->indicators = leds = 0; 417 418 if (which & XkbVirtualModNamesMask) { 419 vmods = req->virtualMods = (CARD16) 420 _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods); 421 if (nVMods > 0) 422 nAtoms += nVMods; 423 else 424 which &= ~XkbVirtualModNamesMask; 425 } 426 else 427 vmods = req->virtualMods = 0; 428 429 if (which & XkbGroupNamesMask) { 430 groups = req->groupNames = (CARD8) 431 _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups); 432 if (nGroups > 0) 433 nAtoms += nGroups; 434 else 435 which &= ~XkbGroupNamesMask; 436 } 437 else 438 groups = req->groupNames = 0; 439 440 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 441 firstKey = req->firstKey; 442 nKeys = req->nKeys; 443 nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 444 } 445 else 446 which &= ~XkbKeyNamesMask; 447 448 if (which & XkbKeyAliasesMask) { 449 nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 450 if (nKA > 0) { 451 req->nKeyAliases = nKA; 452 nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 453 } 454 else { 455 which &= ~XkbKeyAliasesMask; 456 req->nKeyAliases = 0; 457 } 458 } 459 else 460 req->nKeyAliases = 0; 461 462 if (which & XkbRGNamesMask) { 463 nRG = names->num_rg; 464 if (nRG > 0) 465 nAtoms += nRG; 466 else 467 which &= ~XkbRGNamesMask; 468 } 469 470 req->which = which; 471 req->nRadioGroups = nRG; 472 req->length += (nAtoms * 4) / 4; 473 474 if (which & XkbKeycodesNameMask) 475 Data32(dpy, (long *) &names->keycodes, 4); 476 if (which & XkbGeometryNameMask) 477 Data32(dpy, (long *) &names->geometry, 4); 478 if (which & XkbSymbolsNameMask) 479 Data32(dpy, (long *) &names->symbols, 4); 480 if (which & XkbPhysSymbolsNameMask) 481 Data32(dpy, (long *) &names->phys_symbols, 4); 482 if (which & XkbTypesNameMask) 483 Data32(dpy, (long *) &names->types, 4); 484 if (which & XkbCompatNameMask) 485 Data32(dpy, (long *) &names->compat, 4); 486 if (which & XkbKeyTypeNamesMask) { 487 register int i; 488 register XkbKeyTypePtr type; 489 490 type = &xkb->map->types[firstType]; 491 for (i = 0; i < nTypes; i++, type++) { 492 Data32(dpy, (long *) &type->name, 4); 493 } 494 } 495 if (which & XkbKTLevelNamesMask) { 496 XkbKeyTypePtr type; 497 int i; 498 char *tmp; 499 500 BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 501 type = &xkb->map->types[firstLvlType]; 502 for (i = 0; i < nLvlTypes; i++, type++) { 503 *tmp++ = type->num_levels; 504 } 505 type = &xkb->map->types[firstLvlType]; 506 for (i = 0; i < nLvlTypes; i++, type++) { 507 if (type->level_names != NULL) 508 Data32(dpy, (long *) type->level_names, type->num_levels * 4); 509 } 510 } 511 if (which & XkbIndicatorNamesMask) 512 _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 513 if (which & XkbVirtualModNamesMask) 514 _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 515 if (which & XkbGroupNamesMask) 516 _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 517 if (which & XkbKeyNamesMask) { 518 Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 519 } 520 if (which & XkbKeyAliasesMask) { 521 Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 522 } 523 if (which & XkbRGNamesMask) { 524 Data32(dpy, (long *) names->radio_groups, nRG * 4); 525 } 526 UnlockDisplay(dpy); 527 SyncHandle(); 528 return True; 529} 530 531Bool 532XkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes) 533{ 534 register xkbSetNamesReq *req; 535 int nLvlNames = 0; 536 XkbInfoPtr xkbi; 537 XkbNamesPtr names; 538 unsigned which, firstType, nTypes; 539 unsigned firstLvlType, nLvlTypes; 540 int nVMods, nLEDs, nRG, nKA, nGroups; 541 int nKeys = 0, firstKey = 0, nAtoms; 542 CARD32 leds = 0, vmods = 0, groups = 0; 543 544 if ((dpy->flags & XlibDisplayNoXkb) || 545 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 546 return False; 547 if ((!xkb) || (!xkb->names) || (!changes)) 548 return False; 549 which = changes->changed; 550 firstType = changes->first_type; 551 nTypes = changes->num_types; 552 firstLvlType = changes->first_lvl;; 553 nLvlTypes = changes->num_lvls; 554 if (which & XkbKeyTypeNamesMask) { 555 if (nTypes < 1) 556 which &= ~XkbKeyTypeNamesMask; 557 else if (firstType <= XkbLastRequiredType) { 558 int adjust; 559 560 adjust = XkbLastRequiredType - firstType + 1; 561 firstType += adjust; 562 nTypes -= adjust; 563 if (nTypes < 1) 564 which &= ~XkbKeyTypeNamesMask; 565 } 566 } 567 else 568 firstType = nTypes = 0; 569 570 if (which & XkbKTLevelNamesMask) { 571 if (nLvlTypes < 1) 572 which &= ~XkbKTLevelNamesMask; 573 } 574 else 575 firstLvlType = nLvlTypes = 0; 576 577 names = xkb->names; 578 if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 579 register int i; 580 581 if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 582 (firstType + nTypes > xkb->map->num_types) || 583 (firstLvlType + nLvlTypes > xkb->map->num_types)) 584 return False; 585 if (which & XkbKTLevelNamesMask) { 586 XkbKeyTypePtr type = &xkb->map->types[firstLvlType]; 587 588 for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 589 if (type->level_names != NULL) 590 nLvlNames += type->num_levels; 591 } 592 } 593 } 594 595 if (changes->num_keys < 1) 596 which &= ~XkbKeyNamesMask; 597 if ((which & XkbKeyNamesMask) == 0) 598 changes->first_key = changes->num_keys = 0; 599 else if ((changes->first_key < xkb->min_key_code) || 600 (changes->first_key + changes->num_keys > xkb->max_key_code)) { 601 return False; 602 } 603 604 if ((which & XkbVirtualModNamesMask) == 0) 605 changes->changed_vmods = 0; 606 else if (changes->changed_vmods == 0) 607 which &= ~XkbVirtualModNamesMask; 608 609 if ((which & XkbIndicatorNamesMask) == 0) 610 changes->changed_indicators = 0; 611 else if (changes->changed_indicators == 0) 612 which &= ~XkbIndicatorNamesMask; 613 614 if ((which & XkbGroupNamesMask) == 0) 615 changes->changed_groups = 0; 616 else if (changes->changed_groups == 0) 617 which &= ~XkbGroupNamesMask; 618 619 nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 620 LockDisplay(dpy); 621 xkbi = dpy->xkb_info; 622 GetReq(kbSetNames, req); 623 req->reqType = xkbi->codes->major_opcode; 624 req->xkbReqType = X_kbSetNames; 625 req->deviceSpec = xkb->device_spec; 626 req->firstType = firstType; 627 req->nTypes = nTypes; 628 req->firstKey = changes->first_key; 629 req->nKeys = changes->num_keys; 630 631 if (which & XkbKeycodesNameMask) 632 nAtoms++; 633 if (which & XkbGeometryNameMask) 634 nAtoms++; 635 if (which & XkbSymbolsNameMask) 636 nAtoms++; 637 if (which & XkbPhysSymbolsNameMask) 638 nAtoms++; 639 if (which & XkbTypesNameMask) 640 nAtoms++; 641 if (which & XkbCompatNameMask) 642 nAtoms++; 643 if (which & XkbKeyTypeNamesMask) 644 nAtoms += nTypes; 645 if (which & XkbKTLevelNamesMask) { 646 req->firstKTLevel = firstLvlType; 647 req->nKTLevels = nLvlTypes; 648 req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 649 nAtoms += nLvlNames; 650 } 651 else 652 req->firstKTLevel = req->nKTLevels = 0; 653 654 if (which & XkbIndicatorNamesMask) { 655 leds = req->indicators = (CARD32) changes->changed_indicators; 656 nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators); 657 if (nLEDs > 0) 658 nAtoms += nLEDs; 659 else 660 which &= ~XkbIndicatorNamesMask; 661 } 662 else 663 req->indicators = 0; 664 665 if (which & XkbVirtualModNamesMask) { 666 vmods = req->virtualMods = changes->changed_vmods; 667 nVMods = _XkbCountBits(XkbNumVirtualMods, 668 (unsigned long) changes->changed_vmods); 669 if (nVMods > 0) 670 nAtoms += nVMods; 671 else 672 which &= ~XkbVirtualModNamesMask; 673 } 674 else 675 req->virtualMods = 0; 676 677 if (which & XkbGroupNamesMask) { 678 groups = req->groupNames = changes->changed_groups; 679 nGroups = _XkbCountBits(XkbNumKbdGroups, 680 (unsigned long) changes->changed_groups); 681 if (nGroups > 0) 682 nAtoms += nGroups; 683 else 684 which &= ~XkbGroupNamesMask; 685 } 686 else 687 req->groupNames = 0; 688 689 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 690 firstKey = req->firstKey; 691 nKeys = req->nKeys; 692 nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 693 } 694 else 695 which &= ~XkbKeyNamesMask; 696 697 if (which & XkbKeyAliasesMask) { 698 nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 699 if (nKA > 0) 700 nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 701 else 702 which &= ~XkbKeyAliasesMask; 703 } 704 705 if (which & XkbRGNamesMask) { 706 nRG = names->num_rg; 707 if (nRG > 0) 708 nAtoms += nRG; 709 else 710 which &= ~XkbRGNamesMask; 711 } 712 713 req->which = which; 714 req->nRadioGroups = nRG; 715 req->length += (nAtoms * 4) / 4; 716 717 if (which & XkbKeycodesNameMask) 718 Data32(dpy, (long *) &names->keycodes, 4); 719 if (which & XkbGeometryNameMask) 720 Data32(dpy, (long *) &names->geometry, 4); 721 if (which & XkbSymbolsNameMask) 722 Data32(dpy, (long *) &names->symbols, 4); 723 if (which & XkbPhysSymbolsNameMask) 724 Data32(dpy, (long *) &names->phys_symbols, 4); 725 if (which & XkbTypesNameMask) 726 Data32(dpy, (long *) &names->types, 4); 727 if (which & XkbCompatNameMask) 728 Data32(dpy, (long *) &names->compat, 4); 729 if (which & XkbKeyTypeNamesMask) { 730 register int i; 731 register XkbKeyTypePtr type; 732 733 type = &xkb->map->types[firstType]; 734 for (i = 0; i < nTypes; i++, type++) { 735 Data32(dpy, (long *) &type->name, 4); 736 } 737 } 738 if (which & XkbKTLevelNamesMask) { 739 XkbKeyTypePtr type; 740 int i; 741 char *tmp; 742 743 BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 744 type = &xkb->map->types[firstLvlType]; 745 for (i = 0; i < nLvlTypes; i++, type++) { 746 *tmp++ = type->num_levels; 747 } 748 type = &xkb->map->types[firstLvlType]; 749 for (i = 0; i < nLvlTypes; i++, type++) { 750 if (type->level_names != NULL) 751 Data32(dpy, (long *) type->level_names, type->num_levels * 4); 752 } 753 } 754 if (which & XkbIndicatorNamesMask) 755 _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 756 if (which & XkbVirtualModNamesMask) 757 _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 758 if (which & XkbGroupNamesMask) 759 _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 760 if (which & XkbKeyNamesMask) { 761 Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 762 } 763 if (which & XkbKeyAliasesMask) { 764 Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 765 } 766 if (which & XkbRGNamesMask) { 767 Data32(dpy, (long *) names->radio_groups, nRG * 4); 768 } 769 UnlockDisplay(dpy); 770 SyncHandle(); 771 return True; 772} 773 774void 775XkbNoteNameChanges(XkbNameChangesPtr old, 776 XkbNamesNotifyEvent *new, 777 unsigned int wanted) 778{ 779 int first, last, old_last, new_last; 780 781 if ((old == NULL) || (new == NULL)) 782 return; 783 784 wanted &= new->changed; 785 786 if (wanted == 0) 787 return; 788 789 if (wanted & XkbKeyTypeNamesMask) { 790 if (old->changed & XkbKeyTypeNamesMask) { 791 new_last = (new->first_type + new->num_types - 1); 792 old_last = (old->first_type + old->num_types - 1); 793 794 if (new->first_type < old->first_type) 795 first = new->first_type; 796 else 797 first = old->first_type; 798 799 if (old_last > new_last) 800 last = old_last; 801 else 802 last = new_last; 803 804 old->first_type = first; 805 old->num_types = (last - first) + 1; 806 } 807 else { 808 old->first_type = new->first_type; 809 old->num_types = new->num_types; 810 } 811 } 812 if (wanted & XkbKTLevelNamesMask) { 813 if (old->changed & XkbKTLevelNamesMask) { 814 new_last = (new->first_lvl + new->num_lvls - 1); 815 old_last = (old->first_lvl + old->num_lvls - 1); 816 817 if (new->first_lvl < old->first_lvl) 818 first = new->first_lvl; 819 else 820 first = old->first_lvl; 821 822 if (old_last > new_last) 823 last = old_last; 824 else 825 last = new_last; 826 827 old->first_lvl = first; 828 old->num_lvls = (last - first) + 1; 829 } 830 else { 831 old->first_lvl = new->first_lvl; 832 old->num_lvls = new->num_lvls; 833 } 834 } 835 if (wanted & XkbIndicatorNamesMask) { 836 if (old->changed & XkbIndicatorNamesMask) 837 old->changed_indicators |= new->changed_indicators; 838 else 839 old->changed_indicators = new->changed_indicators; 840 } 841 if (wanted & XkbKeyNamesMask) { 842 if (old->changed & XkbKeyNamesMask) { 843 new_last = (new->first_key + new->num_keys - 1); 844 old_last = (old->first_key + old->num_keys - 1); 845 846 first = old->first_key; 847 848 if (new->first_key < old->first_key) 849 first = new->first_key; 850 if (old_last > new_last) 851 new_last = old_last; 852 853 old->first_key = first; 854 old->num_keys = (new_last - first) + 1; 855 } 856 else { 857 old->first_key = new->first_key; 858 old->num_keys = new->num_keys; 859 } 860 } 861 if (wanted & XkbVirtualModNamesMask) { 862 if (old->changed & XkbVirtualModNamesMask) 863 old->changed_vmods |= new->changed_vmods; 864 else 865 old->changed_vmods = new->changed_vmods; 866 } 867 if (wanted & XkbGroupNamesMask) { 868 if (old->changed & XkbGroupNamesMask) 869 old->changed_groups |= new->changed_groups; 870 else 871 old->changed_groups = new->changed_groups; 872 } 873 if (wanted & XkbRGNamesMask) 874 old->num_rg = new->num_radio_groups; 875 if (wanted & XkbKeyAliasesMask) 876 old->num_aliases = new->num_aliases; 877 old->changed |= wanted; 878 return; 879} 880