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