XKBNames.c revision 1ab64890
1/* $Xorg: XKBNames.c,v 1.3 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/* $XFree86: xc/lib/X11/XKBNames.c,v 1.5 2003/04/13 19:22:18 dawes Exp $ */ 28 29#define NEED_REPLIES 30#define NEED_EVENTS 31#define NEED_MAP_READERS 32#ifdef HAVE_CONFIG_H 33#include <config.h> 34#endif 35#include "Xlibint.h" 36#include <X11/extensions/XKBproto.h> 37#include "XKBlibint.h" 38 39 40static Status 41_XkbReadAtoms( XkbReadBufferPtr buf, 42 Atom * atoms, 43 int maxAtoms, 44 CARD32 present) 45{ 46register int i,bit; 47 48 for (i=0,bit=1;(i<maxAtoms)&&(present);i++,bit<<=1) { 49 if (present&bit) { 50 if (!_XkbReadBufferCopy32(buf,(long *)&atoms[i],1)) 51 return BadLength; 52 present&= ~bit; 53 } 54 } 55 return Success; 56} 57 58Status 59_XkbReadGetNamesReply( Display * dpy, 60 xkbGetNamesReply * rep, 61 XkbDescPtr xkb, 62 int * nread_rtrn) 63{ 64 int i,len; 65 XkbReadBufferRec buf; 66 register XkbNamesPtr names; 67 68 if ( xkb->device_spec == XkbUseCoreKbd ) 69 xkb->device_spec = rep->deviceID; 70 71 if ((xkb->names==NULL)&& 72 (XkbAllocNames(xkb,rep->which, 73 rep->nRadioGroups,rep->nKeyAliases)!=Success)) { 74 return BadAlloc; 75 } 76 names= xkb->names; 77 if (rep->length==0) 78 return Success; 79 80 if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 81 return BadAlloc; 82 if (nread_rtrn) 83 *nread_rtrn= (int)rep->length*4; 84 85 if ((rep->which&XkbKeycodesNameMask)&& 86 (!_XkbReadBufferCopy32(&buf,(long *)&names->keycodes,1))) 87 goto BAILOUT; 88 if ((rep->which&XkbGeometryNameMask)&& 89 (!_XkbReadBufferCopy32(&buf,(long *)&names->geometry,1))) 90 goto BAILOUT; 91 if ((rep->which&XkbSymbolsNameMask)&& 92 (!_XkbReadBufferCopy32(&buf,(long *)&names->symbols,1))) 93 goto BAILOUT; 94 if ((rep->which&XkbPhysSymbolsNameMask)&& 95 (!_XkbReadBufferCopy32(&buf,(long *)&names->phys_symbols,1))) 96 goto BAILOUT; 97 if ((rep->which&XkbTypesNameMask)&& 98 (!_XkbReadBufferCopy32(&buf,(long *)&names->types,1))) 99 goto BAILOUT; 100 if ((rep->which&XkbCompatNameMask)&& 101 (!_XkbReadBufferCopy32(&buf,(long *)&names->compat,1))) 102 goto BAILOUT; 103 104 if ( rep->which & XkbKeyTypeNamesMask ) { 105 XkbClientMapPtr map= xkb->map; 106 XkbKeyTypePtr type; 107 108 len= rep->nTypes*4; 109 if (map!=NULL) { 110 type= map->types; 111 for (i=0;(i<map->num_types)&&(i<rep->nTypes);i++,type++) { 112 if (!_XkbReadBufferCopy32(&buf,(long *)&type->name,1)) 113 goto BAILOUT; 114 len-= 4; 115 } 116 } 117 if ((len>0)&&(!_XkbSkipReadBufferData(&buf,len))) 118 goto BAILOUT; 119 } 120 if ( rep->which&XkbKTLevelNamesMask ) { 121 CARD8 *nLevels; 122 XkbClientMapPtr map= xkb->map; 123 XkbKeyTypePtr type; 124 125 nLevels=(CARD8*)_XkbGetReadBufferPtr(&buf,XkbPaddedSize(rep->nTypes)); 126 if (nLevels==NULL) 127 goto BAILOUT; 128 if (map!=NULL) { 129 type= map->types; 130 for (i=0;i<(int)rep->nTypes;i++,type++) { 131 if (i>=map->num_types) { 132 if (!_XkbSkipReadBufferData(&buf,nLevels[i]*4)) 133 goto BAILOUT; 134 continue; 135 } 136 if ((nLevels[i]>0)&&(nLevels[i]!=type->num_levels)) { 137 goto BAILOUT; 138 } 139 if (type->level_names!=NULL) 140 Xfree(type->level_names); 141 if (nLevels[i]==0) { 142 type->level_names= NULL; 143 continue; 144 } 145 type->level_names= _XkbTypedCalloc(nLevels[i],Atom); 146 if (type->level_names!=NULL) { 147 if (!_XkbReadBufferCopy32(&buf,(long *)type->level_names, 148 nLevels[i])) 149 goto BAILOUT; 150 } 151 else { 152 _XkbSkipReadBufferData(&buf,nLevels[i]*4); 153 } 154 } 155 } 156 else { 157 for (i=0;i<(int)rep->nTypes;i++) { 158 _XkbSkipReadBufferData(&buf,nLevels[i]*4); 159 } 160 } 161 } 162 if (rep->which & XkbIndicatorNamesMask) { 163 if (_XkbReadAtoms(&buf,names->indicators,XkbNumIndicators, 164 rep->indicators)!=Success) 165 goto BAILOUT; 166 } 167 if ( rep->which&XkbVirtualModNamesMask ) { 168 if (_XkbReadAtoms(&buf,names->vmods,XkbNumVirtualMods, 169 (CARD32)rep->virtualMods)!=Success) 170 goto BAILOUT; 171 } 172 if ( rep->which&XkbGroupNamesMask ) { 173 if (_XkbReadAtoms(&buf,names->groups,XkbNumKbdGroups, 174 (CARD32)rep->groupNames)!=Success) 175 goto BAILOUT; 176 } 177 if ( rep->which&XkbKeyNamesMask ) { 178 if (names->keys==NULL) { 179 int nKeys; 180 if (xkb->max_key_code==0) { 181 xkb->min_key_code= rep->minKeyCode; 182 xkb->max_key_code= rep->maxKeyCode; 183 } 184 nKeys= xkb->max_key_code+1; 185 names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec); 186 } 187 if (names->keys!=NULL) { 188 if (!_XkbCopyFromReadBuffer(&buf, 189 (char *)&names->keys[rep->firstKey], 190 rep->nKeys*XkbKeyNameLength)) 191 goto BAILOUT; 192 } 193 else _XkbSkipReadBufferData(&buf,rep->nKeys*XkbKeyNameLength); 194 } 195 if ( rep->which&XkbKeyAliasesMask && (rep->nKeyAliases>0) ) { 196 if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,rep->nKeyAliases)!=Success) 197 goto BAILOUT; 198 if (!_XkbCopyFromReadBuffer(&buf,(char *)names->key_aliases, 199 rep->nKeyAliases*XkbKeyNameLength*2)) 200 goto BAILOUT; 201 } 202 if ( rep->which&XkbRGNamesMask ) { 203 if (rep->nRadioGroups>0) { 204 Atom *rgNames; 205 206 if (names->radio_groups==NULL) 207 names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups,Atom); 208 else if (names->num_rg<rep->nRadioGroups) { 209 names->radio_groups = _XkbTypedRealloc(names->radio_groups, 210 rep->nRadioGroups, 211 Atom); 212 } 213 rgNames= names->radio_groups; 214 if (!rgNames) { 215 goto BAILOUT; 216 } 217 if (!_XkbReadBufferCopy32(&buf,(long *)rgNames,rep->nRadioGroups)) 218 goto BAILOUT; 219 names->num_rg= rep->nRadioGroups; 220 } 221 else if (names->num_rg>0) { 222 names->num_rg= 0; 223 Xfree(names->radio_groups); 224 } 225 } 226 len= _XkbFreeReadBuffer(&buf); 227 if (len!=0) return BadLength; 228 else return Success; 229BAILOUT: 230 _XkbFreeReadBuffer(&buf); 231 return BadLength; 232} 233 234Status 235XkbGetNames(Display *dpy,unsigned which,XkbDescPtr xkb) 236{ 237 register xkbGetNamesReq *req; 238 xkbGetNamesReply rep; 239 Status status; 240 XkbInfoPtr xkbi; 241 242 if ((dpy->flags & XlibDisplayNoXkb) || 243 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 244 return BadAccess; 245 LockDisplay(dpy); 246 xkbi = dpy->xkb_info; 247 if (!xkb->names) { 248 xkb->names = _XkbTypedCalloc(1,XkbNamesRec); 249 if (!xkb->names) { 250 UnlockDisplay(dpy); 251 SyncHandle(); 252 return BadAlloc; 253 } 254 } 255 GetReq(kbGetNames, req); 256 req->reqType = xkbi->codes->major_opcode; 257 req->xkbReqType = X_kbGetNames; 258 req->deviceSpec = xkb->device_spec; 259 req->which = which; 260 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 261 UnlockDisplay(dpy); 262 SyncHandle(); 263 return BadImplementation; 264 } 265 266 status = _XkbReadGetNamesReply(dpy,&rep,xkb,NULL); 267 UnlockDisplay(dpy); 268 SyncHandle(); 269 return status; 270} 271 272/***====================================================================***/ 273 274static int 275_XkbCountBits(int nBitsMax,unsigned long mask) 276{ 277register unsigned long y, nBits; 278 279 y = (mask >> 1) &033333333333; 280 y = mask - y - ((y >>1) & 033333333333); 281 nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); 282 283 /* nBitsMax really means max+1 */ 284 return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); 285} 286 287static CARD32 288_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) 289{ 290register unsigned int i,bit,nAtoms; 291register CARD32 atomsPresent; 292 293 for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { 294 if (atoms[i]!=None) { 295 atomsPresent|= bit; 296 nAtoms++; 297 } 298 } 299 if (count) 300 *count= nAtoms; 301 return atomsPresent; 302} 303 304static void 305_XkbCopyAtoms(Display *dpy,Atom *atoms,CARD32 mask,int maxAtoms) 306{ 307register unsigned int i,bit; 308 309 for (i=0,bit=1;i<maxAtoms;i++,bit<<=1) { 310 if (mask&bit) 311 Data32(dpy,&atoms[i],4); 312 } 313 return; 314} 315 316Bool 317XkbSetNames( Display * dpy, 318 unsigned int which, 319 unsigned int firstType, 320 unsigned int nTypes, 321 XkbDescPtr xkb) 322{ 323 register xkbSetNamesReq *req; 324 int nLvlNames = 0; 325 XkbInfoPtr xkbi; 326 XkbNamesPtr names; 327 unsigned firstLvlType,nLvlTypes; 328 int nVMods,nLEDs,nRG,nKA,nGroups; 329 int nKeys=0,firstKey=0,nAtoms; 330 CARD32 leds,vmods,groups; 331 332 if ((dpy->flags & XlibDisplayNoXkb) || 333 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 334 return False; 335 if ((!xkb)||(!xkb->names)) 336 return False; 337 firstLvlType= firstType; 338 nLvlTypes= nTypes; 339 if (nTypes<1) 340 which&= ~(XkbKTLevelNamesMask|XkbKeyTypeNamesMask); 341 else if (firstType<=XkbLastRequiredType) { 342 int adjust; 343 adjust= XkbLastRequiredType-firstType+1; 344 firstType+= adjust; 345 nTypes-= adjust; 346 if (nTypes<1) 347 which&= ~XkbKeyTypeNamesMask; 348 } 349 names= xkb->names; 350 if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) { 351 register int i; 352 XkbKeyTypePtr type; 353 if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)|| 354 (firstType+nTypes>xkb->map->num_types)|| 355 (firstLvlType+nLvlTypes>xkb->map->num_types)) 356 return False; 357 if (which&XkbKTLevelNamesMask) { 358 type= &xkb->map->types[firstLvlType]; 359 for (i=nLvlNames=0;i<nLvlTypes;i++,type++) { 360 if (type->level_names!=NULL) 361 nLvlNames+= type->num_levels; 362 } 363 } 364 } 365 366 nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0; 367 LockDisplay(dpy); 368 xkbi = dpy->xkb_info; 369 GetReq(kbSetNames, req); 370 req->reqType = xkbi->codes->major_opcode; 371 req->xkbReqType = X_kbSetNames; 372 req->deviceSpec = xkb->device_spec; 373 req->firstType = firstType; 374 req->nTypes = nTypes; 375 req->firstKey = xkb->min_key_code; 376 req->nKeys = xkb->max_key_code-xkb->min_key_code+1; 377 378 if (which&XkbKeycodesNameMask) 379 nAtoms++; 380 if (which&XkbGeometryNameMask) 381 nAtoms++; 382 if (which&XkbSymbolsNameMask) 383 nAtoms++; 384 if (which&XkbPhysSymbolsNameMask) 385 nAtoms++; 386 if (which&XkbTypesNameMask) 387 nAtoms++; 388 if (which&XkbCompatNameMask) 389 nAtoms++; 390 if (which&XkbKeyTypeNamesMask) 391 nAtoms+= nTypes; 392 if (which&XkbKTLevelNamesMask) { 393 req->firstKTLevel= firstLvlType; 394 req->nKTLevels= nLvlTypes; 395 req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */ 396 nAtoms+= nLvlNames; 397 } 398 else req->firstKTLevel= req->nKTLevels= 0; 399 400 if (which&XkbIndicatorNamesMask) { 401 req->indicators= leds= 402 _XkbCountAtoms(names->indicators,XkbNumIndicators,&nLEDs); 403 if (nLEDs>0) 404 nAtoms+= nLEDs; 405 else which&= ~XkbIndicatorNamesMask; 406 } 407 else req->indicators= leds= 0; 408 409 if (which&XkbVirtualModNamesMask) { 410 vmods= req->virtualMods= (CARD16) 411 _XkbCountAtoms(names->vmods,XkbNumVirtualMods,&nVMods); 412 if (nVMods>0) 413 nAtoms+= nVMods; 414 else which&= ~XkbVirtualModNamesMask; 415 } 416 else vmods= req->virtualMods= 0; 417 418 if (which&XkbGroupNamesMask) { 419 groups= req->groupNames= (CARD8) 420 _XkbCountAtoms(names->groups,XkbNumKbdGroups,&nGroups); 421 if (nGroups>0) 422 nAtoms+= nGroups; 423 else which&= ~XkbGroupNamesMask; 424 } 425 else groups= req->groupNames= 0; 426 427 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { 428 firstKey= req->firstKey; 429 nKeys= req->nKeys; 430 nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */ 431 } 432 else which&= ~XkbKeyNamesMask; 433 434 if (which&XkbKeyAliasesMask) { 435 nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0); 436 if (nKA>0) { 437 req->nKeyAliases= nKA; 438 nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */ 439 } 440 else { 441 which&= ~XkbKeyAliasesMask; 442 req->nKeyAliases = 0; 443 } 444 } 445 else req->nKeyAliases= 0; 446 447 if (which&XkbRGNamesMask) { 448 nRG= names->num_rg; 449 if (nRG>0) 450 nAtoms+= nRG; 451 else which&= ~XkbRGNamesMask; 452 } 453 454 req->which= which; 455 req->nRadioGroups= nRG; 456 req->length+= (nAtoms*4)/4; 457 458 if (which&XkbKeycodesNameMask) 459 Data32(dpy,(long *)&names->keycodes,4); 460 if (which&XkbGeometryNameMask) 461 Data32(dpy,(long *)&names->geometry,4); 462 if (which&XkbSymbolsNameMask) 463 Data32(dpy,(long *)&names->symbols,4); 464 if (which&XkbPhysSymbolsNameMask) 465 Data32(dpy,(long *)&names->phys_symbols,4); 466 if (which&XkbTypesNameMask) 467 Data32(dpy,(long *)&names->types,4); 468 if (which&XkbCompatNameMask) 469 Data32(dpy,(long *)&names->compat,4); 470 if (which&XkbKeyTypeNamesMask) { 471 register int i; 472 register XkbKeyTypePtr type; 473 type= &xkb->map->types[firstType]; 474 for (i=0;i<nTypes;i++,type++) { 475 Data32(dpy,(long *)&type->name,4); 476 } 477 } 478 if (which&XkbKTLevelNamesMask) { 479 XkbKeyTypePtr type; 480 int i; 481 char *tmp; 482 483 BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes)); 484 type = &xkb->map->types[firstLvlType]; 485 for (i=0;i<nLvlTypes;i++,type++) { 486 *tmp++ = type->num_levels; 487 } 488 type = &xkb->map->types[firstLvlType]; 489 for (i=0;i<nLvlTypes;i++,type++) { 490 if (type->level_names!=NULL) 491 Data32(dpy,(long *)type->level_names,type->num_levels*4); 492 } 493 } 494 if (which&XkbIndicatorNamesMask) 495 _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators); 496 if (which&XkbVirtualModNamesMask) 497 _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods); 498 if (which&XkbGroupNamesMask) 499 _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups); 500 if (which&XkbKeyNamesMask) { 501#ifdef WORD64 502 char *tmp; 503 register int i; 504 BufAlloc(char *,tmp,nKeys*XkbKeyNameLength); 505 for (i=0;i<nKeys;i++,tmp+= XkbKeyNameLength) { 506 tmp[0]= names->keys[firstKey+i].name[0]; 507 tmp[1]= names->keys[firstKey+i].name[1]; 508 tmp[2]= names->keys[firstKey+i].name[2]; 509 tmp[3]= names->keys[firstKey+i].name[3]; 510 } 511#else 512 Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength); 513#endif 514 } 515 if (which&XkbKeyAliasesMask) { 516#ifdef WORD64 517 char *tmp; 518 register int i; 519 BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2); 520 for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) { 521 tmp[0]= names->key_aliases[i].real[0]; 522 tmp[1]= names->key_aliases[i].real[1]; 523 tmp[2]= names->key_aliases[i].real[2]; 524 tmp[3]= names->key_aliases[i].real[3]; 525 tmp[4]= names->key_aliases[i].alias[0]; 526 tmp[5]= names->key_aliases[i].alias[1]; 527 tmp[6]= names->key_aliases[i].alias[2]; 528 tmp[7]= names->key_aliases[i].alias[3]; 529 } 530#else 531 Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2); 532#endif 533 } 534 if (which&XkbRGNamesMask) { 535 Data32(dpy,(long *)names->radio_groups,nRG*4); 536 } 537 UnlockDisplay(dpy); 538 SyncHandle(); 539 return True; 540} 541 542Bool 543XkbChangeNames(Display *dpy,XkbDescPtr xkb,XkbNameChangesPtr changes) 544{ 545 register xkbSetNamesReq *req; 546 int nLvlNames = 0; 547 XkbInfoPtr xkbi; 548 XkbNamesPtr names; 549 unsigned which,firstType,nTypes; 550 unsigned firstLvlType,nLvlTypes; 551 int nVMods,nLEDs,nRG,nKA,nGroups; 552 int nKeys=0,firstKey=0,nAtoms; 553 CARD32 leds=0,vmods=0,groups=0; 554 555 if ((dpy->flags & XlibDisplayNoXkb) || 556 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 557 return False; 558 if ((!xkb)||(!xkb->names)||(!changes)) 559 return False; 560 which= changes->changed; 561 firstType= changes->first_type; 562 nTypes= changes->num_types; 563 firstLvlType= changes->first_lvl;; 564 nLvlTypes= changes->num_lvls; 565 if (which&XkbKeyTypeNamesMask) { 566 if (nTypes<1) 567 which&= ~XkbKeyTypeNamesMask; 568 else if (firstType<=XkbLastRequiredType) { 569 int adjust; 570 adjust= XkbLastRequiredType-firstType+1; 571 firstType+= adjust; 572 nTypes-= adjust; 573 if (nTypes<1) 574 which&= ~XkbKeyTypeNamesMask; 575 } 576 } 577 else firstType= nTypes= 0; 578 579 if (which&XkbKTLevelNamesMask) { 580 if (nLvlTypes<1) 581 which&= ~XkbKTLevelNamesMask; 582 } 583 else firstLvlType= nLvlTypes= 0; 584 585 names= xkb->names; 586 if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) { 587 register int i; 588 XkbKeyTypePtr type; 589 if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)|| 590 (firstType+nTypes>xkb->map->num_types)|| 591 (firstLvlType+nLvlTypes>xkb->map->num_types)) 592 return False; 593 if (which&XkbKTLevelNamesMask) { 594 type= &xkb->map->types[firstLvlType]; 595 for (i=nLvlNames=0;i<nLvlTypes;i++,type++) { 596 if (type->level_names!=NULL) 597 nLvlNames+= type->num_levels; 598 } 599 } 600 } 601 602 if (changes->num_keys<1) 603 which&= ~XkbKeyNamesMask; 604 if ((which&XkbKeyNamesMask)==0) 605 changes->first_key= changes->num_keys= 0; 606 else if ((changes->first_key<xkb->min_key_code)|| 607 (changes->first_key+changes->num_keys>xkb->max_key_code)) { 608 return False; 609 } 610 611 if ((which&XkbVirtualModNamesMask)==0) 612 changes->changed_vmods= 0; 613 else if (changes->changed_vmods==0) 614 which&= ~XkbVirtualModNamesMask; 615 616 if ((which&XkbIndicatorNamesMask)==0) 617 changes->changed_indicators= 0; 618 else if (changes->changed_indicators==0) 619 which&= ~XkbIndicatorNamesMask; 620 621 if ((which&XkbGroupNamesMask)==0) 622 changes->changed_groups= 0; 623 else if (changes->changed_groups==0) 624 which&= ~XkbGroupNamesMask; 625 626 nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0; 627 LockDisplay(dpy); 628 xkbi = dpy->xkb_info; 629 GetReq(kbSetNames, req); 630 req->reqType = xkbi->codes->major_opcode; 631 req->xkbReqType = X_kbSetNames; 632 req->deviceSpec = xkb->device_spec; 633 req->firstType = firstType; 634 req->nTypes = nTypes; 635 req->firstKey = changes->first_key; 636 req->nKeys = changes->num_keys; 637 638 if (which&XkbKeycodesNameMask) 639 nAtoms++; 640 if (which&XkbGeometryNameMask) 641 nAtoms++; 642 if (which&XkbSymbolsNameMask) 643 nAtoms++; 644 if (which&XkbPhysSymbolsNameMask) 645 nAtoms++; 646 if (which&XkbTypesNameMask) 647 nAtoms++; 648 if (which&XkbCompatNameMask) 649 nAtoms++; 650 if (which&XkbKeyTypeNamesMask) 651 nAtoms+= nTypes; 652 if (which&XkbKTLevelNamesMask) { 653 req->firstKTLevel= firstLvlType; 654 req->nKTLevels= nLvlTypes; 655 req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */ 656 nAtoms+= nLvlNames; 657 } 658 else req->firstKTLevel= req->nKTLevels= 0; 659 660 if (which&XkbIndicatorNamesMask) { 661 leds= req->indicators= (CARD32)changes->changed_indicators; 662 nLEDs= _XkbCountBits(XkbNumIndicators,changes->changed_indicators); 663 if (nLEDs>0) 664 nAtoms+= nLEDs; 665 else which&= ~XkbIndicatorNamesMask; 666 } 667 else req->indicators= 0; 668 669 if (which&XkbVirtualModNamesMask) { 670 vmods= req->virtualMods= changes->changed_vmods; 671 nVMods= _XkbCountBits(XkbNumVirtualMods, 672 (unsigned long)changes->changed_vmods); 673 if (nVMods>0) 674 nAtoms+= nVMods; 675 else which&= ~XkbVirtualModNamesMask; 676 } 677 else req->virtualMods= 0; 678 679 if (which&XkbGroupNamesMask) { 680 groups= req->groupNames= changes->changed_groups; 681 nGroups= _XkbCountBits(XkbNumKbdGroups, 682 (unsigned long)changes->changed_groups); 683 if (nGroups>0) 684 nAtoms+= nGroups; 685 else which&= ~XkbGroupNamesMask; 686 } 687 else req->groupNames= 0; 688 689 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { 690 firstKey= req->firstKey; 691 nKeys= req->nKeys; 692 nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */ 693 } 694 else which&= ~XkbKeyNamesMask; 695 696 if (which&XkbKeyAliasesMask) { 697 nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0); 698 if (nKA>0) 699 nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */ 700 else which&= ~XkbKeyAliasesMask; 701 } 702 703 if (which&XkbRGNamesMask) { 704 nRG= names->num_rg; 705 if (nRG>0) 706 nAtoms+= nRG; 707 else which&= ~XkbRGNamesMask; 708 } 709 710 req->which= which; 711 req->nRadioGroups= nRG; 712 req->length+= (nAtoms*4)/4; 713 714 if (which&XkbKeycodesNameMask) 715 Data32(dpy,(long *)&names->keycodes,4); 716 if (which&XkbGeometryNameMask) 717 Data32(dpy,(long *)&names->geometry,4); 718 if (which&XkbSymbolsNameMask) 719 Data32(dpy,(long *)&names->symbols,4); 720 if (which&XkbPhysSymbolsNameMask) 721 Data32(dpy,(long *)&names->phys_symbols,4); 722 if (which&XkbTypesNameMask) 723 Data32(dpy,(long *)&names->types,4); 724 if (which&XkbCompatNameMask) 725 Data32(dpy,(long *)&names->compat,4); 726 if (which&XkbKeyTypeNamesMask) { 727 register int i; 728 register XkbKeyTypePtr type; 729 type= &xkb->map->types[firstType]; 730 for (i=0;i<nTypes;i++,type++) { 731 Data32(dpy,(long *)&type->name,4); 732 } 733 } 734 if (which&XkbKTLevelNamesMask) { 735 XkbKeyTypePtr type; 736 int i; 737 char *tmp; 738 739 BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes)); 740 type = &xkb->map->types[firstLvlType]; 741 for (i=0;i<nLvlTypes;i++,type++) { 742 *tmp++ = type->num_levels; 743 } 744 type = &xkb->map->types[firstLvlType]; 745 for (i=0;i<nLvlTypes;i++,type++) { 746 if (type->level_names!=NULL) 747 Data32(dpy,(long *)type->level_names,type->num_levels*4); 748 } 749 } 750 if (which&XkbIndicatorNamesMask) 751 _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators); 752 if (which&XkbVirtualModNamesMask) 753 _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods); 754 if (which&XkbGroupNamesMask) 755 _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups); 756 if (which&XkbKeyNamesMask) { 757#ifdef WORD64 758 char *tmp; 759 register int i; 760 BufAlloc(char *,tmp,nKeys*4); 761 for (i=0;i<nKeys;i++,tmp+= 4) { 762 tmp[0]= names->keys[firstKey+i].name[0]; 763 tmp[1]= names->keys[firstKey+i].name[1]; 764 tmp[2]= names->keys[firstKey+i].name[2]; 765 tmp[3]= names->keys[firstKey+i].name[3]; 766 } 767#else 768 Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength); 769#endif 770 } 771 if (which&XkbKeyAliasesMask) { 772#ifdef WORD64 773 char *tmp; 774 register int i; 775 BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2); 776 for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) { 777 tmp[0]= names->key_aliases[i].real[0]; 778 tmp[1]= names->key_aliases[i].real[1]; 779 tmp[2]= names->key_aliases[i].real[2]; 780 tmp[3]= names->key_aliases[i].real[3]; 781 tmp[4]= names->key_aliases[i].alias[0]; 782 tmp[5]= names->key_aliases[i].alias[1]; 783 tmp[6]= names->key_aliases[i].alias[2]; 784 tmp[7]= names->key_aliases[i].alias[3]; 785 } 786#else 787 Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2); 788#endif 789 } 790 if (which&XkbRGNamesMask) { 791 Data32(dpy,(long *)names->radio_groups,nRG*4); 792 } 793 UnlockDisplay(dpy); 794 SyncHandle(); 795 return True; 796} 797 798void 799XkbNoteNameChanges( XkbNameChangesPtr old, 800 XkbNamesNotifyEvent * new, 801 unsigned int wanted) 802{ 803int first,last,old_last,new_last; 804 805 wanted&= new->changed; 806 if ((old==NULL)||(new==NULL)||(wanted==0)) 807 return; 808 if (wanted&XkbKeyTypeNamesMask) { 809 if (old->changed&XkbKeyTypeNamesMask) { 810 new_last= (new->first_type+new->num_types-1); 811 old_last= (old->first_type+old->num_types-1); 812 813 if (new->first_type<old->first_type) 814 first= new->first_type; 815 else first= old->first_type; 816 817 if (old_last>new_last) 818 last= old_last; 819 else last= new_last; 820 821 old->first_type= first; 822 old->num_types= (last-first)+1; 823 } 824 else { 825 old->first_type= new->first_type; 826 old->num_types= new->num_types; 827 } 828 } 829 if (wanted&XkbKTLevelNamesMask) { 830 if (old->changed&XkbKTLevelNamesMask) { 831 new_last= (new->first_lvl+new->num_lvls-1); 832 old_last= (old->first_lvl+old->num_lvls-1); 833 834 if (new->first_lvl<old->first_lvl) 835 first= new->first_lvl; 836 else first= old->first_lvl; 837 838 if (old_last>new_last) 839 last= old_last; 840 else last= new_last; 841 842 old->first_lvl= first; 843 old->num_lvls= (last-first)+1; 844 } 845 else { 846 old->first_lvl= new->first_lvl; 847 old->num_lvls= new->num_lvls; 848 } 849 } 850 if (wanted&XkbIndicatorNamesMask) { 851 if (old->changed&XkbIndicatorNamesMask) 852 old->changed_indicators|= new->changed_indicators; 853 else old->changed_indicators= new->changed_indicators; 854 } 855 if (wanted&XkbKeyNamesMask) { 856 if (old->changed&XkbKeyNamesMask) { 857 new_last= (new->first_key+new->num_keys-1); 858 old_last= (old->first_key+old->num_keys-1); 859 860 first= old->first_key; 861 862 if (new->first_key<old->first_key) 863 first= new->first_key; 864 if (old_last>new_last) 865 new_last= old_last; 866 867 old->first_key= first; 868 old->num_keys= (new_last-first)+1; 869 } 870 else { 871 old->first_key= new->first_key; 872 old->num_keys= new->num_keys; 873 } 874 } 875 if (wanted&XkbVirtualModNamesMask) { 876 if (old->changed&XkbVirtualModNamesMask) 877 old->changed_vmods|= new->changed_vmods; 878 else old->changed_vmods= new->changed_vmods; 879 } 880 if (wanted&XkbGroupNamesMask) { 881 if (old->changed&XkbGroupNamesMask) 882 old->changed_groups|= new->changed_groups; 883 else old->changed_groups= new->changed_groups; 884 } 885 if (wanted&XkbRGNamesMask) 886 old->num_rg= new->num_radio_groups; 887 if (wanted&XkbKeyAliasesMask) 888 old->num_aliases= new->num_aliases; 889 old->changed|= wanted; 890 return; 891} 892