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