1 /************************************************************ 2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE 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 static Status 36 _XkbReadKeyTypes(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 37 { 38 int i, n, lastMapCount; 39 XkbKeyTypePtr type; 40 41 if (rep->nTypes > 0) { 42 n = rep->firstType + rep->nTypes; 43 if (xkb->map->num_types >= n) 44 n = xkb->map->num_types; 45 else if (XkbAllocClientMap(xkb, XkbKeyTypesMask, n) != Success) 46 return BadAlloc; 47 48 type = &xkb->map->types[rep->firstType]; 49 for (i = 0; i < (int) rep->nTypes; i++, type++) { 50 xkbKeyTypeWireDesc *desc; 51 register int ndx; 52 53 ndx = i + rep->firstType; 54 if (ndx >= xkb->map->num_types) 55 xkb->map->num_types = ndx + 1; 56 57 desc = (xkbKeyTypeWireDesc *) 58 _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyTypeWireDesc)); 59 if (desc == NULL) 60 return BadLength; 61 62 lastMapCount = type->map_count; 63 if (desc->nMapEntries > 0) { 64 if ((type->map == NULL) || 65 (desc->nMapEntries > type->map_count)) { 66 _XkbResizeArray(type->map, type->map_count, 67 desc->nMapEntries, XkbKTMapEntryRec); 68 if (type->map == NULL) { 69 return BadAlloc; 70 } 71 } 72 } 73 else if (type->map != NULL) { 74 Xfree(type->map); 75 type->map_count = 0; 76 type->map = NULL; 77 } 78 79 if (desc->preserve && (desc->nMapEntries > 0)) { 80 if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) { 81 _XkbResizeArray(type->preserve, lastMapCount, 82 desc->nMapEntries, XkbModsRec); 83 if (type->preserve == NULL) { 84 return BadAlloc; 85 } 86 } 87 } 88 else if (type->preserve != NULL) { 89 Xfree(type->preserve); 90 type->preserve = NULL; 91 } 92 93 type->mods.mask = desc->mask; 94 type->mods.real_mods = desc->realMods; 95 type->mods.vmods = desc->virtualMods; 96 type->num_levels = desc->numLevels; 97 type->map_count = desc->nMapEntries; 98 if (desc->nMapEntries > 0) { 99 register xkbKTMapEntryWireDesc *wire; 100 register XkbKTMapEntryPtr entry; 101 register int size; 102 103 size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc); 104 wire = 105 (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size); 106 if (wire == NULL) 107 return BadLength; 108 entry = type->map; 109 for (n = 0; n < type->map_count; n++, wire++, entry++) { 110 entry->active = wire->active; 111 entry->level = wire->level; 112 entry->mods.mask = wire->mask; 113 entry->mods.real_mods = wire->realMods; 114 entry->mods.vmods = wire->virtualMods; 115 } 116 117 if (desc->preserve) { 118 register xkbModsWireDesc *pwire; 119 register XkbModsPtr preserve; 120 register int sz; 121 122 sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc); 123 pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz); 124 if (pwire == NULL) 125 return BadLength; 126 preserve = type->preserve; 127 for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) { 128 preserve->mask = pwire->mask; 129 preserve->vmods = pwire->virtualMods; 130 preserve->real_mods = pwire->realMods; 131 } 132 } 133 } 134 } 135 } 136 return Success; 137 } 138 139 static Status 140 _XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 141 { 142 register int i; 143 XkbClientMapPtr map; 144 int size = xkb->max_key_code + 1; 145 146 if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size) 147 return BadLength; 148 149 map = xkb->map; 150 if (map->key_sym_map == NULL) { 151 register int offset; 152 XkbSymMapPtr oldMap; 153 xkbSymMapWireDesc *newMap; 154 155 map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec); 156 if (map->key_sym_map == NULL) 157 return BadAlloc; 158 if (map->syms == NULL) { 159 int sz; 160 161 sz = (rep->totalSyms * 12) / 10; 162 sz = ((sz + (unsigned) 128) / 128) * 128; 163 map->syms = _XkbTypedCalloc(sz, KeySym); 164 if (map->syms == NULL) 165 return BadAlloc; 166 map->size_syms = sz; 167 } 168 offset = 1; 169 oldMap = &map->key_sym_map[rep->firstKeySym]; 170 for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 171 newMap = (xkbSymMapWireDesc *) 172 _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 173 if (newMap == NULL) 174 return BadLength; 175 oldMap->kt_index[0] = newMap->ktIndex[0]; 176 oldMap->kt_index[1] = newMap->ktIndex[1]; 177 oldMap->kt_index[2] = newMap->ktIndex[2]; 178 oldMap->kt_index[3] = newMap->ktIndex[3]; 179 oldMap->group_info = newMap->groupInfo; 180 oldMap->width = newMap->width; 181 oldMap->offset = offset; 182 if (offset + newMap->nSyms >= map->size_syms) { 183 register int sz; 184 185 sz = offset + newMap->nSyms; 186 sz = ((sz + (unsigned) 128) / 128) * 128; 187 _XkbResizeArray(map->syms, map->size_syms, sz, KeySym); 188 if (map->syms == NULL) { 189 map->size_syms = 0; 190 return BadAlloc; 191 } 192 map->size_syms = sz; 193 } 194 if (newMap->nSyms > 0) { 195 if (_XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], 196 newMap->nSyms) == 0) 197 return BadLength; 198 offset += newMap->nSyms; 199 } 200 else { 201 map->syms[offset] = 0; 202 } 203 } 204 map->num_syms = offset; 205 } 206 else { 207 XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym]; 208 209 for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 210 xkbSymMapWireDesc *newMap; 211 KeySym *newSyms; 212 int tmp; 213 214 newMap = (xkbSymMapWireDesc *) 215 _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 216 if (newMap == NULL) 217 return BadLength; 218 219 if (newMap->nSyms > 0) 220 tmp = newMap->nSyms; 221 else 222 tmp = 0; 223 224 newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp); 225 if (newSyms == NULL) 226 return BadAlloc; 227 if (newMap->nSyms > 0) { 228 if (_XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms) == 0) 229 return BadLength; 230 } 231 else 232 newSyms[0] = NoSymbol; 233 oldMap->kt_index[0] = newMap->ktIndex[0]; 234 oldMap->kt_index[1] = newMap->ktIndex[1]; 235 oldMap->kt_index[2] = newMap->ktIndex[2]; 236 oldMap->kt_index[3] = newMap->ktIndex[3]; 237 oldMap->group_info = newMap->groupInfo; 238 oldMap->width = newMap->width; 239 } 240 } 241 return Success; 242 } 243 244 static Status 245 _XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep) 246 { 247 int i; 248 CARD8 numDescBuf[248]; 249 CARD8 *numDesc = NULL; 250 register int nKeyActs; 251 Status ret = Success; 252 253 if ((nKeyActs = rep->nKeyActs) > 0) { 254 XkbSymMapPtr symMap; 255 256 if (((int) rep->firstKeyAct + rep->nKeyActs) > (info->max_key_code + 1)) 257 return BadLength; 258 259 if (nKeyActs < sizeof numDescBuf) 260 numDesc = numDescBuf; 261 else 262 numDesc = Xmallocarray(nKeyActs, sizeof(CARD8)); 263 264 if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) { 265 ret = BadLength; 266 goto done; 267 } 268 i = XkbPaddedSize(nKeyActs) - nKeyActs; 269 if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) { 270 ret = BadLength; 271 goto done; 272 } 273 symMap = &info->map->key_sym_map[rep->firstKeyAct]; 274 for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) { 275 if (numDesc[i] == 0) { 276 if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { 277 ret = BadLength; 278 goto done; 279 } 280 info->server->key_acts[i + rep->firstKeyAct] = 0; 281 } 282 else { 283 XkbAction *newActs; 284 285 /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ 286 /* either zero or XkbKeyNumSyms(info,key) */ 287 newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct, 288 numDesc[i]); 289 if (newActs == NULL) { 290 ret = BadAlloc; 291 goto done; 292 } 293 if (!_XkbCopyFromReadBuffer(buf, (char *) newActs, 294 (int) (numDesc[i] * sizeof(XkbAction)))) { 295 ret = BadLength; 296 goto done; 297 } 298 } 299 } 300 } 301 done: 302 if (numDesc != NULL && numDesc != numDescBuf) 303 Xfree(numDesc); 304 return ret; 305 } 306 307 static Status 308 _XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 309 { 310 register int i; 311 312 if (rep->totalKeyBehaviors > 0) { 313 int size = xkb->max_key_code + 1; 314 315 if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) 316 return BadLength; 317 if (xkb->server->behaviors == NULL) { 318 xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior); 319 if (xkb->server->behaviors == NULL) 320 return BadAlloc; 321 } 322 else { 323 bzero(&xkb->server->behaviors[rep->firstKeyBehavior], 324 (rep->nKeyBehaviors * sizeof(XkbBehavior))); 325 } 326 for (i = 0; i < rep->totalKeyBehaviors; i++) { 327 xkbBehaviorWireDesc *wire; 328 329 wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf, 330 SIZEOF(xkbBehaviorWireDesc)); 331 if (wire == NULL || wire->key >= size) 332 return BadLength; 333 xkb->server->behaviors[wire->key].type = wire->type; 334 xkb->server->behaviors[wire->key].data = wire->data; 335 } 336 } 337 return Success; 338 } 339 340 static Status 341 _XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 342 { 343 if (rep->virtualMods) { 344 register int i, bit, nVMods; 345 register char *data; 346 347 for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 348 if (rep->virtualMods & bit) 349 nVMods++; 350 } 351 data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods)); 352 if (data == NULL) 353 return BadLength; 354 for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0); 355 i++, bit <<= 1) { 356 if (rep->virtualMods & bit) { 357 xkb->server->vmods[i] = *data++; 358 nVMods--; 359 } 360 } 361 } 362 return Success; 363 } 364 365 static Status 366 _XkbReadExplicitComponents(XkbReadBufferPtr buf, 367 XkbDescPtr xkb, 368 xkbGetMapReply *rep) 369 { 370 register int i; 371 unsigned char *wire; 372 373 if (rep->totalKeyExplicit > 0) { 374 int size = xkb->max_key_code + 1; 375 376 if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) 377 return BadLength; 378 if (xkb->server->explicit == NULL) { 379 xkb->server->explicit = _XkbTypedCalloc(size, unsigned char); 380 381 if (xkb->server->explicit == NULL) 382 return BadAlloc; 383 } 384 else { 385 bzero(&xkb->server->explicit[rep->firstKeyExplicit], 386 rep->nKeyExplicit); 387 } 388 i = XkbPaddedSize(2 * rep->totalKeyExplicit); 389 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 390 if (!wire) 391 return BadLength; 392 for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) { 393 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 394 return BadLength; 395 xkb->server->explicit[wire[0]] = wire[1]; 396 } 397 } 398 return Success; 399 } 400 401 static Status 402 _XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 403 { 404 register int i; 405 unsigned char *wire; 406 407 if (rep->totalModMapKeys > 0) { 408 if (((int) rep->firstModMapKey + rep->nModMapKeys) > 409 (xkb->max_key_code + 1)) 410 return BadLength; 411 if ((xkb->map->modmap == NULL) && 412 (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) { 413 return BadAlloc; 414 } 415 else { 416 bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys); 417 } 418 i = XkbPaddedSize(2 * rep->totalModMapKeys); 419 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 420 if (!wire) 421 return BadLength; 422 for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) { 423 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 424 return BadLength; 425 xkb->map->modmap[wire[0]] = wire[1]; 426 } 427 } 428 return Success; 429 } 430 431 static Status 432 _XkbReadVirtualModMap(XkbReadBufferPtr buf, 433 XkbDescPtr xkb, 434 xkbGetMapReply *rep) 435 { 436 register int i; 437 xkbVModMapWireDesc *wire; 438 XkbServerMapPtr srv; 439 440 if (rep->totalVModMapKeys > 0) { 441 if (((int) rep->firstVModMapKey + rep->nVModMapKeys) 442 > xkb->max_key_code + 1) 443 return BadLength; 444 if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) && 445 (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) { 446 return BadAlloc; 447 } 448 else { 449 srv = xkb->server; 450 if (rep->nVModMapKeys > rep->firstVModMapKey) 451 bzero((char *) &srv->vmodmap[rep->firstVModMapKey], 452 (rep->nVModMapKeys - rep->firstVModMapKey) * 453 sizeof(unsigned short)); 454 } 455 srv = xkb->server; 456 i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); 457 wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i); 458 if (!wire) 459 return BadLength; 460 for (i = 0; i < rep->totalVModMapKeys; i++, wire++) { 461 if ((wire->key >= xkb->min_key_code) && 462 (wire->key <= xkb->max_key_code)) 463 srv->vmodmap[wire->key] = wire->vmods; 464 } 465 } 466 return Success; 467 } 468 469 static xkbGetMapReq * 470 _XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb) 471 { 472 xkbGetMapReq *req; 473 474 GetReq(kbGetMap, req); 475 req->reqType = dpy->xkb_info->codes->major_opcode; 476 req->xkbReqType = X_kbGetMap; 477 req->deviceSpec = xkb->device_spec; 478 req->full = req->partial = 0; 479 req->firstType = req->nTypes = 0; 480 req->firstKeySym = req->nKeySyms = 0; 481 req->firstKeyAct = req->nKeyActs = 0; 482 req->firstKeyBehavior = req->nKeyBehaviors = 0; 483 req->virtualMods = 0; 484 req->firstKeyExplicit = req->nKeyExplicit = 0; 485 req->firstModMapKey = req->nModMapKeys = 0; 486 req->firstVModMapKey = req->nVModMapKeys = 0; 487 return req; 488 } 489 490 Status 491 _XkbReadGetMapReply(Display *dpy, 492 xkbGetMapReply *rep, 493 XkbDescPtr xkb, 494 int *nread_rtrn) 495 { 496 int extraData; 497 unsigned mask; 498 499 if (xkb->device_spec == XkbUseCoreKbd) 500 xkb->device_spec = rep->deviceID; 501 if (rep->maxKeyCode < rep->minKeyCode) 502 return BadImplementation; 503 xkb->min_key_code = rep->minKeyCode; 504 xkb->max_key_code = rep->maxKeyCode; 505 506 if (!xkb->map) { 507 mask = rep->present & XkbAllClientInfoMask; 508 if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success)) 509 return BadAlloc; 510 } 511 if (!xkb->server) { 512 mask = rep->present & XkbAllServerInfoMask; 513 if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success)) 514 return BadAlloc; 515 } 516 extraData = (int) (rep->length * 4); 517 extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 518 if (rep->length) { 519 XkbReadBufferRec buf; 520 int left; 521 522 if (_XkbInitReadBuffer(dpy, &buf, extraData)) { 523 Status status = Success; 524 525 if (nread_rtrn != NULL) 526 *nread_rtrn = extraData; 527 if (status == Success) 528 status = _XkbReadKeyTypes(&buf, xkb, rep); 529 if (status == Success) 530 status = _XkbReadKeySyms(&buf, xkb, rep); 531 if (status == Success) 532 status = _XkbReadKeyActions(&buf, xkb, rep); 533 if (status == Success) 534 status = _XkbReadKeyBehaviors(&buf, xkb, rep); 535 if (status == Success) 536 status = _XkbReadVirtualMods(&buf, xkb, rep); 537 if (status == Success) 538 status = _XkbReadExplicitComponents(&buf, xkb, rep); 539 if (status == Success) 540 status = _XkbReadModifierMap(&buf, xkb, rep); 541 if (status == Success) 542 status = _XkbReadVirtualModMap(&buf, xkb, rep); 543 left = _XkbFreeReadBuffer(&buf); 544 if (status != Success) 545 return status; 546 else if (left || buf.error) 547 return BadLength; 548 } 549 else 550 return BadAlloc; 551 } 552 return Success; 553 } 554 555 static Status 556 _XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb) 557 { 558 xkbGetMapReply rep; 559 560 if (!_XReply(dpy, (xReply *) &rep, 561 ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2), 562 xFalse)) { 563 return BadImplementation; 564 } 565 return _XkbReadGetMapReply(dpy, &rep, xkb, NULL); 566 } 567 568 Status 569 XkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb) 570 { 571 if ((dpy->flags & XlibDisplayNoXkb) || 572 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 573 return BadAccess; 574 if (which) { 575 register xkbGetMapReq *req; 576 Status status; 577 578 LockDisplay(dpy); 579 580 req = _XkbGetGetMapReq(dpy, xkb); 581 req->full = which; 582 status = _XkbHandleGetMapReply(dpy, xkb); 583 584 UnlockDisplay(dpy); 585 SyncHandle(); 586 return status; 587 } 588 return Success; 589 } 590 591 XkbDescPtr 592 XkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec) 593 { 594 XkbDescPtr xkb; 595 596 xkb = _XkbTypedCalloc(1, XkbDescRec); 597 if (xkb) { 598 xkb->device_spec = deviceSpec; 599 xkb->map = _XkbTypedCalloc(1, XkbClientMapRec); 600 if ((xkb->map == NULL) || 601 ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) { 602 if (xkb->map) { 603 Xfree(xkb->map); 604 xkb->map = NULL; 605 } 606 Xfree(xkb); 607 return NULL; 608 } 609 xkb->dpy = dpy; 610 } 611 return xkb; 612 } 613 614 Status 615 XkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 616 { 617 register xkbGetMapReq *req; 618 Status status; 619 620 if ((dpy->flags & XlibDisplayNoXkb) || 621 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 622 return BadAccess; 623 if ((num < 1) || (num > XkbMaxKeyTypes)) 624 return BadValue; 625 626 LockDisplay(dpy); 627 628 req = _XkbGetGetMapReq(dpy, xkb); 629 req->firstType = first; 630 req->nTypes = num; 631 status = _XkbHandleGetMapReply(dpy, xkb); 632 633 UnlockDisplay(dpy); 634 SyncHandle(); 635 return status; 636 } 637 638 Status 639 XkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 640 { 641 register xkbGetMapReq *req; 642 Status status; 643 644 if ((dpy->flags & XlibDisplayNoXkb) || 645 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 646 return BadAccess; 647 648 if ((num < 1) || (num > XkbMaxKeyCount)) 649 return BadValue; 650 651 LockDisplay(dpy); 652 653 req = _XkbGetGetMapReq(dpy, xkb); 654 req->firstKeyAct = first; 655 req->nKeyActs = num; 656 status = _XkbHandleGetMapReply(dpy, xkb); 657 658 UnlockDisplay(dpy); 659 SyncHandle(); 660 return status; 661 } 662 663 Status 664 XkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 665 { 666 register xkbGetMapReq *req; 667 Status status; 668 669 if ((dpy->flags & XlibDisplayNoXkb) || 670 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 671 return BadAccess; 672 673 if ((num < 1) || (num > XkbMaxKeyCount)) 674 return BadValue; 675 676 LockDisplay(dpy); 677 678 req = _XkbGetGetMapReq(dpy, xkb); 679 req->firstKeySym = first; 680 req->nKeySyms = num; 681 status = _XkbHandleGetMapReply(dpy, xkb); 682 683 UnlockDisplay(dpy); 684 SyncHandle(); 685 686 return status; 687 } 688 689 Status 690 XkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 691 { 692 register xkbGetMapReq *req; 693 Status status; 694 695 if ((dpy->flags & XlibDisplayNoXkb) || 696 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 697 return BadAccess; 698 699 if ((num < 1) || (num > XkbMaxKeyCount)) 700 return BadValue; 701 702 LockDisplay(dpy); 703 704 req = _XkbGetGetMapReq(dpy, xkb); 705 req->firstKeyBehavior = first; 706 req->nKeyBehaviors = num; 707 status = _XkbHandleGetMapReply(dpy, xkb); 708 709 UnlockDisplay(dpy); 710 SyncHandle(); 711 return status; 712 } 713 714 Status 715 XkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb) 716 { 717 register xkbGetMapReq *req; 718 Status status; 719 720 if ((dpy->flags & XlibDisplayNoXkb) || 721 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 722 return BadAccess; 723 724 LockDisplay(dpy); 725 726 req = _XkbGetGetMapReq(dpy, xkb); 727 req->virtualMods = which; 728 status = _XkbHandleGetMapReply(dpy, xkb); 729 730 UnlockDisplay(dpy); 731 SyncHandle(); 732 return status; 733 } 734 735 Status 736 XkbGetKeyExplicitComponents(Display *dpy, 737 unsigned first, 738 unsigned num, 739 XkbDescPtr xkb) 740 { 741 register xkbGetMapReq *req; 742 Status status; 743 744 if ((dpy->flags & XlibDisplayNoXkb) || 745 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 746 return BadAccess; 747 748 if ((num < 1) || (num > XkbMaxKeyCount)) 749 return BadValue; 750 751 LockDisplay(dpy); 752 753 req = _XkbGetGetMapReq(dpy, xkb); 754 req->firstKeyExplicit = first; 755 req->nKeyExplicit = num; 756 if ((xkb != NULL) && (xkb->server != NULL) && 757 (xkb->server->explicit != NULL)) { 758 if ((num > 0) && (first >= xkb->min_key_code) && 759 (first + num <= xkb->max_key_code)) 760 bzero(&xkb->server->explicit[first], num); 761 } 762 if (xkb) 763 status = _XkbHandleGetMapReply(dpy, xkb); 764 else 765 status = BadMatch; 766 767 UnlockDisplay(dpy); 768 SyncHandle(); 769 return status; 770 } 771 772 Status 773 XkbGetKeyModifierMap(Display *dpy, 774 unsigned first, 775 unsigned num, 776 XkbDescPtr xkb) 777 { 778 register xkbGetMapReq *req; 779 Status status; 780 781 if ((dpy->flags & XlibDisplayNoXkb) || 782 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 783 return BadAccess; 784 785 if ((num < 1) || (num > XkbMaxKeyCount)) 786 return BadValue; 787 788 LockDisplay(dpy); 789 790 req = _XkbGetGetMapReq(dpy, xkb); 791 req->firstModMapKey = first; 792 req->nModMapKeys = num; 793 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 794 if ((num > 0) && (first >= xkb->min_key_code) && 795 (first + num <= xkb->max_key_code)) 796 bzero(&xkb->map->modmap[first], num); 797 } 798 if (xkb) 799 status = _XkbHandleGetMapReply(dpy, xkb); 800 else 801 status = BadMatch; 802 803 UnlockDisplay(dpy); 804 SyncHandle(); 805 return status; 806 } 807 808 Status 809 XkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num, 810 XkbDescPtr xkb) 811 { 812 register xkbGetMapReq *req; 813 Status status; 814 815 if ((dpy->flags & XlibDisplayNoXkb) || 816 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 817 return BadAccess; 818 819 if ((num < 1) || (num > XkbMaxKeyCount)) 820 return BadValue; 821 822 LockDisplay(dpy); 823 824 req = _XkbGetGetMapReq(dpy, xkb); 825 req->firstVModMapKey = first; 826 req->nVModMapKeys = num; 827 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 828 if ((num > 0) && (first >= xkb->min_key_code) && 829 (first + num <= xkb->max_key_code)) 830 bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short)); 831 } 832 833 if (xkb) 834 status = _XkbHandleGetMapReply(dpy, xkb); 835 else 836 status = BadMatch; 837 838 UnlockDisplay(dpy); 839 SyncHandle(); 840 return status; 841 } 842 843 Status 844 XkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) 845 { 846 xkbGetMapReq *req; 847 848 if ((dpy->flags & XlibDisplayNoXkb) || 849 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 850 return BadAccess; 851 LockDisplay(dpy); 852 if (changes->changed) { 853 Status status = Success; 854 855 req = _XkbGetGetMapReq(dpy, xkb); 856 req->full = 0; 857 req->partial = changes->changed; 858 req->firstType = changes->first_type; 859 req->nTypes = changes->num_types; 860 req->firstKeySym = changes->first_key_sym; 861 req->nKeySyms = changes->num_key_syms; 862 req->firstKeyAct = changes->first_key_act; 863 req->nKeyActs = changes->num_key_acts; 864 req->firstKeyBehavior = changes->first_key_behavior; 865 req->nKeyBehaviors = changes->num_key_behaviors; 866 req->virtualMods = changes->vmods; 867 req->firstKeyExplicit = changes->first_key_explicit; 868 req->nKeyExplicit = changes->num_key_explicit; 869 req->firstModMapKey = changes->first_modmap_key; 870 req->nModMapKeys = changes->num_modmap_keys; 871 req->firstVModMapKey = changes->first_vmodmap_key; 872 req->nVModMapKeys = changes->num_vmodmap_keys; 873 status = _XkbHandleGetMapReply(dpy, xkb); 874 UnlockDisplay(dpy); 875 SyncHandle(); 876 return status; 877 } 878 UnlockDisplay(dpy); 879 return Success; 880 } 881