xkbtext.c revision 70728a38
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 += 4; 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", *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 = val % XkbGeomPtsPerMM; 762 if (frac != 0) 763 snprintf(buf, bufsize, "%d.%d", whole, frac); 764 else 765 snprintf(buf, bufsize, "%d", whole); 766 } 767 return buf; 768} 769 770char * 771XkbDoodadTypeText(unsigned type, unsigned format) 772{ 773 char *buf; 774 775 if (format == XkbCFile) { 776 const int bufsize = 24; 777 buf = tbGetBuffer(bufsize); 778 if (type == XkbOutlineDoodad) 779 strcpy(buf, "XkbOutlineDoodad"); 780 else if (type == XkbSolidDoodad) 781 strcpy(buf, "XkbSolidDoodad"); 782 else if (type == XkbTextDoodad) 783 strcpy(buf, "XkbTextDoodad"); 784 else if (type == XkbIndicatorDoodad) 785 strcpy(buf, "XkbIndicatorDoodad"); 786 else if (type == XkbLogoDoodad) 787 strcpy(buf, "XkbLogoDoodad"); 788 else 789 snprintf(buf, bufsize, "UnknownDoodad%d", type); 790 } 791 else { 792 const int bufsize = 12; 793 buf = tbGetBuffer(bufsize); 794 if (type == XkbOutlineDoodad) 795 strcpy(buf, "outline"); 796 else if (type == XkbSolidDoodad) 797 strcpy(buf, "solid"); 798 else if (type == XkbTextDoodad) 799 strcpy(buf, "text"); 800 else if (type == XkbIndicatorDoodad) 801 strcpy(buf, "indicator"); 802 else if (type == XkbLogoDoodad) 803 strcpy(buf, "logo"); 804 else 805 snprintf(buf, bufsize, "unknown%d", type); 806 } 807 return buf; 808} 809 810static char *actionTypeNames[XkbSA_NumActions] = { 811 "NoAction", 812 "SetMods", "LatchMods", "LockMods", 813 "SetGroup", "LatchGroup", "LockGroup", 814 "MovePtr", 815 "PtrBtn", "LockPtrBtn", 816 "SetPtrDflt", 817 "ISOLock", 818 "Terminate", "SwitchScreen", 819 "SetControls", "LockControls", 820 "ActionMessage", 821 "RedirectKey", 822 "DeviceBtn", "LockDeviceBtn" 823}; 824 825char * 826XkbActionTypeText(unsigned type, unsigned format) 827{ 828 static char buf[32]; 829 char *rtrn; 830 831 if (type <= XkbSA_LastAction) { 832 rtrn = actionTypeNames[type]; 833 if (format == XkbCFile) { 834 snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn); 835 return buf; 836 } 837 return rtrn; 838 } 839 snprintf(buf, sizeof(buf), "Private"); 840 return buf; 841} 842 843/***====================================================================***/ 844 845static int 846TryCopyStr(char *to, const char *from, int *pLeft) 847{ 848 register int len; 849 850 if (*pLeft > 0) { 851 len = strlen(from); 852 if (len < ((*pLeft) - 3)) { 853 strcat(to, from); 854 *pLeft -= len; 855 return True; 856 } 857 } 858 *pLeft = -1; 859 return False; 860} 861 862/*ARGSUSED*/ 863static Bool 864CopyNoActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 865 char *buf, int *sz) 866{ 867 return True; 868} 869 870static Bool 871CopyModActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 872 char *buf, int *sz) 873{ 874 XkbModAction *act; 875 unsigned tmp; 876 877 act = &action->mods; 878 tmp = XkbModActionVMods(act); 879 TryCopyStr(buf, "modifiers=", sz); 880 if (act->flags & XkbSA_UseModMapMods) 881 TryCopyStr(buf, "modMapMods", sz); 882 else if (act->real_mods || tmp) { 883 TryCopyStr(buf, 884 XkbVModMaskText(dpy, xkb, act->real_mods, tmp, XkbXKBFile), 885 sz); 886 } 887 else 888 TryCopyStr(buf, "none", sz); 889 if (act->type == XkbSA_LockMods) 890 return True; 891 if (act->flags & XkbSA_ClearLocks) 892 TryCopyStr(buf, ",clearLocks", sz); 893 if (act->flags & XkbSA_LatchToLock) 894 TryCopyStr(buf, ",latchToLock", sz); 895 return True; 896} 897 898/*ARGSUSED*/ 899static Bool 900CopyGroupActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 901 char *buf, int *sz) 902{ 903 XkbGroupAction *act; 904 char tbuf[32]; 905 906 act = &action->group; 907 TryCopyStr(buf, "group=", sz); 908 if (act->flags & XkbSA_GroupAbsolute) 909 snprintf(tbuf, sizeof(buf), "%d", XkbSAGroup(act) + 1); 910 else if (XkbSAGroup(act) < 0) 911 snprintf(tbuf, sizeof(buf), "%d", XkbSAGroup(act)); 912 else 913 snprintf(tbuf, sizeof(buf), "+%d", XkbSAGroup(act)); 914 TryCopyStr(buf, tbuf, sz); 915 if (act->type == XkbSA_LockGroup) 916 return True; 917 if (act->flags & XkbSA_ClearLocks) 918 TryCopyStr(buf, ",clearLocks", sz); 919 if (act->flags & XkbSA_LatchToLock) 920 TryCopyStr(buf, ",latchToLock", sz); 921 return True; 922} 923 924/*ARGSUSED*/ 925static Bool 926CopyMovePtrArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 927 char *buf, int *sz) 928{ 929 XkbPtrAction *act; 930 int x, y; 931 char tbuf[32]; 932 933 act = &action->ptr; 934 x = XkbPtrActionX(act); 935 y = XkbPtrActionY(act); 936 if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0)) 937 snprintf(tbuf, sizeof(tbuf), "x=%d", x); 938 else 939 snprintf(tbuf, sizeof(tbuf), "x=+%d", x); 940 TryCopyStr(buf, tbuf, sz); 941 942 if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0)) 943 snprintf(tbuf, sizeof(tbuf), ",y=%d", y); 944 else 945 snprintf(tbuf, sizeof(tbuf), ",y=+%d", y); 946 TryCopyStr(buf, tbuf, sz); 947 if (act->flags & XkbSA_NoAcceleration) 948 TryCopyStr(buf, ",!accel", sz); 949 return True; 950} 951 952/*ARGSUSED*/ 953static Bool 954CopyPtrBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 955 char *buf, int *sz) 956{ 957 XkbPtrBtnAction *act; 958 char tbuf[32]; 959 960 act = &action->btn; 961 TryCopyStr(buf, "button=", sz); 962 if ((act->button > 0) && (act->button < 6)) { 963 snprintf(tbuf, sizeof(tbuf), "%d", act->button); 964 TryCopyStr(buf, tbuf, sz); 965 } 966 else 967 TryCopyStr(buf, "default", sz); 968 if (act->count > 0) { 969 snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count); 970 TryCopyStr(buf, tbuf, sz); 971 } 972 if (action->type == XkbSA_LockPtrBtn) { 973 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 974 case XkbSA_LockNoLock: 975 snprintf(tbuf, sizeof(tbuf), ",affect=unlock"); 976 break; 977 case XkbSA_LockNoUnlock: 978 snprintf(tbuf, sizeof(tbuf), ",affect=lock"); 979 break; 980 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 981 snprintf(tbuf, sizeof(tbuf), ",affect=neither"); 982 break; 983 default: 984 snprintf(tbuf, sizeof(tbuf), ",affect=both"); 985 break; 986 } 987 TryCopyStr(buf, tbuf, sz); 988 } 989 return True; 990} 991 992/*ARGSUSED*/ 993static Bool 994CopySetPtrDfltArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 995 char *buf, int *sz) 996{ 997 XkbPtrDfltAction *act; 998 char tbuf[32]; 999 1000 act = &action->dflt; 1001 if (act->affect == XkbSA_AffectDfltBtn) { 1002 TryCopyStr(buf, "affect=button,button=", sz); 1003 if ((act->flags & XkbSA_DfltBtnAbsolute) || 1004 (XkbSAPtrDfltValue(act) < 0)) 1005 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act)); 1006 else 1007 snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act)); 1008 TryCopyStr(buf, tbuf, sz); 1009 } 1010 return True; 1011} 1012 1013static Bool 1014CopyISOLockArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1015 char *buf, int *sz) 1016{ 1017 XkbISOAction *act; 1018 char tbuf[64]; 1019 1020 act = &action->iso; 1021 if (act->flags & XkbSA_ISODfltIsGroup) { 1022 TryCopyStr(tbuf, "group=", sz); 1023 if (act->flags & XkbSA_GroupAbsolute) 1024 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1); 1025 else if (XkbSAGroup(act) < 0) 1026 snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act)); 1027 else 1028 snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act)); 1029 TryCopyStr(buf, tbuf, sz); 1030 } 1031 else { 1032 unsigned tmp; 1033 1034 tmp = XkbModActionVMods(act); 1035 TryCopyStr(buf, "modifiers=", sz); 1036 if (act->flags & XkbSA_UseModMapMods) 1037 TryCopyStr(buf, "modMapMods", sz); 1038 else if (act->real_mods || tmp) { 1039 if (act->real_mods) { 1040 TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz); 1041 if (tmp) 1042 TryCopyStr(buf, "+", sz); 1043 } 1044 if (tmp) 1045 TryCopyStr(buf, XkbVModMaskText(dpy, xkb, 0, tmp, XkbXKBFile), 1046 sz); 1047 } 1048 else 1049 TryCopyStr(buf, "none", sz); 1050 } 1051 TryCopyStr(buf, ",affect=", sz); 1052 if ((act->affect & XkbSA_ISOAffectMask) == 0) 1053 TryCopyStr(buf, "all", sz); 1054 else { 1055 int nOut = 0; 1056 1057 if ((act->affect & XkbSA_ISONoAffectMods) == 0) { 1058 TryCopyStr(buf, "mods", sz); 1059 nOut++; 1060 } 1061 if ((act->affect & XkbSA_ISONoAffectGroup) == 0) { 1062 snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : "")); 1063 TryCopyStr(buf, tbuf, sz); 1064 nOut++; 1065 } 1066 if ((act->affect & XkbSA_ISONoAffectPtr) == 0) { 1067 snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : "")); 1068 TryCopyStr(buf, tbuf, sz); 1069 nOut++; 1070 } 1071 if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) { 1072 snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : "")); 1073 TryCopyStr(buf, tbuf, sz); 1074 nOut++; 1075 } 1076 } 1077 return True; 1078} 1079 1080/*ARGSUSED*/ 1081static Bool 1082CopySwitchScreenArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1083 char *buf, int *sz) 1084{ 1085 XkbSwitchScreenAction *act; 1086 char tbuf[32]; 1087 1088 act = &action->screen; 1089 if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0)) 1090 snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act)); 1091 else 1092 snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act)); 1093 TryCopyStr(buf, tbuf, sz); 1094 if (act->flags & XkbSA_SwitchApplication) 1095 TryCopyStr(buf, ",!same", sz); 1096 else 1097 TryCopyStr(buf, ",same", sz); 1098 return True; 1099} 1100 1101/*ARGSUSED*/ 1102static Bool 1103CopySetLockControlsArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1104 char *buf, int *sz) 1105{ 1106 XkbCtrlsAction *act; 1107 unsigned tmp; 1108 char tbuf[32]; 1109 1110 act = &action->ctrls; 1111 tmp = XkbActionCtrls(act); 1112 TryCopyStr(buf, "controls=", sz); 1113 if (tmp == 0) 1114 TryCopyStr(buf, "none", sz); 1115 else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask) 1116 TryCopyStr(buf, "all", sz); 1117 else { 1118 int nOut = 0; 1119 1120 if (tmp & XkbRepeatKeysMask) { 1121 snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : "")); 1122 TryCopyStr(buf, tbuf, sz); 1123 nOut++; 1124 } 1125 if (tmp & XkbSlowKeysMask) { 1126 snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : "")); 1127 TryCopyStr(buf, tbuf, sz); 1128 nOut++; 1129 } 1130 if (tmp & XkbBounceKeysMask) { 1131 snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : "")); 1132 TryCopyStr(buf, tbuf, sz); 1133 nOut++; 1134 } 1135 if (tmp & XkbStickyKeysMask) { 1136 snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : "")); 1137 TryCopyStr(buf, tbuf, sz); 1138 nOut++; 1139 } 1140 if (tmp & XkbMouseKeysMask) { 1141 snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : "")); 1142 TryCopyStr(buf, tbuf, sz); 1143 nOut++; 1144 } 1145 if (tmp & XkbMouseKeysAccelMask) { 1146 snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel", (nOut > 0 ? "+" : "")); 1147 TryCopyStr(buf, tbuf, sz); 1148 nOut++; 1149 } 1150 if (tmp & XkbAccessXKeysMask) { 1151 snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys", (nOut > 0 ? "+" : "")); 1152 TryCopyStr(buf, tbuf, sz); 1153 nOut++; 1154 } 1155 if (tmp & XkbAccessXTimeoutMask) { 1156 snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout", (nOut > 0 ? "+" : "")); 1157 TryCopyStr(buf, tbuf, sz); 1158 nOut++; 1159 } 1160 if (tmp & XkbAccessXFeedbackMask) { 1161 snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback", (nOut > 0 ? "+" : "")); 1162 TryCopyStr(buf, tbuf, sz); 1163 nOut++; 1164 } 1165 if (tmp & XkbAudibleBellMask) { 1166 snprintf(tbuf, sizeof(tbuf), "%sAudibleBell", (nOut > 0 ? "+" : "")); 1167 TryCopyStr(buf, tbuf, sz); 1168 nOut++; 1169 } 1170 if (tmp & XkbOverlay1Mask) { 1171 snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : "")); 1172 TryCopyStr(buf, tbuf, sz); 1173 nOut++; 1174 } 1175 if (tmp & XkbOverlay2Mask) { 1176 snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : "")); 1177 TryCopyStr(buf, tbuf, sz); 1178 nOut++; 1179 } 1180 if (tmp & XkbIgnoreGroupLockMask) { 1181 snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock", (nOut > 0 ? "+" : "")); 1182 TryCopyStr(buf, tbuf, sz); 1183 nOut++; 1184 } 1185 } 1186 return True; 1187} 1188 1189/*ARGSUSED*/ 1190static Bool 1191CopyActionMessageArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1192 char *buf, int *sz) 1193{ 1194 XkbMessageAction *act; 1195 unsigned all; 1196 char tbuf[32]; 1197 1198 act = &action->msg; 1199 all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease; 1200 TryCopyStr(buf, "report=", sz); 1201 if ((act->flags & all) == 0) 1202 TryCopyStr(buf, "none", sz); 1203 else if ((act->flags & all) == all) 1204 TryCopyStr(buf, "all", sz); 1205 else if (act->flags & XkbSA_MessageOnPress) 1206 TryCopyStr(buf, "KeyPress", sz); 1207 else 1208 TryCopyStr(buf, "KeyRelease", sz); 1209 snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]); 1210 TryCopyStr(buf, tbuf, sz); 1211 snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]); 1212 TryCopyStr(buf, tbuf, sz); 1213 snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]); 1214 TryCopyStr(buf, tbuf, sz); 1215 snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]); 1216 TryCopyStr(buf, tbuf, sz); 1217 snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]); 1218 TryCopyStr(buf, tbuf, sz); 1219 snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]); 1220 TryCopyStr(buf, tbuf, sz); 1221 return True; 1222} 1223 1224static Bool 1225CopyRedirectKeyArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1226 char *buf, int *sz) 1227{ 1228 XkbRedirectKeyAction *act; 1229 char tbuf[32], *tmp; 1230 unsigned kc; 1231 unsigned vmods, vmods_mask; 1232 1233 act = &action->redirect; 1234 kc = act->new_key; 1235 vmods = XkbSARedirectVMods(act); 1236 vmods_mask = XkbSARedirectVModsMask(act); 1237 if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) && 1238 (xkb->names->keys[kc].name[0] != '\0')) { 1239 char *kn; 1240 1241 kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile); 1242 snprintf(tbuf, sizeof(tbuf), "key=%s", kn); 1243 } 1244 else 1245 snprintf(tbuf, sizeof(tbuf), "key=%d", kc); 1246 TryCopyStr(buf, tbuf, sz); 1247 if ((act->mods_mask == 0) && (vmods_mask == 0)) 1248 return True; 1249 if ((act->mods_mask == XkbAllModifiersMask) && 1250 (vmods_mask == XkbAllVirtualModsMask)) { 1251 tmp = XkbVModMaskText(dpy, xkb, act->mods, vmods, XkbXKBFile); 1252 TryCopyStr(buf, ",mods=", sz); 1253 TryCopyStr(buf, tmp, sz); 1254 } 1255 else { 1256 if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) { 1257 tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & act->mods, 1258 vmods_mask & vmods, XkbXKBFile); 1259 TryCopyStr(buf, ",mods= ", sz); 1260 TryCopyStr(buf, tmp, sz); 1261 } 1262 if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) { 1263 tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & (~act->mods), 1264 vmods_mask & (~vmods), XkbXKBFile); 1265 TryCopyStr(buf, ",clearMods= ", sz); 1266 TryCopyStr(buf, tmp, sz); 1267 } 1268 } 1269 return True; 1270} 1271 1272/*ARGSUSED*/ 1273static Bool 1274CopyDeviceBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1275 char *buf, int *sz) 1276{ 1277 XkbDeviceBtnAction *act; 1278 char tbuf[32]; 1279 1280 act = &action->devbtn; 1281 snprintf(tbuf, sizeof(tbuf), "device= %d", act->device); 1282 TryCopyStr(buf, tbuf, sz); 1283 TryCopyStr(buf, ",button=", sz); 1284 snprintf(tbuf, sizeof(tbuf), "%d", act->button); 1285 TryCopyStr(buf, tbuf, sz); 1286 if (act->count > 0) { 1287 snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count); 1288 TryCopyStr(buf, tbuf, sz); 1289 } 1290 if (action->type == XkbSA_LockDeviceBtn) { 1291 switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) { 1292 case XkbSA_LockNoLock: 1293 snprintf(tbuf, sizeof(tbuf), ",affect=unlock"); 1294 break; 1295 case XkbSA_LockNoUnlock: 1296 snprintf(tbuf, sizeof(tbuf), ",affect=lock"); 1297 break; 1298 case XkbSA_LockNoUnlock | XkbSA_LockNoLock: 1299 snprintf(tbuf, sizeof(tbuf), ",affect=neither"); 1300 break; 1301 default: 1302 snprintf(tbuf, sizeof(tbuf), ",affect=both"); 1303 break; 1304 } 1305 TryCopyStr(buf, tbuf, sz); 1306 } 1307 return True; 1308} 1309 1310/*ARGSUSED*/ 1311static Bool 1312CopyOtherArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action, 1313 char *buf, int *sz) 1314{ 1315 XkbAnyAction *act; 1316 char tbuf[32]; 1317 1318 act = &action->any; 1319 snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type); 1320 TryCopyStr(buf, tbuf, sz); 1321 snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]); 1322 TryCopyStr(buf, tbuf, sz); 1323 snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]); 1324 TryCopyStr(buf, tbuf, sz); 1325 snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]); 1326 TryCopyStr(buf, tbuf, sz); 1327 snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]); 1328 TryCopyStr(buf, tbuf, sz); 1329 snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]); 1330 TryCopyStr(buf, tbuf, sz); 1331 snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]); 1332 TryCopyStr(buf, tbuf, sz); 1333 snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]); 1334 TryCopyStr(buf, tbuf, sz); 1335 return True; 1336} 1337 1338typedef Bool (*actionCopy) (Display * /* dpy */ , 1339 XkbDescPtr /* xkb */ , 1340 XkbAction * /* action */ , 1341 char * /* buf */ , 1342 int * /* sz */ 1343 ); 1344 1345static actionCopy copyActionArgs[XkbSA_NumActions] = { 1346 CopyNoActionArgs /* NoAction */ , 1347 CopyModActionArgs /* SetMods */ , 1348 CopyModActionArgs /* LatchMods */ , 1349 CopyModActionArgs /* LockMods */ , 1350 CopyGroupActionArgs /* SetGroup */ , 1351 CopyGroupActionArgs /* LatchGroup */ , 1352 CopyGroupActionArgs /* LockGroup */ , 1353 CopyMovePtrArgs /* MovePtr */ , 1354 CopyPtrBtnArgs /* PtrBtn */ , 1355 CopyPtrBtnArgs /* LockPtrBtn */ , 1356 CopySetPtrDfltArgs /* SetPtrDflt */ , 1357 CopyISOLockArgs /* ISOLock */ , 1358 CopyNoActionArgs /* Terminate */ , 1359 CopySwitchScreenArgs /* SwitchScreen */ , 1360 CopySetLockControlsArgs /* SetControls */ , 1361 CopySetLockControlsArgs /* LockControls */ , 1362 CopyActionMessageArgs /* ActionMessage */ , 1363 CopyRedirectKeyArgs /* RedirectKey */ , 1364 CopyDeviceBtnArgs /* DeviceBtn */ , 1365 CopyDeviceBtnArgs /* LockDeviceBtn */ 1366}; 1367 1368#define ACTION_SZ 256 1369 1370char * 1371XkbActionText(Display *dpy, XkbDescPtr xkb, XkbAction *action, unsigned format) 1372{ 1373 char buf[ACTION_SZ], *tmp; 1374 int sz; 1375 1376 if (format == XkbCFile) { 1377 snprintf(buf, sizeof(buf), 1378 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }", 1379 XkbActionTypeText(action->type, XkbCFile), 1380 action->any.data[0], action->any.data[1], action->any.data[2], 1381 action->any.data[3], action->any.data[4], action->any.data[5], 1382 action->any.data[6]); 1383 } 1384 else { 1385 snprintf(buf, sizeof(buf), 1386 "%s(", XkbActionTypeText(action->type, XkbXKBFile)); 1387 sz = ACTION_SZ - strlen(buf) + 2; /* room for close paren and NULL */ 1388 if (action->type < (unsigned) XkbSA_NumActions) 1389 (*copyActionArgs[action->type]) (dpy, xkb, action, buf, &sz); 1390 else 1391 CopyOtherArgs(dpy, xkb, action, buf, &sz); 1392 TryCopyStr(buf, ")", &sz); 1393 } 1394 tmp = tbGetBuffer(strlen(buf) + 1); 1395 if (tmp != NULL) 1396 strcpy(tmp, buf); 1397 return tmp; 1398} 1399 1400char * 1401XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format) 1402{ 1403 char buf[256], *tmp; 1404 1405 if (format == XkbCFile) { 1406 if (behavior->type == XkbKB_Default) 1407 snprintf(buf, sizeof(buf), "{ 0, 0 }"); 1408 else 1409 snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type, behavior->data); 1410 } 1411 else { 1412 unsigned type, permanent; 1413 1414 type = behavior->type & XkbKB_OpMask; 1415 permanent = ((behavior->type & XkbKB_Permanent) != 0); 1416 1417 if (type == XkbKB_Lock) { 1418 snprintf(buf, sizeof(buf), "lock= %s", (permanent ? "Permanent" : "True")); 1419 } 1420 else if (type == XkbKB_RadioGroup) { 1421 int g; 1422 char *tmp; 1423 size_t tmpsize; 1424 1425 g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1; 1426 if (XkbKB_RGAllowNone & behavior->data) { 1427 snprintf(buf, sizeof(buf), "allowNone,"); 1428 tmp = &buf[strlen(buf)]; 1429 } 1430 else 1431 tmp = buf; 1432 tmpsize = sizeof(buf) - (tmp - buf); 1433 if (permanent) 1434 snprintf(tmp, tmpsize, "permanentRadioGroup= %d", g); 1435 else 1436 snprintf(tmp, tmpsize, "radioGroup= %d", g); 1437 } 1438 else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) { 1439 int ndx, kc; 1440 char *kn; 1441 1442 ndx = ((type == XkbKB_Overlay1) ? 1 : 2); 1443 kc = behavior->data; 1444 if ((xkb) && (xkb->names) && (xkb->names->keys)) 1445 kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile); 1446 else { 1447 static char tbuf[8]; 1448 1449 snprintf(tbuf, sizeof(tbuf), "%d", kc); 1450 kn = tbuf; 1451 } 1452 if (permanent) 1453 snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn); 1454 else 1455 snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn); 1456 } 1457 } 1458 tmp = tbGetBuffer(strlen(buf) + 1); 1459 if (tmp != NULL) 1460 strcpy(tmp, buf); 1461 return tmp; 1462} 1463 1464/***====================================================================***/ 1465 1466char * 1467XkbIndentText(unsigned size) 1468{ 1469 static char buf[32]; 1470 register int i; 1471 1472 if (size > 31) 1473 size = 31; 1474 1475 for (i = 0; i < size; i++) { 1476 buf[i] = ' '; 1477 } 1478 buf[size] = '\0'; 1479 return buf; 1480} 1481 1482 1483/***====================================================================***/ 1484 1485#define PIXEL_MAX 65535 1486 1487Bool 1488XkbLookupCanonicalRGBColor(char *def, XColor *color) 1489{ 1490 int tmp; 1491 1492 if (_XkbStrCaseEqual(def, "black")) { 1493 color->red = color->green = color->blue = 0; 1494 return True; 1495 } 1496 else if (_XkbStrCaseEqual(def, "white")) { 1497 color->red = color->green = color->blue = PIXEL_MAX; 1498 return True; 1499 } 1500 else if ((sscanf(def, "grey%d", &tmp) == 1) || 1501 (sscanf(def, "gray%d", &tmp) == 1) || 1502 (sscanf(def, "Grey%d", &tmp) == 1) || 1503 (sscanf(def, "Gray%d", &tmp) == 1)) { 1504 if ((tmp > 0) && (tmp <= 100)) { 1505 tmp = (PIXEL_MAX * tmp) / 100; 1506 color->red = color->green = color->blue = tmp; 1507 return True; 1508 } 1509 } 1510 else if ((tmp = (_XkbStrCaseEqual(def, "red") * 100)) || 1511 (sscanf(def, "red%d", &tmp) == 1)) { 1512 if ((tmp > 0) && (tmp <= 100)) { 1513 tmp = (PIXEL_MAX * tmp) / 100; 1514 color->red = tmp; 1515 color->green = color->blue = 0; 1516 return True; 1517 } 1518 } 1519 else if ((tmp = (_XkbStrCaseEqual(def, "green") * 100)) || 1520 (sscanf(def, "green%d", &tmp) == 1)) { 1521 if ((tmp > 0) && (tmp <= 100)) { 1522 tmp = (PIXEL_MAX * tmp) / 100; 1523 color->green = tmp; 1524 color->red = color->blue = 0; 1525 return True; 1526 } 1527 } 1528 else if ((tmp = (_XkbStrCaseEqual(def, "blue") * 100)) || 1529 (sscanf(def, "blue%d", &tmp) == 1)) { 1530 if ((tmp > 0) && (tmp <= 100)) { 1531 tmp = (PIXEL_MAX * tmp) / 100; 1532 color->blue = tmp; 1533 color->red = color->green = 0; 1534 return True; 1535 } 1536 } 1537 else if ((tmp = (_XkbStrCaseEqual(def, "magenta") * 100)) || 1538 (sscanf(def, "magenta%d", &tmp) == 1)) { 1539 if ((tmp > 0) && (tmp <= 100)) { 1540 tmp = (PIXEL_MAX * tmp) / 100; 1541 color->green = 0; 1542 color->red = color->blue = tmp; 1543 return True; 1544 } 1545 } 1546 else if ((tmp = (_XkbStrCaseEqual(def, "cyan") * 100)) || 1547 (sscanf(def, "cyan%d", &tmp) == 1)) { 1548 if ((tmp > 0) && (tmp <= 100)) { 1549 tmp = (PIXEL_MAX * tmp) / 100; 1550 color->red = 0; 1551 color->green = color->blue = tmp; 1552 return True; 1553 } 1554 } 1555 else if ((tmp = (_XkbStrCaseEqual(def, "yellow") * 100)) || 1556 (sscanf(def, "yellow%d", &tmp) == 1)) { 1557 if ((tmp > 0) && (tmp <= 100)) { 1558 tmp = (PIXEL_MAX * tmp) / 100; 1559 color->blue = 0; 1560 color->red = color->green = tmp; 1561 return True; 1562 } 1563 } 1564 return False; 1565} 1566 1567