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