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#elif defined(HAVE_CONFIG_H) 30#include <config.h> 31#endif 32 33#include <stdio.h> 34#include <ctype.h> 35#include <stdlib.h> 36 37#include <X11/Xos.h> 38 39 40#include <X11/Xlib.h> 41#include <X11/XKBlib.h> 42#include <X11/extensions/XKBgeom.h> 43 44#include "XKMformat.h" 45#include "XKBfileInt.h" 46 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{ 58 char *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(Display *dpy, Atom atm, unsigned format) 73{ 74 char *rtrn, *tmp; 75 76 tmp = XkbAtomGetString(dpy, atm); 77 if (tmp != NULL) { 78 int len; 79 80 len = strlen(tmp) + 1; 81 if (len > BUFFER_SIZE) 82 len = BUFFER_SIZE - 2; 83 rtrn = tbGetBuffer(len); 84 strncpy(rtrn, tmp, len); 85 rtrn[len] = '\0'; 86 _XkbFree(tmp); 87 } 88 else { 89 rtrn = tbGetBuffer(1); 90 rtrn[0] = '\0'; 91 } 92 if (format == XkbCFile) { 93 for (tmp = rtrn; *tmp != '\0'; tmp++) { 94 if ((tmp == rtrn) && (!isalpha(*tmp))) 95 *tmp = '_'; 96 else if (!isalnum(*tmp)) 97 *tmp = '_'; 98 } 99 } 100 return XkbStringText(rtrn, format); 101} 102 103/***====================================================================***/ 104 105char * 106XkbVModIndexText(Display *dpy, XkbDescPtr xkb, unsigned ndx, unsigned format) 107{ 108 register int len; 109 register Atom *vmodNames; 110 char *rtrn, *tmp; 111 112 if (xkb && xkb->names) 113 vmodNames = xkb->names->vmods; 114 else 115 vmodNames = NULL; 116 117 tmp = NULL; 118 if (ndx >= XkbNumVirtualMods) 119 tmp = strdup("illegal"); 120 else if (vmodNames && (vmodNames[ndx] != None)) 121 tmp = XkbAtomGetString(dpy, vmodNames[ndx]); 122 if (tmp == NULL) { 123 tmp = (char *) _XkbAlloc(20 * sizeof(char)); 124 snprintf(tmp, 20, "%d", ndx); 125 } 126 127 len = strlen(tmp) + 1; 128 if (format == XkbCFile) 129 len += 5; 130 if (len >= BUFFER_SIZE) 131 len = BUFFER_SIZE - 1; 132 rtrn = tbGetBuffer(len); 133 if (format == XkbCFile) { 134 snprintf(rtrn, len, "vmod_%s", tmp); 135 } 136 else 137 strncpy(rtrn, tmp, len); 138 _XkbFree(tmp); 139 return rtrn; 140} 141 142char * 143XkbVModMaskText(Display * dpy, 144 XkbDescPtr xkb, 145 unsigned modMask, 146 unsigned mask, 147 unsigned format) 148{ 149 register int i, bit; 150 int len; 151 char *mm, *rtrn; 152 char *str, buf[BUFFER_SIZE]; 153 154 if ((modMask == 0) && (mask == 0)) { 155 const int rtrnsize = 5; 156 rtrn = tbGetBuffer(rtrnsize); 157 if (format == XkbCFile) 158 snprintf(rtrn, rtrnsize, "0"); 159 else 160 snprintf(rtrn, rtrnsize, "none"); 161 return rtrn; 162 } 163 if (modMask != 0) 164 mm = XkbModMaskText(modMask, format); 165 else 166 mm = NULL; 167 168 str = buf; 169 buf[0] = '\0'; 170 if (mask) { 171 char *tmp; 172 173 for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 174 if (mask & bit) { 175 tmp = XkbVModIndexText(dpy, xkb, i, format); 176 len = strlen(tmp) + 1 + (str == buf ? 0 : 1); 177 if (format == XkbCFile) 178 len += 4; 179 if ((str - (buf + len)) <= BUFFER_SIZE) { 180 if (str != buf) { 181 if (format == XkbCFile) 182 *str++ = '|'; 183 else 184 *str++ = '+'; 185 len--; 186 } 187 } 188 if (format == XkbCFile) 189 sprintf(str, "%sMask", tmp); 190 else 191 strcpy(str, tmp); 192 str = &str[len - 1]; 193 } 194 } 195 str = buf; 196 } 197 else 198 str = NULL; 199 if (mm) 200 len = strlen(mm); 201 else 202 len = 0; 203 if (str) 204 len += strlen(str) + (mm == NULL ? 0 : 1); 205 if (len >= BUFFER_SIZE) 206 len = BUFFER_SIZE - 1; 207 rtrn = tbGetBuffer(len + 1); 208 rtrn[0] = '\0'; 209 210 if (mm != NULL) { 211 i = strlen(mm); 212 if (i > len) 213 i = len; 214 strcpy(rtrn, mm); 215 } 216 else { 217 i = 0; 218 } 219 if (str != NULL) { 220 if (mm != NULL) { 221 if (format == XkbCFile) 222 strcat(rtrn, "|"); 223 else 224 strcat(rtrn, "+"); 225 } 226 strncat(rtrn, str, len - i); 227 } 228 rtrn[len] = '\0'; 229 return rtrn; 230} 231 232static const char *modNames[XkbNumModifiers] = { 233 "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5" 234}; 235 236char * 237XkbModIndexText(unsigned ndx, unsigned format) 238{ 239 char *rtrn; 240 char buf[100]; 241 242 if (format == XkbCFile) { 243 if (ndx < XkbNumModifiers) 244 snprintf(buf, sizeof(buf), "%sMapIndex", modNames[ndx]); 245 else if (ndx == XkbNoModifier) 246 snprintf(buf, sizeof(buf), "XkbNoModifier"); 247 else 248 snprintf(buf, sizeof(buf), "0x%02x", ndx); 249 } 250 else { 251 if (ndx < XkbNumModifiers) 252 strcpy(buf, modNames[ndx]); 253 else if (ndx == XkbNoModifier) 254 strcpy(buf, "none"); 255 else 256 snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx); 257 } 258 rtrn = tbGetBuffer(strlen(buf) + 1); 259 strcpy(rtrn, buf); 260 return rtrn; 261} 262 263char * 264XkbModMaskText(unsigned mask, unsigned format) 265{ 266 register int i, bit; 267 char buf[64], *rtrn; 268 269 if ((mask & 0xff) == 0xff) { 270 if (format == XkbCFile) 271 strcpy(buf, "0xff"); 272 else 273 strcpy(buf, "all"); 274 } 275 else if ((mask & 0xff) == 0) { 276 if (format == XkbCFile) 277 strcpy(buf, "0"); 278 else 279 strcpy(buf, "none"); 280 } 281 else { 282 char *str = buf; 283 284 buf[0] = '\0'; 285 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 286 if (mask & bit) { 287 if (str != buf) { 288 if (format == XkbCFile) 289 *str++ = '|'; 290 else 291 *str++ = '+'; 292 } 293 strcpy(str, modNames[i]); 294 str = &str[strlen(str)]; 295 if (format == XkbCFile) { 296 strcpy(str, "Mask"); 297 str += 4; 298 } 299 } 300 } 301 } 302 rtrn = tbGetBuffer(strlen(buf) + 1); 303 strcpy(rtrn, buf); 304 return rtrn; 305} 306 307/***====================================================================***/ 308 309/*ARGSUSED*/ 310char * 311XkbConfigText(unsigned config, unsigned format) 312{ 313 static char *buf; 314 const int bufsize = 32; 315 316 buf = tbGetBuffer(bufsize); 317 switch (config) { 318 case XkmSemanticsFile: 319 strcpy(buf, "Semantics"); 320 break; 321 case XkmLayoutFile: 322 strcpy(buf, "Layout"); 323 break; 324 case XkmKeymapFile: 325 strcpy(buf, "Keymap"); 326 break; 327 case XkmGeometryFile: 328 case XkmGeometryIndex: 329 strcpy(buf, "Geometry"); 330 break; 331 case XkmTypesIndex: 332 strcpy(buf, "Types"); 333 break; 334 case XkmCompatMapIndex: 335 strcpy(buf, "CompatMap"); 336 break; 337 case XkmSymbolsIndex: 338 strcpy(buf, "Symbols"); 339 break; 340 case XkmIndicatorsIndex: 341 strcpy(buf, "Indicators"); 342 break; 343 case XkmKeyNamesIndex: 344 strcpy(buf, "KeyNames"); 345 break; 346 case XkmVirtualModsIndex: 347 strcpy(buf, "VirtualMods"); 348 break; 349 default: 350 snprintf(buf, bufsize, "unknown(%d)", config); 351 break; 352 } 353 return buf; 354} 355 356/***====================================================================***/ 357 358char * 359XkbKeysymText(KeySym sym, unsigned format) 360{ 361 static char buf[32], *rtrn; 362 363 if (sym == NoSymbol) 364 strcpy(rtrn = buf, "NoSymbol"); 365 else if ((rtrn = XKeysymToString(sym)) == NULL) { 366 snprintf(buf, sizeof(buf), "0x%lx", (long) sym); 367 rtrn = buf; 368 } 369 else if (format == XkbCFile) { 370 snprintf(buf, sizeof(buf), "XK_%s", rtrn); 371 rtrn = buf; 372 } 373 return rtrn; 374} 375 376char * 377XkbKeyNameText(char *name, unsigned format) 378{ 379 char *buf; 380 381 if (format == XkbCFile) { 382 buf = tbGetBuffer(5); 383 memcpy(buf, name, 4); 384 buf[4] = '\0'; 385 } 386 else { 387 int len; 388 389 buf = tbGetBuffer(7); 390 buf[0] = '<'; 391 memcpy(&buf[1], name, 4); 392 buf[5] = '\0'; 393 len = strlen(buf); 394 buf[len++] = '>'; 395 buf[len] = '\0'; 396 } 397 return buf; 398} 399 400/***====================================================================***/ 401 402static char *siMatchText[5] = { 403 "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly" 404}; 405 406char * 407XkbSIMatchText(unsigned type, unsigned format) 408{ 409 static char buf[40]; 410 411 char *rtrn; 412 413 switch (type & XkbSI_OpMask) { 414 case XkbSI_NoneOf: rtrn = siMatchText[0]; break; 415 case XkbSI_AnyOfOrNone: rtrn = siMatchText[1]; break; 416 case XkbSI_AnyOf: rtrn = siMatchText[2]; break; 417 case XkbSI_AllOf: rtrn = siMatchText[3]; break; 418 case XkbSI_Exactly: rtrn = siMatchText[4]; break; 419 default: 420 snprintf(buf, sizeof(buf), "0x%x", type & XkbSI_OpMask); 421 return buf; 422 } 423 if (format == XkbCFile) { 424 if (type & XkbSI_LevelOneOnly) 425 snprintf(buf, sizeof(buf), "XkbSI_LevelOneOnly|XkbSI_%s", rtrn); 426 else 427 snprintf(buf, sizeof(buf), "XkbSI_%s", rtrn); 428 rtrn = buf; 429 } 430 return rtrn; 431} 432 433/***====================================================================***/ 434 435static const char *imWhichNames[] = { 436 "base", 437 "latched", 438 "locked", 439 "effective", 440 "compat" 441}; 442 443char * 444XkbIMWhichStateMaskText(unsigned use_which, unsigned format) 445{ 446 int len, bufsize; 447 unsigned i, bit, tmp; 448 char *buf; 449 450 if (use_which == 0) { 451 buf = tbGetBuffer(2); 452 strcpy(buf, "0"); 453 return buf; 454 } 455 tmp = use_which & XkbIM_UseAnyMods; 456 for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) { 457 if (tmp & bit) { 458 tmp &= ~bit; 459 len += strlen(imWhichNames[i]) + 1; 460 if (format == XkbCFile) 461 len += 9; 462 } 463 } 464 bufsize = len + 1; 465 buf = tbGetBuffer(bufsize); 466 tmp = use_which & XkbIM_UseAnyMods; 467 for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) { 468 if (tmp & bit) { 469 tmp &= ~bit; 470 if (format == XkbCFile) { 471 if (len != 0) 472 buf[len++] = '|'; 473 snprintf(&buf[len], bufsize - len, 474 "XkbIM_Use%s", imWhichNames[i]); 475 buf[len + 9] = toupper(buf[len + 9]); 476 } 477 else { 478 if (len != 0) 479 buf[len++] = '+'; 480 snprintf(&buf[len], bufsize - len, 481 "%s", imWhichNames[i]); 482 } 483 len += strlen(&buf[len]); 484 } 485 } 486 return buf; 487} 488 489char * 490XkbAccessXDetailText(unsigned state, unsigned format) 491{ 492 char *buf; 493 const char *prefix; 494 const int bufsize = 32; 495 496 buf = tbGetBuffer(bufsize); 497 if (format == XkbMessage) 498 prefix = ""; 499 else 500 prefix = "XkbAXN_"; 501 switch (state) { 502 case XkbAXN_SKPress: 503 snprintf(buf, bufsize, "%sSKPress", prefix); 504 break; 505 case XkbAXN_SKAccept: 506 snprintf(buf, bufsize, "%sSKAccept", prefix); 507 break; 508 case XkbAXN_SKRelease: 509 snprintf(buf, bufsize, "%sSKRelease", prefix); 510 break; 511 case XkbAXN_SKReject: 512 snprintf(buf, bufsize, "%sSKReject", prefix); 513 break; 514 case XkbAXN_BKAccept: 515 snprintf(buf, bufsize, "%sBKAccept", prefix); 516 break; 517 case XkbAXN_BKReject: 518 snprintf(buf, bufsize, "%sBKReject", prefix); 519 break; 520 case XkbAXN_AXKWarning: 521 snprintf(buf, bufsize, "%sAXKWarning", prefix); 522 break; 523 default: 524 snprintf(buf, bufsize, "ILLEGAL"); 525 break; 526 } 527 return buf; 528} 529 530static const char *nknNames[] = { 531 "keycodes", "geometry", "deviceID" 532}; 533#define NUM_NKN (sizeof(nknNames)/sizeof(char *)) 534 535char * 536XkbNKNDetailMaskText(unsigned detail, unsigned format) 537{ 538 char *buf; 539 const char *prefix, *suffix; 540 register int i; 541 register unsigned bit; 542 int len, plen, slen; 543 544 if ((detail & XkbAllNewKeyboardEventsMask) == 0) { 545 const char *tmp = ""; 546 547 if (format == XkbCFile) 548 tmp = "0"; 549 else if (format == XkbMessage) 550 tmp = "none"; 551 buf = tbGetBuffer(strlen(tmp) + 1); 552 strcpy(buf, tmp); 553 return buf; 554 } 555 else if ((detail & XkbAllNewKeyboardEventsMask) == 556 XkbAllNewKeyboardEventsMask) { 557 const char *tmp; 558 559 if (format == XkbCFile) 560 tmp = "XkbAllNewKeyboardEventsMask"; 561 else 562 tmp = "all"; 563 buf = tbGetBuffer(strlen(tmp) + 1); 564 strcpy(buf, tmp); 565 return buf; 566 } 567 if (format == XkbMessage) { 568 prefix = ""; 569 suffix = ""; 570 slen = plen = 0; 571 } 572 else { 573 prefix = "XkbNKN_"; 574 plen = 7; 575 if (format == XkbCFile) 576 suffix = "Mask"; 577 else 578 suffix = ""; 579 slen = strlen(suffix); 580 } 581 for (len = 0, i = 0, bit = 1; i < NUM_NKN; i++, bit <<= 1) { 582 if (detail & bit) { 583 if (len != 0) 584 len += 1; /* room for '+' or '|' */ 585 len += plen + slen + strlen(nknNames[i]); 586 } 587 } 588 buf = tbGetBuffer(len + 1); 589 buf[0] = '\0'; 590 for (len = 0, i = 0, bit = 1; i < NUM_NKN; i++, bit <<= 1) { 591 if (detail & bit) { 592 if (len != 0) { 593 if (format == XkbCFile) 594 buf[len++] = '|'; 595 else 596 buf[len++] = '+'; 597 } 598 if (plen) { 599 strcpy(&buf[len], prefix); 600 len += plen; 601 } 602 strcpy(&buf[len], nknNames[i]); 603 len += strlen(nknNames[i]); 604 if (slen) { 605 strcpy(&buf[len], suffix); 606 len += slen; 607 } 608 } 609 } 610 buf[len++] = '\0'; 611 return buf; 612} 613 614static const char *ctrlNames[] = { 615 "repeatKeys", 616 "slowKeys", 617 "bounceKeys", 618 "stickyKeys", 619 "mouseKeys", 620 "mouseKeysAccel", 621 "accessXKeys", 622 "accessXTimeout", 623 "accessXFeedback", 624 "audibleBell", 625 "overlay1", 626 "overlay2", 627 "ignoreGroupLock" 628}; 629 630char * 631XkbControlsMaskText(unsigned ctrls, unsigned format) 632{ 633 int len; 634 unsigned i, bit, tmp; 635 char *buf; 636 637 if (ctrls == 0) { 638 buf = tbGetBuffer(5); 639 if (format == XkbCFile) 640 strcpy(buf, "0"); 641 else 642 strcpy(buf, "none"); 643 return buf; 644 } 645 tmp = ctrls & XkbAllBooleanCtrlsMask; 646 for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) { 647 if (tmp & bit) { 648 tmp &= ~bit; 649 len += strlen(ctrlNames[i]) + 1; 650 if (format == XkbCFile) 651 len += 7; 652 } 653 } 654 buf = tbGetBuffer(len + 1); 655 tmp = ctrls & XkbAllBooleanCtrlsMask; 656 for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) { 657 if (tmp & bit) { 658 tmp &= ~bit; 659 if (format == XkbCFile) { 660 if (len != 0) 661 buf[len++] = '|'; 662 sprintf(&buf[len], "Xkb%sMask", ctrlNames[i]); 663 buf[len + 3] = toupper(buf[len + 3]); 664 } 665 else { 666 if (len != 0) 667 buf[len++] = '+'; 668 sprintf(&buf[len], "%s", ctrlNames[i]); 669 } 670 len += strlen(&buf[len]); 671 } 672 } 673 return buf; 674} 675 676/***====================================================================***/ 677 678char * 679XkbStringText(char *str, unsigned format) 680{ 681 char *buf; 682 register char *in, *out; 683 int len; 684 Bool ok; 685 686 if (str == NULL) { 687 buf = tbGetBuffer(2); 688 buf[0] = '\0'; 689 return buf; 690 } 691 else if (format == XkbXKMFile) 692 return str; 693 for (ok = True, len = 0, in = str; *in != '\0'; in++, len++) { 694 if (!isprint(*in)) { 695 ok = False; 696 switch (*in) { 697 case '\n': 698 case '\t': 699 case '\v': 700 case '\b': 701 case '\r': 702 case '\f': 703 len++; 704 break; 705 default: 706 len += 4; 707 break; 708 } 709 } 710 } 711 if (ok) 712 return str; 713 buf = tbGetBuffer(len + 1); 714 for (in = str, out = buf; *in != '\0'; in++) { 715 if (isprint(*in)) 716 *out++ = *in; 717 else { 718 *out++ = '\\'; 719 if (*in == '\n') 720 *out++ = 'n'; 721 else if (*in == '\t') 722 *out++ = 't'; 723 else if (*in == '\v') 724 *out++ = 'v'; 725 else if (*in == '\b') 726 *out++ = 'b'; 727 else if (*in == '\r') 728 *out++ = 'r'; 729 else if (*in == '\f') 730 *out++ = 'f'; 731 else if ((*in == '\033') && (format == XkbXKMFile)) { 732 *out++ = 'e'; 733 } 734 else { 735 *out++ = '0'; 736 sprintf(out, "%o", (unsigned char)*in); 737 while (*out != '\0') 738 out++; 739 } 740 } 741 } 742 *out++ = '\0'; 743 return buf; 744} 745 746/***====================================================================***/ 747 748char * 749XkbGeomFPText(int val, unsigned format) 750{ 751 int whole, frac; 752 char *buf; 753 const int bufsize = 12; 754 755 buf = tbGetBuffer(bufsize); 756 if (format == XkbCFile) { 757 snprintf(buf, bufsize, "%d", val); 758 } 759 else { 760 whole = val / XkbGeomPtsPerMM; 761 frac = abs(val % XkbGeomPtsPerMM); 762 if (frac != 0) { 763 if (val < 0) 764 { 765 int wholeabs; 766 wholeabs = abs(whole); 767 snprintf(buf, bufsize, "-%d.%d", wholeabs, frac); 768 } 769 else 770 snprintf(buf, bufsize, "%d.%d", whole, frac); 771 } 772 else 773 snprintf(buf, bufsize, "%d", whole); 774 } 775 return buf; 776} 777 778char * 779XkbDoodadTypeText(unsigned type, unsigned format) 780{ 781 char *buf; 782 783 if (format == XkbCFile) { 784 const int bufsize = 24; 785 buf = tbGetBuffer(bufsize); 786 if (type == XkbOutlineDoodad) 787 strcpy(buf, "XkbOutlineDoodad"); 788 else if (type == XkbSolidDoodad) 789 strcpy(buf, "XkbSolidDoodad"); 790 else if (type == XkbTextDoodad) 791 strcpy(buf, "XkbTextDoodad"); 792 else if (type == XkbIndicatorDoodad) 793 strcpy(buf, "XkbIndicatorDoodad"); 794 else if (type == XkbLogoDoodad) 795 strcpy(buf, "XkbLogoDoodad"); 796 else 797 snprintf(buf, bufsize, "UnknownDoodad%d", type); 798 } 799 else { 800 const int bufsize = 12; 801 buf = tbGetBuffer(bufsize); 802 if (type == XkbOutlineDoodad) 803 strcpy(buf, "outline"); 804 else if (type == XkbSolidDoodad) 805 strcpy(buf, "solid"); 806 else if (type == XkbTextDoodad) 807 strcpy(buf, "text"); 808 else if (type == XkbIndicatorDoodad) 809 strcpy(buf, "indicator"); 810 else if (type == XkbLogoDoodad) 811 strcpy(buf, "logo"); 812 else 813 snprintf(buf, bufsize, "unknown%d", type); 814 } 815 return buf; 816} 817 818static char *actionTypeNames[XkbSA_NumActions] = { 819 "NoAction", 820 "SetMods", "LatchMods", "LockMods", 821 "SetGroup", "LatchGroup", "LockGroup", 822 "MovePtr", 823 "PtrBtn", "LockPtrBtn", 824 "SetPtrDflt", 825 "ISOLock", 826 "Terminate", "SwitchScreen", 827 "SetControls", "LockControls", 828 "ActionMessage", 829 "RedirectKey", 830 "DeviceBtn", "LockDeviceBtn" 831}; 832 833char * 834XkbActionTypeText(unsigned type, unsigned format) 835{ 836 static char buf[32]; 837 char *rtrn; 838 839 if (type <= XkbSA_LastAction) { 840 rtrn = actionTypeNames[type]; 841 if (format == XkbCFile) { 842 snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn); 843 return buf; 844 } 845 return rtrn; 846 } 847 snprintf(buf, sizeof(buf), "Private"); 848 return buf; 849} 850 851/***====================================================================***/ 852 853static int 854TryCopyStr(char *to, const char *from, int *pLeft) 855{ 856 register int len; 857 858 if (*pLeft > 0) { 859 len = strlen(from); 860 if (len < ((*pLeft) - 3)) { 861 strcat(to, from); 862 *pLeft -= len; 863 return True; 864 } 865 } 866 *pLeft = -1; 867 return False; 868} 869 870/*ARGSUSED*/ 871static Bool 872CopyNoActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 873 char *buf, int *sz) 874{ 875 return True; 876} 877 878static Bool 879CopyModActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 880 char *buf, int *sz) 881{ 882 XkbModAction *act; 883 unsigned tmp; 884 885 act = &action->mods; 886 tmp = XkbModActionVMods(act); 887 TryCopyStr(buf, "modifiers=", sz); 888 if (act->flags & XkbSA_UseModMapMods) 889 TryCopyStr(buf, "modMapMods", sz); 890 else if (act->real_mods || tmp) { 891 TryCopyStr(buf, 892 XkbVModMaskText(dpy, xkb, act->real_mods, tmp, XkbXKBFile), 893 sz); 894 } 895 else 896 TryCopyStr(buf, "none", sz); 897 if (act->type == XkbSA_LockMods) { 898 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 899 case XkbSA_LockNoLock: 900 TryCopyStr(buf, ",affect=unlock", sz); 901 break; 902 case XkbSA_LockNoUnlock: 903 TryCopyStr(buf, ",affect=lock", sz); 904 break; 905 case XkbSA_LockNoUnlock|XkbSA_LockNoLock: 906 TryCopyStr(buf, ",affect=neither", sz); 907 break; 908 default: 909 break; 910 } 911 return True; 912 } 913 if (act->flags & XkbSA_ClearLocks) 914 TryCopyStr(buf, ",clearLocks", sz); 915 if (act->flags & XkbSA_LatchToLock) 916 TryCopyStr(buf, ",latchToLock", sz); 917 return True; 918} 919 920/*ARGSUSED*/ 921static Bool 922CopyGroupActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 923 char *buf, int *sz) 924{ 925 XkbGroupAction *act; 926 char tbuf[32]; 927 928 act = &action->group; 929 TryCopyStr(buf, "group=", sz); 930 if (act->flags & XkbSA_GroupAbsolute) 931 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1); 932 else if (XkbSAGroup(act) < 0) 933 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act)); 934 else 935 snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act)); 936 TryCopyStr(buf, tbuf, sz); 937 if (act->type == XkbSA_LockGroup) 938 return True; 939 if (act->flags & XkbSA_ClearLocks) 940 TryCopyStr(buf, ",clearLocks", sz); 941 if (act->flags & XkbSA_LatchToLock) 942 TryCopyStr(buf, ",latchToLock", sz); 943 return True; 944} 945 946/*ARGSUSED*/ 947static Bool 948CopyMovePtrArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 949 char *buf, int *sz) 950{ 951 XkbPtrAction *act; 952 int x, y; 953 char tbuf[32]; 954 955 act = &action->ptr; 956 x = XkbPtrActionX(act); 957 y = XkbPtrActionY(act); 958 if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0)) 959 snprintf(tbuf, sizeof(tbuf), "x=%d", x); 960 else 961 snprintf(tbuf, sizeof(tbuf), "x=+%d", x); 962 TryCopyStr(buf, tbuf, sz); 963 964 if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0)) 965 snprintf(tbuf, sizeof(tbuf), ",y=%d", y); 966 else 967 snprintf(tbuf, sizeof(tbuf), ",y=+%d", y); 968 TryCopyStr(buf, tbuf, sz); 969 if (act->flags & XkbSA_NoAcceleration) 970 TryCopyStr(buf, ",!accel", sz); 971 return True; 972} 973 974/*ARGSUSED*/ 975static Bool 976CopyPtrBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 977 char *buf, int *sz) 978{ 979 XkbPtrBtnAction *act; 980 char tbuf[32]; 981 982 act = &action->btn; 983 TryCopyStr(buf, "button=", sz); 984 if ((act->button > 0) && (act->button < 6)) { 985 snprintf(tbuf, sizeof(tbuf), "%d", act->button); 986 TryCopyStr(buf, tbuf, sz); 987 } 988 else 989 TryCopyStr(buf, "default", sz); 990 if (act->count > 0) { 991 snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count); 992 TryCopyStr(buf, tbuf, sz); 993 } 994 if (action->type == XkbSA_LockPtrBtn) { 995 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 996 case XkbSA_LockNoLock: 997 snprintf(tbuf, sizeof(tbuf), ",affect=unlock"); 998 break; 999 case XkbSA_LockNoUnlock: 1000 snprintf(tbuf, sizeof(tbuf), ",affect=lock"); 1001 break; 1002 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 1003 snprintf(tbuf, sizeof(tbuf), ",affect=neither"); 1004 break; 1005 default: 1006 snprintf(tbuf, sizeof(tbuf), ",affect=both"); 1007 break; 1008 } 1009 TryCopyStr(buf, tbuf, sz); 1010 } 1011 return True; 1012} 1013 1014/*ARGSUSED*/ 1015static Bool 1016CopySetPtrDfltArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1017 char *buf, int *sz) 1018{ 1019 XkbPtrDfltAction *act; 1020 char tbuf[32]; 1021 1022 act = &action->dflt; 1023 if (act->affect == XkbSA_AffectDfltBtn) { 1024 TryCopyStr(buf, "affect=button,button=", sz); 1025 if ((act->flags & XkbSA_DfltBtnAbsolute) || 1026 (XkbSAPtrDfltValue(act) < 0)) 1027 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act)); 1028 else 1029 snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act)); 1030 TryCopyStr(buf, tbuf, sz); 1031 } 1032 return True; 1033} 1034 1035static Bool 1036CopyISOLockArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1037 char *buf, int *sz) 1038{ 1039 XkbISOAction *act; 1040 char tbuf[64]; 1041 1042 act = &action->iso; 1043 if (act->flags & XkbSA_ISODfltIsGroup) { 1044 TryCopyStr(tbuf, "group=", sz); 1045 if (act->flags & XkbSA_GroupAbsolute) 1046 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1); 1047 else if (XkbSAGroup(act) < 0) 1048 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act)); 1049 else 1050 snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act)); 1051 TryCopyStr(buf, tbuf, sz); 1052 } 1053 else { 1054 unsigned tmp; 1055 1056 tmp = XkbModActionVMods(act); 1057 TryCopyStr(buf, "modifiers=", sz); 1058 if (act->flags & XkbSA_UseModMapMods) 1059 TryCopyStr(buf, "modMapMods", sz); 1060 else if (act->real_mods || tmp) { 1061 if (act->real_mods) { 1062 TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz); 1063 if (tmp) 1064 TryCopyStr(buf, "+", sz); 1065 } 1066 if (tmp) 1067 TryCopyStr(buf, XkbVModMaskText(dpy, xkb, 0, tmp, XkbXKBFile), 1068 sz); 1069 } 1070 else 1071 TryCopyStr(buf, "none", sz); 1072 } 1073 TryCopyStr(buf, ",affect=", sz); 1074 if ((act->affect & XkbSA_ISOAffectMask) == 0) { 1075 TryCopyStr(buf, "all", sz); 1076 } 1077 else if ((act->affect & XkbSA_ISOAffectMask) == XkbSA_ISOAffectMask) { 1078 TryCopyStr(buf, "none", sz); 1079 } 1080 else { 1081 int nOut = 0; 1082 1083 if ((act->affect & XkbSA_ISONoAffectMods) == 0) { 1084 TryCopyStr(buf, "mods", sz); 1085 nOut++; 1086 } 1087 if ((act->affect & XkbSA_ISONoAffectGroup) == 0) { 1088 snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : "")); 1089 TryCopyStr(buf, tbuf, sz); 1090 nOut++; 1091 } 1092 if ((act->affect & XkbSA_ISONoAffectPtr) == 0) { 1093 snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : "")); 1094 TryCopyStr(buf, tbuf, sz); 1095 nOut++; 1096 } 1097 if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) { 1098 snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : "")); 1099 TryCopyStr(buf, tbuf, sz); 1100 nOut++; 1101 } 1102 } 1103 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 1104 case XkbSA_LockNoLock: 1105 TryCopyStr(buf, "+unlock", sz); 1106 break; 1107 case XkbSA_LockNoUnlock: 1108 TryCopyStr(buf, "+lock", sz); 1109 break; 1110 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 1111 TryCopyStr(buf, "+neither", sz); 1112 break; 1113 default: ; 1114 } 1115 return True; 1116} 1117 1118/*ARGSUSED*/ 1119static Bool 1120CopySwitchScreenArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1121 char *buf, int *sz) 1122{ 1123 XkbSwitchScreenAction *act; 1124 char tbuf[32]; 1125 1126 act = &action->screen; 1127 if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0)) 1128 snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act)); 1129 else 1130 snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act)); 1131 TryCopyStr(buf, tbuf, sz); 1132 if (act->flags & XkbSA_SwitchApplication) 1133 TryCopyStr(buf, ",!same", sz); 1134 else 1135 TryCopyStr(buf, ",same", sz); 1136 return True; 1137} 1138 1139/*ARGSUSED*/ 1140static Bool 1141CopySetLockControlsArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1142 char *buf, int *sz) 1143{ 1144 XkbCtrlsAction *act; 1145 unsigned tmp; 1146 char tbuf[32]; 1147 1148 act = &action->ctrls; 1149 tmp = XkbActionCtrls(act); 1150 TryCopyStr(buf, "controls=", sz); 1151 if (tmp == 0) 1152 TryCopyStr(buf, "none", sz); 1153 else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask) 1154 TryCopyStr(buf, "all", sz); 1155 else { 1156 int nOut = 0; 1157 1158 if (tmp & XkbRepeatKeysMask) { 1159 snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : "")); 1160 TryCopyStr(buf, tbuf, sz); 1161 nOut++; 1162 } 1163 if (tmp & XkbSlowKeysMask) { 1164 snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : "")); 1165 TryCopyStr(buf, tbuf, sz); 1166 nOut++; 1167 } 1168 if (tmp & XkbBounceKeysMask) { 1169 snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : "")); 1170 TryCopyStr(buf, tbuf, sz); 1171 nOut++; 1172 } 1173 if (tmp & XkbStickyKeysMask) { 1174 snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : "")); 1175 TryCopyStr(buf, tbuf, sz); 1176 nOut++; 1177 } 1178 if (tmp & XkbMouseKeysMask) { 1179 snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : "")); 1180 TryCopyStr(buf, tbuf, sz); 1181 nOut++; 1182 } 1183 if (tmp & XkbMouseKeysAccelMask) { 1184 snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel", (nOut > 0 ? "+" : "")); 1185 TryCopyStr(buf, tbuf, sz); 1186 nOut++; 1187 } 1188 if (tmp & XkbAccessXKeysMask) { 1189 snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys", (nOut > 0 ? "+" : "")); 1190 TryCopyStr(buf, tbuf, sz); 1191 nOut++; 1192 } 1193 if (tmp & XkbAccessXTimeoutMask) { 1194 snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout", (nOut > 0 ? "+" : "")); 1195 TryCopyStr(buf, tbuf, sz); 1196 nOut++; 1197 } 1198 if (tmp & XkbAccessXFeedbackMask) { 1199 snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback", (nOut > 0 ? "+" : "")); 1200 TryCopyStr(buf, tbuf, sz); 1201 nOut++; 1202 } 1203 if (tmp & XkbAudibleBellMask) { 1204 snprintf(tbuf, sizeof(tbuf), "%sAudibleBell", (nOut > 0 ? "+" : "")); 1205 TryCopyStr(buf, tbuf, sz); 1206 nOut++; 1207 } 1208 if (tmp & XkbOverlay1Mask) { 1209 snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : "")); 1210 TryCopyStr(buf, tbuf, sz); 1211 nOut++; 1212 } 1213 if (tmp & XkbOverlay2Mask) { 1214 snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : "")); 1215 TryCopyStr(buf, tbuf, sz); 1216 nOut++; 1217 } 1218 if (tmp & XkbIgnoreGroupLockMask) { 1219 snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock", (nOut > 0 ? "+" : "")); 1220 TryCopyStr(buf, tbuf, sz); 1221 nOut++; 1222 } 1223 } 1224 if (action->type == XkbSA_LockControls) { 1225 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 1226 case XkbSA_LockNoLock: 1227 TryCopyStr(buf, ",affect=unlock", sz); 1228 break; 1229 case XkbSA_LockNoUnlock: 1230 TryCopyStr(buf, ",affect=lock", sz); 1231 break; 1232 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 1233 TryCopyStr(buf, ",affect=neither", sz); 1234 break; 1235 default: ; 1236 } 1237 } 1238 return True; 1239} 1240 1241/*ARGSUSED*/ 1242static Bool 1243CopyActionMessageArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1244 char *buf, int *sz) 1245{ 1246 XkbMessageAction *act; 1247 unsigned all; 1248 char tbuf[32]; 1249 1250 act = &action->msg; 1251 all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease; 1252 TryCopyStr(buf, "report=", sz); 1253 if ((act->flags & all) == 0) 1254 TryCopyStr(buf, "none", sz); 1255 else if ((act->flags & all) == all) 1256 TryCopyStr(buf, "all", sz); 1257 else if (act->flags & XkbSA_MessageOnPress) 1258 TryCopyStr(buf, "KeyPress", sz); 1259 else 1260 TryCopyStr(buf, "KeyRelease", sz); 1261 snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]); 1262 TryCopyStr(buf, tbuf, sz); 1263 snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]); 1264 TryCopyStr(buf, tbuf, sz); 1265 snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]); 1266 TryCopyStr(buf, tbuf, sz); 1267 snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]); 1268 TryCopyStr(buf, tbuf, sz); 1269 snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]); 1270 TryCopyStr(buf, tbuf, sz); 1271 snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]); 1272 TryCopyStr(buf, tbuf, sz); 1273 if (act->flags & XkbSA_MessageGenKeyEvent) 1274 TryCopyStr(buf, ",genKeyEvent", sz); 1275 return True; 1276} 1277 1278static Bool 1279CopyRedirectKeyArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1280 char *buf, int *sz) 1281{ 1282 XkbRedirectKeyAction *act; 1283 char tbuf[32], *tmp; 1284 unsigned kc; 1285 unsigned vmods, vmods_mask; 1286 1287 act = &action->redirect; 1288 kc = act->new_key; 1289 vmods = XkbSARedirectVMods(act); 1290 vmods_mask = XkbSARedirectVModsMask(act); 1291 if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) && 1292 (xkb->names->keys[kc].name[0] != '\0')) { 1293 char *kn; 1294 1295 kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile); 1296 snprintf(tbuf, sizeof(tbuf), "key=%s", kn); 1297 } 1298 else 1299 snprintf(tbuf, sizeof(tbuf), "key=%d", kc); 1300 TryCopyStr(buf, tbuf, sz); 1301 if ((act->mods_mask == 0) && (vmods_mask == 0)) 1302 return True; 1303 if ((act->mods_mask == XkbAllModifiersMask) && 1304 (vmods_mask == XkbAllVirtualModsMask)) { 1305 tmp = XkbVModMaskText(dpy, xkb, act->mods, vmods, XkbXKBFile); 1306 TryCopyStr(buf, ",mods=", sz); 1307 TryCopyStr(buf, tmp, sz); 1308 } 1309 else { 1310 if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) { 1311 tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & act->mods, 1312 vmods_mask & vmods, XkbXKBFile); 1313 TryCopyStr(buf, ",mods= ", sz); 1314 TryCopyStr(buf, tmp, sz); 1315 } 1316 if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) { 1317 tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & (~act->mods), 1318 vmods_mask & (~vmods), XkbXKBFile); 1319 TryCopyStr(buf, ",clearMods= ", sz); 1320 TryCopyStr(buf, tmp, sz); 1321 } 1322 } 1323 return True; 1324} 1325 1326/*ARGSUSED*/ 1327static Bool 1328CopyDeviceBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1329 char *buf, int *sz) 1330{ 1331 XkbDeviceBtnAction *act; 1332 char tbuf[32]; 1333 1334 act = &action->devbtn; 1335 snprintf(tbuf, sizeof(tbuf), "device= %d", act->device); 1336 TryCopyStr(buf, tbuf, sz); 1337 TryCopyStr(buf, ",button=", sz); 1338 snprintf(tbuf, sizeof(tbuf), "%d", act->button); 1339 TryCopyStr(buf, tbuf, sz); 1340 if (act->count > 0) { 1341 snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count); 1342 TryCopyStr(buf, tbuf, sz); 1343 } 1344 if (action->type == XkbSA_LockDeviceBtn) { 1345 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 1346 case XkbSA_LockNoLock: 1347 snprintf(tbuf, sizeof(tbuf), ",affect=unlock"); 1348 break; 1349 case XkbSA_LockNoUnlock: 1350 snprintf(tbuf, sizeof(tbuf), ",affect=lock"); 1351 break; 1352 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 1353 snprintf(tbuf, sizeof(tbuf), ",affect=neither"); 1354 break; 1355 default: 1356 snprintf(tbuf, sizeof(tbuf), ",affect=both"); 1357 break; 1358 } 1359 TryCopyStr(buf, tbuf, sz); 1360 } 1361 return True; 1362} 1363 1364/*ARGSUSED*/ 1365static Bool 1366CopyOtherArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1367 char *buf, int *sz) 1368{ 1369 XkbAnyAction *act; 1370 char tbuf[32]; 1371 1372 act = &action->any; 1373 snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type); 1374 TryCopyStr(buf, tbuf, sz); 1375 snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]); 1376 TryCopyStr(buf, tbuf, sz); 1377 snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]); 1378 TryCopyStr(buf, tbuf, sz); 1379 snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]); 1380 TryCopyStr(buf, tbuf, sz); 1381 snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]); 1382 TryCopyStr(buf, tbuf, sz); 1383 snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]); 1384 TryCopyStr(buf, tbuf, sz); 1385 snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]); 1386 TryCopyStr(buf, tbuf, sz); 1387 snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]); 1388 TryCopyStr(buf, tbuf, sz); 1389 return True; 1390} 1391 1392typedef Bool (*actionCopy) (Display * /* dpy */ , 1393 XkbDescPtr /* xkb */ , 1394 XkbAction * /* action */ , 1395 char * /* buf */ , 1396 int * /* sz */ 1397 ); 1398 1399static actionCopy copyActionArgs[XkbSA_NumActions] = { 1400 CopyNoActionArgs /* NoAction */ , 1401 CopyModActionArgs /* SetMods */ , 1402 CopyModActionArgs /* LatchMods */ , 1403 CopyModActionArgs /* LockMods */ , 1404 CopyGroupActionArgs /* SetGroup */ , 1405 CopyGroupActionArgs /* LatchGroup */ , 1406 CopyGroupActionArgs /* LockGroup */ , 1407 CopyMovePtrArgs /* MovePtr */ , 1408 CopyPtrBtnArgs /* PtrBtn */ , 1409 CopyPtrBtnArgs /* LockPtrBtn */ , 1410 CopySetPtrDfltArgs /* SetPtrDflt */ , 1411 CopyISOLockArgs /* ISOLock */ , 1412 CopyNoActionArgs /* Terminate */ , 1413 CopySwitchScreenArgs /* SwitchScreen */ , 1414 CopySetLockControlsArgs /* SetControls */ , 1415 CopySetLockControlsArgs /* LockControls */ , 1416 CopyActionMessageArgs /* ActionMessage */ , 1417 CopyRedirectKeyArgs /* RedirectKey */ , 1418 CopyDeviceBtnArgs /* DeviceBtn */ , 1419 CopyDeviceBtnArgs /* LockDeviceBtn */ 1420}; 1421 1422#define ACTION_SZ 256 1423 1424char * 1425XkbActionText(Display *dpy, XkbDescPtr xkb, XkbAction *action, unsigned format) 1426{ 1427 char buf[ACTION_SZ], *tmp; 1428 int sz; 1429 1430 if (format == XkbCFile) { 1431 snprintf(buf, sizeof(buf), 1432 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }", 1433 XkbActionTypeText(action->type, XkbCFile), 1434 action->any.data[0], action->any.data[1], action->any.data[2], 1435 action->any.data[3], action->any.data[4], action->any.data[5], 1436 action->any.data[6]); 1437 } 1438 else { 1439 snprintf(buf, sizeof(buf), 1440 "%s(", XkbActionTypeText(action->type, XkbXKBFile)); 1441 sz = ACTION_SZ - strlen(buf) + 2; /* room for close paren and NULL */ 1442 if (action->type < (unsigned) XkbSA_NumActions) 1443 (*copyActionArgs[action->type]) (dpy, xkb, action, buf, &sz); 1444 else 1445 CopyOtherArgs(dpy, xkb, action, buf, &sz); 1446 TryCopyStr(buf, ")", &sz); 1447 } 1448 tmp = tbGetBuffer(strlen(buf) + 1); 1449 if (tmp != NULL) 1450 strcpy(tmp, buf); 1451 return tmp; 1452} 1453 1454char * 1455XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format) 1456{ 1457 char buf[256], *tmp; 1458 1459 if (format == XkbCFile) { 1460 if (behavior->type == XkbKB_Default) 1461 snprintf(buf, sizeof(buf), "{ 0, 0 }"); 1462 else 1463 snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type, behavior->data); 1464 } 1465 else { 1466 unsigned type, permanent; 1467 1468 type = behavior->type & XkbKB_OpMask; 1469 permanent = ((behavior->type & XkbKB_Permanent) != 0); 1470 1471 if (type == XkbKB_Lock) { 1472 snprintf(buf, sizeof(buf), "lock= %s", (permanent ? "Permanent" : "True")); 1473 } 1474 else if (type == XkbKB_RadioGroup) { 1475 int g; 1476 char *tmp; 1477 size_t tmpsize; 1478 1479 g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1; 1480 if (XkbKB_RGAllowNone & behavior->data) { 1481 snprintf(buf, sizeof(buf), "allowNone,"); 1482 tmp = &buf[strlen(buf)]; 1483 } 1484 else 1485 tmp = buf; 1486 tmpsize = sizeof(buf) - (tmp - buf); 1487 if (permanent) 1488 snprintf(tmp, tmpsize, "permanentRadioGroup= %d", g); 1489 else 1490 snprintf(tmp, tmpsize, "radioGroup= %d", g); 1491 } 1492 else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) { 1493 int ndx, kc; 1494 char *kn; 1495 1496 ndx = ((type == XkbKB_Overlay1) ? 1 : 2); 1497 kc = behavior->data; 1498 if ((xkb) && (xkb->names) && (xkb->names->keys)) 1499 kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile); 1500 else { 1501 static char tbuf[8]; 1502 1503 snprintf(tbuf, sizeof(tbuf), "%d", kc); 1504 kn = tbuf; 1505 } 1506 if (permanent) 1507 snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn); 1508 else 1509 snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn); 1510 } 1511 } 1512 tmp = tbGetBuffer(strlen(buf) + 1); 1513 if (tmp != NULL) 1514 strcpy(tmp, buf); 1515 return tmp; 1516} 1517 1518/***====================================================================***/ 1519 1520char * 1521XkbIndentText(unsigned size) 1522{ 1523 static char buf[32]; 1524 register int i; 1525 1526 if (size > 31) 1527 size = 31; 1528 1529 for (i = 0; i < size; i++) { 1530 buf[i] = ' '; 1531 } 1532 buf[size] = '\0'; 1533 return buf; 1534} 1535 1536 1537/***====================================================================***/ 1538 1539#define PIXEL_MAX 65535 1540 1541Bool 1542XkbLookupCanonicalRGBColor(char *def, XColor *color) 1543{ 1544 int tmp; 1545 1546 if (_XkbStrCaseEqual(def, "black")) { 1547 color->red = color->green = color->blue = 0; 1548 return True; 1549 } 1550 else if (_XkbStrCaseEqual(def, "white")) { 1551 color->red = color->green = color->blue = PIXEL_MAX; 1552 return True; 1553 } 1554 else if ((sscanf(def, "grey%d", &tmp) == 1) || 1555 (sscanf(def, "gray%d", &tmp) == 1) || 1556 (sscanf(def, "Grey%d", &tmp) == 1) || 1557 (sscanf(def, "Gray%d", &tmp) == 1)) { 1558 if ((tmp > 0) && (tmp <= 100)) { 1559 tmp = (PIXEL_MAX * tmp) / 100; 1560 color->red = color->green = color->blue = tmp; 1561 return True; 1562 } 1563 } 1564 else if ((tmp = (_XkbStrCaseEqual(def, "red") * 100)) || 1565 (sscanf(def, "red%d", &tmp) == 1)) { 1566 if ((tmp > 0) && (tmp <= 100)) { 1567 tmp = (PIXEL_MAX * tmp) / 100; 1568 color->red = tmp; 1569 color->green = color->blue = 0; 1570 return True; 1571 } 1572 } 1573 else if ((tmp = (_XkbStrCaseEqual(def, "green") * 100)) || 1574 (sscanf(def, "green%d", &tmp) == 1)) { 1575 if ((tmp > 0) && (tmp <= 100)) { 1576 tmp = (PIXEL_MAX * tmp) / 100; 1577 color->green = tmp; 1578 color->red = color->blue = 0; 1579 return True; 1580 } 1581 } 1582 else if ((tmp = (_XkbStrCaseEqual(def, "blue") * 100)) || 1583 (sscanf(def, "blue%d", &tmp) == 1)) { 1584 if ((tmp > 0) && (tmp <= 100)) { 1585 tmp = (PIXEL_MAX * tmp) / 100; 1586 color->blue = tmp; 1587 color->red = color->green = 0; 1588 return True; 1589 } 1590 } 1591 else if ((tmp = (_XkbStrCaseEqual(def, "magenta") * 100)) || 1592 (sscanf(def, "magenta%d", &tmp) == 1)) { 1593 if ((tmp > 0) && (tmp <= 100)) { 1594 tmp = (PIXEL_MAX * tmp) / 100; 1595 color->green = 0; 1596 color->red = color->blue = tmp; 1597 return True; 1598 } 1599 } 1600 else if ((tmp = (_XkbStrCaseEqual(def, "cyan") * 100)) || 1601 (sscanf(def, "cyan%d", &tmp) == 1)) { 1602 if ((tmp > 0) && (tmp <= 100)) { 1603 tmp = (PIXEL_MAX * tmp) / 100; 1604 color->red = 0; 1605 color->green = color->blue = tmp; 1606 return True; 1607 } 1608 } 1609 else if ((tmp = (_XkbStrCaseEqual(def, "yellow") * 100)) || 1610 (sscanf(def, "yellow%d", &tmp) == 1)) { 1611 if ((tmp > 0) && (tmp <= 100)) { 1612 tmp = (PIXEL_MAX * tmp) / 100; 1613 color->blue = 0; 1614 color->red = color->green = tmp; 1615 return True; 1616 } 1617 } 1618 return False; 1619} 1620 1621