xkbtext.c revision 4642e01f
1/************************************************************ 2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <ctype.h> 33#include <stdlib.h> 34 35#include <X11/Xos.h> 36 37#include <X11/X.h> 38#define NEED_EVENTS 39#include <X11/Xproto.h> 40#include "misc.h" 41#include "inputstr.h" 42#include "dix.h" 43#include "xkbstr.h" 44#define XKBSRV_NEED_FILE_FUNCS 1 45#include <xkbsrv.h> 46#include "xkbgeom.h" 47 48/***====================================================================***/ 49 50#define BUFFER_SIZE 512 51 52static char textBuffer[BUFFER_SIZE]; 53static int tbNext= 0; 54 55static char * 56tbGetBuffer(unsigned size) 57{ 58char *rtrn; 59 60 if (size>=BUFFER_SIZE) 61 return NULL; 62 if ((BUFFER_SIZE-tbNext)<=size) 63 tbNext= 0; 64 rtrn= &textBuffer[tbNext]; 65 tbNext+= size; 66 return rtrn; 67} 68 69/***====================================================================***/ 70 71char * 72XkbAtomText(Atom atm,unsigned format) 73{ 74char *rtrn,*tmp; 75 76 tmp= XkbAtomGetString(atm); 77 if (tmp!=NULL) { 78 int len; 79 len= strlen(tmp)+1; 80 if (len>BUFFER_SIZE) 81 len= BUFFER_SIZE-2; 82 rtrn= tbGetBuffer(len); 83 strncpy(rtrn,tmp,len); 84 rtrn[len]= '\0'; 85 } 86 else { 87 rtrn= tbGetBuffer(1); 88 rtrn[0]= '\0'; 89 } 90 if (format==XkbCFile) { 91 for (tmp=rtrn;*tmp!='\0';tmp++) { 92 if ((tmp==rtrn)&&(!isalpha(*tmp))) 93 *tmp= '_'; 94 else if (!isalnum(*tmp)) 95 *tmp= '_'; 96 } 97 } 98 return XkbStringText(rtrn,format); 99} 100 101/***====================================================================***/ 102 103char * 104XkbVModIndexText(XkbDescPtr xkb,unsigned ndx,unsigned format) 105{ 106register int len; 107register Atom *vmodNames; 108char *rtrn,*tmp; 109char numBuf[20]; 110 111 if (xkb && xkb->names) 112 vmodNames= xkb->names->vmods; 113 else vmodNames= NULL; 114 115 tmp= NULL; 116 if (ndx>=XkbNumVirtualMods) 117 tmp= "illegal"; 118 else if (vmodNames&&(vmodNames[ndx]!=None)) 119 tmp= XkbAtomGetString(vmodNames[ndx]); 120 if (tmp==NULL) 121 sprintf(tmp=numBuf,"%d",ndx); 122 123 len= strlen(tmp)+1; 124 if (format==XkbCFile) 125 len+= 4; 126 if (len>=BUFFER_SIZE) 127 len= BUFFER_SIZE-1; 128 rtrn= tbGetBuffer(len); 129 if (format==XkbCFile) { 130 strcpy(rtrn,"vmod_"); 131 strncpy(&rtrn[5],tmp,len-4); 132 } 133 else strncpy(rtrn,tmp,len); 134 return rtrn; 135} 136 137char * 138XkbVModMaskText( XkbDescPtr xkb, 139 unsigned modMask, 140 unsigned mask, 141 unsigned format) 142{ 143register int i,bit; 144int len; 145char *mm,*rtrn; 146char *str,buf[BUFFER_SIZE]; 147 148 if ((modMask==0)&&(mask==0)) { 149 rtrn= tbGetBuffer(5); 150 if (format==XkbCFile) 151 sprintf(rtrn,"0"); 152 else sprintf(rtrn,"none"); 153 return rtrn; 154 } 155 if (modMask!=0) 156 mm= XkbModMaskText(modMask,format); 157 else mm= NULL; 158 159 str= buf; 160 buf[0]= '\0'; 161 if (mask) { 162 char *tmp; 163 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 164 if (mask&bit) { 165 tmp= XkbVModIndexText(xkb,i,format); 166 len= strlen(tmp)+1+(str==buf?0:1); 167 if (format==XkbCFile) 168 len+= 4; 169 if ((str-(buf+len))<=BUFFER_SIZE) { 170 if (str!=buf) { 171 if (format==XkbCFile) *str++= '|'; 172 else *str++= '+'; 173 len--; 174 } 175 } 176 if (format==XkbCFile) 177 sprintf(str,"%sMask",tmp); 178 else strcpy(str,tmp); 179 str= &str[len-1]; 180 } 181 } 182 str= buf; 183 } 184 else str= NULL; 185 if (mm) 186 len= strlen(mm); 187 else len= 0; 188 if (str) 189 len+= strlen(str)+(mm==NULL?0:1); 190 if (len>=BUFFER_SIZE) 191 len= BUFFER_SIZE-1; 192 rtrn= tbGetBuffer(len+1); 193 rtrn[0]= '\0'; 194 195 if (mm!=NULL) { 196 i= strlen(mm); 197 if (i>len) 198 i= len; 199 strcpy(rtrn,mm); 200 } 201 else { 202 i=0; 203 } 204 if (str!=NULL) { 205 if (mm!=NULL) { 206 if (format==XkbCFile) strcat(rtrn,"|"); 207 else strcat(rtrn,"+"); 208 } 209 strncat(rtrn,str,len-i); 210 } 211 rtrn[len]= '\0'; 212 return rtrn; 213} 214 215static char *modNames[XkbNumModifiers] = { 216 "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5" 217}; 218 219char * 220XkbModIndexText(unsigned ndx,unsigned format) 221{ 222char * rtrn; 223char buf[100]; 224 225 if (format==XkbCFile) { 226 if (ndx<XkbNumModifiers) 227 sprintf(buf,"%sMapIndex",modNames[ndx]); 228 else if (ndx==XkbNoModifier) 229 sprintf(buf,"XkbNoModifier"); 230 else sprintf(buf,"0x%02x",ndx); 231 } 232 else { 233 if (ndx<XkbNumModifiers) 234 strcpy(buf,modNames[ndx]); 235 else if (ndx==XkbNoModifier) 236 strcpy(buf,"none"); 237 else sprintf(buf,"ILLEGAL_%02x",ndx); 238 } 239 rtrn= tbGetBuffer(strlen(buf)+1); 240 strcpy(rtrn,buf); 241 return rtrn; 242} 243 244char * 245XkbModMaskText(unsigned mask,unsigned format) 246{ 247register int i,bit; 248char buf[64],*rtrn; 249 250 if ((mask&0xff)==0xff) { 251 if (format==XkbCFile) strcpy(buf,"0xff"); 252 else strcpy(buf,"all"); 253 } 254 else if ((mask&0xff)==0) { 255 if (format==XkbCFile) strcpy(buf,"0"); 256 else strcpy(buf,"none"); 257 } 258 else { 259 char *str= buf; 260 buf[0]= '\0'; 261 for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { 262 if (mask&bit) { 263 if (str!=buf) { 264 if (format==XkbCFile) *str++= '|'; 265 else *str++= '+'; 266 } 267 strcpy(str,modNames[i]); 268 str= &str[strlen(str)]; 269 if (format==XkbCFile) { 270 strcpy(str,"Mask"); 271 str+= 4; 272 } 273 } 274 } 275 } 276 rtrn= tbGetBuffer(strlen(buf)+1); 277 strcpy(rtrn,buf); 278 return rtrn; 279} 280 281/***====================================================================***/ 282 283/*ARGSUSED*/ 284char * 285XkbConfigText(unsigned config,unsigned format) 286{ 287static char *buf; 288 289 buf= tbGetBuffer(32); 290 switch (config) { 291 case XkmSemanticsFile: 292 strcpy(buf,"Semantics"); 293 break; 294 case XkmLayoutFile: 295 strcpy(buf,"Layout"); 296 break; 297 case XkmKeymapFile: 298 strcpy(buf,"Keymap"); 299 break; 300 case XkmGeometryFile: 301 case XkmGeometryIndex: 302 strcpy(buf,"Geometry"); 303 break; 304 case XkmTypesIndex: 305 strcpy(buf,"Types"); 306 break; 307 case XkmCompatMapIndex: 308 strcpy(buf,"CompatMap"); 309 break; 310 case XkmSymbolsIndex: 311 strcpy(buf,"Symbols"); 312 break; 313 case XkmIndicatorsIndex: 314 strcpy(buf,"Indicators"); 315 break; 316 case XkmKeyNamesIndex: 317 strcpy(buf,"KeyNames"); 318 break; 319 case XkmVirtualModsIndex: 320 strcpy(buf,"VirtualMods"); 321 break; 322 default: 323 sprintf(buf,"unknown(%d)",config); 324 break; 325 } 326 return buf; 327} 328 329/***====================================================================***/ 330 331char * 332XkbKeysymText(KeySym sym,unsigned format) 333{ 334static char buf[32],*rtrn; 335 336 if (sym==NoSymbol) 337 strcpy(rtrn=buf,"NoSymbol"); 338 else sprintf(rtrn=buf, "0x%lx", (long)sym); 339 return rtrn; 340} 341 342char * 343XkbKeyNameText(char *name,unsigned format) 344{ 345char *buf; 346 347 if (format==XkbCFile) { 348 buf= tbGetBuffer(5); 349 memcpy(buf,name,4); 350 buf[4]= '\0'; 351 } 352 else { 353 int len; 354 buf= tbGetBuffer(7); 355 buf[0]= '<'; 356 memcpy(&buf[1],name,4); 357 buf[5]= '\0'; 358 len= strlen(buf); 359 buf[len++]= '>'; 360 buf[len]= '\0'; 361 } 362 return buf; 363} 364 365/***====================================================================***/ 366 367static char *siMatchText[5] = { 368 "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly" 369}; 370 371char * 372XkbSIMatchText(unsigned type,unsigned format) 373{ 374static char buf[40]; 375char *rtrn; 376 377 switch (type&XkbSI_OpMask) { 378 case XkbSI_NoneOf: rtrn= siMatchText[0]; break; 379 case XkbSI_AnyOfOrNone: rtrn= siMatchText[1]; break; 380 case XkbSI_AnyOf: rtrn= siMatchText[2]; break; 381 case XkbSI_AllOf: rtrn= siMatchText[3]; break; 382 case XkbSI_Exactly: rtrn= siMatchText[4]; break; 383 default: sprintf(buf,"0x%x",type&XkbSI_OpMask); 384 return buf; 385 } 386 if (format==XkbCFile) { 387 if (type&XkbSI_LevelOneOnly) 388 sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn); 389 else sprintf(buf,"XkbSI_%s",rtrn); 390 rtrn= buf; 391 } 392 return rtrn; 393} 394 395/***====================================================================***/ 396 397static char *imWhichNames[]= { 398 "base", 399 "latched", 400 "locked", 401 "effective", 402 "compat" 403}; 404 405char * 406XkbIMWhichStateMaskText(unsigned use_which,unsigned format) 407{ 408int len; 409unsigned i,bit,tmp; 410char * buf; 411 412 if (use_which==0) { 413 buf= tbGetBuffer(2); 414 strcpy(buf,"0"); 415 return buf; 416 } 417 tmp= use_which&XkbIM_UseAnyMods; 418 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { 419 if (tmp&bit) { 420 tmp&= ~bit; 421 len+= strlen(imWhichNames[i])+1; 422 if (format==XkbCFile) 423 len+= 9; 424 } 425 } 426 buf= tbGetBuffer(len+1); 427 tmp= use_which&XkbIM_UseAnyMods; 428 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { 429 if (tmp&bit) { 430 tmp&= ~bit; 431 if (format==XkbCFile) { 432 if (len!=0) 433 buf[len++]= '|'; 434 sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]); 435 buf[len+9]= toupper(buf[len+9]); 436 } 437 else { 438 if (len!=0) 439 buf[len++]= '+'; 440 sprintf(&buf[len],"%s",imWhichNames[i]); 441 } 442 len+= strlen(&buf[len]); 443 } 444 } 445 return buf; 446} 447 448static char *ctrlNames[] = { 449 "repeatKeys", 450 "slowKeys", 451 "bounceKeys", 452 "stickyKeys", 453 "mouseKeys", 454 "mouseKeysAccel", 455 "accessXKeys", 456 "accessXTimeout", 457 "accessXFeedback", 458 "audibleBell", 459 "overlay1", 460 "overlay2", 461 "ignoreGroupLock" 462}; 463 464char * 465XkbControlsMaskText(unsigned ctrls,unsigned format) 466{ 467int len; 468unsigned i,bit,tmp; 469char * buf; 470 471 if (ctrls==0) { 472 buf= tbGetBuffer(5); 473 if (format==XkbCFile) 474 strcpy(buf,"0"); 475 else strcpy(buf,"none"); 476 return buf; 477 } 478 tmp= ctrls&XkbAllBooleanCtrlsMask; 479 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { 480 if (tmp&bit) { 481 tmp&= ~bit; 482 len+= strlen(ctrlNames[i])+1; 483 if (format==XkbCFile) 484 len+= 7; 485 } 486 } 487 buf= tbGetBuffer(len+1); 488 tmp= ctrls&XkbAllBooleanCtrlsMask; 489 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { 490 if (tmp&bit) { 491 tmp&= ~bit; 492 if (format==XkbCFile) { 493 if (len!=0) 494 buf[len++]= '|'; 495 sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]); 496 buf[len+3]= toupper(buf[len+3]); 497 } 498 else { 499 if (len!=0) 500 buf[len++]= '+'; 501 sprintf(&buf[len],"%s",ctrlNames[i]); 502 } 503 len+= strlen(&buf[len]); 504 } 505 } 506 return buf; 507} 508 509/***====================================================================***/ 510 511char * 512XkbStringText(char *str,unsigned format) 513{ 514char * buf; 515register char *in,*out; 516int len; 517Bool ok; 518 519 if (str==NULL) { 520 buf= tbGetBuffer(2); 521 buf[0]='\0'; 522 return buf; 523 } 524 else if (format==XkbXKMFile) 525 return str; 526 for (ok= True,len=0,in=str;*in!='\0';in++,len++) { 527 if (!isprint(*in)) { 528 ok= False; 529 switch (*in) { 530 case '\n': case '\t': case '\v': 531 case '\b': case '\r': case '\f': 532 len++; 533 break; 534 default: 535 len+= 4; 536 break; 537 } 538 } 539 } 540 if (ok) 541 return str; 542 buf= tbGetBuffer(len+1); 543 for (in=str,out=buf;*in!='\0';in++) { 544 if (isprint(*in)) 545 *out++= *in; 546 else { 547 *out++= '\\'; 548 if (*in=='\n') *out++= 'n'; 549 else if (*in=='\t') *out++= 't'; 550 else if (*in=='\v') *out++= 'v'; 551 else if (*in=='\b') *out++= 'b'; 552 else if (*in=='\r') *out++= 'r'; 553 else if (*in=='\f') *out++= 'f'; 554 else if ((*in=='\033')&&(format==XkbXKMFile)) { 555 *out++= 'e'; 556 } 557 else { 558 *out++= '0'; 559 sprintf(out,"%o",*in); 560 while (*out!='\0') 561 out++; 562 } 563 } 564 } 565 *out++= '\0'; 566 return buf; 567} 568 569/***====================================================================***/ 570 571char * 572XkbGeomFPText(int val,unsigned format) 573{ 574int whole,frac; 575char * buf; 576 577 buf= tbGetBuffer(12); 578 if (format==XkbCFile) { 579 sprintf(buf,"%d",val); 580 } 581 else { 582 whole= val/XkbGeomPtsPerMM; 583 frac= val%XkbGeomPtsPerMM; 584 if (frac!=0) 585 sprintf(buf,"%d.%d",whole,frac); 586 else sprintf(buf,"%d",whole); 587 } 588 return buf; 589} 590 591char * 592XkbDoodadTypeText(unsigned type,unsigned format) 593{ 594char * buf; 595 if (format==XkbCFile) { 596 buf= tbGetBuffer(24); 597 if (type==XkbOutlineDoodad) strcpy(buf,"XkbOutlineDoodad"); 598 else if (type==XkbSolidDoodad) strcpy(buf,"XkbSolidDoodad"); 599 else if (type==XkbTextDoodad) strcpy(buf,"XkbTextDoodad"); 600 else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad"); 601 else if (type==XkbLogoDoodad) strcpy(buf,"XkbLogoDoodad"); 602 else sprintf(buf,"UnknownDoodad%d",type); 603 } 604 else { 605 buf= tbGetBuffer(12); 606 if (type==XkbOutlineDoodad) strcpy(buf,"outline"); 607 else if (type==XkbSolidDoodad) strcpy(buf,"solid"); 608 else if (type==XkbTextDoodad) strcpy(buf,"text"); 609 else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator"); 610 else if (type==XkbLogoDoodad) strcpy(buf,"logo"); 611 else sprintf(buf,"unknown%d",type); 612 } 613 return buf; 614} 615 616static char *actionTypeNames[XkbSA_NumActions]= { 617 "NoAction", 618 "SetMods", "LatchMods", "LockMods", 619 "SetGroup", "LatchGroup", "LockGroup", 620 "MovePtr", 621 "PtrBtn", "LockPtrBtn", 622 "SetPtrDflt", 623 "ISOLock", 624 "Terminate", "SwitchScreen", 625 "SetControls", "LockControls", 626 "ActionMessage", 627 "RedirectKey", 628 "DeviceBtn", "LockDeviceBtn" 629}; 630 631char * 632XkbActionTypeText(unsigned type,unsigned format) 633{ 634static char buf[32]; 635char *rtrn; 636 637 if (type<=XkbSA_LastAction) { 638 rtrn= actionTypeNames[type]; 639 if (format==XkbCFile) { 640 sprintf(buf,"XkbSA_%s",rtrn); 641 return buf; 642 } 643 return rtrn; 644 } 645 sprintf(buf,"Private"); 646 return buf; 647} 648 649/***====================================================================***/ 650 651static int 652TryCopyStr(char *to,char *from,int *pLeft) 653{ 654register int len; 655 if (*pLeft>0) { 656 len= strlen(from); 657 if (len<((*pLeft)-3)) { 658 strcat(to,from); 659 *pLeft-= len; 660 return True; 661 } 662 } 663 *pLeft= -1; 664 return False; 665} 666 667/*ARGSUSED*/ 668static Bool 669CopyNoActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int*sz) 670{ 671 return True; 672} 673 674static Bool 675CopyModActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 676 int* sz) 677{ 678XkbModAction * act; 679unsigned tmp; 680 681 act= &action->mods; 682 tmp= XkbModActionVMods(act); 683 TryCopyStr(buf,"modifiers=",sz); 684 if (act->flags&XkbSA_UseModMapMods) 685 TryCopyStr(buf,"modMapMods",sz); 686 else if (act->real_mods || tmp) { 687 TryCopyStr(buf, 688 XkbVModMaskText(xkb,act->real_mods,tmp,XkbXKBFile), 689 sz); 690 } 691 else TryCopyStr(buf,"none",sz); 692 if (act->type==XkbSA_LockMods) 693 return True; 694 if (act->flags&XkbSA_ClearLocks) 695 TryCopyStr(buf,",clearLocks",sz); 696 if (act->flags&XkbSA_LatchToLock) 697 TryCopyStr(buf,",latchToLock",sz); 698 return True; 699} 700 701/*ARGSUSED*/ 702static Bool 703CopyGroupActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 704 int *sz) 705{ 706XkbGroupAction * act; 707char tbuf[32]; 708 709 act= &action->group; 710 TryCopyStr(buf,"group=",sz); 711 if (act->flags&XkbSA_GroupAbsolute) 712 sprintf(tbuf,"%d",XkbSAGroup(act)+1); 713 else if (XkbSAGroup(act)<0) 714 sprintf(tbuf,"%d",XkbSAGroup(act)); 715 else sprintf(tbuf,"+%d",XkbSAGroup(act)); 716 TryCopyStr(buf,tbuf,sz); 717 if (act->type==XkbSA_LockGroup) 718 return True; 719 if (act->flags&XkbSA_ClearLocks) 720 TryCopyStr(buf,",clearLocks",sz); 721 if (act->flags&XkbSA_LatchToLock) 722 TryCopyStr(buf,",latchToLock",sz); 723 return True; 724} 725 726/*ARGSUSED*/ 727static Bool 728CopyMovePtrArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) 729{ 730XkbPtrAction * act; 731int x,y; 732char tbuf[32]; 733 734 act= &action->ptr; 735 x= XkbPtrActionX(act); 736 y= XkbPtrActionY(act); 737 if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0)) 738 sprintf(tbuf,"x=%d",x); 739 else sprintf(tbuf,"x=+%d",x); 740 TryCopyStr(buf,tbuf,sz); 741 742 if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0)) 743 sprintf(tbuf,",y=%d",y); 744 else sprintf(tbuf,",y=+%d",y); 745 TryCopyStr(buf,tbuf,sz); 746 if (act->flags&XkbSA_NoAcceleration) 747 TryCopyStr(buf,",!accel",sz); 748 return True; 749} 750 751/*ARGSUSED*/ 752static Bool 753CopyPtrBtnArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) 754{ 755XkbPtrBtnAction * act; 756char tbuf[32]; 757 758 act= &action->btn; 759 TryCopyStr(buf,"button=",sz); 760 if ((act->button>0)&&(act->button<6)) { 761 sprintf(tbuf,"%d",act->button); 762 TryCopyStr(buf,tbuf,sz); 763 } 764 else TryCopyStr(buf,"default",sz); 765 if (act->count>0) { 766 sprintf(tbuf,",count=%d",act->count); 767 TryCopyStr(buf,tbuf,sz); 768 } 769 if (action->type==XkbSA_LockPtrBtn) { 770 switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { 771 case XkbSA_LockNoLock: 772 sprintf(tbuf,",affect=unlock"); break; 773 case XkbSA_LockNoUnlock: 774 sprintf(tbuf,",affect=lock"); break; 775 case XkbSA_LockNoUnlock|XkbSA_LockNoLock: 776 sprintf(tbuf,",affect=neither"); break; 777 default: 778 sprintf(tbuf,",affect=both"); break; 779 } 780 TryCopyStr(buf,tbuf,sz); 781 } 782 return True; 783} 784 785/*ARGSUSED*/ 786static Bool 787CopySetPtrDfltArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 788 int *sz) 789{ 790XkbPtrDfltAction * act; 791char tbuf[32]; 792 793 act= &action->dflt; 794 if (act->affect==XkbSA_AffectDfltBtn) { 795 TryCopyStr(buf,"affect=button,button=",sz); 796 if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0)) 797 sprintf(tbuf,"%d",XkbSAPtrDfltValue(act)); 798 else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act)); 799 TryCopyStr(buf,tbuf,sz); 800 } 801 return True; 802} 803 804static Bool 805CopyISOLockArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) 806{ 807XkbISOAction * act; 808char tbuf[64]; 809 810 act= &action->iso; 811 if (act->flags&XkbSA_ISODfltIsGroup) { 812 TryCopyStr(tbuf,"group=",sz); 813 if (act->flags&XkbSA_GroupAbsolute) 814 sprintf(tbuf,"%d",XkbSAGroup(act)+1); 815 else if (XkbSAGroup(act)<0) 816 sprintf(tbuf,"%d",XkbSAGroup(act)); 817 else sprintf(tbuf,"+%d",XkbSAGroup(act)); 818 TryCopyStr(buf,tbuf,sz); 819 } 820 else { 821 unsigned tmp; 822 tmp= XkbModActionVMods(act); 823 TryCopyStr(buf,"modifiers=",sz); 824 if (act->flags&XkbSA_UseModMapMods) 825 TryCopyStr(buf,"modMapMods",sz); 826 else if (act->real_mods || tmp) { 827 if (act->real_mods) { 828 TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz); 829 if (tmp) 830 TryCopyStr(buf,"+",sz); 831 } 832 if (tmp) 833 TryCopyStr(buf,XkbVModMaskText(xkb,0,tmp,XkbXKBFile),sz); 834 } 835 else TryCopyStr(buf,"none",sz); 836 } 837 TryCopyStr(buf,",affect=",sz); 838 if ((act->affect&XkbSA_ISOAffectMask)==0) 839 TryCopyStr(buf,"all",sz); 840 else { 841 int nOut= 0; 842 if ((act->affect&XkbSA_ISONoAffectMods)==0) { 843 TryCopyStr(buf,"mods",sz); 844 nOut++; 845 } 846 if ((act->affect&XkbSA_ISONoAffectGroup)==0) { 847 sprintf(tbuf,"%sgroups",(nOut>0?"+":"")); 848 TryCopyStr(buf,tbuf,sz); 849 nOut++; 850 } 851 if ((act->affect&XkbSA_ISONoAffectPtr)==0) { 852 sprintf(tbuf,"%spointer",(nOut>0?"+":"")); 853 TryCopyStr(buf,tbuf,sz); 854 nOut++; 855 } 856 if ((act->affect&XkbSA_ISONoAffectCtrls)==0) { 857 sprintf(tbuf,"%scontrols",(nOut>0?"+":"")); 858 TryCopyStr(buf,tbuf,sz); 859 nOut++; 860 } 861 } 862 return True; 863} 864 865/*ARGSUSED*/ 866static Bool 867CopySwitchScreenArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 868 int *sz) 869{ 870XkbSwitchScreenAction * act; 871char tbuf[32]; 872 873 act= &action->screen; 874 if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0)) 875 sprintf(tbuf,"screen=%d",XkbSAScreen(act)); 876 else sprintf(tbuf,"screen=+%d",XkbSAScreen(act)); 877 TryCopyStr(buf,tbuf,sz); 878 if (act->flags&XkbSA_SwitchApplication) 879 TryCopyStr(buf,",!same",sz); 880 else TryCopyStr(buf,",same",sz); 881 return True; 882} 883 884/*ARGSUSED*/ 885static Bool 886CopySetLockControlsArgs(XkbDescPtr xkb,XkbAction *action, 887 char *buf,int *sz) 888{ 889XkbCtrlsAction * act; 890unsigned tmp; 891char tbuf[32]; 892 893 act= &action->ctrls; 894 tmp= XkbActionCtrls(act); 895 TryCopyStr(buf,"controls=",sz); 896 if (tmp==0) 897 TryCopyStr(buf,"none",sz); 898 else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask) 899 TryCopyStr(buf,"all",sz); 900 else { 901 int nOut= 0; 902 if (tmp&XkbRepeatKeysMask) { 903 sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":"")); 904 TryCopyStr(buf,tbuf,sz); 905 nOut++; 906 } 907 if (tmp&XkbSlowKeysMask) { 908 sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":"")); 909 TryCopyStr(buf,tbuf,sz); 910 nOut++; 911 } 912 if (tmp&XkbBounceKeysMask) { 913 sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":"")); 914 TryCopyStr(buf,tbuf,sz); 915 nOut++; 916 } 917 if (tmp&XkbStickyKeysMask) { 918 sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":"")); 919 TryCopyStr(buf,tbuf,sz); 920 nOut++; 921 } 922 if (tmp&XkbMouseKeysMask) { 923 sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":"")); 924 TryCopyStr(buf,tbuf,sz); 925 nOut++; 926 } 927 if (tmp&XkbMouseKeysAccelMask) { 928 sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":"")); 929 TryCopyStr(buf,tbuf,sz); 930 nOut++; 931 } 932 if (tmp&XkbAccessXKeysMask) { 933 sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":"")); 934 TryCopyStr(buf,tbuf,sz); 935 nOut++; 936 } 937 if (tmp&XkbAccessXTimeoutMask) { 938 sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":"")); 939 TryCopyStr(buf,tbuf,sz); 940 nOut++; 941 } 942 if (tmp&XkbAccessXFeedbackMask) { 943 sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":"")); 944 TryCopyStr(buf,tbuf,sz); 945 nOut++; 946 } 947 if (tmp&XkbAudibleBellMask) { 948 sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":"")); 949 TryCopyStr(buf,tbuf,sz); 950 nOut++; 951 } 952 if (tmp&XkbOverlay1Mask) { 953 sprintf(tbuf,"%sOverlay1",(nOut>0?"+":"")); 954 TryCopyStr(buf,tbuf,sz); 955 nOut++; 956 } 957 if (tmp&XkbOverlay2Mask) { 958 sprintf(tbuf,"%sOverlay2",(nOut>0?"+":"")); 959 TryCopyStr(buf,tbuf,sz); 960 nOut++; 961 } 962 if (tmp&XkbIgnoreGroupLockMask) { 963 sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":"")); 964 TryCopyStr(buf,tbuf,sz); 965 nOut++; 966 } 967 } 968 return True; 969} 970 971/*ARGSUSED*/ 972static Bool 973CopyActionMessageArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 974 int *sz) 975{ 976XkbMessageAction * act; 977unsigned all; 978char tbuf[32]; 979 980 act= &action->msg; 981 all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease; 982 TryCopyStr(buf,"report=",sz); 983 if ((act->flags&all)==0) 984 TryCopyStr(buf,"none",sz); 985 else if ((act->flags&all)==all) 986 TryCopyStr(buf,"all",sz); 987 else if (act->flags&XkbSA_MessageOnPress) 988 TryCopyStr(buf,"KeyPress",sz); 989 else TryCopyStr(buf,"KeyRelease",sz); 990 sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz); 991 sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz); 992 sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz); 993 sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz); 994 sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz); 995 sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz); 996 return True; 997} 998 999static Bool 1000CopyRedirectKeyArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 1001 int *sz) 1002{ 1003XkbRedirectKeyAction * act; 1004char tbuf[32],*tmp; 1005unsigned kc; 1006unsigned vmods,vmods_mask; 1007 1008 act= &action->redirect; 1009 kc= act->new_key; 1010 vmods= XkbSARedirectVMods(act); 1011 vmods_mask= XkbSARedirectVModsMask(act); 1012 if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) && 1013 (xkb->names->keys[kc].name[0]!='\0')) { 1014 char *kn; 1015 kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); 1016 sprintf(tbuf,"key=%s",kn); 1017 } 1018 else sprintf(tbuf,"key=%d",kc); 1019 TryCopyStr(buf,tbuf,sz); 1020 if ((act->mods_mask==0)&&(vmods_mask==0)) 1021 return True; 1022 if ((act->mods_mask==XkbAllModifiersMask)&& 1023 (vmods_mask==XkbAllVirtualModsMask)) { 1024 tmp= XkbVModMaskText(xkb,act->mods,vmods,XkbXKBFile); 1025 TryCopyStr(buf,",mods=",sz); 1026 TryCopyStr(buf,tmp,sz); 1027 } 1028 else { 1029 if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) { 1030 tmp= XkbVModMaskText(xkb,act->mods_mask&act->mods, 1031 vmods_mask&vmods,XkbXKBFile); 1032 TryCopyStr(buf,",mods= ",sz); 1033 TryCopyStr(buf,tmp,sz); 1034 } 1035 if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) { 1036 tmp= XkbVModMaskText(xkb,act->mods_mask&(~act->mods), 1037 vmods_mask&(~vmods),XkbXKBFile); 1038 TryCopyStr(buf,",clearMods= ",sz); 1039 TryCopyStr(buf,tmp,sz); 1040 } 1041 } 1042 return True; 1043} 1044 1045/*ARGSUSED*/ 1046static Bool 1047CopyDeviceBtnArgs(XkbDescPtr xkb,XkbAction *action,char *buf, 1048 int *sz) 1049{ 1050XkbDeviceBtnAction * act; 1051char tbuf[32]; 1052 1053 act= &action->devbtn; 1054 sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz); 1055 TryCopyStr(buf,",button=",sz); 1056 sprintf(tbuf,"%d",act->button); 1057 TryCopyStr(buf,tbuf,sz); 1058 if (act->count>0) { 1059 sprintf(tbuf,",count=%d",act->count); 1060 TryCopyStr(buf,tbuf,sz); 1061 } 1062 if (action->type==XkbSA_LockDeviceBtn) { 1063 switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { 1064 case XkbSA_LockNoLock: 1065 sprintf(tbuf,",affect=unlock"); break; 1066 case XkbSA_LockNoUnlock: 1067 sprintf(tbuf,",affect=lock"); break; 1068 case XkbSA_LockNoUnlock|XkbSA_LockNoLock: 1069 sprintf(tbuf,",affect=neither"); break; 1070 default: 1071 sprintf(tbuf,",affect=both"); break; 1072 } 1073 TryCopyStr(buf,tbuf,sz); 1074 } 1075 return True; 1076} 1077 1078/*ARGSUSED*/ 1079static Bool 1080CopyOtherArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) 1081{ 1082XkbAnyAction * act; 1083char tbuf[32]; 1084 1085 act= &action->any; 1086 sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz); 1087 sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz); 1088 sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz); 1089 sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz); 1090 sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz); 1091 sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz); 1092 sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz); 1093 sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz); 1094 return True; 1095} 1096 1097typedef Bool (*actionCopy)( 1098 XkbDescPtr /* xkb */, 1099 XkbAction * /* action */, 1100 char * /* buf */, 1101 int* /* sz */ 1102); 1103static actionCopy copyActionArgs[XkbSA_NumActions] = { 1104 CopyNoActionArgs /* NoAction */, 1105 CopyModActionArgs /* SetMods */, 1106 CopyModActionArgs /* LatchMods */, 1107 CopyModActionArgs /* LockMods */, 1108 CopyGroupActionArgs /* SetGroup */, 1109 CopyGroupActionArgs /* LatchGroup */, 1110 CopyGroupActionArgs /* LockGroup */, 1111 CopyMovePtrArgs /* MovePtr */, 1112 CopyPtrBtnArgs /* PtrBtn */, 1113 CopyPtrBtnArgs /* LockPtrBtn */, 1114 CopySetPtrDfltArgs /* SetPtrDflt */, 1115 CopyISOLockArgs /* ISOLock */, 1116 CopyNoActionArgs /* Terminate */, 1117 CopySwitchScreenArgs /* SwitchScreen */, 1118 CopySetLockControlsArgs /* SetControls */, 1119 CopySetLockControlsArgs /* LockControls */, 1120 CopyActionMessageArgs /* ActionMessage*/, 1121 CopyRedirectKeyArgs /* RedirectKey */, 1122 CopyDeviceBtnArgs /* DeviceBtn */, 1123 CopyDeviceBtnArgs /* LockDeviceBtn*/ 1124}; 1125 1126#define ACTION_SZ 256 1127 1128char * 1129XkbActionText(XkbDescPtr xkb,XkbAction *action,unsigned format) 1130{ 1131char buf[ACTION_SZ],*tmp; 1132int sz; 1133 1134 if (format==XkbCFile) { 1135 sprintf(buf, 1136 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }", 1137 XkbActionTypeText(action->type,XkbCFile), 1138 action->any.data[0],action->any.data[1],action->any.data[2], 1139 action->any.data[3],action->any.data[4],action->any.data[5], 1140 action->any.data[6]); 1141 } 1142 else { 1143 sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile)); 1144 sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */ 1145 if (action->type<(unsigned)XkbSA_NumActions) 1146 (*copyActionArgs[action->type])(xkb,action,buf,&sz); 1147 else CopyOtherArgs(xkb,action,buf,&sz); 1148 TryCopyStr(buf,")",&sz); 1149 } 1150 tmp= tbGetBuffer(strlen(buf)+1); 1151 if (tmp!=NULL) 1152 strcpy(tmp,buf); 1153 return tmp; 1154} 1155 1156char * 1157XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format) 1158{ 1159char buf[256],*tmp; 1160 1161 if (format==XkbCFile) { 1162 if (behavior->type==XkbKB_Default) 1163 sprintf(buf,"{ 0, 0 }"); 1164 else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data); 1165 } 1166 else { 1167 unsigned type,permanent; 1168 type= behavior->type&XkbKB_OpMask; 1169 permanent=((behavior->type&XkbKB_Permanent)!=0); 1170 1171 if (type==XkbKB_Lock) { 1172 sprintf(buf,"lock= %s",(permanent?"Permanent":"True")); 1173 } 1174 else if (type==XkbKB_RadioGroup) { 1175 int g; 1176 char *tmp; 1177 g= ((behavior->data)&(~XkbKB_RGAllowNone))+1; 1178 if (XkbKB_RGAllowNone&behavior->data) { 1179 sprintf(buf,"allowNone,"); 1180 tmp= &buf[strlen(buf)]; 1181 } 1182 else tmp= buf; 1183 if (permanent) 1184 sprintf(tmp,"permanentRadioGroup= %d",g); 1185 else sprintf(tmp,"radioGroup= %d",g); 1186 } 1187 else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) { 1188 int ndx,kc; 1189 char *kn; 1190 1191 ndx= ((type==XkbKB_Overlay1)?1:2); 1192 kc= behavior->data; 1193 if ((xkb)&&(xkb->names)&&(xkb->names->keys)) 1194 kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); 1195 else { 1196 static char tbuf[8]; 1197 sprintf(tbuf,"%d",kc); 1198 kn= tbuf; 1199 } 1200 if (permanent) 1201 sprintf(buf,"permanentOverlay%d= %s",ndx,kn); 1202 else sprintf(buf,"overlay%d= %s",ndx,kn); 1203 } 1204 } 1205 tmp= tbGetBuffer(strlen(buf)+1); 1206 if (tmp!=NULL) 1207 strcpy(tmp,buf); 1208 return tmp; 1209} 1210 1211/***====================================================================***/ 1212 1213char * 1214XkbIndentText(unsigned size) 1215{ 1216static char buf[32]; 1217register int i; 1218 1219 if (size>31) 1220 size= 31; 1221 1222 for (i=0;i<size;i++) { 1223 buf[i]= ' '; 1224 } 1225 buf[size]= '\0'; 1226 return buf; 1227} 1228