1: /* 2: * WARNING: This file is overwritten at code generation time. 3: * Any changes to this file will be lost. 4: */ 5: /* 6: * MODULE: BxConvert.c 7: * AUTHOR: Automatically generated by Builder Xcessory 8: * 9: * Description: This module contains various utilities, converters 10: * for XmStrings (to work properly with app-defaults), and if needed 11: * the XPM pixmap utilities. 12: * 13: * Edit the file ${BX}/gen/bxutils.c (BX$SYSTEM:[gen]bxutils.c on VMS) to 14: * make system wide changes to this file which will be visible next time 15: * this file is generated. 16: * ${BX} is the directory where Builder Xcessory is installed. 17: */ 18: 19: /* 20: * BX supplies a string format for compound strings: 21: * 22: * ::[#tag][:t][:r]["str"] 23: * 24: * where: 25: * :: = indicates compound string. 26: * tag = the font tag 27: * :t = separator (if not seen no separator added to segment) 28: * :r = right to left (if not seen left to right assumed) 29: * "str" = the text of the string. 30: * 31: * The components for the compound string can be repeated any number of 32: * times. 33: */ 34: 35: /***************************************************************************** 36: * INCLUDE FILES 37: *****************************************************************************/ 38: 39: #include <Xm/Xm.h> 40: #include <Xm/RowColumn.h> 41: #include <stdio.h> 42: #include <ctype.h> 43: #include <string.h> 44: 45: /* 46: * Include stdlib.h and malloc.h if code is C++, ANSI, or Extended ANSI. 47: */ 48: #if defined(__cplusplus) || defined(__STDC__) || defined(__EXTENSIONS__) 49: #include <stdlib.h> 50: #ifndef VMS 51: #include <malloc.h> 52: #endif 53: #endif 54: 55: /***************************************************************************** 56: * TYPDEFS AND DEFINES 57: *****************************************************************************/ 58: 59: /* 60: * Undefine this if you want to use native strcasecmp. 61: */ 62: #define LOCAL_STRCASECMP 63: 64: #ifdef _NO_PROTO 65: #ifdef NeedFunctionPrototypes 66: #undef NeedFunctionPrototypes 67: #endif 68: #endif 69: 70: /* 71: * Define SUPPORTS_WCHARS if the system supports wide character sets 72: * Note: the following line flags the VAXC compiler and not the 73: * DECC compiler running VAXC emulation. 74: */ 75: #if !((defined(VAXC) && !defined(__DECC)) || defined(__CENTERLINE__)) 76: #define SUPPORTS_WCHARS 77: #endif 78: 79: /* 80: * Handy definition used in SET_BACKGROUND_COLOR 81: */ 82: #define UNSET (-1) 83: 84: /* 85: * Set state of inclusion of prototypes properly 86: */ 87: #ifdef NeedFunctionPrototypes 88: #define ARGLIST(p) ( 89: #define ARG(a, b) a b, 90: #define GRA(a, b) a b) 91: #else 92: #define ARGLIST(p) p 93: #define ARG(a, b) a b; 94: #define GRA(a, b) a b; 95: #endif 96: 97: #ifdef NeedFunctionPrototypes 98: #ifdef __cplusplus 99: #define UARG(a, b) a, 100: #define GRAU(a, b) a) 101: #else 102: #define UARG(a, b) a b, 103: #define GRAU(a, b) a b) 104: #endif 105: #else 106: #define UARG(a, b) a b; 107: #define GRAU(a, b) a b; 108: #endif 109: 110: /* 111: * Set up strcasecmp function 112: */ 113: #if defined(LOCAL_STRCASECMP) 114: #define STRCASECMP StrCasecmp 115: #ifndef NeedFunctionPrototypes 116: static int StrCasecmp(); 117: #else 118: static int StrCasecmp(char*, char*); 119: #endif 120: #else 121: #define STRCASECMP strcasecmp 122: #endif 123: 124: /* 125: * Define XTPOINTER so it works with all releases of 126: * Xt and c++. 127: */ 128: #ifdef __cplusplus 129: #if XtSpecificationRelease < 5 130: #define XTPOINTER char * 131: #else 132: #define XTPOINTER XPointer 133: #endif 134: #else 135: #define XTPOINTER XtPointer 136: #endif 137: 138: /* 139: * The following enum is used to support wide character sets. 140: * Use this enum for references into the Common Wide Characters array. 141: * If you add to the array, ALWAYS keep NUM_COMMON_WCHARS as the last 142: * entry in the enum. This will maintain correct memory usage, etc. 143: */ 144: enum { WNull, WTab, WNewLine, WCarriageReturn, WFormFeed, WVerticalTab, 145: WBackSlash, WQuote, WHash, WColon, WideF, WideL, WideN, WideR, 146: WideT, WideV, WideUF, WideUL, WideUR, WideUT, WideZero, WideOne, 147: NUM_COMMON_WCHARS }; 148: 149: /***************************************************************************** 150: * GLOBAL DECLARATIONS 151: *****************************************************************************/ 152: 153: /***************************************************************************** 154: * EXTERNAL DECLARATIONS 155: *****************************************************************************/ 156: 157: /***************************************************************************** 158: * STATIC DECLARATION 159: *****************************************************************************/ 160: 161: #ifndef NeedFunctionPrototypes 162: 163: #ifndef SUPPORTS_WCHARS 164: static int mblen (); 165: #endif 166: static int strlenWc (); 167: static size_t doMbstowcs (); 168: static size_t doWcstombs (); 169: static void copyWcsToMbs (); 170: static int dombtowc (); 171: static Boolean extractSegment (); 172: static XmString StringToXmString (); 173: static char* getNextCStrDelim (); 174: static int getCStrCount (); 175: static wchar_t *CStrCommonWideCharsGet (); 176: 177: #else 178: 179: #ifndef SUPPORTS_WCHARS 180: static int mblen (char*, size_t); 181: #endif 182: static int strlenWc (wchar_t*); 183: static size_t doMbstowcs (wchar_t*, char*, size_t); 184: static size_t doWcstombs (char*, wchar_t*, size_t); 185: static void copyWcsToMbs (char*, wchar_t*, int, Boolean); 186: static int dombtowc (wchar_t*, char*, size_t); 187: static Boolean extractSegment (wchar_t**, wchar_t**, int *, 188: wchar_t**, int*, int*, Boolean*); 189: static XmString StringToXmString (char*); 190: static char* getNextCStrDelim (char*); 191: static int getCStrCount (char*); 192: static wchar_t *CStrCommonWideCharsGet (); 193: 194: #endif 195: 196: /***************************************************************************** 197: * STATIC CODE 198: *****************************************************************************/ 199: 200: #if defined(LOCAL_STRCASECMP) 201: 202: /* 203: * Function: 204: * cmp = StrCasecmp(s1, s2); 205: * Description: 206: * Compare two strings ignoring case 207: * Input: 208: * s1 - char * : string 1 to compare 209: * s2 - char * : string 2 to compare 210: * Output: 211: * int : 0; s1 == s2 212: * 1; s1 != s2 213: */ 214: static int StrCasecmp 215: ARGLIST((s1, s2)) 216: ARG(register char *, s1) 217: GRA(register char *, s2) 218: { 219: register int c1, c2; 220: 221: while (*s1 && *s2) 222: { 223: c1 = isupper(*s1) ? tolower(*s1) : *s1; 224: c2 = isupper(*s2) ? tolower(*s2) : *s2; 225: if (c1 != c2) 226: { 227: return(1); 228: } 229: s1++; 230: s2++; 231: } 232: if (*s1 || *s2) 233: { 234: return(1); 235: } 236: return(0); 237: } 238: #endif 239: 240: #ifndef SUPPORTS_WCHARS 241: /* 242: * Function: 243: * len = mblen(s, n); 244: * Description: 245: * The mblen function for platforms that don't have one. This 246: * function simply returns a length of 1 since no wide character 247: * support exists for this platform. 248: * Input: 249: * s - char * : the character string to get the length from 250: * n - size_t : the size of the string 251: * Output: 252: * int : always 1 253: */ 254: static int mblen 255: ARGLIST((s, n)) 256: ARG(char *, s) 257: GRA(size_t, n) 258: { 259: return(1); 260: } 261: #endif 262: 263: /* 264: * Function: 265: * len = strlenWc(ptr); 266: * Description: 267: * Return the number of characters in a wide character string (not 268: * the characters in the resultant mbs). 269: * Input: 270: * ptr - wchar_t* : pointer to the wcs to count 271: * Output: 272: * int : the number of characters found 273: */ 274: static int strlenWc 275: ARGLIST((ptr)) 276: GRA(wchar_t *,ptr) 277: { 278: register wchar_t *p = ptr; 279: register int x = 0; 280: 281: if (!ptr) return(0); 282: 283: while (*p++) x++; 284: return (x); 285: } 286: 287: /* 288: * Function: 289: * bytesConv = doMbstowcs(wcs, mbs, n); 290: * Description: 291: * Create a wcs string from an input mbs. 292: * Input: 293: * wcs - wchar_t* : pointer to result buffer of wcs 294: * mbs - char* : pointer to the source mbs 295: * n - size_t : the number of characters to convert 296: * Output: 297: * bytesConv - size_t : number of bytes converted 298: */ 299: static size_t doMbstowcs 300: ARGLIST((wcs, mbs, n)) 301: ARG(wchar_t *,wcs) 302: ARG(char *, mbs) 303: GRA(size_t, n) 304: { 305: #ifndef SUPPORTS_WCHARS 306: int i; 307: 308: for (i = 0; i < n && mbs[i] != 0; ++i) 309: { 310: wcs[i] = mbs[i]; 311: } 312: wcs[i++] = 0; 313: return(i); 314: #else 315: return(mbstowcs(wcs, mbs, n)); 316: #endif 317: } 318: 319: /* 320: * Function: 321: * bytesConv = doWcstombs(wcs, mbs, n); 322: * Description: 323: * Create a mbs string from an input wcs. 324: * Input: 325: * wcs - wchar_t* : pointer to the source wcs 326: * mbs - char* : pointer to result mbs buffer 327: * n - size_t : the number of characters to convert 328: * Output: 329: * bytesConv - size_t : number of bytes converted 330: */ 331: static size_t doWcstombs 332: ARGLIST((mbs, wcs, n)) 333: ARG(char *, mbs) 334: ARG(wchar_t *, wcs) 335: GRA(size_t, n) 336: { 337: #ifndef SUPPORTS_WCHARS 338: int i; 339: 340: for (i = 0; i < n && wcs[i] != 0; ++i) 341: { 342: mbs[i] = wcs[i]; 343: } 344: mbs[i] = 0; 345: return(i); 346: #else 347: size_t retval; 348: 349: retval = wcstombs(mbs, wcs, (n * sizeof(wchar_t))); 350: if ( retval == (size_t)-1 ) return(0); 351: else return(retval); 352: #endif 353: } 354: 355: /* 356: * Function: 357: * copyWcsToMbs(mbs, wcs, len); 358: * Description: 359: * Create a mbs string from an input wcs. This function allocates 360: * a buffer if necessary. 361: * Input: 362: * mbs - char* : destination for the converted/copied output 363: * wcs - wchar_t* : pointer to wcs to copy/convert 364: * len - int : the number of wchar_t' to convert 365: * process_it - Boolean : True if processing of quoted charcters, 366: * False if blind. 367: * Output: 368: * None 369: */ 370: static void copyWcsToMbs 371: ARGLIST((mbs, wcs, len, process_it)) 372: ARG(char *, mbs) 373: ARG(wchar_t *, wcs) 374: ARG(int, len) 375: GRA(Boolean, process_it) 376: { 377: static wchar_t *tbuf = NULL; 378: static int tbufSize = 0; 379: 380: int numCvt; 381: int lenToConvert; 382: wchar_t *fromP = wcs; 383: wchar_t *x = &fromP[len]; 384: wchar_t *toP; 385: wchar_t *commonWChars = CStrCommonWideCharsGet(); 386: wchar_t tmp; 387: 388: /* 389: * Make sure there's room in the buffer 390: */ 391: if (tbufSize < len) 392: { 393: tbuf = (wchar_t*)XtRealloc((char*)tbuf, (len + 1) * sizeof(wchar_t)); 394: tbufSize = len; 395: } 396: 397: /* 398: * Now copy and process 399: */ 400: toP = tbuf; 401: lenToConvert = 0; 402: while (fromP < x) 403: { 404: /* 405: * Check for quoted characters 406: */ 407: if ((*fromP == commonWChars[WBackSlash]) && process_it) 408: { 409: fromP++; /* Skip quote */ 410: if (fromP == x) /* Hanging quote? */ 411: { 412: *toP++ = commonWChars[WBackSlash]; 413: lenToConvert++; 414: break; 415: } 416: tmp = *fromP++; 417: if (tmp == commonWChars[WideN]) 418: { 419: *toP++ = commonWChars[WNewLine]; 420: } 421: else if (tmp == commonWChars[WideT]) 422: { 423: *toP++ = commonWChars[WTab]; 424: } 425: else if (tmp == commonWChars[WideR]) 426: { 427: *toP++ = commonWChars[WCarriageReturn]; 428: } 429: else if (tmp == commonWChars[WideF]) 430: { 431: *toP++ = commonWChars[WFormFeed]; 432: } 433: else if (tmp == commonWChars[WideV]) 434: { 435: *toP++ = commonWChars[WVerticalTab]; 436: } 437: else if (tmp == commonWChars[WBackSlash]) 438: { 439: *toP++ = commonWChars[WBackSlash]; 440: } 441: else 442: { 443: /* 444: * No special translation needed 445: */ 446: *toP++ = tmp; 447: } 448: } 449: else 450: { 451: *toP++ = *fromP++; 452: } 453: lenToConvert++; 454: } 455: 456: tmp = tbuf[lenToConvert]; 457: tbuf[lenToConvert] = (wchar_t) NULL; 458: numCvt = doWcstombs(mbs, tbuf, lenToConvert); 459: tbuf[lenToConvert] = tmp; 460: 461: mbs[numCvt] = '\0'; 462: } 463: 464: /* 465: * Function: 466: * status = dombtowc(wide, multi, size); 467: * Description: 468: * Convert a multibyte character to a wide character. 469: * Input: 470: * wide - wchar_t * : where to put the wide character 471: * multi - char * : the multibyte character to convert 472: * size - size_t : the number of characters to convert 473: * Output: 474: * 0 - if multi is a NULL pointer or points to a NULL character 475: * #bytes - number of bytes in the multibyte character 476: * -1 - multi is an invalid multibyte character. 477: * 478: * NOTE: if wide is NULL, then this returns the number of bytes in 479: * the multibyte character. 480: */ 481: static int dombtowc 482: ARGLIST((wide, multi, size)) 483: ARG(wchar_t *, wide) 484: ARG(char *, multi) 485: GRA(size_t, size) 486: { 487: int retVal = 0; 488: 489: #ifndef SUPPORTS_WCHARS 490: if ((multi == NULL) || (*multi == '\000')) 491: { 492: if (wide) wide[0] = '\0'; 493: return (0); 494: } 495: 496: for (retVal = 0; retVal < size && multi[retVal] != '\000'; retVal++) 497: { 498: if (wide != NULL) 499: { 500: wide[retVal] = multi[retVal]; 501: } 502: } 503: #else 504: retVal = mbtowc(wide, multi, size); 505: #endif 506: return(retVal); 507: } 508: 509: /* 510: * Function: 511: * ptr = getNextSepartor(str); 512: * Description: 513: * Parse through a string looking for the next compound string 514: * field separator 515: * Inputs: 516: * str - wchar_t* : the address of address of the string to parse 517: * Outputs: 518: * ptr - wchar_t* : pointer to character, if found, points to end 519: * of string otherwise ('\0'). 520: */ 521: static wchar_t* getNextSeparator 522: ARGLIST((str)) 523: GRA(wchar_t *, str) 524: { 525: wchar_t *ptr = str; 526: wchar_t *commonWChars = CStrCommonWideCharsGet(); 527: 528: while (*ptr) 529: { 530: /* 531: * Check for separator 532: */ 533: if ((*ptr == commonWChars[WHash]) || 534: (*ptr == commonWChars[WQuote]) || 535: (*ptr == commonWChars[WColon])) 536: { 537: return(ptr); 538: } 539: else if (*ptr == commonWChars[WBackSlash]) 540: { 541: ptr++; 542: if (*ptr) ptr++; /* Skip quoted character */ 543: } 544: else 545: { 546: ptr++; 547: } 548: } 549: return(ptr); 550: } 551: 552: /* 553: * Function: 554: * more = 555: * extractSegment(str, tagStart, tagLen, txtStart, txtLen, 556: * pDir, pSep); 557: * Description: 558: * Parse through a string version of a compound string and extract 559: * the first compound string segment from the string. 560: * Inputs: 561: * str - char** : the address of address of the string to parse 562: * tagStart - char** : address to return pointer to tag start into 563: * tagLen - int* : address where to return the tag length into 564: * txtStart - char** : address to return the text start into 565: * txtLen - int* : address where to return the text length 566: * pDir - int* : address to return the string direction into 567: * pSep - Boolean * : address to return the separtor into 568: * Outputs: 569: * more - Boolean : True if more of the string to parse. 570: * False means done. 571: */ 572: static Boolean extractSegment 573: ARGLIST((str, tagStart, tagLen, txtStart, txtLen, pDir, pSep)) 574: ARG(wchar_t **, str) 575: ARG(wchar_t **, tagStart) 576: ARG(int *, tagLen) 577: ARG(wchar_t **, txtStart) 578: ARG(int *, txtLen) 579: ARG(int *, pDir) 580: GRA(Boolean *, pSep) 581: { 582: wchar_t *start; 583: wchar_t *text; 584: int textL; 585: Boolean tagSeen; 586: wchar_t *tag; 587: int tagL; 588: Boolean modsSeen; 589: Boolean sep; 590: int dir; 591: Boolean done; 592: int *lenUp; 593: Boolean checkDir; 594: wchar_t *commonWChars; 595: wchar_t emptyStrWcs[1]; 596: 597: /* 598: * Initialize variables 599: */ 600: text = NULL; 601: textL = 0; 602: tagSeen = False; 603: tag = NULL; 604: tagL = 0; 605: modsSeen = False; 606: dir = XmSTRING_DIRECTION_L_TO_R; 607: sep = False; 608: done = False; 609: lenUp = NULL; 610: commonWChars = CStrCommonWideCharsGet(); 611: 612: /* 613: * Guard against nulls 614: */ 615: if (!(start = *str)) 616: { 617: start = emptyStrWcs; 618: emptyStrWcs[0] = commonWChars[WNull]; 619: } 620: 621: /* 622: * If the first character of the string isn't a # or a ", then we 623: * just have a regular old simple string. Do the same the thing for 624: * the empty string. 625: */ 626: if ((*start == '\0') || (start != getNextSeparator(start))) 627: { 628: text = start; 629: if (!(textL = strlenWc(start))) 630: { 631: text = NULL; 632: } 633: start += textL; 634: } 635: else 636: { 637: done = False; 638: while (!done) 639: { 640: if (*start == commonWChars[WHash]) 641: { 642: if (tagSeen) 643: { 644: done = True; 645: break; 646: } 647: else 648: { 649: tagSeen = True; 650: tag = ++start; 651: start = getNextSeparator(tag); 652: if ((tagL = start - tag) == 0) 653: { 654: tag = NULL; /* Null tag specified */ 655: } 656: } 657: } 658: else if (*start == commonWChars[WQuote]) 659: { 660: text = ++start; 661: start = getNextSeparator(start); 662: while (!((*start == commonWChars[WQuote]) || 663: (*start == commonWChars[WNull]))) 664: { 665: start = getNextSeparator(++start); 666: } 667: 668: if ((textL = start - text) == 0) 669: { 670: text = NULL; /* Null text specified */ 671: } 672: /* 673: * if a quote, skip over it 674: */ 675: if (*start == commonWChars[WQuote]) 676: { 677: start++; 678: } 679: done = True; 680: } 681: else if (*start == commonWChars[WColon]) 682: { 683: if (modsSeen) 684: { 685: done = True; 686: break; 687: } 688: 689: /* 690: * If the next character is a t or f, the we've got 691: * a separator. 692: */ 693: modsSeen = True; 694: checkDir = False; 695: start++; 696: if ((*start == commonWChars[WideT]) || 697: (*start == commonWChars[WideUT]) || 698: (*start == commonWChars[WideOne])) 699: { 700: sep = True; 701: start++; 702: checkDir = True; 703: } 704: else if ((*start == commonWChars[WideF]) || 705: (*start == commonWChars[WideUF]) || 706: (*start == commonWChars[WideZero])) 707: { 708: sep = False; 709: start++; 710: checkDir = True; 711: } 712: else if ((*start == commonWChars[WideR]) || 713: (*start == commonWChars[WideUR])) 714: { 715: start++; 716: dir = XmSTRING_DIRECTION_R_TO_L; 717: } 718: else if ((*start == commonWChars[WideL]) || 719: (*start == commonWChars[WideUL])) 720: { 721: start++; 722: dir = XmSTRING_DIRECTION_L_TO_R; 723: } 724: /* 725: * Look for direction if necessary. This requires a bit of 726: * look ahead. 727: */ 728: if (checkDir && (*start == commonWChars[WColon])) 729: { 730: if ((*(start + 1) == commonWChars[WideL]) || 731: (*(start + 1) == commonWChars[WideUL])) 732: { 733: dir = XmSTRING_DIRECTION_L_TO_R; 734: start += 2; 735: } 736: else if ((*(start + 1) == commonWChars[WideR]) || 737: (*(start + 1) == commonWChars[WideUR])) 738: { 739: dir = XmSTRING_DIRECTION_R_TO_L; 740: start+=2; 741: } 742: } 743: } 744: else 745: { 746: /* 747: * A bad string format! We'll just skip the character. 748: */ 749: start++; 750: } 751: } 752: } 753: 754: /* 755: * Now fill in return values 756: */ 757: if (*str) *str = start; 758: if (tagStart) *tagStart = tag; 759: if (tagLen) *tagLen = tagL; 760: if (txtStart) *txtStart = text; 761: if (txtLen) *txtLen = textL; 762: if (pDir) *pDir = dir; 763: if (pSep) *pSep = sep; 764: 765: return ((*start == commonWChars[WNull]) ? False : True); 766: } 767: 768: /* 769: * Function: 770: * xstr = StringToXmString(str); 771: * Description: 772: * Parse a string into an XmString. 773: * Inputs: 774: * str - char * : the string to parse 775: * Outputs: 776: * xstr - XmString : the allocated return structure 777: */ 778: static XmString StringToXmString 779: ARGLIST((str)) 780: GRA(char *,str) 781: { 782: static char* tagBuf = NULL; 783: static int tagBufLen = 0; 784: static char* textBuf = NULL; 785: static int textBufLen = 0; 786: 787: wchar_t *ctx; 788: wchar_t *tag; 789: int tagLen; 790: wchar_t *text; 791: int textLen; 792: Boolean sep; 793: int dir; 794: 795: Boolean more; 796: wchar_t *wcStr; 797: int curDir; 798: XmString xmStr; 799: XmString s1; 800: XmString s2; 801: 802: if (!str) return(NULL); 803: 804: /* 805: * For expediencies sake, we'll overallocate this buffer so that 806: * the wcs is guaranteed to fit (1 wc per byte in original string). 807: */ 808: wcStr = (wchar_t*)XtMalloc((strlen(str) + 1) * sizeof(wchar_t)); 809: doMbstowcs(wcStr, str, strlen(str) + 1); 810: 811: /* 812: * Create the beginning segment 813: */ 814: curDir = XmSTRING_DIRECTION_L_TO_R; 815: xmStr = XmStringDirectionCreate(curDir); 816: 817: /* 818: * Convert the string. 819: */ 820: more = True; 821: ctx = wcStr; 822: while (more) 823: { 824: more = extractSegment(&ctx, &tag, &tagLen, 825: &text, &textLen, &dir, &sep); 826: /* 827: * Pick up a direction change 828: */ 829: if (dir != curDir) 830: { 831: #if defined(VMS) || (defined(__osf__) && defined(__alpha)) 832: #if XmVERSION > 1 || (XmVERSION == 1 && XmREVISION >= 2) 833: /* 834: * This is required on DEC Windows systems because they've 835: * added the REVERT direction. 836: */ 837: s1 = XmStringDirectionCreate(XmSTRING_DIRECTION_REVERT); 838: s2 = xmStr; 839: xmStr = XmStringConcat(s2, s1); 840: XmStringFree(s1); 841: XmStringFree(s2); 842: #endif 843: #endif 844: curDir = dir; 845: s1 = XmStringDirectionCreate(curDir); 846: s2 = xmStr; 847: xmStr = XmStringConcat(s2, s1); 848: XmStringFree(s1); 849: XmStringFree(s2); 850: 851: } 852: 853: /* 854: * Create the segment. Text and tag first. 855: */ 856: if (textLen) 857: { 858: if (textBufLen <= (textLen * sizeof(wchar_t))) 859: { 860: textBufLen = (textLen + 1) * sizeof(wchar_t); 861: textBuf = (char*)XtRealloc(textBuf, textBufLen); 862: } 863: copyWcsToMbs(textBuf, text, textLen, True); 864: 865: if (tagLen) 866: { 867: if (tagBufLen <= (tagLen * sizeof(wchar_t))) 868: { 869: tagBufLen = (tagLen + 1) * sizeof(wchar_t); 870: tagBuf = (char*)XtRealloc(tagBuf, tagBufLen); 871: } 872: copyWcsToMbs(tagBuf, tag, tagLen, False); 873: } 874: else 875: { 876: if (!tagBuf) 877: { 878: tagBufLen = strlen(XmSTRING_DEFAULT_CHARSET) + 1; 879: tagBuf = (char*)XtMalloc(tagBufLen); 880: } 881: strcpy(tagBuf, XmSTRING_DEFAULT_CHARSET); 882: } 883: 884: s1 = XmStringCreate(textBuf, tagBuf); 885: s2 = xmStr; 886: xmStr = XmStringConcat(s2, s1); 887: XmStringFree(s1); 888: XmStringFree(s2); 889: } 890: 891: /* 892: * Add in the separators. 893: */ 894: if (sep) 895: { 896: s1 = XmStringSeparatorCreate(); 897: s2 = xmStr; 898: xmStr = XmStringConcat(s2, s1); 899: XmStringFree(s1); 900: XmStringFree(s2); 901: } 902: } 903: 904: /* 905: * Free up memory and return 906: */ 907: XtFree((char*)wcStr); 908: return(xmStr); 909: } 910: 911: /* 912: * Function: 913: * nextCStr = getNextCStrDelim(str); 914: * Description: 915: * Find the next unquoted , or \n in the string 916: * Input: 917: * str - char * : the input string 918: * Output: 919: * nextCStr - char* : pointer to the next delimiter. Returns NULL if no 920: * delimiter found. 921: */ 922: static char* getNextCStrDelim 923: ARGLIST((str)) 924: GRA(char *,str) 925: { 926: char *comma = str; 927: Boolean inQuotes = False; 928: int len; 929: 930: if (!str) return(NULL); 931: if (!*str) return(NULL); /* At end */ 932: 933: #ifdef __CENTERLINE__ 934: mblen((char *)NULL, sizeof(wchar_t)); 935: #else 936: mblen(NULL, sizeof(wchar_t)); 937: #endif 938: while (*comma) 939: { 940: if ((len = mblen(comma, sizeof(wchar_t))) > 1) 941: { 942: comma += len; 943: continue; 944: } 945: 946: if (*comma == '\\') 947: { 948: comma++; /* Over quote */ 949: comma += mblen(comma, sizeof(wchar_t)); 950: continue; 951: } 952: 953: /* 954: * See if we have a delimiter 955: */ 956: if (!inQuotes) 957: { 958: if ((*comma == ',') || (*comma == '\012')) 959: { 960: return(comma); 961: } 962: } 963: 964: /* 965: * Deal with quotes 966: */ 967: if (*comma == '\"') 968: { 969: inQuotes = ~inQuotes; 970: } 971: 972: comma++; 973: } 974: 975: return(NULL); /* None found */ 976: } 977: 978: /* 979: * Function: 980: * cnt = getCStrCount(str); 981: * Description: 982: * Get the count of cstrings in a compound string table ascii 983: * format. 984: * Input: 985: * str - char * : string to parse 986: * Output: 987: * cnt - int : the number of XmStrings found 988: */ 989: static int getCStrCount 990: ARGLIST((str)) 991: GRA(char *, str) 992: { 993: int x = 1; 994: char *newStr; 995: 996: if (!str) return(0); 997: if (!*str) return(0); 998: 999: while (newStr = getNextCStrDelim(str)) 1000: { 1001: x++; 1002: str = ++newStr; 1003: } 1004: return(x); 1005: } 1006: 1007: /* 1008: * Function: 1009: * cwc = CStrCommonWideCharsGet(); 1010: * Description: 1011: * Return the array of common wide characters. 1012: * Input: 1013: * None. 1014: * Output: 1015: * cwc - wchar_t * : this array should never be written to or FREEd. 1016: */ 1017: static wchar_t *CStrCommonWideCharsGet() 1018: { 1019: static wchar_t *CommonWideChars = NULL; 1020: /* 1021: * If you add to this array, don't forget to change the enum in 1022: * the TYPEDEFS and DEFINES section above to correspond to this 1023: * array. 1024: */ 1025: static char *characters[] = { "\000", "\t", "\n", "\r", "\f", "\v", 1026: "\\", "\"", "#", ":", "f", "l", "n", "r", 1027: "t", "v", "F", "L", "R", "T", "0", "1" }; 1028: 1029: 1030: if (CommonWideChars == NULL) 1031: { 1032: int i; 1033: 1034: /* 1035: * Allocate and create the array. 1036: */ 1037: CommonWideChars = (wchar_t*)XtMalloc(NUM_COMMON_WCHARS * sizeof(wchar_t)); 1038: 1039: for (i = 0; i < NUM_COMMON_WCHARS; i++) 1040: { 1041: (void)dombtowc(&(CommonWideChars[i]), characters[i], 1); 1042: } 1043: } 1044: return(CommonWideChars); 1045: } 1046: 1047: /* 1048: * Function: 1049: * CONVERTER CvtStringToXmString 1050: * and 1051: * XmStringCvtDestroy 1052: * Description: 1053: * Convert a string to an XmString. This allows a string contained in 1054: * resource file to contain multiple fonts. The syntax for the string 1055: * is: 1056: * ::[#[font-tag]]"string"[#[font-tag]"string"] ... 1057: * 1058: * note that the # can be escaped (\#). 1059: * 1060: * Input: 1061: * Output: 1062: * Standard. 1063: */ 1064: static Boolean CvtStringToXmString 1065: ARGLIST((d, args, num_args, fromVal, toVal, data)) 1066: ARG(Display *, d) 1067: UARG(XrmValue *, args) 1068: ARG(Cardinal *, num_args) 1069: ARG(XrmValue *, fromVal) 1070: ARG(XrmValue *, toVal) 1071: GRAU(XtPointer, data) 1072: { 1073: static XmString resStr; 1074: char *str; 1075: 1076: /* 1077: * This converter takes no parameters 1078: */ 1079: if (*num_args != 0) 1080: { 1081: XtAppWarningMsg(XtDisplayToApplicationContext(d), 1082: "cvtStringToXmString", 1083: "wrongParameters", 1084: "XtToolkitError", 1085: "String to XmString converter needs no extra arguments", 1086: (String *)NULL, 1087: (Cardinal *)NULL); 1088: } 1089: 1090: /* 1091: * See if this is a simple string 1092: */ 1093: str = (char*)fromVal->addr; 1094: if (strncmp(str, "::", 2)) 1095: { 1096: resStr = XmStringCreateLtoR(fromVal->addr, XmSTRING_DEFAULT_CHARSET); 1097: } 1098: else 1099: { 1100: /* 1101: * Convert into internal format 1102: */ 1103: resStr = StringToXmString(fromVal->addr + 2); /* skip :: */ 1104: } 1105: 1106: /* 1107: * Done, return result 1108: */ 1109: if (toVal->addr == NULL) 1110: { 1111: toVal->addr = (XTPOINTER)&resStr; 1112: toVal->size = sizeof(XmString); 1113: } 1114: else if (toVal->size < sizeof(XmString)) 1115: { 1116: toVal->size = sizeof(XmString); 1117: XtDisplayStringConversionWarning(d, fromVal->addr, "XmString"); 1118: XmStringFree(resStr); 1119: return(False); 1120: } 1121: else 1122: { 1123: *(XmString *)toVal->addr = resStr; 1124: toVal->size = sizeof(XmString); 1125: } 1126: return(True); 1127: } 1128: static void XmStringCvtDestroy 1129: ARGLIST((app, to, data, args, num_args)) 1130: UARG(XtAppContext, app) 1131: ARG(XrmValue *, to) 1132: UARG(XtPointer, data) 1133: UARG(XrmValue *, args) 1134: GRAU(Cardinal *, num_args) 1135: { 1136: XmStringFree(*(XmString*)(to->addr)); 1137: } 1138: 1139: /* 1140: * Function: 1141: * CONVERTER CvtStringToXmStringTable 1142: * and 1143: * XmStringTableCvtDestroy 1144: * 1145: * Description: 1146: * Convert a string to an XmString table. This allows a string contained in 1147: * resource file to contain multiple fonts. The syntax for the string 1148: * is: 1149: * compound_string = [#[font-tag]]"string"[#[font-tag]"string"] ... 1150: * compound_string_table = [compound_string][,compound_string] ... 1151: * 1152: * note that the # can be escaped (\#). 1153: * 1154: * Input: 1155: * Output: 1156: * Standard. 1157: */ 1158: static Boolean CvtStringToXmStringTable 1159: ARGLIST((d, args, num_args, fromVal, toVal, data)) 1160: ARG(Display *, d) 1161: ARG(XrmValue *, args) 1162: ARG(Cardinal *, num_args) 1163: ARG(XrmValue *, fromVal) 1164: ARG(XrmValue *, toVal) 1165: GRAU(XtPointer, data) 1166: { 1167: static XmString *CStrTable; 1168: XmString *tblPtr; 1169: char *str; 1170: char *tmpBuf; 1171: char *nextDelim; 1172: XrmValue fVal; 1173: XrmValue tVal; 1174: 1175: /* 1176: * This converter takes no parameters 1177: */ 1178: if (*num_args != 0) 1179: { 1180: XtAppWarningMsg 1181: (XtDisplayToApplicationContext(d), 1182: "cvtStringToXmStringTable", 1183: "wrongParameters", 1184: "XtToolkitError", 1185: "String to XmStringTable converter needs no extra arguments", 1186: (String *)NULL, 1187: (Cardinal *)NULL); 1188: } 1189: 1190: /* 1191: * Set str and make sure there's somethin' there 1192: */ 1193: if (!(str = (char*)fromVal->addr)) 1194: { 1195: str = ""; 1196: } 1197: 1198: /* 1199: * Allocate the XmStrings + 1 for NULL termination 1200: */ 1201: CStrTable = (XmString*)XtMalloc((getCStrCount(str) + 1) * sizeof(XmString*)); 1202: 1203: /* 1204: * Use the string converter for the strings 1205: */ 1206: tmpBuf = (char*)XtMalloc(strlen(str) + 1); 1207: strcpy(tmpBuf, str); 1208: str = tmpBuf; 1209: 1210: /* 1211: * Create strings 1212: */ 1213: tblPtr = CStrTable; 1214: if (*str) 1215: { 1216: while (str) 1217: { 1218: nextDelim = getNextCStrDelim(str); 1219: 1220: /* 1221: * Overwrite nextDelim 1222: */ 1223: if (nextDelim) 1224: { 1225: *nextDelim = '\0'; 1226: nextDelim++; 1227: } 1228: 1229: /* 1230: * Convert it 1231: */ 1232: fVal.size = strlen(str) + 1; 1233: fVal.addr = str; 1234: tVal.size = sizeof(XTPOINTER); 1235: tVal.addr = (XTPOINTER)tblPtr; 1236: 1237: /* 1238: * Call converter ourselves since this is used to create 1239: * the strings in the table we create. We need to do this 1240: * since we don't have a widget to send to the XtConvertAndStore 1241: * function. Side effects are that we can never get these 1242: * compound strings cached and that no destructor function is 1243: * called when the strings leave existance, but we nuke 'em 1244: * in the XmStringTable destuctor. 1245: */ 1246: CvtStringToXmString(d, args, num_args, &fVal, &tVal, NULL); 1247: tblPtr++; 1248: str = nextDelim; 1249: } 1250: } 1251: XtFree(tmpBuf); 1252: 1253: /* 1254: * Null terminate 1255: */ 1256: *tblPtr = NULL; 1257: 1258: /* 1259: * Done, return result 1260: */ 1261: if (toVal->addr == NULL) 1262: { 1263: toVal->addr = (XTPOINTER)&CStrTable; 1264: toVal->size = sizeof(XmString); 1265: } 1266: else if (toVal->size < sizeof(XmString*)) 1267: { 1268: toVal->size = sizeof(XmString*); 1269: XtDisplayStringConversionWarning(d, fromVal->addr, "XmStringTable"); 1270: 1271: tblPtr = CStrTable; 1272: while (*tblPtr) 1273: { 1274: XmStringFree(*tblPtr); 1275: } 1276: XtFree((char*)CStrTable); 1277: return(False); 1278: } 1279: else 1280: { 1281: *(XmString **)toVal->addr = CStrTable; 1282: toVal->size = sizeof(XmString*); 1283: } 1284: return(True); 1285: } 1286: static void XmStringTableCvtDestroy 1287: ARGLIST((app, to, data, args, num_args)) 1288: UARG(XtAppContext, app) 1289: ARG(XrmValue *, to) 1290: UARG(XtPointer, data) 1291: UARG(XrmValue *, args) 1292: GRAU(Cardinal *, num_args) 1293: { 1294: XmString *tblPtr = *(XmString**)(to->addr); 1295: 1296: while (*tblPtr) 1297: { 1298: XmStringFree(*tblPtr); 1299: } 1300: XtFree((char*)(*(XmString**)(to->addr))); 1301: } 1302: 1303: /***************************************************************************** 1304: * GLOBAL CODE 1305: *****************************************************************************/ 1306: 1307: /* 1308: * Function: 1309: * RegisterBxConverters(appContext); 1310: * Description: 1311: * This globally available function installs all the converters necessary 1312: * to run BuilderXcessory generated interfaces that use compound 1313: * strings. This is necessary since Motif has not supplied very smart 1314: * converters. 1315: * Input: 1316: * appContext - XtAppContext : the application context 1317: * Output: 1318: * None 1319: */ 1320: void RegisterBxConverters 1321: ARGLIST((appContext)) 1322: GRA(XtAppContext, appContext) 1323: { 1324: XtAppSetTypeConverter(appContext, XmRString, XmRXmString, 1325: (XtTypeConverter)CvtStringToXmString, 1326: NULL, 0, XtCacheNone, XmStringCvtDestroy); 1327: 1328: XtAppSetTypeConverter(appContext, XmRString, XmRXmStringTable, 1329: (XtTypeConverter)CvtStringToXmStringTable, 1330: NULL, 0, XtCacheNone, XmStringTableCvtDestroy); 1331: } 1332: 1333: /* 1334: * Function: 1335: * CONVERT(w, from_string, to_type, to_size, success); 1336: * Description: 1337: * A converter wrapper for convenience from BuilderXcessory. 1338: * Input: 1339: * w - Widget : the widget to use for conversion 1340: * from_string - char * : the string to convert from 1341: * to_type - char * : the type to convert to 1342: * to_size - int : the size of the conversion result 1343: * success - Boolean* : Set to the result value of the conversion 1344: * Output: 1345: * None 1346: */ 1347: #ifndef IGNORE_CONVERT 1348: XtPointer CONVERT 1349: ARGLIST((w, from_string, to_type, to_size, success)) 1350: ARG(Widget, w) 1351: ARG(char *, from_string) 1352: ARG(char *, to_type) 1353: ARG(int, to_size) 1354: GRA(Boolean *, success) 1355: { 1356: XrmValue fromVal, toVal; /* resource holders */ 1357: Boolean convResult; /* return value */ 1358: XtPointer val; /* Pointer size return value */ 1359: 1360: to_size = 0; 1361: 1362: /* 1363: * We will assume that the conversion is going to fail and change this 1364: * value later if the conversion is a success. 1365: */ 1366: *success = False; 1367: 1368: /* 1369: * Since we are converting from a string to some type we need to 1370: * set the fromVal structure up with the string information that 1371: * the caller passed in. 1372: */ 1373: fromVal.size = strlen(from_string) + 1; 1374: fromVal.addr = from_string; 1375: 1376: /* 1377: * Since we are not sure what type and size of data we are going to 1378: * get back we will set this up so that the converter will point us 1379: * at a block of valid data. 1380: */ 1381: toVal.size = 0; 1382: toVal.addr = NULL; 1383: 1384: /* 1385: * Now lets try to convert this data by calling this handy-dandy Xt 1386: * routine. 1387: */ 1388: convResult = XtConvertAndStore(w, XmRString, &fromVal, to_type, &toVal); 1389: 1390: 1391: /* 1392: * Now we have two conditions here. One the conversion was a success 1393: * and two the conversion failed. 1394: */ 1395: if(!convResult) 1396: { 1397: /* 1398: * If this conversion failed that we can pretty much return right 1399: * here because there is nothing else we can do. 1400: */ 1401: return((XtPointer) NULL); 1402: } 1403: 1404: /* 1405: * If we get this far that means we did the conversion and all is 1406: * well. Now we have to handle the special cases for type and 1407: * size constraints. 1408: */ 1409: if(!strcmp(to_type, "String")) 1410: { 1411: /* 1412: * Since strings are handled different in Xt we have to deal with 1413: * the conversion from a string to a string. When this happens the 1414: * toVal.size will hold the strlen of the string so generic 1415: * conversion code can't handle it. It is possible for a string to 1416: * string conversion to happen so we do have to watch for it. 1417: */ 1418: val = (XTPOINTER)toVal.addr; 1419: } 1420: else if(!strcmp(to_type, "Double")) 1421: { 1422: val = (XTPOINTER)((double*)toVal.addr); 1423: } 1424: else if(!strcmp(to_type, "Float")) 1425: { 1426: val = (XTPOINTER)((float*)toVal.addr); 1427: } 1428: else 1429: { 1430: /* 1431: * Here is the generic conversion return value handler. This 1432: * just does some size specific casting so that value that we 1433: * return is in the correct bytes of the XtPointer that we 1434: * return. Here we check all sizes from 1 to 8 bytes. 1435: */ 1436: switch(toVal.size) 1437: { 1438: case 1: 1439: val = (XTPOINTER)(*(char*)toVal.addr); 1440: break; 1441: case 2: 1442: val = (XTPOINTER)(*(short*)toVal.addr); 1443: break; 1444: case 4: 1445: val = (XTPOINTER)(*(int*)toVal.addr); 1446: break; 1447: case 8: 1448: default: 1449: val = (XTPOINTER)(*(long*)toVal.addr); 1450: break; 1451: } 1452: } 1453: 1454: /* 1455: * Well everything is done and the conversion was a success so lets 1456: * set the success flag to True. 1457: */ 1458: *success = convResult; 1459: 1460: /* 1461: * Finally lets return the converted value. 1462: */ 1463: /*SUPPRESS 80*/ 1464: return(val); 1465: } 1466: #endif 1467: 1468: /* 1469: * Function: 1470: * MENU_POST(p, mw, ev, dispatch); 1471: * Description: 1472: * A converter wrapper for convenience from BuilderXcessory. 1473: * Input: 1474: * p - Widget : the widget to post 1475: * mw - XtPointer : the menu widget 1476: * ev - XEvent* : the event that caused the menu post 1477: * dispatch - Boolean* : not used 1478: * Output: 1479: * None 1480: */ 1481: 1482: #ifndef IGNORE_MENU_POST 1483: 1484: void MENU_POST 1485: ARGLIST((p, mw, ev, dispatch)) 1486: UARG(Widget, p) 1487: ARG(XtPointer, mw) 1488: ARG(XEvent *, ev) 1489: GRAU(Boolean *, dispatch) 1490: { 1491: Arg args[2]; 1492: int argcnt; 1493: int button; 1494: Widget m = (Widget)mw; 1495: XButtonEvent *e = (XButtonEvent *)ev; 1496: 1497: argcnt = 0; 1498: XtSetArg(args[argcnt], XmNwhichButton, &button); 1499: argcnt++; 1500: XtGetValues(m, args, argcnt); 1501: if(e->button != button) return; 1502: XmMenuPosition(m, e); 1503: XtManageChild(m); 1504: } 1505: #endif 1506: 1507: /* 1508: * Function: 1509: * SET_BACKGROUND_COLOR(w, args, argcnt, bg_color); 1510: * Description: 1511: * Sets the background color and shadows of a widget. 1512: * Input: 1513: * w - The widget to set the background color on. 1514: * args, argcnt - The argument list so far. 1515: * bg_color - The new background color as a pixel. 1516: * Output: 1517: * none 1518: * 1519: * NOTES: This assumes that args later in the argument list 1520: * override those already in the list. Therfore i f 1521: * there are shadow colors later in the list they will win. 1522: * 1523: * There is no need to use this function when creating a widget 1524: * only when doing a set values, shadow colors are automatically 1525: * calculated at creation time. 1526: */ 1527: 1528: void SET_BACKGROUND_COLOR 1529: ARGLIST((w, args, argcnt, bg_color)) 1530: ARG(Widget, w) 1531: ARG(ArgList, args) 1532: ARG(Cardinal *, argcnt) 1533: GRA(Pixel, bg_color) 1534: { 1535: int i; 1536: int topShadowLoc; 1537: int bottomShadowLoc; 1538: int selectLoc; 1539: int fgLoc; 1540: 1541: #if ((XmVERSION == 1) && (XmREVISION > 0)) 1542: 1543: /* 1544: * Walk through the arglist to see if the user set the top or 1545: * bottom shadow colors. 1546: */ 1547: selectLoc = topShadowLoc = bottomShadowLoc = UNSET; 1548: for (i = 0; i < *argcnt; i++) 1549: { 1550: if ((strcmp(args[i].name, XmNtopShadowColor) == 0) || 1551: (strcmp(args[i].name, XmNtopShadowPixmap) == 0)) 1552: { 1553: topShadowLoc = i; 1554: } 1555: else if ((strcmp(args[i].name, XmNbottomShadowColor) == 0) || 1556: (strcmp(args[i].name, XmNbottomShadowPixmap) == 0)) 1557: { 1558: bottomShadowLoc = i; 1559: } 1560: else if (strcmp(args[i].name, XmNarmColor) == 0) 1561: { 1562: selectLoc = i; 1563: } 1564: else if (strcmp(args[i].name, XmNforeground) == 0) 1565: { 1566: fgLoc = i; 1567: } 1568: } 1569: 1570: /* 1571: * If either the top or bottom shadow are not set then we 1572: * need to use XmGetColors to get the shadow colors from the backgound 1573: * color and add those that are not already in the arglist to the 1574: * arglist. 1575: * 1576: */ 1577: if ((bottomShadowLoc == UNSET) || 1578: (topShadowLoc == UNSET) || 1579: (selectLoc == UNSET) || 1580: (fgLoc == UNSET)) 1581: { 1582: Arg larg[1]; 1583: Colormap cmap; 1584: Pixel topShadow; 1585: Pixel bottomShadow; 1586: Pixel select; 1587: Pixel fgColor; 1588: 1589: XtSetArg(larg[0], XmNcolormap, &cmap); 1590: XtGetValues(w, larg, 1); 1591: XmGetColors(XtScreen(w), cmap, bg_color, 1592: &fgColor, &topShadow, &bottomShadow, &select); 1593: 1594: if (topShadowLoc == UNSET) 1595: { 1596: XtSetArg(args[*argcnt], XmNtopShadowColor, topShadow); 1597: (*argcnt)++; 1598: } 1599: 1600: if (bottomShadowLoc == UNSET) 1601: { 1602: XtSetArg(args[*argcnt], XmNbottomShadowColor, bottomShadow); 1603: (*argcnt)++; 1604: } 1605: 1606: if (selectLoc == UNSET) 1607: { 1608: XtSetArg(args[*argcnt], XmNarmColor, select); 1609: (*argcnt)++; 1610: } 1611: 1612: if (fgLoc == UNSET) 1613: { 1614: XtSetArg(args[*argcnt], XmNforeground, fgColor); 1615: (*argcnt)++; 1616: } 1617: } 1618: #endif 1619: 1620: XtSetArg(args[*argcnt], XmNbackground, bg_color); (*argcnt)++; 1621: } 1622: 1623: /* 1624: * Function: 1625: * w = BxFindTopShell(start); 1626: * Description: 1627: * Go up the hierarhcy until we find a shell widget. 1628: * Input: 1629: * start - Widget : the widget to start with. 1630: * Output: 1631: * w - Widget : the shell widget. 1632: */ 1633: #ifndef _BX_FIND_TOP_SHELL 1634: #define _BX_FIND_TOP_SHELL 1635: 1636: Widget BxFindTopShell 1637: ARGLIST((start)) 1638: GRA(Widget, start) 1639: { 1640: Widget p; 1641: 1642: while(p = XtParent(start)) 1643: { 1644: start = p; 1645: } 1646: return(start); 1647: } 1648: #endif /* _BX_FIND_TOP_SHELL */ 1649: 1650: /* 1651: * Function: 1652: * BxWidgetIdsFromNames(ref, cbName, stringList) 1653: * Description: 1654: * Return an array of widget ids from a list of widget names. 1655: * Input: 1656: * ref - Widget : reference widget. 1657: * cbName - char* : callback name. 1658: * stringList - char*: list of widget names. 1659: * Output: 1660: * WidgetList : array of widget IDs. 1661: */ 1662: 1663: #ifndef _BX_WIDGETIDS_FROM_NAMES 1664: #define _BX_WIDGETIDS_FROM_NAMES 1665: 1666: WidgetList BxWidgetIdsFromNames 1667: ARGLIST((ref, cbName, stringList)) 1668: ARG(Widget, ref) 1669: ARG(char, *cbName) 1670: GRA(char, *stringList) 1671: { 1672: WidgetList wgtIds = NULL; 1673: int wgtCount = 0; 1674: Widget inst; 1675: Widget current; 1676: String tmp; 1677: String start; 1678: String widget; 1679: char *ptr; 1680: 1681: /* 1682: * For backward compatibility, remove [ and ] from the list. 1683: */ 1684: tmp = start = XtNewString(stringList); 1685: if((start = strchr(start, '[')) != NULL) start++; 1686: else start = tmp; 1687: 1688: while((start && *start) && isspace(*start)) 1689: { 1690: start++; 1691: } 1692: ptr = strrchr(start, ']'); 1693: if (ptr) 1694: { 1695: *ptr = '\0'; 1696: } 1697: 1698: ptr = start + strlen(start) - 1; 1699: while(ptr && *ptr) 1700: { 1701: if (isspace(*ptr)) 1702: { 1703: ptr--; 1704: } 1705: else 1706: { 1707: ptr++; 1708: break; 1709: } 1710: } 1711: if (ptr && *ptr) 1712: { 1713: *ptr = '\0'; 1714: } 1715: 1716: /* 1717: * start now points to the first character after the [. 1718: * the list is now either empty, one, or more widget 1719: * instance names. 1720: */ 1721: start = strtok(start, ","); 1722: while(start) 1723: { 1724: while((start && *start) && isspace(*start)) 1725: { 1726: start++; 1727: } 1728: ptr = start + strlen(start) - 1; 1729: while(ptr && *ptr) 1730: { 1731: if (isspace(*ptr)) 1732: { 1733: ptr--; 1734: } 1735: else 1736: { 1737: ptr++; 1738: break; 1739: } 1740: } 1741: if (ptr && *ptr) 1742: { 1743: *ptr = '\0'; 1744: } 1745: 1746: /* 1747: * Form a string to use with XtNameToWidget(). 1748: */ 1749: widget = (char *)XtMalloc((strlen(start) + 2) * sizeof(char)); 1750: sprintf(widget, "*%s", start); 1751: 1752: /* 1753: * Start at this level and continue up until the widget is found 1754: * or until the top of the hierarchy is reached. 1755: */ 1756: current = ref; 1757: while (current != NULL) 1758: { 1759: inst = XtNameToWidget(current, widget); 1760: if (inst != NULL ) 1761: { 1762: wgtCount++; 1763: wgtIds = (WidgetList)XtRealloc((char *)wgtIds, 1764: wgtCount * sizeof(Widget)); 1765: wgtIds[wgtCount - 1] = inst; 1766: break; 1767: } 1768: current = XtParent(current); 1769: } 1770: 1771: if (current == NULL) 1772: { 1773: printf("Callback Error (%s):\n\t\ 1774: Cannot find widget %s\n", cbName, widget); 1775: } 1776: XtFree(widget); 1777: start = strtok(NULL, ","); 1778: } 1779: 1780: /* 1781: * NULL terminate the list. 1782: */ 1783: wgtIds = (WidgetList)XtRealloc((char *)wgtIds, 1784: (wgtCount + 1) * sizeof(Widget)); 1785: wgtIds[wgtCount] = NULL; 1786: 1787: XtFree((char *)tmp); 1788: return(wgtIds); 1789: } 1790: #endif /* _BX_WIDGETIDS_FROM_NAMES */ 1791: 1792: XtPointer SINGLE 1793: ARGLIST((val)) 1794: GRA(float, val) 1795: { 1796: XtPointer pointer; 1797: 1798: pointer = (XtPointer)XtMalloc(sizeof(float)); 1799: if ( pointer != NULL ) *((float *)pointer) = val; 1800: return(pointer); 1801: } 1802: 1803: XtPointer DOUBLE 1804: ARGLIST((val)) 1805: GRA(double, val) 1806: { 1807: XtPointer pointer; 1808: 1809: pointer = (XtPointer)XtMalloc(sizeof(double)); 1810: if ( pointer != NULL ) *((double *)pointer) = val; 1811: return(pointer); 1812: } 1813: 1814: 1815: /**************************************************************************** 1816: * 1817: * Big chunk of code inserted from Bull (based on modified 3.3) 1818: * 1819: ****************************************************************************/ 1820: 1821: #ifndef IGNORE_XPM_PIXMAP 1822: 1823: #ifndef USE_XPM_LIBRARY 1824: 1825: #ifdef SYSV 1826: #include <memory.h> 1827: #endif 1828: 1829: /* 1830: * Copyright 1990, 1991 GROUPE BULL 1831: * 1832: * Permission to use, copy, modify, and distribute this software and its 1833: * documentation for any purpose and without fee is hereby granted, provided 1834: * that the above copyright notice appear in all copies and that both that 1835: * copyright notice and this permission notice appear in supporting 1836: * documentation, and that the name of GROUPE BULL not be used in advertising 1837: * or publicity pertaining to distribution of the software without specific, 1838: * written prior permission. GROUPE BULL makes no representations about the 1839: * suitability of this software for any purpose. It is provided "as is" 1840: * without express or implied warranty. 1841: * 1842: * GROUPE BULL disclaims all warranties with regard to this software, 1843: * including all implied warranties of merchantability and fitness, 1844: * in no event shall GROUPE BULL be liable for any special, 1845: * indirect or consequential damages or any damages 1846: * whatsoever resulting from loss of use, data or profits, 1847: * whether in an action of contract, negligence or other tortious 1848: * action, arising out of or in connection with the use 1849: * or performance of this software. 1850: * 1851: */ 1852: 1853: /* Return ErrorStatus codes: 1854: * null if full success 1855: * positive if partial success 1856: * negative if failure 1857: */ 1858: 1859: #define BxXpmColorError 1 1860: #define BxXpmSuccess 0 1861: #define BxXpmOpenFailed -1 1862: #define BxXpmFileInvalid -2 1863: #define BxXpmNoMemory -3 1864: #define BxXpmColorFailed -4 1865: 1866: typedef struct { 1867: char *name; /* Symbolic color name */ 1868: char *value; /* Color value */ 1869: Pixel pixel; /* Color pixel */ 1870: } BxXpmColorSymbol; 1871: 1872: typedef struct { 1873: unsigned long valuemask; /* Specifies which attributes are 1874: * defined */ 1875: 1876: Visual *visual; /* Specifies the visual to use */ 1877: Colormap colormap; /* Specifies the colormap to use */ 1878: unsigned int depth; /* Specifies the depth */ 1879: unsigned int width; /* Returns the width of the created 1880: * pixmap */ 1881: unsigned int height; /* Returns the height of the created 1882: * pixmap */ 1883: unsigned int x_hotspot; /* Returns the x hotspot's 1884: * coordinate */ 1885: unsigned int y_hotspot; /* Returns the y hotspot's 1886: * coordinate */ 1887: unsigned int cpp; /* Specifies the number of char per 1888: * pixel */ 1889: Pixel *pixels; /* List of used color pixels */ 1890: unsigned int npixels; /* Number of pixels */ 1891: BxXpmColorSymbol *colorsymbols; /* Array of color symbols to 1892: * override */ 1893: unsigned int numsymbols; /* Number of symbols */ 1894: char *rgb_fname; /* RGB text file name */ 1895: 1896: /* Infos */ 1897: unsigned int ncolors; /* Number of colors */ 1898: char ***colorTable; /* Color table pointer */ 1899: char *hints_cmt; /* Comment of the hints section */ 1900: char *colors_cmt; /* Comment of the colors section */ 1901: char *pixels_cmt; /* Comment of the pixels section */ 1902: unsigned int mask_pixel; /* Transparent pixel's color table 1903: * index */ 1904: } BxXpmAttributes; 1905: 1906: /* Xpm attribute value masks bits */ 1907: #define BxXpmVisual (1L<<0) 1908: #define BxXpmColormap (1L<<1) 1909: #define BxXpmDepth (1L<<2) 1910: #define BxXpmSize (1L<<3) /* width & height */ 1911: #define BxXpmHotspot (1L<<4) /* x_hotspot & y_hotspot */ 1912: #define BxXpmCharsPerPixel (1L<<5) 1913: #define BxXpmColorSymbols (1L<<6) 1914: #define BxXpmRgbFilename (1L<<7) 1915: #define BxXpmInfos (1L<<8) /* all infos members */ 1916: 1917: #define BxXpmReturnPixels (1L<<9) 1918: #define BxXpmReturnInfos BxXpmInfos 1919: 1920: /* 1921: * minimal portability layer between ansi and KR C 1922: */ 1923: 1924: /* forward declaration of functions with prototypes */ 1925: 1926: #ifdef NeedFunctionPrototypes 1927: #define LFUNC(f, t, p) static t f p 1928: #else 1929: #define LFUNC(f, t, p) static t f() 1930: #endif 1931: 1932: /* 1933: * functions declarations 1934: */ 1935: 1936: #ifdef __cplusplus 1937: extern "C" { 1938: #endif 1939: 1940: LFUNC(XpmCreatePixmapFromData, int, (Display * display, 1941: Drawable d, 1942: char **data, 1943: Pixmap * pixmap_return, 1944: Pixmap * shapemask_return, 1945: BxXpmAttributes * attributes)); 1946: 1947: LFUNC(XpmCreateImageFromData, int, (Display * display, 1948: char **data, 1949: XImage ** image_return, 1950: XImage ** shapemask_return, 1951: BxXpmAttributes * attributes)); 1952: 1953: LFUNC(XpmFreeAttributes, void, (BxXpmAttributes * attributes)); 1954: 1955: #ifdef __cplusplus 1956: } /* for C++ V2.0 */ 1957: #endif 1958: 1959: 1960: typedef struct { 1961: unsigned int type; 1962: union { 1963: FILE *file; 1964: char **data; 1965: } stream; 1966: char *cptr; 1967: unsigned int line; 1968: int CommentLength; 1969: char Comment[BUFSIZ]; 1970: char *Bcmt, *Ecmt, Bos, Eos; 1971: unsigned int InsideString; /* used during parsing: 0 or 1 1972: * whether we are inside or not */ 1973: } bxxpmData; 1974: 1975: #define BXXPMARRAY 0 1976: #define BXXPMFILE 1 1977: #define BXXPMPIPE 2 1978: 1979: typedef unsigned char byte; 1980: 1981: #define BX_TRANSPARENT_COLOR "None" /* this must be a string! */ 1982: 1983: /* number of BxXpmColorKeys */ 1984: #define BXNKEYS 5 1985: 1986: /* 1987: * key numbers for visual type, they must fit along with the number key of 1988: * each corresponding element in BxXpmColorKeys[] defined in xpm.h 1989: */ 1990: #define BXMONO 2 1991: #define BXGRAY4 3 1992: #define BXGRAY 4 1993: #define BXCOLOR 5 1994: 1995: /* structure containing data related to an Xpm pixmap */ 1996: typedef struct { 1997: char *name; 1998: unsigned int width; 1999: unsigned int height; 2000: unsigned int cpp; 2001: unsigned int ncolors; 2002: char ***colorTable; 2003: unsigned int *pixelindex; 2004: XColor *xcolors; 2005: char **colorStrings; 2006: unsigned int mask_pixel; /* mask pixel's colorTable index */ 2007: } bxxpmInternAttrib; 2008: 2009: #define BX_UNDEF_PIXEL 0x80000000 2010: 2011: char *BxXpmColorKeys[] = 2012: { 2013: "s", /* key #1: symbol */ 2014: "m", /* key #2: mono visual */ 2015: "g4", /* key #3: 4 grays visual */ 2016: "g", /* key #4: gray visual */ 2017: "c", /* key #5: color visual */ 2018: }; 2019: 2020: /* XPM private routines */ 2021: 2022: LFUNC(xpmCreateImage, int, (Display * display, 2023: bxxpmInternAttrib * attrib, 2024: XImage ** image_return, 2025: XImage ** shapeimage_return, 2026: BxXpmAttributes * attributes)); 2027: 2028: LFUNC(xpmParseData, int, (bxxpmData * data, 2029: bxxpmInternAttrib * attrib_return, 2030: BxXpmAttributes * attributes)); 2031: 2032: LFUNC(BxXpmVisualType, int, (Visual * visual)); 2033: LFUNC(xpmFreeColorTable, void, (char ***colorTable, int ncolors)); 2034: 2035: LFUNC(xpmInitInternAttrib, void, (bxxpmInternAttrib * xmpdata)); 2036: 2037: LFUNC(xpmFreeInternAttrib, void, (bxxpmInternAttrib * xmpdata)); 2038: 2039: LFUNC(xpmSetAttributes, void, (bxxpmInternAttrib * attrib, 2040: BxXpmAttributes * attributes)); 2041: 2042: /* I/O utility */ 2043: 2044: LFUNC(xpmNextString, void, (bxxpmData * mdata)); 2045: LFUNC(xpmNextUI, int, (bxxpmData * mdata, unsigned int *ui_return)); 2046: LFUNC(xpmGetC, int, (bxxpmData * mdata)); 2047: LFUNC(xpmUngetC, int, (int c, bxxpmData * mdata)); 2048: LFUNC(xpmNextWord, unsigned int, (bxxpmData * mdata, char *buf)); 2049: LFUNC(xpmGetCmt, void, (bxxpmData * mdata, char **cmt)); 2050: LFUNC(xpmOpenArray, int, (char **data, bxxpmData * mdata)); 2051: LFUNC(XpmDataClose, void, (bxxpmData * mdata)); 2052: 2053: /* RGB utility */ 2054: 2055: LFUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp, 2056: register XImage * img)); 2057: LFUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp, 2058: register XImage * img)); 2059: 2060: /* Image utility */ 2061: 2062: LFUNC(SetColor, int, (Display * display, Colormap colormap, char *colorname, 2063: unsigned int color_index, Pixel * image_pixel, 2064: Pixel * mask_pixel, unsigned int *mask_pixel_index)); 2065: 2066: LFUNC(CreateXImage, int, (Display * display, Visual * visual, 2067: unsigned int depth, unsigned int width, 2068: unsigned int height, XImage ** image_return)); 2069: 2070: LFUNC(SetImagePixels, void, (XImage * image, unsigned int width, 2071: unsigned int height, unsigned int *pixelindex, 2072: Pixel * pixels)); 2073: 2074: LFUNC(SetImagePixels32, void, (XImage * image, unsigned int width, 2075: unsigned int height, unsigned int *pixelindex, 2076: Pixel * pixels)); 2077: 2078: LFUNC(SetImagePixels16, void, (XImage * image, unsigned int width, 2079: unsigned int height, unsigned int *pixelindex, 2080: Pixel * pixels)); 2081: 2082: LFUNC(SetImagePixels8, void, (XImage * image, unsigned int width, 2083: unsigned int height, unsigned int *pixelindex, 2084: Pixel * pixels)); 2085: 2086: LFUNC(SetImagePixels1, void, (XImage * image, unsigned int width, 2087: unsigned int height, unsigned int *pixelindex, 2088: Pixel * pixels)); 2089: 2090: LFUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return)); 2091: 2092: /* 2093: * Macros 2094: * 2095: * The BXXYNORMALIZE macro determines whether XY format data requires 2096: * normalization and calls a routine to do so if needed. The logic in 2097: * this module is designed for LSBFirst byte and bit order, so 2098: * normalization is done as required to present the data in this order. 2099: * 2100: * The BXZNORMALIZE macro performs byte and nibble order normalization if 2101: * required for Z format data. 2102: * 2103: * The BXXYINDEX macro computes the index to the starting byte (char) boundary 2104: * for a bitmap_unit containing a pixel with coordinates x and y for image 2105: * data in XY format. 2106: * 2107: * The BXZINDEX* macros compute the index to the starting byte (char) boundary 2108: * for a pixel with coordinates x and y for image data in ZPixmap format. 2109: * 2110: */ 2111: 2112: #define BXXYNORMALIZE(bp, img) \ 2113: if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ 2114: xpm_xynormalizeimagebits((unsigned char *)(bp), img) 2115: 2116: #define BXZNORMALIZE(bp, img) \ 2117: if (img->byte_order == MSBFirst) \ 2118: xpm_znormalizeimagebits((unsigned char *)(bp), img) 2119: 2120: #define BXXYINDEX(x, y, img) \ 2121: ((y) * img->bytes_per_line) + \ 2122: (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) 2123: 2124: #define BXZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ 2125: (((x) * img->bits_per_pixel) >> 3) 2126: 2127: #define BXZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2) 2128: 2129: #define BXZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1) 2130: 2131: #define BXZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x) 2132: 2133: #define BXZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3) 2134: 2135: #if __STDC__ 2136: #define Const const 2137: #else 2138: #define Const 2139: #endif 2140: 2141: 2142: 2143: static unsigned int atoui 2144: ARGLIST((p, l, ui_return)) 2145: ARG(register char *, p) 2146: ARG(unsigned int, l) 2147: GRA(unsigned int *, ui_return) 2148: { 2149: register int n, i; 2150: 2151: n = 0; 2152: for (i = 0; i < l; i++) 2153: if (*p >= '0' && *p <= '9') 2154: n = n * 10 + *p++ - '0'; 2155: else 2156: break; 2157: 2158: if (i != 0 && i == l) { 2159: *ui_return = n; 2160: return 1; 2161: } else 2162: return 0; 2163: } 2164: 2165: static int XpmCreatePixmapFromData 2166: ARGLIST((display, d, data, pixmap_return, shapemask_return, attributes)) 2167: ARG(Display *, display) 2168: ARG(Drawable, d) 2169: ARG(char **, data) 2170: ARG(Pixmap *, pixmap_return) 2171: ARG(Pixmap *, shapemask_return) 2172: GRA(BxXpmAttributes *,attributes) 2173: { 2174: XImage *image, **imageptr = NULL; 2175: XImage *shapeimage, **shapeimageptr = NULL; 2176: int ErrorStatus; 2177: XGCValues gcv; 2178: GC gc; 2179: 2180: /* 2181: * initialize return values 2182: */ 2183: if (pixmap_return) { 2184: *pixmap_return = (Pixmap) NULL; 2185: imageptr = ℑ 2186: } 2187: if (shapemask_return) { 2188: *shapemask_return = (Pixmap) NULL; 2189: shapeimageptr = &shapeimage; 2190: } 2191: 2192: /* 2193: * create the images 2194: */ 2195: ErrorStatus = XpmCreateImageFromData(display, data, imageptr, 2196: shapeimageptr, attributes); 2197: if (ErrorStatus < 0) 2198: return (ErrorStatus); 2199: 2200: /* 2201: * create the pixmaps 2202: */ 2203: if (imageptr && image) { 2204: *pixmap_return = XCreatePixmap(display, d, image->width, 2205: image->height, image->depth); 2206: gcv.function = GXcopy; 2207: gc = XCreateGC(display, *pixmap_return, GCFunction, &gcv); 2208: 2209: XPutImage(display, *pixmap_return, gc, image, 0, 0, 0, 0, 2210: image->width, image->height); 2211: 2212: XDestroyImage(image); 2213: XFreeGC(display, gc); 2214: } 2215: if (shapeimageptr && shapeimage) { 2216: *shapemask_return = XCreatePixmap(display, d, shapeimage->width, 2217: shapeimage->height, 2218: shapeimage->depth); 2219: gcv.function = GXcopy; 2220: gc = XCreateGC(display, *shapemask_return, GCFunction, &gcv); 2221: 2222: XPutImage(display, *shapemask_return, gc, shapeimage, 0, 0, 0, 0, 2223: shapeimage->width, shapeimage->height); 2224: 2225: XDestroyImage(shapeimage); 2226: XFreeGC(display, gc); 2227: } 2228: return (ErrorStatus); 2229: } 2230: 2231: 2232: static int XpmCreateImageFromData 2233: ARGLIST((display, data, image_return, shapeimage_return, attributes)) 2234: ARG(Display *,display) 2235: ARG(char **, data) 2236: ARG(XImage **, image_return) 2237: ARG(XImage **, shapeimage_return) 2238: GRA(BxXpmAttributes *, attributes) 2239: { 2240: bxxpmData mdata; 2241: int ErrorStatus; 2242: bxxpmInternAttrib attrib; 2243: 2244: /* 2245: * initialize return values 2246: */ 2247: if (image_return) 2248: *image_return = NULL; 2249: if (shapeimage_return) 2250: *shapeimage_return = NULL; 2251: 2252: if ((ErrorStatus = xpmOpenArray(data, &mdata)) != BxXpmSuccess) 2253: return (ErrorStatus); 2254: 2255: xpmInitInternAttrib(&attrib); 2256: 2257: ErrorStatus = xpmParseData(&mdata, &attrib, attributes); 2258: 2259: if (ErrorStatus == BxXpmSuccess) 2260: ErrorStatus = xpmCreateImage(display, &attrib, image_return, 2261: shapeimage_return, attributes); 2262: 2263: if (ErrorStatus >= 0) 2264: xpmSetAttributes(&attrib, attributes); 2265: else if (attributes) 2266: XpmFreeAttributes(attributes); 2267: 2268: xpmFreeInternAttrib(&attrib); 2269: XpmDataClose(&mdata); 2270: 2271: return (ErrorStatus); 2272: } 2273: 2274: /* 2275: * open the given array to be read or written as an bxxpmData which is returned 2276: */ 2277: static int xpmOpenArray 2278: ARGLIST((data, mdata)) 2279: ARG(char **,data) 2280: GRA(bxxpmData *,mdata) 2281: { 2282: mdata->type = BXXPMARRAY; 2283: mdata->stream.data = data; 2284: mdata->cptr = *data; 2285: mdata->line = 0; 2286: mdata->CommentLength = 0; 2287: mdata->Bcmt = mdata->Ecmt = NULL; 2288: mdata->Bos = mdata->Eos = '\0'; 2289: mdata->InsideString = 0; 2290: return (BxXpmSuccess); 2291: } 2292: 2293: /* 2294: * Intialize the bxxpmInternAttrib pointers to Null to know 2295: * which ones must be freed later on. 2296: */ 2297: static void xpmInitInternAttrib 2298: ARGLIST((attrib)) 2299: GRA(bxxpmInternAttrib *,attrib) 2300: { 2301: attrib->ncolors = 0; 2302: attrib->colorTable = NULL; 2303: attrib->pixelindex = NULL; 2304: attrib->xcolors = NULL; 2305: attrib->colorStrings = NULL; 2306: attrib->mask_pixel = BX_UNDEF_PIXEL; 2307: } 2308: 2309: /* function call in case of error, frees only localy allocated variables */ 2310: #undef RETURN 2311: #define RETURN(status) \ 2312: { if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ 2313: if (chars) free(chars); \ 2314: if (pixelindex) free((char *)pixelindex); \ 2315: if (hints_cmt) free((char *)hints_cmt); \ 2316: if (colors_cmt) free((char *)colors_cmt); \ 2317: if (pixels_cmt) free((char *)pixels_cmt); \ 2318: return(status); } 2319: 2320: /* 2321: * This function parses an Xpm file or data and store the found informations 2322: * in an an bxxpmInternAttrib structure which is returned. 2323: */ 2324: static int xpmParseData 2325: ARGLIST((data, attrib_return, attributes)) 2326: ARG(bxxpmData *,data) 2327: ARG(bxxpmInternAttrib *, attrib_return) 2328: GRA(BxXpmAttributes *, attributes) 2329: { 2330: /* variables to return */ 2331: unsigned int width, height; 2332: unsigned int ncolors = 0; 2333: unsigned int cpp; 2334: unsigned int x_hotspot, y_hotspot, hotspot = 0; 2335: char ***colorTable = NULL; 2336: unsigned int *pixelindex = NULL; 2337: char *hints_cmt = NULL; 2338: char *colors_cmt = NULL; 2339: char *pixels_cmt = NULL; 2340: 2341: /* calculation variables */ 2342: unsigned int rncolors = 0; /* read number of colors, it is 2343: * different to ncolors to avoid 2344: * problem when freeing the 2345: * colorTable in case an error 2346: * occurs while reading the hints 2347: * line */ 2348: unsigned int key; /* color key */ 2349: char *chars = NULL, buf[BUFSIZ]; 2350: unsigned int *iptr; 2351: unsigned int a, b, x, y, l; 2352: 2353: unsigned int curkey; /* current color key */ 2354: unsigned int lastwaskey; /* key read */ 2355: char curbuf[BUFSIZ]; /* current buffer */ 2356: 2357: /* 2358: * read hints: width, height, ncolors, chars_per_pixel 2359: */ 2360: if (!(xpmNextUI(data, &width) && xpmNextUI(data, &height) 2361: && xpmNextUI(data, &rncolors) && xpmNextUI(data, &cpp))) 2362: RETURN(BxXpmFileInvalid); 2363: 2364: ncolors = rncolors; 2365: 2366: /* 2367: * read hotspot coordinates if any 2368: */ 2369: hotspot = xpmNextUI(data, &x_hotspot) && xpmNextUI(data, &y_hotspot); 2370: 2371: /* 2372: * store the hints comment line 2373: */ 2374: if (attributes && (attributes->valuemask & BxXpmReturnInfos)) 2375: xpmGetCmt(data, &hints_cmt); 2376: 2377: /* 2378: * read colors 2379: */ 2380: colorTable = (char ***) calloc(ncolors, sizeof(char **)); 2381: if (!colorTable) 2382: RETURN(BxXpmNoMemory); 2383: 2384: for (a = 0; a < ncolors; a++) { 2385: xpmNextString(data); /* skip the line */ 2386: colorTable[a] = (char **) calloc((BXNKEYS + 1), sizeof(char *)); 2387: if (!colorTable[a]) 2388: RETURN(BxXpmNoMemory); 2389: 2390: /* 2391: * read pixel value 2392: */ 2393: colorTable[a][0] = (char *) malloc(cpp); 2394: if (!colorTable[a][0]) 2395: RETURN(BxXpmNoMemory); 2396: for (b = 0; b < cpp; b++) 2397: colorTable[a][0][b] = xpmGetC(data); 2398: 2399: /* 2400: * read color keys and values 2401: */ 2402: curkey = 0; 2403: lastwaskey = 0; 2404: while (l = xpmNextWord(data, buf)) { 2405: if (!lastwaskey) { 2406: for (key = 1; key < BXNKEYS + 1; key++) 2407: if ((strlen(BxXpmColorKeys[key - 1]) == l) 2408: && (!strncmp(BxXpmColorKeys[key - 1], buf, l))) 2409: break; 2410: } 2411: if (!lastwaskey && key <= BXNKEYS) { /* open new key */ 2412: if (curkey) { /* flush string */ 2413: colorTable[a][curkey] = 2414: (char *) malloc(strlen(curbuf) + 1); 2415: if (!colorTable[a][curkey]) 2416: RETURN(BxXpmNoMemory); 2417: strcpy(colorTable[a][curkey], curbuf); 2418: } 2419: curkey = key; /* set new key */ 2420: curbuf[0] = '\0'; /* reset curbuf */ 2421: lastwaskey = 1; 2422: } else { 2423: if (!curkey) 2424: RETURN(BxXpmFileInvalid); /* key without value */ 2425: if (!lastwaskey) 2426: strcat(curbuf, " ");/* append space */ 2427: buf[l] = '\0'; 2428: strcat(curbuf, buf); /* append buf */ 2429: lastwaskey = 0; 2430: } 2431: } 2432: if (!curkey) 2433: RETURN(BxXpmFileInvalid); /* key without value */ 2434: colorTable[a][curkey] = (char *) malloc(strlen(curbuf) + 1); 2435: if (!colorTable[a][curkey]) 2436: RETURN(BxXpmNoMemory); 2437: strcpy(colorTable[a][curkey], curbuf); 2438: } 2439: 2440: /* 2441: * store the colors comment line 2442: */ 2443: if (attributes && (attributes->valuemask & BxXpmReturnInfos)) 2444: xpmGetCmt(data, &colors_cmt); 2445: 2446: /* 2447: * read pixels and index them on color number 2448: */ 2449: pixelindex = 2450: (unsigned int *) malloc(sizeof(unsigned int) * width * height); 2451: if (!pixelindex) 2452: RETURN(BxXpmNoMemory); 2453: 2454: iptr = pixelindex; 2455: 2456: chars = (char *) malloc(cpp); 2457: if (!chars) 2458: RETURN(BxXpmNoMemory); 2459: 2460: for (y = 0; y < height; y++) { 2461: xpmNextString(data); 2462: for (x = 0; x < width; x++, iptr++) { 2463: for (a = 0; a < cpp; a++) 2464: chars[a] = xpmGetC(data); 2465: for (a = 0; a < ncolors; a++) 2466: if (!strncmp(colorTable[a][0], chars, cpp)) 2467: break; 2468: if (a == ncolors) 2469: RETURN(BxXpmFileInvalid); /* no color matches */ 2470: *iptr = a; 2471: } 2472: } 2473: 2474: /* 2475: * store the pixels comment line 2476: */ 2477: if (attributes && (attributes->valuemask & BxXpmReturnInfos)) 2478: xpmGetCmt(data, &pixels_cmt); 2479: 2480: free(chars); 2481: 2482: /* 2483: * store found informations in the bxxpmInternAttrib structure 2484: */ 2485: attrib_return->width = width; 2486: attrib_return->height = height; 2487: attrib_return->cpp = cpp; 2488: attrib_return->ncolors = ncolors; 2489: attrib_return->colorTable = colorTable; 2490: attrib_return->pixelindex = pixelindex; 2491: 2492: if (attributes) { 2493: if (attributes->valuemask & BxXpmReturnInfos) { 2494: attributes->hints_cmt = hints_cmt; 2495: attributes->colors_cmt = colors_cmt; 2496: attributes->pixels_cmt = pixels_cmt; 2497: } 2498: if (hotspot) { 2499: attributes->x_hotspot = x_hotspot; 2500: attributes->y_hotspot = y_hotspot; 2501: attributes->valuemask |= BxXpmHotspot; 2502: } 2503: } 2504: return (BxXpmSuccess); 2505: } 2506: 2507: /* 2508: * set the color pixel related to the given colorname, 2509: * return 0 if success, 1 otherwise. 2510: */ 2511: 2512: static int SetColor 2513: ARGLIST((display, colormap,colorname, color_index, image_pixel, mask_pixel, mask_pixel_index)) 2514: ARG(Display *, display) 2515: ARG(Colormap, colormap) 2516: ARG(char *, colorname) 2517: ARG(unsigned int, color_index) 2518: ARG(Pixel *, image_pixel) 2519: ARG(Pixel *, mask_pixel) 2520: GRA(unsigned int *, mask_pixel_index) 2521: { 2522: XColor xcolor; 2523: 2524: if (STRCASECMP(colorname, BX_TRANSPARENT_COLOR)) { 2525: if (!XParseColor(display, colormap, colorname, &xcolor) 2526: || (!XAllocColor(display, colormap, &xcolor))) 2527: return (1); 2528: *image_pixel = xcolor.pixel; 2529: *mask_pixel = 1; 2530: } else { 2531: *image_pixel = 0; 2532: *mask_pixel = 0; 2533: *mask_pixel_index = color_index;/* store the color table index */ 2534: } 2535: return (0); 2536: } 2537: 2538: /* function call in case of error, frees only localy allocated variables */ 2539: #undef RETURN 2540: #define RETURN(status) \ 2541: { if (image) XDestroyImage(image); \ 2542: if (shapeimage) XDestroyImage(shapeimage); \ 2543: if (image_pixels) free((char *)image_pixels); \ 2544: if (mask_pixels) free((char *)mask_pixels); \ 2545: return(status); } 2546: 2547: static int xpmCreateImage 2548: ARGLIST((display, attrib, image_return, shapeimage_return, attributes)) 2549: ARG(Display *, display) 2550: ARG(bxxpmInternAttrib *, attrib) 2551: ARG(XImage **, image_return) 2552: ARG(XImage **, shapeimage_return) 2553: GRA(BxXpmAttributes *, attributes) 2554: { 2555: /* variables stored in the BxXpmAttributes structure */ 2556: Visual *visual; 2557: Colormap colormap; 2558: unsigned int depth; 2559: BxXpmColorSymbol *colorsymbols; 2560: unsigned int numsymbols; 2561: 2562: /* variables to return */ 2563: XImage *image = NULL; 2564: XImage *shapeimage = NULL; 2565: unsigned int mask_pixel; 2566: unsigned int ErrorStatus, ErrorStatus2; 2567: 2568: /* calculation variables */ 2569: Pixel *image_pixels = NULL; 2570: Pixel *mask_pixels = NULL; 2571: char *colorname; 2572: unsigned int a, b, l; 2573: Boolean pixel_defined; 2574: unsigned int key; 2575: 2576: 2577: /* 2578: * retrieve information from the BxXpmAttributes 2579: */ 2580: if (attributes && attributes->valuemask & BxXpmColorSymbols) { 2581: colorsymbols = attributes->colorsymbols; 2582: numsymbols = attributes->numsymbols; 2583: } else 2584: numsymbols = 0; 2585: 2586: if (attributes && attributes->valuemask & BxXpmVisual) 2587: visual = attributes->visual; 2588: else 2589: visual = DefaultVisual(display, DefaultScreen(display)); 2590: 2591: if (attributes && attributes->valuemask & BxXpmColormap) 2592: colormap = attributes->colormap; 2593: else 2594: colormap = DefaultColormap(display, DefaultScreen(display)); 2595: 2596: if (attributes && attributes->valuemask & BxXpmDepth) 2597: depth = attributes->depth; 2598: else 2599: depth = DefaultDepth(display, DefaultScreen(display)); 2600: 2601: 2602: ErrorStatus = BxXpmSuccess; 2603: 2604: /* 2605: * alloc pixels index tables 2606: */ 2607: 2608: key = BxXpmVisualType(visual); 2609: image_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors); 2610: if (!image_pixels) 2611: RETURN(BxXpmNoMemory); 2612: 2613: mask_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors); 2614: if (!mask_pixels) 2615: RETURN(BxXpmNoMemory); 2616: 2617: mask_pixel = BX_UNDEF_PIXEL; 2618: 2619: /* 2620: * get pixel colors, store them in index tables 2621: */ 2622: for (a = 0; a < attrib->ncolors; a++) { 2623: colorname = NULL; 2624: pixel_defined = False; 2625: 2626: /* 2627: * look for a defined symbol 2628: */ 2629: if (numsymbols && attrib->colorTable[a][1]) { 2630: for (l = 0; l < numsymbols; l++) 2631: if (!strcmp(colorsymbols[l].name, attrib->colorTable[a][1])) 2632: break; 2633: if (l != numsymbols) { 2634: if (colorsymbols[l].value) 2635: colorname = colorsymbols[l].value; 2636: else 2637: pixel_defined = True; 2638: } 2639: } 2640: if (!pixel_defined) { /* pixel not given as symbol value */ 2641: 2642: if (colorname) { /* colorname given as symbol value */ 2643: if (!SetColor(display, colormap, colorname, a, 2644: &image_pixels[a], &mask_pixels[a], &mask_pixel)) 2645: pixel_defined = True; 2646: else 2647: ErrorStatus = BxXpmColorError; 2648: } 2649: b = key; 2650: while (!pixel_defined && b > 1) { 2651: if (attrib->colorTable[a][b]) { 2652: if (!SetColor(display, colormap, attrib->colorTable[a][b], 2653: a, &image_pixels[a], &mask_pixels[a], 2654: &mask_pixel)) { 2655: pixel_defined = True; 2656: break; 2657: } else 2658: ErrorStatus = BxXpmColorError; 2659: } 2660: b--; 2661: } 2662: 2663: b = key + 1; 2664: while (!pixel_defined && b < BXNKEYS + 1) { 2665: if (attrib->colorTable[a][b]) { 2666: if (!SetColor(display, colormap, attrib->colorTable[a][b], 2667: a, &image_pixels[a], &mask_pixels[a], 2668: &mask_pixel)) { 2669: pixel_defined = True; 2670: break; 2671: } else 2672: ErrorStatus = BxXpmColorError; 2673: } 2674: b++; 2675: } 2676: 2677: if (!pixel_defined) 2678: RETURN(BxXpmColorFailed); 2679: 2680: } else { 2681: image_pixels[a] = colorsymbols[l].pixel; 2682: mask_pixels[a] = 1; 2683: } 2684: } 2685: 2686: /* 2687: * create the image 2688: */ 2689: if (image_return) { 2690: ErrorStatus2 = CreateXImage(display, visual, depth, 2691: attrib->width, attrib->height, &image); 2692: if (ErrorStatus2 != BxXpmSuccess) 2693: RETURN(ErrorStatus2); 2694: 2695: /* 2696: * set the image data 2697: * 2698: * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use 2699: * optimized functions, otherwise use slower but sure general one. 2700: * 2701: */ 2702: 2703: if (image->depth == 1) 2704: SetImagePixels1(image, attrib->width, attrib->height, 2705: attrib->pixelindex, image_pixels); 2706: else if (image->bits_per_pixel == 8) 2707: SetImagePixels8(image, attrib->width, attrib->height, 2708: attrib->pixelindex, image_pixels); 2709: else if (image->bits_per_pixel == 16) 2710: SetImagePixels16(image, attrib->width, attrib->height, 2711: attrib->pixelindex, image_pixels); 2712: else if (image->bits_per_pixel == 32) 2713: SetImagePixels32(image, attrib->width, attrib->height, 2714: attrib->pixelindex, image_pixels); 2715: else 2716: SetImagePixels(image, attrib->width, attrib->height, 2717: attrib->pixelindex, image_pixels); 2718: } 2719: 2720: /* 2721: * create the shape mask image 2722: */ 2723: if (mask_pixel != BX_UNDEF_PIXEL && shapeimage_return) { 2724: ErrorStatus2 = CreateXImage(display, visual, 1, attrib->width, 2725: attrib->height, &shapeimage); 2726: if (ErrorStatus2 != BxXpmSuccess) 2727: RETURN(ErrorStatus2); 2728: 2729: SetImagePixels1(shapeimage, attrib->width, attrib->height, 2730: attrib->pixelindex, mask_pixels); 2731: } 2732: free((char *)mask_pixels); 2733: 2734: /* 2735: * if requested store allocated pixels in the BxXpmAttributes structure 2736: */ 2737: if (attributes && 2738: (attributes->valuemask & BxXpmReturnInfos 2739: || attributes->valuemask & BxXpmReturnPixels)) { 2740: if (mask_pixel != BX_UNDEF_PIXEL) { 2741: Pixel *pixels, *p1, *p2; 2742: 2743: attributes->npixels = attrib->ncolors - 1; 2744: pixels = (Pixel *) malloc(sizeof(Pixel) * attributes->npixels); 2745: if (pixels) { 2746: p1 = image_pixels; 2747: p2 = pixels; 2748: for (a = 0; a < attrib->ncolors; a++, p1++) 2749: if (a != mask_pixel) 2750: *p2++ = *p1; 2751: attributes->pixels = pixels; 2752: } else { 2753: /* if error just say we can't return requested data */ 2754: attributes->valuemask &= ~BxXpmReturnPixels; 2755: attributes->valuemask &= ~BxXpmReturnInfos; 2756: attributes->pixels = NULL; 2757: attributes->npixels = 0; 2758: } 2759: free((char *)image_pixels); 2760: } else { 2761: attributes->pixels = image_pixels; 2762: attributes->npixels = attrib->ncolors; 2763: } 2764: attributes->mask_pixel = mask_pixel; 2765: } else 2766: free((char *)image_pixels); 2767: 2768: 2769: /* 2770: * return created images 2771: */ 2772: if (image_return) 2773: *image_return = image; 2774: 2775: if (shapeimage_return) 2776: *shapeimage_return = shapeimage; 2777: 2778: return (ErrorStatus); 2779: } 2780: 2781: 2782: /* 2783: * Create an XImage 2784: */ 2785: static int CreateXImage 2786: ARGLIST((display, visual, depth, width, height, image_return)) 2787: ARG(Display *, display) 2788: ARG(Visual *, visual) 2789: ARG(unsigned int, depth) 2790: ARG(unsigned int, width) 2791: ARG(unsigned int, height) 2792: GRA(XImage **, image_return) 2793: { 2794: int bitmap_pad; 2795: 2796: /* first get bitmap_pad */ 2797: if (depth > 16) 2798: bitmap_pad = 32; 2799: else if (depth > 8) 2800: bitmap_pad = 16; 2801: else 2802: bitmap_pad = 8; 2803: 2804: /* then create the XImage with data = NULL and bytes_per_line = 0 */ 2805: 2806: *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0, 2807: width, height, bitmap_pad, 0); 2808: if (!*image_return) 2809: return (BxXpmNoMemory); 2810: 2811: /* now that bytes_per_line must have been set properly alloc data */ 2812: 2813: (*image_return)->data = 2814: (char *) malloc((*image_return)->bytes_per_line * height); 2815: 2816: if (!(*image_return)->data) { 2817: XDestroyImage(*image_return); 2818: *image_return = NULL; 2819: return (BxXpmNoMemory); 2820: } 2821: return (BxXpmSuccess); 2822: } 2823: 2824: 2825: /* 2826: * The functions below are written from X11R5 MIT's code (XImUtil.c) 2827: * 2828: * The idea is to have faster functions than the standard XPutPixel function 2829: * to build the image data. Indeed we can speed up things by supressing tests 2830: * performed for each pixel. We do exactly the same tests but at the image 2831: * level. Assuming that we use only ZPixmap images. 2832: */ 2833: 2834: LFUNC(_putbits, void, (register char *src, int dstoffset, 2835: register int numbits, register char *dst)); 2836: 2837: LFUNC(_XReverse_Bytes, void, (register unsigned char *bpt, register int nb)); 2838: 2839: static unsigned char Const _reverse_byte[0x100] = { 2840: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 2841: 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 2842: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 2843: 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 2844: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 2845: 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 2846: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 2847: 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 2848: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 2849: 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 2850: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 2851: 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 2852: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 2853: 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 2854: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 2855: 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 2856: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 2857: 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 2858: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 2859: 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 2860: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 2861: 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 2862: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 2863: 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 2864: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 2865: 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 2866: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 2867: 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 2868: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 2869: 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 2870: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 2871: 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 2872: }; 2873: 2874: static void _XReverse_Bytes 2875: ARGLIST((bpt, nb)) 2876: ARG(register unsigned char *, bpt) 2877: GRA(register int, nb) 2878: { 2879: do { 2880: *bpt = _reverse_byte[*bpt]; 2881: bpt++; 2882: } while (--nb > 0); 2883: } 2884: 2885: static void xpm_xynormalizeimagebits 2886: ARGLIST((bp,img)) 2887: ARG(register unsigned char *, bp) 2888: GRA(register XImage *, img) 2889: { 2890: register unsigned char c; 2891: 2892: if (img->byte_order != img->bitmap_bit_order) { 2893: switch (img->bitmap_unit) { 2894: 2895: case 16: 2896: c = *bp; 2897: *bp = *(bp + 1); 2898: *(bp + 1) = c; 2899: break; 2900: 2901: case 32: 2902: c = *(bp + 3); 2903: *(bp + 3) = *bp; 2904: *bp = c; 2905: c = *(bp + 2); 2906: *(bp + 2) = *(bp + 1); 2907: *(bp + 1) = c; 2908: break; 2909: } 2910: } 2911: if (img->bitmap_bit_order == MSBFirst) 2912: _XReverse_Bytes(bp, img->bitmap_unit >> 3); 2913: } 2914: 2915: static void xpm_znormalizeimagebits 2916: ARGLIST((bp,img)) 2917: ARG(register unsigned char *, bp) 2918: GRA(register XImage *, img) 2919: { 2920: register unsigned char c; 2921: 2922: switch (img->bits_per_pixel) { 2923: 2924: case 4: 2925: *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); 2926: break; 2927: 2928: case 16: 2929: c = *bp; 2930: *bp = *(bp + 1); 2931: *(bp + 1) = c; 2932: break; 2933: 2934: case 24: 2935: c = *(bp + 2); 2936: *(bp + 2) = *bp; 2937: *bp = c; 2938: break; 2939: 2940: case 32: 2941: c = *(bp + 3); 2942: *(bp + 3) = *bp; 2943: *bp = c; 2944: c = *(bp + 2); 2945: *(bp + 2) = *(bp + 1); 2946: *(bp + 1) = c; 2947: break; 2948: } 2949: } 2950: 2951: static unsigned char Const _lomask[0x09] = { 2952: 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 2953: static unsigned char Const _himask[0x09] = { 2954: 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; 2955: 2956: static void _putbits 2957: ARGLIST((src, dstoffset, numbits, dst)) 2958: ARG(register char *, src) /* address of source bit string */ 2959: ARG(int, dstoffset) /* bit offset into destination; 2960: * range is 0-31 */ 2961: ARG(register int, numbits) /* number of bits to copy to 2962: * destination */ 2963: GRA(register char *, dst) /* address of destination bit string */ 2964: { 2965: register unsigned char chlo, chhi; 2966: int hibits; 2967: 2968: dst = dst + (dstoffset >> 3); 2969: dstoffset = dstoffset & 7; 2970: hibits = 8 - dstoffset; 2971: chlo = *dst & _lomask[dstoffset]; 2972: for (;;) { 2973: chhi = (*src << dstoffset) & _himask[dstoffset]; 2974: if (numbits <= hibits) { 2975: chhi = chhi & _lomask[dstoffset + numbits]; 2976: *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; 2977: break; 2978: } 2979: *dst = chhi | chlo; 2980: dst++; 2981: numbits = numbits - hibits; 2982: chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; 2983: src++; 2984: if (numbits <= dstoffset) { 2985: chlo = chlo & _lomask[numbits]; 2986: *dst = (*dst & _himask[numbits]) | chlo; 2987: break; 2988: } 2989: numbits = numbits - dstoffset; 2990: } 2991: } 2992: 2993: /* 2994: * Default method to write pixels into a Z image data structure. 2995: * The algorithm used is: 2996: * 2997: * copy the destination bitmap_unit or Zpixel to temp 2998: * normalize temp if needed 2999: * copy the pixel bits into the temp 3000: * renormalize temp if needed 3001: * copy the temp back into the destination image data 3002: */ 3003: 3004: static void SetImagePixels 3005: ARGLIST((image, width, height, pixelindex, pixels)) 3006: ARG(XImage *, image) 3007: ARG(unsigned int, width) 3008: ARG(unsigned int, height) 3009: ARG(unsigned int *, pixelindex) 3010: GRA(Pixel *, pixels) 3011: { 3012: Pixel pixel; 3013: unsigned long px; 3014: register char *src; 3015: register char *dst; 3016: int nbytes; 3017: register unsigned int *iptr; 3018: register int x, y, i; 3019: 3020: iptr = pixelindex; 3021: if (image->depth == 1) { 3022: for (y = 0; y < height; y++) 3023: for (x = 0; x < width; x++, iptr++) { 3024: pixel = pixels[*iptr]; 3025: for (i = 0, px = pixel; 3026: i < sizeof(unsigned long); i++, px >>= 8) 3027: ((unsigned char *) &pixel)[i] = (unsigned char)px; 3028: src = &image->data[BXXYINDEX(x, y, image)]; 3029: dst = (char *) &px; 3030: px = 0; 3031: nbytes = image->bitmap_unit >> 3; 3032: for (i = nbytes; --i >= 0;) 3033: *dst++ = *src++; 3034: BXXYNORMALIZE(&px, image); 3035: i = ((x + image->xoffset) % image->bitmap_unit); 3036: _putbits((char *) &pixel, i, 1, (char *) &px); 3037: BXXYNORMALIZE(&px, image); 3038: src = (char *) &px; 3039: dst = &image->data[BXXYINDEX(x, y, image)]; 3040: for (i = nbytes; --i >= 0;) 3041: *dst++ = *src++; 3042: } 3043: } else { 3044: for (y = 0; y < height; y++) 3045: for (x = 0; x < width; x++, iptr++) { 3046: pixel = pixels[*iptr]; 3047: if (image->depth == 4) 3048: pixel &= 0xf; 3049: for (i = 0, px = pixel; 3050: i < sizeof(unsigned long); i++, px >>= 8) 3051: ((unsigned char *) &pixel)[i] = (unsigned char)px; 3052: src = &image->data[BXZINDEX(x, y, image)]; 3053: dst = (char *) &px; 3054: px = 0; 3055: nbytes = (image->bits_per_pixel + 7) >> 3; 3056: for (i = nbytes; --i >= 0;) 3057: *dst++ = *src++; 3058: BXZNORMALIZE(&px, image); 3059: _putbits((char *) &pixel, 3060: (x * image->bits_per_pixel) & 7, 3061: image->bits_per_pixel, (char *) &px); 3062: BXZNORMALIZE(&px, image); 3063: src = (char *) &px; 3064: dst = &image->data[BXZINDEX(x, y, image)]; 3065: for (i = nbytes; --i >= 0;) 3066: *dst++ = *src++; 3067: } 3068: } 3069: } 3070: 3071: /* 3072: * write pixels into a 32-bits Z image data structure 3073: */ 3074: 3075: #ifndef WORD64 3076: static unsigned long byteorderpixel = MSBFirst << 24; 3077: 3078: #endif 3079: 3080: static void SetImagePixels32 3081: ARGLIST((image, width, height, pixelindex, pixels)) 3082: ARG(XImage *, image) 3083: ARG(unsigned int, width) 3084: ARG(unsigned int, height) 3085: ARG(unsigned int *, pixelindex) 3086: GRA(Pixel *, pixels) 3087: { 3088: register unsigned char *addr; 3089: register unsigned int *paddr; 3090: register unsigned int *iptr; 3091: register int x, y; 3092: 3093: iptr = pixelindex; 3094: #ifndef WORD64 3095: if (*((char *) &byteorderpixel) == image->byte_order) { 3096: for (y = 0; y < height; y++) 3097: for (x = 0; x < width; x++, iptr++) { 3098: paddr = 3099: (unsigned int *)(&(image->data[BXZINDEX32(x, y, image)])); 3100: *paddr = (unsigned int)pixels[*iptr]; 3101: } 3102: } else 3103: #endif 3104: if (image->byte_order == MSBFirst) 3105: for (y = 0; y < height; y++) 3106: for (x = 0; x < width; x++, iptr++) { 3107: addr = &((unsigned char *) image->data)[BXZINDEX32(x, y, image)]; 3108: addr[0] = (unsigned char)(pixels[*iptr] >> 24); 3109: addr[1] = (unsigned char)(pixels[*iptr] >> 16); 3110: addr[2] = (unsigned char)(pixels[*iptr] >> 8); 3111: addr[3] = (unsigned char)(pixels[*iptr]); 3112: } 3113: else 3114: for (y = 0; y < height; y++) 3115: for (x = 0; x < width; x++, iptr++) { 3116: addr = &((unsigned char *) image->data)[BXZINDEX32(x, y, image)]; 3117: addr[3] = (unsigned char)(pixels[*iptr] >> 24); 3118: addr[2] = (unsigned char)(pixels[*iptr] >> 16); 3119: addr[1] = (unsigned char)(pixels[*iptr] >> 8); 3120: addr[0] = (unsigned char)(pixels[*iptr]); 3121: } 3122: } 3123: 3124: /* 3125: * write pixels into a 16-bits Z image data structure 3126: */ 3127: 3128: static void SetImagePixels16 3129: ARGLIST((image, width, height, pixelindex, pixels)) 3130: ARG(XImage *, image) 3131: ARG(unsigned int, width) 3132: ARG(unsigned int, height) 3133: ARG(unsigned int *, pixelindex) 3134: GRA(Pixel *, pixels) 3135: { 3136: register unsigned char *addr; 3137: register unsigned int *iptr; 3138: register int x, y; 3139: 3140: iptr = pixelindex; 3141: if (image->byte_order == MSBFirst) 3142: for (y = 0; y < height; y++) 3143: for (x = 0; x < width; x++, iptr++) { 3144: addr = &((unsigned char *) image->data)[BXZINDEX16(x, y, image)]; 3145: addr[0] = (unsigned char)(pixels[*iptr] >> 8); 3146: addr[1] = (unsigned char)(pixels[*iptr]); 3147: } 3148: else 3149: for (y = 0; y < height; y++) 3150: for (x = 0; x < width; x++, iptr++) { 3151: addr = &((unsigned char *) image->data)[BXZINDEX16(x, y, image)]; 3152: addr[1] = (unsigned char)(pixels[*iptr] >> 8); 3153: addr[0] = (unsigned char)(pixels[*iptr]); 3154: } 3155: } 3156: 3157: /* 3158: * write pixels into a 8-bits Z image data structure 3159: */ 3160: 3161: static void SetImagePixels8 3162: ARGLIST((image, width, height, pixelindex, pixels)) 3163: ARG(XImage *, image) 3164: ARG(unsigned int, width) 3165: ARG(unsigned int, height) 3166: ARG(unsigned int *, pixelindex) 3167: GRA(Pixel *, pixels) 3168: 3169: { 3170: register unsigned int *iptr; 3171: register int x, y; 3172: 3173: iptr = pixelindex; 3174: for (y = 0; y < height; y++) 3175: for (x = 0; x < width; x++, iptr++) 3176: image->data[BXZINDEX8(x, y, image)] = (char)pixels[*iptr]; 3177: } 3178: 3179: /* 3180: * write pixels into a 1-bit depth image data structure and **offset null** 3181: */ 3182: 3183: static void SetImagePixels1 3184: ARGLIST((image, width, height, pixelindex, pixels)) 3185: ARG(XImage *, image) 3186: ARG(unsigned int, width) 3187: ARG(unsigned int, height) 3188: ARG(unsigned int *, pixelindex) 3189: GRA(Pixel *, pixels) 3190: { 3191: unsigned char bit; 3192: int xoff, yoff; 3193: register unsigned int *iptr; 3194: register int x, y; 3195: 3196: if (image->byte_order != image->bitmap_bit_order) 3197: SetImagePixels(image, width, height, pixelindex, pixels); 3198: else { 3199: iptr = pixelindex; 3200: if (image->bitmap_bit_order == MSBFirst) 3201: for (y = 0; y < height; y++) 3202: for (x = 0; x < width; x++, iptr++) { 3203: yoff = BXZINDEX1(x, y, image); 3204: xoff = x & 7; 3205: bit = 0x80 >> xoff; 3206: if (pixels[*iptr] & 1) 3207: image->data[yoff] |= bit; 3208: else 3209: image->data[yoff] &= ~bit; 3210: } 3211: else 3212: for (y = 0; y < height; y++) 3213: for (x = 0; x < width; x++, iptr++) { 3214: yoff = BXZINDEX1(x, y, image); 3215: xoff = x & 7; 3216: bit = 1 << xoff; 3217: if (pixels[*iptr] & 1) 3218: image->data[yoff] |= bit; 3219: else 3220: image->data[yoff] &= ~bit; 3221: } 3222: } 3223: } 3224: 3225: /* 3226: * Store into the BxXpmAttributes structure the required informations stored in 3227: * the bxxpmInternAttrib structure. 3228: */ 3229: 3230: static void xpmSetAttributes 3231: ARGLIST((attrib, attributes)) 3232: ARG(bxxpmInternAttrib *, attrib) 3233: GRA(BxXpmAttributes *, attributes) 3234: { 3235: if (attributes) { 3236: if (attributes->valuemask & BxXpmReturnInfos) { 3237: attributes->cpp = attrib->cpp; 3238: attributes->ncolors = attrib->ncolors; 3239: attributes->colorTable = attrib->colorTable; 3240: 3241: attrib->ncolors = 0; 3242: attrib->colorTable = NULL; 3243: } 3244: attributes->width = attrib->width; 3245: attributes->height = attrib->height; 3246: attributes->valuemask |= BxXpmSize; 3247: } 3248: } 3249: 3250: /* 3251: * Free the BxXpmAttributes structure members 3252: * but the structure itself 3253: */ 3254: 3255: static void XpmFreeAttributes 3256: ARGLIST((attributes)) 3257: GRA(BxXpmAttributes *, attributes) 3258: { 3259: if (attributes) { 3260: if (attributes->valuemask & BxXpmReturnPixels && attributes->pixels) { 3261: free((char *)attributes->pixels); 3262: attributes->pixels = NULL; 3263: attributes->npixels = 0; 3264: } 3265: if (attributes->valuemask & BxXpmInfos) { 3266: if (attributes->colorTable) { 3267: xpmFreeColorTable(attributes->colorTable, attributes->ncolors); 3268: attributes->colorTable = NULL; 3269: attributes->ncolors = 0; 3270: } 3271: if (attributes->hints_cmt) { 3272: free(attributes->hints_cmt); 3273: attributes->hints_cmt = NULL; 3274: } 3275: if (attributes->colors_cmt) { 3276: free(attributes->colors_cmt); 3277: attributes->colors_cmt = NULL; 3278: } 3279: if (attributes->pixels_cmt) { 3280: free(attributes->pixels_cmt); 3281: attributes->pixels_cmt = NULL; 3282: } 3283: if (attributes->pixels) { 3284: free((char *)attributes->pixels); 3285: attributes->pixels = NULL; 3286: } 3287: } 3288: attributes->valuemask = 0; 3289: } 3290: } 3291: 3292: /* 3293: * Free the bxxpmInternAttrib pointers which have been allocated 3294: */ 3295: 3296: static void xpmFreeInternAttrib 3297: ARGLIST((attrib)) 3298: GRA(bxxpmInternAttrib *, attrib) 3299: { 3300: unsigned int a; 3301: 3302: if (attrib->colorTable) 3303: xpmFreeColorTable(attrib->colorTable, attrib->ncolors); 3304: if (attrib->pixelindex) 3305: free((char *)attrib->pixelindex); 3306: if (attrib->xcolors) 3307: free((char *)attrib->xcolors); 3308: if (attrib->colorStrings) { 3309: for (a = 0; a < attrib->ncolors; a++) 3310: if (attrib->colorStrings[a]) 3311: free((char *)attrib->colorStrings[a]); 3312: free((char *)attrib->colorStrings); 3313: } 3314: } 3315: 3316: /* 3317: * close the file related to the bxxpmData if any 3318: */ 3319: static void XpmDataClose 3320: ARGLIST((mdata)) 3321: GRA(bxxpmData *, mdata) 3322: { 3323: switch (mdata->type) { 3324: case BXXPMARRAY: 3325: break; 3326: case BXXPMFILE: 3327: if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin)) 3328: fclose(mdata->stream.file); 3329: break; 3330: #ifdef ZPIPE 3331: case BXXPMPIPE: 3332: pclose(mdata->stream.file); 3333: #endif 3334: } 3335: } 3336: 3337: /* 3338: * skip whitespace and compute the following unsigned int, 3339: * returns 1 if one is found and 0 if not 3340: */ 3341: static int xpmNextUI 3342: ARGLIST((mdata, ui_return)) 3343: ARG(bxxpmData *, mdata) 3344: GRA(unsigned int *, ui_return) 3345: { 3346: char buf[BUFSIZ]; 3347: int l; 3348: 3349: l = xpmNextWord(mdata, buf); 3350: return atoui(buf, l, ui_return); 3351: } 3352: 3353: /* 3354: * get the current comment line 3355: */ 3356: static void xpmGetCmt 3357: ARGLIST((mdata, cmt)) 3358: ARG(bxxpmData *, mdata) 3359: GRA(char **, cmt) 3360: { 3361: switch (mdata->type) { 3362: case BXXPMARRAY: 3363: *cmt = NULL; 3364: break; 3365: case BXXPMFILE: 3366: case BXXPMPIPE: 3367: if (mdata->CommentLength) { 3368: *cmt = (char *) malloc(mdata->CommentLength + 1); 3369: strncpy(*cmt, mdata->Comment, mdata->CommentLength); 3370: (*cmt)[mdata->CommentLength] = '\0'; 3371: mdata->CommentLength = 0; 3372: } else 3373: *cmt = NULL; 3374: break; 3375: } 3376: } 3377: 3378: /* 3379: * skip to the end of the current string and the beginning of the next one 3380: */ 3381: static void xpmNextString 3382: ARGLIST((mdata)) 3383: GRA(bxxpmData *, mdata) 3384: { 3385: int c; 3386: 3387: switch (mdata->type) { 3388: case BXXPMARRAY: 3389: mdata->cptr = (mdata->stream.data)[++mdata->line]; 3390: break; 3391: case BXXPMFILE: 3392: case BXXPMPIPE: 3393: if (mdata->Eos) 3394: while ((c = xpmGetC(mdata)) != mdata->Eos && c != EOF); 3395: if (mdata->Bos) /* if not natural XPM2 */ 3396: while ((c = xpmGetC(mdata)) != mdata->Bos && c != EOF); 3397: break; 3398: } 3399: } 3400: 3401: /* 3402: * return the current character, skipping comments 3403: */ 3404: static int xpmGetC 3405: ARGLIST((mdata)) 3406: GRA(bxxpmData *, mdata) 3407: { 3408: int c; 3409: register unsigned int n = 0, a; 3410: unsigned int notend; 3411: 3412: switch (mdata->type) { 3413: case BXXPMARRAY: 3414: return (*mdata->cptr++); 3415: case BXXPMFILE: 3416: case BXXPMPIPE: 3417: c = getc(mdata->stream.file); 3418: 3419: if (mdata->Bos && mdata->Eos 3420: && (c == mdata->Bos || c == mdata->Eos)) { 3421: /* if not natural XPM2 */ 3422: mdata->InsideString = !mdata->InsideString; 3423: return (c); 3424: } 3425: if (!mdata->InsideString && mdata->Bcmt && c == mdata->Bcmt[0]) { 3426: mdata->Comment[0] = c; 3427: 3428: /* 3429: * skip the string begining comment 3430: */ 3431: do { 3432: c = getc(mdata->stream.file); 3433: mdata->Comment[++n] = c; 3434: } while (c == mdata->Bcmt[n] && mdata->Bcmt[n] != '\0' 3435: && c != EOF); 3436: 3437: if (mdata->Bcmt[n] != '\0') { 3438: /* this wasn't the begining of a comment */ 3439: /* put characters back in the order that we got them */ 3440: for (a = n; a > 0; a--) 3441: xpmUngetC(mdata->Comment[a], mdata); 3442: return (mdata->Comment[0]); 3443: } 3444: 3445: /* 3446: * store comment 3447: */ 3448: mdata->Comment[0] = mdata->Comment[n]; 3449: notend = 1; 3450: n = 0; 3451: while (notend) { 3452: while (mdata->Comment[n] != mdata->Ecmt[0] && c != EOF) { 3453: c = getc(mdata->stream.file); 3454: mdata->Comment[++n] = c; 3455: } 3456: mdata->CommentLength = n; 3457: a = 0; 3458: do { 3459: c = getc(mdata->stream.file); 3460: n++; 3461: a++; 3462: mdata->Comment[n] = c; 3463: } while (c == mdata->Ecmt[a] && mdata->Ecmt[a] != '\0' 3464: && c != EOF); 3465: if (mdata->Ecmt[a] == '\0') { 3466: /* this is the end of the comment */ 3467: notend = 0; 3468: xpmUngetC(mdata->Comment[n], mdata); 3469: } 3470: } 3471: c = xpmGetC(mdata); 3472: } 3473: return (c); 3474: } 3475: return('\0'); 3476: } 3477: 3478: 3479: /* 3480: * push the given character back 3481: */ 3482: static int xpmUngetC 3483: ARGLIST((c, mdata)) 3484: ARG(int, c) 3485: GRA(bxxpmData *, mdata) 3486: { 3487: switch (mdata->type) { 3488: case BXXPMARRAY: 3489: return (*--mdata->cptr = c); 3490: case BXXPMFILE: 3491: case BXXPMPIPE: 3492: if (mdata->Bos && (c == mdata->Bos || c == mdata->Eos)) 3493: /* if not natural XPM2 */ 3494: mdata->InsideString = !mdata->InsideString; 3495: return (ungetc(c, mdata->stream.file)); 3496: } 3497: return('\0'); 3498: } 3499: 3500: /* 3501: * skip whitespace and return the following word 3502: */ 3503: static unsigned int xpmNextWord 3504: ARGLIST((mdata, buf)) 3505: ARG(bxxpmData *, mdata) 3506: GRA(char *, buf) 3507: { 3508: register unsigned int n = 0; 3509: int c; 3510: 3511: switch (mdata->type) { 3512: case BXXPMARRAY: 3513: while (isspace(c = *mdata->cptr) && c != mdata->Eos) 3514: mdata->cptr++; 3515: do { 3516: c = *mdata->cptr++; 3517: buf[n++] = c; 3518: } while (!isspace(c) && c != mdata->Eos && c != '\0'); 3519: n--; 3520: mdata->cptr--; 3521: break; 3522: case BXXPMFILE: 3523: case BXXPMPIPE: 3524: while (isspace(c = xpmGetC(mdata)) && c != mdata->Eos); 3525: while (!isspace(c) && c != mdata->Eos && c != EOF) { 3526: buf[n++] = c; 3527: c = xpmGetC(mdata); 3528: } 3529: xpmUngetC(c, mdata); 3530: break; 3531: } 3532: return (n); 3533: } 3534: 3535: static int BxXpmVisualType 3536: ARGLIST((visual)) 3537: GRA(Visual *, visual) 3538: { 3539: #if defined(__cplusplus) || defined(c_plusplus) 3540: switch ( visual->c_class ) 3541: #else 3542: switch ( visual->class ) 3543: #endif 3544: { 3545: case StaticGray: 3546: case GrayScale: 3547: switch (visual->map_entries) 3548: { 3549: case 2: 3550: return (BXMONO); 3551: case 4: 3552: return (BXGRAY4); 3553: default: 3554: return (BXGRAY); 3555: } 3556: default: 3557: return (BXCOLOR); 3558: } 3559: } 3560: 3561: /* 3562: * Free the computed color table 3563: */ 3564: 3565: static void xpmFreeColorTable 3566: ARGLIST((colorTable, ncolors)) 3567: ARG(char ***, colorTable) 3568: GRA(int, ncolors) 3569: { 3570: int a, b; 3571: 3572: if (colorTable) { 3573: for (a = 0; a < ncolors; a++) 3574: if (colorTable[a]) { 3575: for (b = 0; b < (BXNKEYS + 1); b++) 3576: if (colorTable[a][b]) 3577: free(colorTable[a][b]); 3578: free((char *)colorTable[a]); 3579: } 3580: free((char *)colorTable); 3581: } 3582: } 3583: 3584: #else /* USE_XPM_LIBRARY */ 3585: 3586: #include <xpm.h> 3587: 3588: #define BxXpmColorError XpmColorError 3589: #define BxXpmSuccess XpmSuccess 3590: #define BxXpmOpenFailed XpmOpenFailed 3591: #define BxXpmFileInvalid XpmFileInvalid 3592: #define BxXpmNoMemory XpmNoMemory 3593: #define BxXpmColorFailed XpmColorFailed 3594: 3595: #define BxXpmVisual XpmVisual 3596: #define BxXpmColormap XpmColormap 3597: #define BxXpmDepth XpmDepth 3598: #define BxXpmSize XpmSize 3599: #define BxXpmHotspot XpmHotspot 3600: #define BxXpmCharsPerPixel XpmCharsPerPixel 3601: #define BxXpmColorSymbols XpmColorSymbols 3602: #define BxXpmRgbFilename XpmRgbFilename 3603: #define BxXpmInfos XpmInfos 3604: 3605: #define BxXpmReturnPixels XpmReturnPixels 3606: #define BxXpmReturnInfos XpmReturnInfos 3607: 3608: typedef XpmAttributes BxXpmAttributes; 3609: 3610: #endif /* USE_XPM_LIBRARY */ 3611: 3612: Pixmap XPM_PIXMAP 3613: ARGLIST((w, pixmapName)) 3614: ARG(Widget, w) 3615: GRA(char **, pixmapName) 3616: { 3617: BxXpmAttributes attributes; 3618: int argcnt; 3619: Arg args[10]; 3620: Pixmap pixmap; 3621: Pixmap shape; 3622: int returnValue; 3623: 3624: argcnt = 0; 3625: XtSetArg(args[argcnt], XmNdepth, &(attributes.depth)); argcnt++; 3626: XtSetArg(args[argcnt], XmNcolormap, &(attributes.colormap)); argcnt++; 3627: XtGetValues(w, args, argcnt); 3628: 3629: attributes.visual = DefaultVisual(XtDisplay(w), 3630: DefaultScreen(XtDisplay(w))); 3631: attributes.valuemask = (BxXpmDepth | BxXpmColormap | BxXpmVisual); 3632: 3633: returnValue = XpmCreatePixmapFromData(XtDisplay(w), 3634: DefaultRootWindow(XtDisplay(w)), 3635: pixmapName, &pixmap, &shape, 3636: &attributes); 3637: if ( shape ) 3638: { 3639: XFreePixmap(XtDisplay(w), shape); 3640: } 3641: 3642: switch(returnValue) 3643: { 3644: case BxXpmOpenFailed: 3645: case BxXpmFileInvalid: 3646: case BxXpmNoMemory: 3647: case BxXpmColorFailed: 3648: XtWarning("Could not create pixmap."); 3649: return(XmUNSPECIFIED_PIXMAP); 3650: default: 3651: return(pixmap); 3652: } 3653: } 3654: 3655: #endif 3656: 3657: /* This structure is for capturing app-defaults values for a Class */ 3658: 3659: typedef struct _UIAppDefault 3660: { 3661: char* cName; /* Class name */ 3662: char* wName; /* Widget name */ 3663: char* cInstName; /* Name of class instance(nested) */ 3664: char* wRsc; /* Widget resource */ 3665: char* value; /* value read from app-defaults */ 3666: } UIAppDefault; 3667: 3668: 3669: void setDefaultResources ARGLIST((_name, w, resourceSpec)) 3670: ARG(char*, _name) 3671: ARG(Widget, w) 3672: GRA(String *,resourceSpec) 3673: { 3674: int i; 3675: Display *dpy = XtDisplay ( w ); /* Retrieve the display pointer */ 3676: XrmDatabase rdb = NULL; /* A resource data base */ 3677: 3678: /* Create an empty resource database */ 3679: 3680: rdb = XrmGetStringDatabase ( "" ); 3681: 3682: /* Add the Component resources, prepending the name of the component */ 3683: 3684: i = 0; 3685: while ( resourceSpec[i] != NULL ) 3686: { 3687: char buf[1000]; 3688: 3689: sprintf(buf, "*%s%s", _name, resourceSpec[i++]); 3690: XrmPutLineResource( &rdb, buf ); 3691: } 3692: 3693: /* Merge them into the Xt database, with lowest precendence */ 3694: 3695: if ( rdb ) 3696: { 3697: #if (XlibSpecificationRelease>=5) 3698: XrmDatabase db = XtDatabase(dpy); 3699: XrmCombineDatabase(rdb, &db, FALSE); 3700: #else 3701: XrmMergeDatabases ( dpy->db, &rdb ); 3702: dpy->db = rdb; 3703: #endif 3704: } 3705: } 3706: 3707: /* 3708: * This method gets all the resources from the app-defaults file 3709: * (resource databse) and fills in the table (defs) if the app default 3710: * value exists. 3711: */ 3712: void 3713: InitAppDefaults ARGLIST((parent, defs)) 3714: ARG(Widget, parent) 3715: GRA(UIAppDefault *, defs) 3716: { 3717: XrmQuark cQuark; 3718: XrmQuark rsc[6]; 3719: XrmRepresentation rep; 3720: XrmValue val; 3721: XrmDatabase rdb; 3722: int rscIdx; 3723: 3724: /* Get the database */ 3725: 3726: #if (XlibSpecificationRelease >= 5) 3727: if ((rdb = XrmGetDatabase(XtDisplay(parent))) == NULL) 3728: { 3729: return; /* Can't get the database */ 3730: } 3731: #else 3732: Display *dpy = XtDisplay(parent); 3733: if ((rdb = dpy->db) == NULL) 3734: { 3735: return; 3736: } 3737: #endif 3738: 3739: /* Look for each resource in the table */ 3740: 3741: while (defs->wName) 3742: { 3743: rscIdx = 0; 3744: 3745: cQuark = XrmStringToQuark(defs->cName); /* class quark */ 3746: rsc[rscIdx++] = cQuark; 3747: if (defs->wName[0] == '\0') 3748: { 3749: rsc[rscIdx++] = cQuark; 3750: } 3751: else 3752: { 3753: if( strchr(defs->wName, '.') == NULL ) 3754: { 3755: rsc[rscIdx++] = XrmStringToQuark(defs->wName); 3756: } 3757: else 3758: { 3759: /* 3760: * If we found a '.' that means that this is not 3761: * a simple widget name, but a sub specification so 3762: * we need to split this into several quarks. 3763: */ 3764: char *copy = strdup(defs->wName), *ptr; 3765: 3766: for( ptr = strtok(copy, "."); ptr != NULL; 3767: ptr = strtok(NULL, ".") ) 3768: { 3769: rsc[rscIdx++] = XrmStringToQuark(ptr); 3770: } 3771: free(copy); 3772: } 3773: } 3774: 3775: if (defs->cInstName && defs->cInstName[0] != '\0') 3776: { 3777: rsc[rscIdx++] = XrmStringToQuark(defs->cInstName); 3778: } 3779: 3780: rsc[rscIdx++] = XrmStringToQuark(defs->wRsc); 3781: rsc[rscIdx++] = NULLQUARK; 3782: 3783: if (XrmQGetResource(rdb, rsc, rsc, &rep, &val)) 3784: { 3785: defs->value = strdup((char*)val.addr); 3786: } 3787: defs++; 3788: } 3789: } 3790: 3791: /* 3792: * This method applies the app defaults for the class to a specific 3793: * instance. All the widgets in the path are loosly coupled (use *). 3794: * To override a specific instance, use a tightly coupled app defaults 3795: * resource line (use .). 3796: */ 3797: void 3798: SetAppDefaults ARGLIST((w, defs, inst_name)) 3799: ARG(Widget,w) 3800: ARG(UIAppDefault*, defs) 3801: GRA(char*, inst_name) 3802: { 3803: Display* dpy = XtDisplay ( w ); /* Retrieve the display */ 3804: XrmDatabase rdb = NULL; /* A resource data base */ 3805: char lineage[1000]; 3806: char buf[1000]; 3807: Widget parent; 3808: char* wName; 3809: 3810: /* Protect ourselves */ 3811: 3812: if (inst_name == NULL) return; 3813: 3814: /* Create an empty resource database */ 3815: 3816: rdb = XrmGetStringDatabase ( "" ); 3817: 3818: /* Start the lineage with our name and then get our parents */ 3819: 3820: lineage[0] = '\0'; 3821: parent = w; 3822: 3823: while (parent) 3824: { 3825: WidgetClass wclass = XtClass(parent); 3826: 3827: if (wclass == applicationShellWidgetClass) break; 3828: 3829: strcpy(buf, lineage); 3830: sprintf(lineage, "*%s%s", XtName(parent), buf); 3831: 3832: parent = XtParent(parent); 3833: } 3834: 3835: /* Add the Component resources, prepending the name of the component */ 3836: 3837: while (defs->wName != NULL) 3838: { 3839: if ( !strcmp(defs->wName, "" ) ) wName = inst_name; 3840: else wName = (char *)(defs->wName); 3841: 3842: /* 3843: * See if we need to deal with this record. 3844: * (1) If we've been passed an instance name (meaning we're 3845: * creating a nested instance of a class), then make sure 3846: * we're dealing with the proper nested instance. 3847: * (2) If we're not creating a nested instance, then 3848: * ignore resources for nested instances. 3849: * (3) We didn't find a default value in the app-defaults 3850: */ 3851: 3852: if ((inst_name && strcmp(inst_name, wName)) || /* (1) */ 3853: (!inst_name && defs->cInstName) || /* (2) */ 3854: (defs->value == NULL)) /* (3) */ 3855: { 3856: defs++; 3857: continue; 3858: } 3859: 3860: /* Build up string after lineage */ 3861: if (defs->cInstName != NULL) 3862: { 3863: /* Don't include class instance name if it is also the instance */ 3864: /* being affected. */ 3865: 3866: if (*defs->cInstName != '\0') 3867: { 3868: sprintf(buf, "%s.%s*%s.%s: %s", 3869: lineage, wName, defs->cInstName, defs->wRsc, 3870: defs->value); 3871: } 3872: else 3873: { 3874: sprintf(buf, "%s.%s.%s: %s", 3875: lineage, wName, defs->wRsc, defs->value); 3876: } 3877: } 3878: else if (*defs->wName != '\0') 3879: { 3880: sprintf(buf, "%s*%s*%s.%s: %s", 3881: lineage, inst_name, defs->wName, defs->wRsc, defs->value); 3882: } 3883: else 3884: { 3885: sprintf(buf, "%s*%s.%s: %s", 3886: lineage, inst_name, defs->wRsc, defs->value); 3887: } 3888: 3889: XrmPutLineResource( &rdb, buf ); 3890: defs++; 3891: } 3892: 3893: /* Merge them into the Xt database, with lowest precendence */ 3894: if ( rdb ) 3895: { 3896: #if (XlibSpecificationRelease >= 5) 3897: XrmDatabase db = XtDatabase(dpy); 3898: XrmCombineDatabase(rdb, &db, FALSE); 3899: #else 3900: XrmMergeDatabases ( dpy->db, &rdb ); 3901: dpy->db = rdb; 3902: #endif 3903: } 3904: } 3905: 3906: 3907: