Create Xref-Html Frames Remove All Frames
file:d:/code/LRC/Splicer/splicer_code_ver2.2/splicer-bxutil-c.c (Tue Mar 14 16:29:00 2000
)
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:
Html form generated by Xrefactory version 1.6.7 on Fri Sep 03 17:18:59 2004