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