XKBGetMap.c revision cbfda780
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 _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 139static 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 244static 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 (nKeyActs < sizeof numDescBuf) 257 numDesc = numDescBuf; 258 else 259 numDesc = Xmallocarray(nKeyActs, sizeof(CARD8)); 260 261 if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) { 262 ret = BadLength; 263 goto done; 264 } 265 i = XkbPaddedSize(nKeyActs) - nKeyActs; 266 if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) { 267 ret = BadLength; 268 goto done; 269 } 270 symMap = &info->map->key_sym_map[rep->firstKeyAct]; 271 for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) { 272 if (numDesc[i] == 0) { 273 if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { 274 ret = BadLength; 275 goto done; 276 } 277 info->server->key_acts[i + rep->firstKeyAct] = 0; 278 } 279 else { 280 XkbAction *newActs; 281 282 /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ 283 /* either zero or XkbKeyNumSyms(info,key) */ 284 newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct, 285 numDesc[i]); 286 if (newActs == NULL) { 287 ret = BadAlloc; 288 goto done; 289 } 290 if (!_XkbCopyFromReadBuffer(buf, (char *) newActs, 291 (int) (numDesc[i] * sizeof(XkbAction)))) { 292 ret = BadLength; 293 goto done; 294 } 295 } 296 } 297 } 298 done: 299 if (numDesc != NULL && numDesc != numDescBuf) 300 Xfree(numDesc); 301 return ret; 302} 303 304static Status 305_XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 306{ 307 register int i; 308 309 if (rep->totalKeyBehaviors > 0) { 310 int size = xkb->max_key_code + 1; 311 312 if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) 313 return BadLength; 314 if (xkb->server->behaviors == NULL) { 315 xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior); 316 if (xkb->server->behaviors == NULL) 317 return BadAlloc; 318 } 319 else { 320 bzero(&xkb->server->behaviors[rep->firstKeyBehavior], 321 (rep->nKeyBehaviors * sizeof(XkbBehavior))); 322 } 323 for (i = 0; i < rep->totalKeyBehaviors; i++) { 324 xkbBehaviorWireDesc *wire; 325 326 wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf, 327 SIZEOF(xkbBehaviorWireDesc)); 328 if (wire == NULL || wire->key >= size) 329 return BadLength; 330 xkb->server->behaviors[wire->key].type = wire->type; 331 xkb->server->behaviors[wire->key].data = wire->data; 332 } 333 } 334 return Success; 335} 336 337static Status 338_XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 339{ 340 if (rep->virtualMods) { 341 register int i, bit, nVMods; 342 register char *data; 343 344 for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 345 if (rep->virtualMods & bit) 346 nVMods++; 347 } 348 data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods)); 349 if (data == NULL) 350 return BadLength; 351 for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0); 352 i++, bit <<= 1) { 353 if (rep->virtualMods & bit) { 354 xkb->server->vmods[i] = *data++; 355 nVMods--; 356 } 357 } 358 } 359 return Success; 360} 361 362static Status 363_XkbReadExplicitComponents(XkbReadBufferPtr buf, 364 XkbDescPtr xkb, 365 xkbGetMapReply *rep) 366{ 367 register int i; 368 unsigned char *wire; 369 370 if (rep->totalKeyExplicit > 0) { 371 int size = xkb->max_key_code + 1; 372 373 if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) 374 return BadLength; 375 if (xkb->server->explicit == NULL) { 376 xkb->server->explicit = _XkbTypedCalloc(size, unsigned char); 377 378 if (xkb->server->explicit == NULL) 379 return BadAlloc; 380 } 381 else { 382 bzero(&xkb->server->explicit[rep->firstKeyExplicit], 383 rep->nKeyExplicit); 384 } 385 i = XkbPaddedSize(2 * rep->totalKeyExplicit); 386 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 387 if (!wire) 388 return BadLength; 389 for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) { 390 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 391 return BadLength; 392 xkb->server->explicit[wire[0]] = wire[1]; 393 } 394 } 395 return Success; 396} 397 398static Status 399_XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 400{ 401 register int i; 402 unsigned char *wire; 403 404 if (rep->totalModMapKeys > 0) { 405 if (((int) rep->firstModMapKey + rep->nModMapKeys) > 406 (xkb->max_key_code + 1)) 407 return BadLength; 408 if ((xkb->map->modmap == NULL) && 409 (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) { 410 return BadAlloc; 411 } 412 else { 413 bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys); 414 } 415 i = XkbPaddedSize(2 * rep->totalModMapKeys); 416 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 417 if (!wire) 418 return BadLength; 419 for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) { 420 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 421 return BadLength; 422 xkb->map->modmap[wire[0]] = wire[1]; 423 } 424 } 425 return Success; 426} 427 428static Status 429_XkbReadVirtualModMap(XkbReadBufferPtr buf, 430 XkbDescPtr xkb, 431 xkbGetMapReply *rep) 432{ 433 register int i; 434 xkbVModMapWireDesc *wire; 435 XkbServerMapPtr srv; 436 437 if (rep->totalVModMapKeys > 0) { 438 if (((int) rep->firstVModMapKey + rep->nVModMapKeys) 439 > xkb->max_key_code + 1) 440 return BadLength; 441 if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) && 442 (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) { 443 return BadAlloc; 444 } 445 else { 446 srv = xkb->server; 447 if (rep->nVModMapKeys > rep->firstVModMapKey) 448 bzero((char *) &srv->vmodmap[rep->firstVModMapKey], 449 (rep->nVModMapKeys - rep->firstVModMapKey) * 450 sizeof(unsigned short)); 451 } 452 srv = xkb->server; 453 i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); 454 wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i); 455 if (!wire) 456 return BadLength; 457 for (i = 0; i < rep->totalVModMapKeys; i++, wire++) { 458 if ((wire->key >= xkb->min_key_code) && 459 (wire->key <= xkb->max_key_code)) 460 srv->vmodmap[wire->key] = wire->vmods; 461 } 462 } 463 return Success; 464} 465 466static xkbGetMapReq * 467_XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb) 468{ 469 xkbGetMapReq *req; 470 471 GetReq(kbGetMap, req); 472 req->reqType = dpy->xkb_info->codes->major_opcode; 473 req->xkbReqType = X_kbGetMap; 474 req->deviceSpec = xkb->device_spec; 475 req->full = req->partial = 0; 476 req->firstType = req->nTypes = 0; 477 req->firstKeySym = req->nKeySyms = 0; 478 req->firstKeyAct = req->nKeyActs = 0; 479 req->firstKeyBehavior = req->nKeyBehaviors = 0; 480 req->virtualMods = 0; 481 req->firstKeyExplicit = req->nKeyExplicit = 0; 482 req->firstModMapKey = req->nModMapKeys = 0; 483 req->firstVModMapKey = req->nVModMapKeys = 0; 484 return req; 485} 486 487Status 488_XkbReadGetMapReply(Display *dpy, 489 xkbGetMapReply *rep, 490 XkbDescPtr xkb, 491 int *nread_rtrn) 492{ 493 int extraData; 494 unsigned mask; 495 496 if (xkb->device_spec == XkbUseCoreKbd) 497 xkb->device_spec = rep->deviceID; 498 if (rep->maxKeyCode < rep->minKeyCode) 499 return BadImplementation; 500 xkb->min_key_code = rep->minKeyCode; 501 xkb->max_key_code = rep->maxKeyCode; 502 503 if (!xkb->map) { 504 mask = rep->present & XkbAllClientInfoMask; 505 if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success)) 506 return BadAlloc; 507 } 508 if (!xkb->server) { 509 mask = rep->present & XkbAllServerInfoMask; 510 if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success)) 511 return BadAlloc; 512 } 513 extraData = (int) (rep->length * 4); 514 extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 515 if (rep->length) { 516 XkbReadBufferRec buf; 517 int left; 518 519 if (_XkbInitReadBuffer(dpy, &buf, extraData)) { 520 Status status = Success; 521 522 if (nread_rtrn != NULL) 523 *nread_rtrn = extraData; 524 if (status == Success) 525 status = _XkbReadKeyTypes(&buf, xkb, rep); 526 if (status == Success) 527 status = _XkbReadKeySyms(&buf, xkb, rep); 528 if (status == Success) 529 status = _XkbReadKeyActions(&buf, xkb, rep); 530 if (status == Success) 531 status = _XkbReadKeyBehaviors(&buf, xkb, rep); 532 if (status == Success) 533 status = _XkbReadVirtualMods(&buf, xkb, rep); 534 if (status == Success) 535 status = _XkbReadExplicitComponents(&buf, xkb, rep); 536 if (status == Success) 537 status = _XkbReadModifierMap(&buf, xkb, rep); 538 if (status == Success) 539 status = _XkbReadVirtualModMap(&buf, xkb, rep); 540 left = _XkbFreeReadBuffer(&buf); 541 if (status != Success) 542 return status; 543 else if (left || buf.error) 544 return BadLength; 545 } 546 else 547 return BadAlloc; 548 } 549 return Success; 550} 551 552static Status 553_XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb) 554{ 555 xkbGetMapReply rep; 556 557 if (!_XReply(dpy, (xReply *) &rep, 558 ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2), 559 xFalse)) { 560 return BadImplementation; 561 } 562 return _XkbReadGetMapReply(dpy, &rep, xkb, NULL); 563} 564 565Status 566XkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb) 567{ 568 if ((dpy->flags & XlibDisplayNoXkb) || 569 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 570 return BadAccess; 571 if (which) { 572 register xkbGetMapReq *req; 573 Status status; 574 575 LockDisplay(dpy); 576 577 req = _XkbGetGetMapReq(dpy, xkb); 578 req->full = which; 579 status = _XkbHandleGetMapReply(dpy, xkb); 580 581 UnlockDisplay(dpy); 582 SyncHandle(); 583 return status; 584 } 585 return Success; 586} 587 588XkbDescPtr 589XkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec) 590{ 591 XkbDescPtr xkb; 592 593 xkb = _XkbTypedCalloc(1, XkbDescRec); 594 if (xkb) { 595 xkb->device_spec = deviceSpec; 596 xkb->map = _XkbTypedCalloc(1, XkbClientMapRec); 597 if ((xkb->map == NULL) || 598 ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) { 599 if (xkb->map) { 600 Xfree(xkb->map); 601 xkb->map = NULL; 602 } 603 Xfree(xkb); 604 return NULL; 605 } 606 xkb->dpy = dpy; 607 } 608 return xkb; 609} 610 611Status 612XkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 613{ 614 register xkbGetMapReq *req; 615 Status status; 616 617 if ((dpy->flags & XlibDisplayNoXkb) || 618 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 619 return BadAccess; 620 if ((num < 1) || (num > XkbMaxKeyTypes)) 621 return BadValue; 622 623 LockDisplay(dpy); 624 625 req = _XkbGetGetMapReq(dpy, xkb); 626 req->firstType = first; 627 req->nTypes = num; 628 status = _XkbHandleGetMapReply(dpy, xkb); 629 630 UnlockDisplay(dpy); 631 SyncHandle(); 632 return status; 633} 634 635Status 636XkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 637{ 638 register xkbGetMapReq *req; 639 Status status; 640 641 if ((dpy->flags & XlibDisplayNoXkb) || 642 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 643 return BadAccess; 644 645 if ((num < 1) || (num > XkbMaxKeyCount)) 646 return BadValue; 647 648 LockDisplay(dpy); 649 650 req = _XkbGetGetMapReq(dpy, xkb); 651 req->firstKeyAct = first; 652 req->nKeyActs = num; 653 status = _XkbHandleGetMapReply(dpy, xkb); 654 655 UnlockDisplay(dpy); 656 SyncHandle(); 657 return status; 658} 659 660Status 661XkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 662{ 663 register xkbGetMapReq *req; 664 Status status; 665 666 if ((dpy->flags & XlibDisplayNoXkb) || 667 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 668 return BadAccess; 669 670 if ((num < 1) || (num > XkbMaxKeyCount)) 671 return BadValue; 672 673 LockDisplay(dpy); 674 675 req = _XkbGetGetMapReq(dpy, xkb); 676 req->firstKeySym = first; 677 req->nKeySyms = num; 678 status = _XkbHandleGetMapReply(dpy, xkb); 679 680 UnlockDisplay(dpy); 681 SyncHandle(); 682 683 return status; 684} 685 686Status 687XkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 688{ 689 register xkbGetMapReq *req; 690 Status status; 691 692 if ((dpy->flags & XlibDisplayNoXkb) || 693 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 694 return BadAccess; 695 696 if ((num < 1) || (num > XkbMaxKeyCount)) 697 return BadValue; 698 699 LockDisplay(dpy); 700 701 req = _XkbGetGetMapReq(dpy, xkb); 702 req->firstKeyBehavior = first; 703 req->nKeyBehaviors = num; 704 status = _XkbHandleGetMapReply(dpy, xkb); 705 706 UnlockDisplay(dpy); 707 SyncHandle(); 708 return status; 709} 710 711Status 712XkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb) 713{ 714 register xkbGetMapReq *req; 715 Status status; 716 717 if ((dpy->flags & XlibDisplayNoXkb) || 718 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 719 return BadAccess; 720 721 LockDisplay(dpy); 722 723 req = _XkbGetGetMapReq(dpy, xkb); 724 req->virtualMods = which; 725 status = _XkbHandleGetMapReply(dpy, xkb); 726 727 UnlockDisplay(dpy); 728 SyncHandle(); 729 return status; 730} 731 732Status 733XkbGetKeyExplicitComponents(Display *dpy, 734 unsigned first, 735 unsigned num, 736 XkbDescPtr xkb) 737{ 738 register xkbGetMapReq *req; 739 Status status; 740 741 if ((dpy->flags & XlibDisplayNoXkb) || 742 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 743 return BadAccess; 744 745 if ((num < 1) || (num > XkbMaxKeyCount)) 746 return BadValue; 747 748 LockDisplay(dpy); 749 750 req = _XkbGetGetMapReq(dpy, xkb); 751 req->firstKeyExplicit = first; 752 req->nKeyExplicit = num; 753 if ((xkb != NULL) && (xkb->server != NULL) && 754 (xkb->server->explicit != NULL)) { 755 if ((num > 0) && (first >= xkb->min_key_code) && 756 (first + num <= xkb->max_key_code)) 757 bzero(&xkb->server->explicit[first], num); 758 } 759 if (xkb) 760 status = _XkbHandleGetMapReply(dpy, xkb); 761 else 762 status = BadMatch; 763 764 UnlockDisplay(dpy); 765 SyncHandle(); 766 return status; 767} 768 769Status 770XkbGetKeyModifierMap(Display *dpy, 771 unsigned first, 772 unsigned num, 773 XkbDescPtr xkb) 774{ 775 register xkbGetMapReq *req; 776 Status status; 777 778 if ((dpy->flags & XlibDisplayNoXkb) || 779 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 780 return BadAccess; 781 782 if ((num < 1) || (num > XkbMaxKeyCount)) 783 return BadValue; 784 785 LockDisplay(dpy); 786 787 req = _XkbGetGetMapReq(dpy, xkb); 788 req->firstModMapKey = first; 789 req->nModMapKeys = num; 790 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 791 if ((num > 0) && (first >= xkb->min_key_code) && 792 (first + num <= xkb->max_key_code)) 793 bzero(&xkb->map->modmap[first], num); 794 } 795 if (xkb) 796 status = _XkbHandleGetMapReply(dpy, xkb); 797 else 798 status = BadMatch; 799 800 UnlockDisplay(dpy); 801 SyncHandle(); 802 return status; 803} 804 805Status 806XkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num, 807 XkbDescPtr xkb) 808{ 809 register xkbGetMapReq *req; 810 Status status; 811 812 if ((dpy->flags & XlibDisplayNoXkb) || 813 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 814 return BadAccess; 815 816 if ((num < 1) || (num > XkbMaxKeyCount)) 817 return BadValue; 818 819 LockDisplay(dpy); 820 821 req = _XkbGetGetMapReq(dpy, xkb); 822 req->firstVModMapKey = first; 823 req->nVModMapKeys = num; 824 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 825 if ((num > 0) && (first >= xkb->min_key_code) && 826 (first + num <= xkb->max_key_code)) 827 bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short)); 828 } 829 830 if (xkb) 831 status = _XkbHandleGetMapReply(dpy, xkb); 832 else 833 status = BadMatch; 834 835 UnlockDisplay(dpy); 836 SyncHandle(); 837 return status; 838} 839 840Status 841XkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) 842{ 843 xkbGetMapReq *req; 844 845 if ((dpy->flags & XlibDisplayNoXkb) || 846 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 847 return BadAccess; 848 LockDisplay(dpy); 849 if (changes->changed) { 850 Status status = Success; 851 852 req = _XkbGetGetMapReq(dpy, xkb); 853 req->full = 0; 854 req->partial = changes->changed; 855 req->firstType = changes->first_type; 856 req->nTypes = changes->num_types; 857 req->firstKeySym = changes->first_key_sym; 858 req->nKeySyms = changes->num_key_syms; 859 req->firstKeyAct = changes->first_key_act; 860 req->nKeyActs = changes->num_key_acts; 861 req->firstKeyBehavior = changes->first_key_behavior; 862 req->nKeyBehaviors = changes->num_key_behaviors; 863 req->virtualMods = changes->vmods; 864 req->firstKeyExplicit = changes->first_key_explicit; 865 req->nKeyExplicit = changes->num_key_explicit; 866 req->firstModMapKey = changes->first_modmap_key; 867 req->nModMapKeys = changes->num_modmap_keys; 868 req->firstVModMapKey = changes->first_vmodmap_key; 869 req->nVModMapKeys = changes->num_vmodmap_keys; 870 status = _XkbHandleGetMapReply(dpy, xkb); 871 UnlockDisplay(dpy); 872 SyncHandle(); 873 return status; 874 } 875 UnlockDisplay(dpy); 876 return Success; 877} 878