Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/aclvis/bxutilsC.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 //
00027 // WARNING: This file is overwritten at code generation time.
00028 // Any changes to this file will be lost.
00029 //
00030 /*
00031  * MODULE: BxConvert.c
00032  * AUTHOR: Automatically generated by Builder Xcessory
00033  * 
00034  * Description: This module contains various utilities, converters 
00035  *      for XmStrings (to work properly with app-defaults), and if needed
00036  *      the XPM pixmap utilities.
00037  *      
00038  * Edit the file ${BX}/gen/bxutils.c (BX$SYSTEM:[gen]bxutils.c on VMS) to
00039  * make system wide changes to this file which will be visible next time
00040  * this file is generated. 
00041  * ${BX} is the directory where Builder Xcessory is installed.
00042  */
00043 
00044 /*
00045  * BX supplies a string format for compound strings:
00046  *
00047  *              ::[#tag][:t][:r]["str"]
00048  *
00049  * where:
00050  *      :: = indicates compound string.
00051  *      tag =  the font tag
00052  *      :t = separator (if not seen no separator added to segment)
00053  *      :r = right to left (if not seen left to right assumed)
00054  *      "str" = the text of the string.
00055  *
00056  * The components for the compound string can be repeated any number of
00057  * times.
00058  */
00059 
00060 /*****************************************************************************
00061  *       INCLUDE FILES
00062  *****************************************************************************/
00063 
00064 #include <Xm/Xm.h>
00065 #include <Xm/RowColumn.h>
00066 #include <stdio.h>
00067 #include <ctype.h>
00068 #include <string.h>
00069 
00070 /*
00071  * Include stdlib.h and malloc.h if code is C++, ANSI, or Extended ANSI.
00072  */
00073 #if ( defined(__cplusplus) || defined(__STDC__) || defined(__EXTENSIONS__) )
00074 #include <stdlib.h>
00075 #ifndef VMS
00076 #include <malloc.h>
00077 #endif
00078 #endif
00079 
00080 /*****************************************************************************
00081  *       TYPDEFS AND DEFINES
00082  *****************************************************************************/
00083 
00084 /*
00085  * Undefine this if you want to use native strcasecmp.
00086  */
00087 #define LOCAL_STRCASECMP
00088 
00089 #ifdef _NO_PROTO
00090 #ifdef NeedFunctionPrototypes
00091 #undef NeedFunctionPrototypes
00092 #endif
00093 #endif
00094 
00095 /*
00096  * Define SUPPORTS_WCHARS if the system supports wide character sets
00097  * Note: the following line flags the VAXC compiler and not the
00098  * DECC compiler running VAXC emulation. 
00099  */
00100 #if !( ( defined(VAXC) && !defined(__DECC) ) || defined(__CENTERLINE__) )
00101 #define SUPPORTS_WCHARS
00102 #endif
00103 
00104 /*
00105  * Handy definition used in SET_BACKGROUND_COLOR
00106 */
00107 #define UNSET           (-1)
00108 
00109 /*
00110  * Set state of inclusion of prototypes properly
00111  */
00112 #ifdef NeedFunctionPrototypes
00113 #define ARGLIST(p)      (
00114 #define ARG(a, b)       a b,
00115 #define GRA(a, b)       a b)
00116 #else
00117 #define ARGLIST(p)      p
00118 #define ARG(a, b)       a b;
00119 #define GRA(a, b)       a b;
00120 #endif
00121 
00122 #ifdef NeedFunctionPrototypes
00123 #ifdef __cplusplus
00124 #define UARG(a, b)      a,
00125 #define GRAU(a, b)      a)
00126 #else
00127 #define UARG(a, b)      a b,
00128 #define GRAU(a, b)      a b)
00129 #endif
00130 #else
00131 #define UARG(a, b)      a b;
00132 #define GRAU(a, b)      a b;
00133 #endif
00134 
00135 /*
00136  * Set up strcasecmp function
00137  */
00138 #if defined(LOCAL_STRCASECMP)
00139 #define STRCASECMP      StrCasecmp
00140 #ifndef NeedFunctionPrototypes
00141 static int StrCasecmp();
00142 #else
00143 static int StrCasecmp(char*, char*);
00144 #endif
00145 #else
00146 #define STRCASECMP      strcasecmp
00147 #endif
00148 
00149 /*
00150  * Define XTPOINTER so it works with all releases of
00151  * Xt and c++.
00152  */
00153 #ifdef __cplusplus
00154 #if XtSpecificationRelease < 5
00155 #define XTPOINTER       char *
00156 #else
00157 #define XTPOINTER       XPointer
00158 #endif
00159 #else
00160 #define XTPOINTER       XtPointer
00161 #endif
00162 
00163 /*
00164  * The following enum is used to support wide character sets.
00165  * Use this enum for references into the Common Wide Characters array.
00166  * If you add to the array, ALWAYS keep NUM_COMMON_WCHARS as the last
00167  * entry in the enum.  This will maintain correct memory usage, etc.
00168  */
00169 enum { WNull, WTab, WNewLine, WCarriageReturn, WFormFeed, WVerticalTab,
00170        WBackSlash, WQuote, WHash, WColon, WideF, WideL, WideN, WideR,
00171        WideT, WideV, WideUF, WideUL, WideUR, WideUT, WideZero, WideOne,
00172        NUM_COMMON_WCHARS };
00173 
00174 /*****************************************************************************
00175  *       GLOBAL DECLARATIONS
00176  *****************************************************************************/
00177 
00178 /*****************************************************************************
00179  *       EXTERNAL DECLARATIONS
00180  *****************************************************************************/
00181 
00182 /*****************************************************************************
00183  *      STATIC DECLARATION
00184  *****************************************************************************/
00185 
00186 #ifndef NeedFunctionPrototypes
00187 
00188 #ifndef SUPPORTS_WCHARS
00189 static int       mblen                  ();
00190 #endif
00191 static int      strlenWc                ();
00192 static size_t   doMbstowcs              ();
00193 static size_t   doWcstombs              ();
00194 static void     copyWcsToMbs            ();
00195 static int      dombtowc                ();
00196 static Boolean  extractSegment          ();
00197 static XmString StringToXmString        ();
00198 static char*    getNextCStrDelim        ();
00199 static int      getCStrCount            ();
00200 static wchar_t *CStrCommonWideCharsGet  ();
00201 
00202 #else
00203 
00204 #ifndef SUPPORTS_WCHARS
00205 static int      mblen                   (char*, size_t);
00206 #endif
00207 static int      strlenWc                (wchar_t*);
00208 static size_t   doMbstowcs              (wchar_t*, char*, size_t);
00209 static size_t   doWcstombs              (char*, wchar_t*, size_t);
00210 static void     copyWcsToMbs            (char*, wchar_t*, int, Boolean);
00211 static int      dombtowc                (wchar_t*, char*, size_t);
00212 static Boolean  extractSegment          (wchar_t**, wchar_t**, int *,
00213                                          wchar_t**, int*, int*, Boolean*);
00214 static XmString StringToXmString        (char*);
00215 static char*    getNextCStrDelim        (char*);
00216 static int      getCStrCount            (char*);
00217 static wchar_t *CStrCommonWideCharsGet  ();
00218 
00219 #endif
00220 
00221 /*****************************************************************************
00222  *      STATIC CODE
00223  *****************************************************************************/
00224 
00225 #if defined(LOCAL_STRCASECMP) 
00226 
00227 /*
00228  * Function:
00229  *      cmp = StrCasecmp(s1, s2);
00230  * Description:
00231  *      Compare two strings ignoring case
00232  * Input:
00233  *      s1 - char * : string 1 to compare
00234  *      s2 - char * : string 2 to compare
00235  * Output:
00236  *      int :  0; s1 == s2
00237  *             1; s1 != s2
00238  */
00239 static int StrCasecmp
00240     ARGLIST((s1, s2))
00241         ARG(register char *, s1)
00242         GRA(register char *, s2)
00243 {
00244     register int        c1, c2;
00245     
00246     while (*s1 && *s2)
00247     {
00248         c1 = isupper(*s1) ? tolower(*s1) : *s1;
00249         c2 = isupper(*s2) ? tolower(*s2) : *s2;
00250         if (c1 != c2)
00251         {
00252             return(1);
00253         }
00254         s1++;
00255         s2++;
00256     }
00257     if (*s1 || *s2)
00258     {
00259         return(1);
00260     }
00261     return(0);
00262 }
00263 #endif
00264 
00265 #ifndef SUPPORTS_WCHARS
00266 /*
00267  * Function:
00268  *      len = mblen(s, n);
00269  * Description:
00270  *      The mblen function for platforms that don't have one. This
00271  *      function simply returns a length of 1 since no wide character
00272  *      support exists for this platform.
00273  * Input:
00274  *      s - char * : the character string to get the length from
00275  *      n - size_t : the size of the string
00276  * Output:
00277  *      int : always 1
00278  */
00279 static int mblen
00280     ARGLIST((s, n))
00281         ARG(char *, s)
00282         GRA(size_t, n)
00283 {
00284     return(1);
00285 }
00286 #endif
00287 
00288 /*
00289  * Function:
00290  *      len = strlenWc(ptr);
00291  * Description:
00292  *      Return the number of characters in a wide character string (not
00293  *      the characters in the resultant mbs).
00294  * Input:
00295  *      ptr - wchar_t* : pointer to the wcs to count
00296  * Output:
00297  *      int : the number of characters found
00298  */
00299 static int strlenWc
00300     ARGLIST((ptr))
00301         GRA(wchar_t *,ptr)
00302 {
00303     register wchar_t    *p = ptr;
00304     register int        x = 0;
00305     
00306     if (!ptr) return(0);
00307     
00308     while (*p++) x++;
00309     return (x);
00310 }
00311 
00312 /*
00313  * Function:
00314  *      bytesConv = doMbstowcs(wcs, mbs, n);
00315  * Description:
00316  *      Create a wcs string from an input mbs. 
00317  * Input:
00318  *      wcs - wchar_t* : pointer to result buffer of wcs
00319  *      mbs - char* : pointer to the source mbs
00320  *      n - size_t : the number of characters to convert
00321  * Output:
00322  *      bytesConv - size_t : number of bytes converted
00323  */
00324 static size_t doMbstowcs
00325     ARGLIST((wcs, mbs, n))
00326         ARG(wchar_t *,wcs)
00327         ARG(char *, mbs)
00328         GRA(size_t, n)
00329 {
00330 #ifndef SUPPORTS_WCHARS
00331     int i;
00332     
00333     for (i = 0; i < n && mbs[i] != 0; ++i)
00334     {
00335         wcs[i] = mbs[i];
00336     }
00337     wcs[i++] = 0;
00338     return(i);
00339 #else
00340     return(mbstowcs(wcs, mbs, n));
00341 #endif
00342 }
00343 
00344 /*
00345  * Function:
00346  *      bytesConv = doWcstombs(wcs, mbs, n);
00347  * Description:
00348  *      Create a mbs string from an input wcs.
00349  * Input:
00350  *      wcs - wchar_t* : pointer to the source wcs
00351  *      mbs - char* : pointer to result mbs buffer 
00352  *      n - size_t : the number of characters to convert
00353  * Output:
00354  *      bytesConv - size_t : number of bytes converted
00355  */
00356 static size_t doWcstombs
00357     ARGLIST((mbs, wcs, n))
00358         ARG(char *, mbs)
00359         ARG(wchar_t *, wcs)
00360         GRA(size_t, n)
00361 {
00362 #ifndef SUPPORTS_WCHARS
00363     int i;
00364     
00365     for (i = 0; i < n && wcs[i] != 0; ++i)
00366     {
00367         mbs[i] = wcs[i];
00368     }
00369     mbs[i] = 0;
00370     return(i);
00371 #else
00372     size_t      retval;
00373 
00374     retval = wcstombs(mbs, wcs, (n * sizeof(wchar_t)));
00375     if ( retval == (size_t)-1 ) return(0);
00376     else return(retval);
00377 #endif
00378 }
00379 
00380 /*
00381  * Function:
00382  *      copyWcsToMbs(mbs, wcs, len);
00383  * Description:
00384  *      Create a mbs string from an input wcs. This function allocates
00385  *      a buffer if necessary.
00386  * Input:
00387  *      mbs - char* : destination for the converted/copied output
00388  *      wcs - wchar_t* : pointer to wcs to copy/convert
00389  *      len - int : the number of wchar_t' to convert
00390  *      process_it - Boolean : True if processing of quoted charcters,
00391  *                      False if blind.
00392  * Output:
00393  *      None
00394  */
00395 static void copyWcsToMbs
00396     ARGLIST((mbs, wcs, len, process_it))
00397         ARG(char *, mbs)
00398         ARG(wchar_t *, wcs)
00399         ARG(int, len)
00400         GRA(Boolean, process_it)
00401 {
00402     static      wchar_t *tbuf = NULL;
00403     static      int     tbufSize = 0;
00404     
00405     int         numCvt;
00406     int         lenToConvert;
00407     wchar_t     *fromP = wcs;
00408     wchar_t     *x = &fromP[len];
00409     wchar_t     *toP;
00410     wchar_t     *commonWChars = CStrCommonWideCharsGet();
00411     wchar_t     tmp;
00412     
00413     /*
00414      * Make sure there's room in the buffer
00415      */
00416     if (tbufSize < len)
00417     {
00418         tbuf = (wchar_t*)XtRealloc((char*)tbuf, (len + 1) * sizeof(wchar_t));
00419         tbufSize = len;
00420     }
00421     
00422     /*
00423      * Now copy and process
00424      */
00425     toP = tbuf;
00426     lenToConvert = 0;
00427     while (fromP < x)
00428     {
00429         /*
00430          * Check for quoted characters
00431          */
00432         if ((*fromP == commonWChars[WBackSlash]) && process_it)
00433         {
00434             fromP++;            /* Skip quote */
00435             if (fromP == x)     /* Hanging quote? */
00436             {
00437                 *toP++ = commonWChars[WBackSlash];
00438                 lenToConvert++;
00439                 break;
00440             }
00441             tmp = *fromP++;
00442             if (tmp == commonWChars[WideN])
00443             {
00444                 *toP++ = commonWChars[WNewLine];
00445             }
00446             else if (tmp == commonWChars[WideT])
00447             {
00448                 *toP++ = commonWChars[WTab];
00449             }
00450             else if (tmp == commonWChars[WideR])
00451             {
00452                 *toP++ = commonWChars[WCarriageReturn];
00453             }
00454             else if (tmp == commonWChars[WideF])
00455             {
00456                 *toP++ = commonWChars[WFormFeed];
00457             }
00458             else if (tmp == commonWChars[WideV])
00459             {
00460                 *toP++ = commonWChars[WVerticalTab];
00461             }
00462             else if (tmp == commonWChars[WBackSlash])
00463             {
00464                 *toP++ = commonWChars[WBackSlash];
00465             }
00466             else
00467             {
00468                 /*
00469                  * No special translation needed
00470                  */
00471                 *toP++ = tmp;
00472             }
00473         }
00474         else
00475         {
00476             *toP++ = *fromP++;
00477         }
00478         lenToConvert++;
00479     }
00480 
00481     tmp = tbuf[lenToConvert];
00482     tbuf[lenToConvert] = (wchar_t) NULL;
00483     numCvt = doWcstombs(mbs, tbuf, lenToConvert);
00484     tbuf[lenToConvert] = tmp;
00485     
00486     mbs[numCvt] = '\0';
00487 }
00488 
00489 /*
00490  * Function:
00491  *      status = dombtowc(wide, multi, size);
00492  * Description:
00493  *      Convert a multibyte character to a wide character.
00494  * Input:
00495  *      wide    - wchar_t *     : where to put the wide character
00496  *      multi   - char *        : the multibyte character to convert
00497  *      size    - size_t        : the number of characters to convert
00498  * Output:
00499  *      0       - if multi is a NULL pointer or points to a NULL character
00500  *      #bytes  - number of bytes in the multibyte character
00501  *      -1      - multi is an invalid multibyte character.
00502  *
00503  *      NOTE:  if wide is NULL, then this returns the number of bytes in
00504  *             the multibyte character.
00505  */
00506 static int dombtowc
00507     ARGLIST((wide, multi, size))
00508         ARG(wchar_t *, wide)
00509         ARG(char *, multi)
00510         GRA(size_t, size)
00511 {
00512     int         retVal = 0;
00513     
00514 #ifndef SUPPORTS_WCHARS
00515     if ((multi == NULL) || (*multi == '\000'))
00516     {
00517         if (wide) wide[0] = '\0';
00518         return (0);
00519     }
00520     
00521     for (retVal = 0; retVal < size && multi[retVal] != '\000'; retVal++)
00522     {
00523         if (wide != NULL)
00524         {
00525             wide[retVal] = multi[retVal];
00526         }
00527     }
00528 #else
00529     retVal = mbtowc(wide, multi, size);
00530 #endif
00531     return(retVal);
00532 }
00533 
00534 /*
00535  * Function:
00536  *      ptr = getNextSepartor(str);
00537  * Description:
00538  *      Parse through a string looking for the next compound string
00539  *      field separator
00540  * Inputs:
00541  *      str - wchar_t* : the address of address of the string to parse
00542  * Outputs:
00543  *      ptr - wchar_t* : pointer to character, if found, points to end
00544  *                      of string otherwise ('\0').
00545  */
00546 static wchar_t* getNextSeparator
00547     ARGLIST((str))
00548         GRA(wchar_t *, str)     
00549 {
00550     wchar_t     *ptr = str;
00551     wchar_t     *commonWChars = CStrCommonWideCharsGet();
00552     
00553     while (*ptr)
00554     {
00555         /*
00556          * Check for separator
00557          */
00558         if ((*ptr == commonWChars[WHash]) ||
00559             (*ptr == commonWChars[WQuote]) ||
00560             (*ptr == commonWChars[WColon]))
00561         {
00562             return(ptr);
00563         }
00564         else if (*ptr == commonWChars[WBackSlash])
00565         {
00566             ptr++;
00567             if (*ptr) ptr++;    /* Skip quoted character */
00568         }
00569         else
00570         {
00571             ptr++;
00572         }
00573     }
00574     return(ptr);
00575 }
00576 
00577 /*
00578  * Function:
00579  *      more =
00580  *        extractSegment(str, tagStart, tagLen, txtStart, txtLen, 
00581  *                      pDir, pSep);
00582  * Description:
00583  *      Parse through a string version of a compound string and extract
00584  *      the first compound string segment from the string.
00585  * Inputs:
00586  *      str - char** : the address of address of the string to parse
00587  *      tagStart - char** : address to return pointer to tag start into 
00588  *      tagLen - int* : address where to return the tag length into
00589  *      txtStart - char** : address to return the text start into
00590  *      txtLen - int* : address where to return the text length
00591  *      pDir - int* : address to return the string direction into
00592  *      pSep - Boolean * : address to return the separtor into
00593  * Outputs:
00594  *      more - Boolean : True if more of the string to parse.
00595  *                      False means done.
00596  */
00597 static Boolean extractSegment
00598     ARGLIST((str, tagStart, tagLen, txtStart, txtLen, pDir, pSep))
00599         ARG(wchar_t **, str)
00600         ARG(wchar_t **, tagStart)
00601         ARG(int *, tagLen)
00602         ARG(wchar_t **, txtStart)
00603         ARG(int *, txtLen)
00604         ARG(int *, pDir)
00605         GRA(Boolean *, pSep)
00606 {
00607     wchar_t             *start;
00608     wchar_t             *text;
00609     int                 textL;
00610     Boolean             tagSeen;
00611     wchar_t             *tag;
00612     int                 tagL;
00613     Boolean             modsSeen;
00614     Boolean             sep;
00615     int                 dir;
00616     Boolean             done;
00617     Boolean             checkDir;
00618     wchar_t             *commonWChars;
00619     wchar_t             emptyStrWcs[1];
00620 
00621     /*
00622      * Initialize variables
00623      */
00624     text = NULL;
00625     textL = 0;
00626     tagSeen = False;
00627     tag = NULL;
00628     tagL = 0;
00629     modsSeen = False;
00630     dir = XmSTRING_DIRECTION_L_TO_R;
00631     sep = False;
00632     done = False;
00633     commonWChars = CStrCommonWideCharsGet();
00634 
00635     /*
00636      * Guard against nulls
00637      */
00638     if (!(start = *str))
00639     {
00640         start = emptyStrWcs;
00641         emptyStrWcs[0] = commonWChars[WNull];
00642     }
00643 
00644     /*
00645      * If the first character of the string isn't a # or a ", then we
00646      * just have a regular old simple string. Do the same the thing for
00647      * the empty string.
00648      */
00649     if ((*start == '\0') || (start != getNextSeparator(start)))
00650     {
00651         text = start;
00652         if (!(textL = strlenWc(start)))
00653         {
00654             text = NULL;
00655         }
00656         start += textL;
00657     }
00658     else
00659     {
00660         done = False;
00661         while (!done)
00662         {
00663             if (*start == commonWChars[WHash])
00664             {
00665                 if (tagSeen)
00666                 {
00667                     done = True;
00668                     break;
00669                 }
00670                 else
00671                 {
00672                     tagSeen = True;
00673                     tag = ++start;
00674                     start = getNextSeparator(tag);
00675                     if ((tagL = start - tag) == 0)
00676                     {
00677                         tag = NULL;             /* Null tag specified */
00678                     }
00679                 }
00680             }
00681             else if (*start == commonWChars[WQuote])
00682             {
00683                 text = ++start;
00684                 start = getNextSeparator(start);
00685                 while (!((*start == commonWChars[WQuote]) ||
00686                          (*start == commonWChars[WNull])))
00687                 {
00688                     start = getNextSeparator(++start);
00689                 }
00690                 
00691                 if ((textL = start - text) == 0)
00692                 {
00693                     text = NULL;        /* Null text specified  */
00694                 }
00695                 /*
00696                  * if a quote, skip over it
00697                  */
00698                 if (*start == commonWChars[WQuote])
00699                 {
00700                     start++;
00701                 }
00702                 done = True;
00703             }
00704             else if (*start == commonWChars[WColon])
00705             {
00706                 if (modsSeen)
00707                 {
00708                     done = True;
00709                     break;
00710                 }
00711                 
00712                 /*
00713                  * If the next character is a t or f, the we've got 
00714                  * a separator.
00715                  */
00716                 modsSeen = True;
00717                 checkDir = False;
00718                 start++;
00719                 if ((*start == commonWChars[WideT]) ||
00720                     (*start == commonWChars[WideUT]) ||
00721                     (*start == commonWChars[WideOne]))
00722                 {
00723                     sep = True;
00724                     start++;
00725                     checkDir = True;
00726                 }
00727                 else if ((*start == commonWChars[WideF]) ||
00728                          (*start == commonWChars[WideUF]) ||
00729                          (*start == commonWChars[WideZero]))
00730                 {
00731                     sep = False;
00732                     start++;
00733                     checkDir = True;
00734                 }
00735                 else if ((*start == commonWChars[WideR]) ||
00736                          (*start == commonWChars[WideUR]))
00737                 {
00738                     start++;
00739                     dir = XmSTRING_DIRECTION_R_TO_L;
00740                 }
00741                 else if ((*start == commonWChars[WideL]) ||
00742                          (*start == commonWChars[WideUL]))
00743                 {
00744                     start++;
00745                     dir = XmSTRING_DIRECTION_L_TO_R;
00746                 }
00747                 /*
00748                  * Look for direction if necessary. This requires a bit of
00749                  * look ahead.
00750                  */
00751                 if (checkDir && (*start == commonWChars[WColon]))
00752                 {
00753                     if ((*(start + 1) == commonWChars[WideL]) ||
00754                         (*(start + 1) == commonWChars[WideUL]))
00755                     {
00756                         dir = XmSTRING_DIRECTION_L_TO_R;
00757                         start += 2;
00758                     }
00759                     else if ((*(start + 1) == commonWChars[WideR]) ||
00760                              (*(start + 1) == commonWChars[WideUR]))
00761                     {
00762                         dir = XmSTRING_DIRECTION_R_TO_L;
00763                         start+=2;
00764                     }
00765                 }
00766             }
00767             else
00768             {
00769                 /*
00770                  * A bad string format! We'll just skip the character.
00771                  */
00772                 start++;
00773             }
00774         }
00775     }
00776 
00777     /*
00778      * Now fill in return values
00779      */
00780     if (*str)           *str = start;
00781     if (tagStart)       *tagStart = tag;
00782     if (tagLen)         *tagLen = tagL;
00783     if (txtStart)       *txtStart = text;
00784     if (txtLen)         *txtLen = textL;
00785     if (pDir)           *pDir = dir;
00786     if (pSep)           *pSep = sep;
00787 
00788     return ((*start == commonWChars[WNull]) ? False : True);
00789 }
00790 
00791 /*
00792  * Function:
00793  *      xstr = StringToXmString(str);
00794  * Description:
00795  *      Parse a string into an XmString.
00796  * Inputs:
00797  *      str - char * : the string to parse
00798  * Outputs:
00799  *      xstr - XmString : the allocated return structure
00800  */
00801 static XmString StringToXmString
00802     ARGLIST((str))
00803         GRA(char *,str)
00804 {
00805     static char*        tagBuf = NULL;
00806     static int          tagBufLen = 0;
00807     static char*        textBuf = NULL;
00808     static int          textBufLen = 0;
00809 
00810     wchar_t             *ctx;
00811     wchar_t             *tag;
00812     int                 tagLen;
00813     wchar_t             *text;
00814     int                 textLen;
00815     Boolean             sep;
00816     int                 dir;
00817     
00818     Boolean             more;
00819     wchar_t             *wcStr;
00820     int                 curDir;
00821     XmString            xmStr;
00822     XmString            s1;
00823     XmString            s2;
00824 
00825     if (!str) return(NULL);
00826 
00827     /*
00828      * For expediencies sake, we'll overallocate this buffer so that
00829      * the wcs is guaranteed to fit (1 wc per byte in original string).
00830      */
00831     wcStr = (wchar_t*)XtMalloc((strlen(str) + 1) * sizeof(wchar_t));
00832     doMbstowcs(wcStr, str, strlen(str) + 1);
00833 
00834     /*
00835      * Create the beginning segment
00836      */
00837     curDir = XmSTRING_DIRECTION_L_TO_R;
00838     xmStr = XmStringDirectionCreate(curDir);
00839 
00840     /*
00841      * Convert the string.
00842      */
00843     more = True;
00844     ctx = wcStr;
00845     while (more)
00846     {
00847         more = extractSegment(&ctx, &tag, &tagLen,
00848                               &text, &textLen, &dir, &sep);
00849         /*
00850          * Pick up a direction change
00851          */
00852         if (dir != curDir)
00853         {
00854 #if ( defined(VMS) || ( defined(__osf__) && defined(__alpha) ) )
00855 #if ( XmVERSION > 1 || (XmVERSION == 1 && XmREVISION >= 2) )
00856             /*
00857              * This is required on DEC Windows systems because they've
00858              * added the REVERT direction.
00859              */
00860             s1 = XmStringDirectionCreate(XmSTRING_DIRECTION_REVERT);
00861             s2 = xmStr;
00862             xmStr = XmStringConcat(s2, s1);
00863             XmStringFree(s1);
00864             XmStringFree(s2);
00865 #endif
00866 #endif
00867             curDir = dir;
00868             s1 = XmStringDirectionCreate(curDir);
00869             s2 = xmStr;
00870             xmStr = XmStringConcat(s2, s1);
00871             XmStringFree(s1);
00872             XmStringFree(s2);
00873 
00874         }
00875 
00876         /*
00877          * Create the segment. Text and tag first.
00878          */
00879         if (textLen)
00880         {
00881             if (textBufLen <= (textLen * sizeof(wchar_t)))
00882             {
00883                 textBufLen = (textLen + 1) * sizeof(wchar_t);
00884                 textBuf = (char*)XtRealloc(textBuf, textBufLen);
00885             }
00886             copyWcsToMbs(textBuf, text, textLen, True);
00887 
00888             if (tagLen)
00889             {
00890                 if (tagBufLen <= (tagLen * sizeof(wchar_t)))
00891                 {
00892                     tagBufLen = (tagLen + 1) * sizeof(wchar_t);
00893                     tagBuf = (char*)XtRealloc(tagBuf, tagBufLen);
00894                 }
00895                 copyWcsToMbs(tagBuf, tag, tagLen, False);
00896             }
00897             else
00898             {
00899                 if (!tagBuf)
00900                 {
00901                     tagBufLen = strlen(XmSTRING_DEFAULT_CHARSET) + 1;
00902                     tagBuf = (char*)XtMalloc(tagBufLen);
00903                 }
00904                 strcpy(tagBuf, XmSTRING_DEFAULT_CHARSET);
00905             }
00906 
00907             s1 = XmStringCreate(textBuf, tagBuf); 
00908             s2 = xmStr;
00909             xmStr = XmStringConcat(s2, s1);
00910             XmStringFree(s1);
00911             XmStringFree(s2);
00912         }
00913 
00914         /*
00915          * Add in the separators.
00916          */
00917         if (sep)
00918         {
00919             s1 = XmStringSeparatorCreate();
00920             s2 = xmStr;
00921             xmStr = XmStringConcat(s2, s1);
00922             XmStringFree(s1);
00923             XmStringFree(s2);
00924         }
00925     }
00926     
00927     /*
00928      * Free up memory and return
00929      */
00930     XtFree((char*)wcStr);
00931     return(xmStr);
00932 }
00933 
00934 /*
00935  * Function:
00936  *      nextCStr = getNextCStrDelim(str);
00937  * Description:
00938  *      Find the next unquoted , or \n in the string
00939  * Input:
00940  *      str - char * : the input string
00941  * Output:
00942  *      nextCStr - char* : pointer to the next delimiter. Returns NULL if no
00943  *                      delimiter found.
00944  */
00945 static char* getNextCStrDelim
00946     ARGLIST((str))
00947         GRA(char *,str)
00948 {
00949     char        *comma = str;
00950     Boolean     inQuotes = False;
00951     int         len;
00952 
00953     if (!str) return(NULL);
00954     if (!*str) return(NULL);    /* At end */
00955 
00956 #ifdef __CENTERLINE__
00957     mblen((char *)NULL, sizeof(wchar_t));
00958 #else
00959     mblen(NULL, sizeof(wchar_t));
00960 #endif
00961     while (*comma)
00962     {
00963         if ((len = mblen(comma, sizeof(wchar_t))) > 1)
00964         {
00965             comma += len;
00966             continue;
00967         }
00968         
00969         if (*comma == '\\')
00970         {
00971             comma++;    /* Over quote */
00972             comma += mblen(comma, sizeof(wchar_t));
00973             continue;
00974         }
00975 
00976         /*
00977          * See if we have a delimiter
00978          */
00979         if (!inQuotes)
00980         {
00981             if ((*comma == ',') || (*comma == '\012'))
00982             {
00983                 return(comma);
00984             }
00985         }
00986 
00987         /*
00988          * Deal with quotes
00989          */
00990         if (*comma == '\"')
00991         {
00992             inQuotes = ~inQuotes;
00993         }
00994 
00995         comma++;
00996     }
00997 
00998     return(NULL);               /* None found */
00999 }
01000 
01001 /*
01002  * Function:
01003  *      cnt = getCStrCount(str);
01004  * Description:
01005  *      Get the count of cstrings in a compound string table ascii
01006  *      format.
01007  * Input:
01008  *      str - char * : string to parse
01009  * Output:
01010  *      cnt - int : the number of XmStrings found
01011  */
01012 static int getCStrCount
01013     ARGLIST((str))
01014         GRA(char *, str)
01015 {
01016     int         x = 1;
01017     char        *newStr;
01018 
01019     if (!str) return(0);
01020     if (!*str) return(0);
01021 
01022     while (newStr = getNextCStrDelim(str))
01023     {
01024         x++;
01025         str = ++newStr;
01026     }
01027     return(x);
01028 }
01029 
01030 /*
01031  * Function:
01032  *      cwc = CStrCommonWideCharsGet();
01033  * Description:
01034  *      Return the array of common wide characters.
01035  * Input:
01036  *      None.
01037  * Output:
01038  *      cwc - wchar_t * : this array should never be written to or FREEd.
01039  */
01040 static wchar_t *CStrCommonWideCharsGet()
01041 {
01042     static wchar_t      *CommonWideChars = NULL;
01043     /*
01044      * If you add to this array, don't forget to change the enum in
01045      * the TYPEDEFS and DEFINES section above to correspond to this
01046      * array.
01047      */
01048     static char *characters[] = { "\000", "\t", "\n", "\r", "\f", "\v",
01049                                   "\\", "\"", "#", ":", "f", "l", "n", "r",
01050                                   "t", "v", "F", "L", "R", "T", "0", "1" };
01051         
01052 
01053     if (CommonWideChars == NULL)
01054     {
01055         int     i;
01056 
01057         /*
01058          * Allocate and create the array.
01059          */
01060         CommonWideChars = (wchar_t*)XtMalloc(NUM_COMMON_WCHARS * sizeof(wchar_t));
01061         
01062         for (i = 0; i < NUM_COMMON_WCHARS; i++)
01063         {
01064             (void)dombtowc(&(CommonWideChars[i]), characters[i], 1);
01065         }
01066     }
01067     return(CommonWideChars);
01068 }
01069 
01070 /*
01071  * Function:
01072  *      CONVERTER CvtStringToXmString
01073  *           and
01074  *      XmStringCvtDestroy
01075  * Description:
01076  *      Convert a string to an XmString. This allows a string contained in
01077  *      resource file to contain multipple fonts. The syntax for the string
01078  *      is:
01079  *              ::[#[font-tag]]"string"[#[font-tag]"string"] ...
01080  *
01081  *      note that the # can be escaped (\#).
01082  *
01083  * Input:
01084  * Output:
01085  *      Standard.
01086  */
01087 static Boolean CvtStringToXmString
01088     ARGLIST((d, args, num_args, fromVal, toVal, data))
01089         ARG(Display *, d)
01090         UARG(XrmValue *, args)
01091         ARG(Cardinal *, num_args)
01092         ARG(XrmValue *, fromVal)
01093         ARG(XrmValue *, toVal)
01094         GRAU(XtPointer, data)
01095 {
01096     static XmString     resStr;
01097     char                *str;
01098 
01099     /*
01100      * This converter takes no parameters
01101      */
01102     if (*num_args != 0)
01103     {
01104         XtAppWarningMsg(XtDisplayToApplicationContext(d), 
01105                         "cvtStringToXmString",
01106                         "wrongParameters",
01107                         "XtToolkitError",
01108                         "String to XmString converter needs no extra arguments",
01109                         (String *)NULL,
01110                         (Cardinal *)NULL);
01111     }
01112 
01113     /*
01114      * See if this is a simple string
01115      */
01116     str = (char*)fromVal->addr;
01117     if (strncmp(str, "::", 2))
01118     {
01119         resStr = XmStringCreateLtoR(fromVal->addr, XmSTRING_DEFAULT_CHARSET);
01120     }
01121     else
01122     {
01123         /*
01124          * Convert into internal format
01125          */
01126         resStr = StringToXmString(fromVal->addr + 2);   /* skip :: */
01127     }
01128 
01129     /*
01130      * Done, return result
01131      */
01132     if (toVal->addr == NULL)
01133     {
01134         toVal->addr = (XTPOINTER)&resStr;
01135         toVal->size = sizeof(XmString);
01136     }
01137     else if (toVal->size < sizeof(XmString))
01138     {
01139         toVal->size = sizeof(XmString);
01140         XtDisplayStringConversionWarning(d, fromVal->addr, "XmString");
01141         XmStringFree(resStr);
01142         return(False);
01143     }
01144     else 
01145     {
01146         *(XmString *)toVal->addr = resStr;
01147         toVal->size = sizeof(XmString);
01148     }
01149     return(True);
01150 }
01151 static void XmStringCvtDestroy
01152     ARGLIST((app, to, data, args, num_args))
01153         UARG(XtAppContext, app)
01154         ARG(XrmValue *, to)
01155         UARG(XtPointer, data)
01156         UARG(XrmValue *, args)
01157         GRAU(Cardinal *, num_args)
01158 {
01159     XmStringFree(*(XmString*)(to->addr));
01160 }
01161 
01162 /*
01163  * Function:
01164  *      CONVERTER CvtStringToXmStringTable
01165  *          and
01166  *      XmStringTableCvtDestroy
01167  *
01168  * Description:
01169  *      Convert a string to an XmString table. This allows a string contained in
01170  *      resource file to contain multipple fonts. The syntax for the string
01171  *      is:
01172  *         compound_string = [#[font-tag]]"string"[#[font-tag]"string"] ...
01173  *         compound_string_table = [compound_string][,compound_string] ...
01174  *
01175  *      note that the # can be escaped (\#).
01176  *
01177  * Input:
01178  * Output:
01179  *      Standard.
01180  */
01181 static Boolean CvtStringToXmStringTable
01182     ARGLIST((d, args, num_args, fromVal, toVal, data))
01183         ARG(Display *, d)
01184         ARG(XrmValue *, args)
01185         ARG(Cardinal *, num_args)
01186         ARG(XrmValue *, fromVal)
01187         ARG(XrmValue *, toVal)
01188         GRAU(XtPointer, data)
01189 {
01190     static XmString     *CStrTable;
01191     XmString            *tblPtr;
01192     char                *str;
01193     char                *tmpBuf;
01194     char                *nextDelim;
01195     XrmValue            fVal;
01196     XrmValue            tVal;
01197 
01198     /*
01199      * This converter takes no parameters
01200      */
01201     if (*num_args != 0)
01202     {
01203         XtAppWarningMsg
01204             (XtDisplayToApplicationContext(d), 
01205              "cvtStringToXmStringTable",
01206              "wrongParameters",
01207              "XtToolkitError",
01208              "String to XmStringTable converter needs no extra arguments",
01209              (String *)NULL,
01210              (Cardinal *)NULL);
01211     }
01212 
01213     /*
01214      * Set str and make sure there's somethin' there
01215      */
01216     if (!(str = (char*)fromVal->addr))
01217     {
01218         str = "";
01219     }
01220 
01221     /*
01222      * Allocate the XmStrings + 1 for NULL termination
01223      */
01224     CStrTable = (XmString*)XtMalloc((getCStrCount(str) + 1) * sizeof(XmString*));
01225 
01226     /*
01227      * Use the string converter for the strings
01228      */
01229     tmpBuf = (char*)XtMalloc(strlen(str) + 1);
01230     strcpy(tmpBuf, str);
01231     str = tmpBuf;
01232 
01233     /*
01234      * Create strings
01235      */
01236     tblPtr = CStrTable;
01237     if (*str)
01238     {
01239         while (str)
01240         {
01241             nextDelim = getNextCStrDelim(str);
01242             
01243             /*
01244              * Overwrite nextDelim
01245              */
01246             if (nextDelim)
01247             {
01248                 *nextDelim = '\0';
01249                 nextDelim++;
01250             }
01251             
01252             /*
01253              * Convert it
01254              */
01255             fVal.size = strlen(str) + 1;
01256             fVal.addr = str;
01257             tVal.size = sizeof(XTPOINTER);
01258             tVal.addr = (XTPOINTER)tblPtr;
01259             
01260             /*
01261              * Call converter ourselves since this is used to create
01262              * the strings in the table we create. We need to do this
01263              * since we don't have a widget to send to the XtConvertAndStore
01264              * function. Side effects are that we can never get these
01265              * compound strings cached and that no destructor function is
01266              * called when the strings leave existance, but we nuke 'em
01267              * in the XmStringTable destuctor.
01268              */
01269             CvtStringToXmString(d, args, num_args, &fVal, &tVal, NULL);
01270             tblPtr++;
01271             str = nextDelim;
01272         }
01273     }
01274     XtFree(tmpBuf);
01275 
01276     /*
01277      * Null terminate
01278      */
01279     *tblPtr = NULL;
01280 
01281     /*
01282      * Done, return result
01283      */
01284     if (toVal->addr == NULL)
01285     {
01286         toVal->addr = (XTPOINTER)&CStrTable;
01287         toVal->size = sizeof(XmString);
01288     }
01289     else if (toVal->size < sizeof(XmString*))
01290     {
01291         toVal->size = sizeof(XmString*);
01292         XtDisplayStringConversionWarning(d, fromVal->addr, "XmStringTable");
01293 
01294         tblPtr = CStrTable;
01295         while (*tblPtr)
01296         {
01297             XmStringFree(*tblPtr);
01298         }
01299         XtFree((char*)CStrTable);
01300         return(False);
01301     }
01302     else 
01303     {
01304         *(XmString **)toVal->addr = CStrTable;
01305         toVal->size = sizeof(XmString*);
01306     }
01307     return(True);
01308 }
01309 static void XmStringTableCvtDestroy
01310     ARGLIST((app, to, data, args, num_args))
01311         UARG(XtAppContext, app)
01312         ARG(XrmValue *, to)
01313         UARG(XtPointer, data)
01314         UARG(XrmValue *, args)
01315         GRAU(Cardinal *, num_args)
01316 {
01317     XmString    *tblPtr = *(XmString**)(to->addr);
01318 
01319     while (*tblPtr)
01320     {
01321         XmStringFree(*tblPtr);
01322     }
01323     XtFree((char*)(*(XmString**)(to->addr)));
01324 }    
01325 
01326 /*****************************************************************************
01327  *      GLOBAL CODE
01328  *****************************************************************************/
01329 
01330 /*
01331  * Function:
01332  *      RegisterBxConverters(appContext);
01333  * Description:
01334  *      This globally available function installs all the converters necessary
01335  *      to run BuilderXcessory generated interfaces that use compound
01336  *      strings. This is necessary since Motif has not supplied very smart
01337  *      converters.
01338  * Input:
01339  *      appContext - XtAppContext : the application context
01340  * Output:
01341  *      None
01342  */
01343 void RegisterBxConverters
01344     ARGLIST((appContext))
01345         GRA(XtAppContext, appContext)
01346 {
01347     XtAppSetTypeConverter(appContext, XmRString, XmRXmString,
01348                           (XtTypeConverter)CvtStringToXmString,
01349                           NULL, 0, XtCacheNone, XmStringCvtDestroy);
01350 
01351     XtAppSetTypeConverter(appContext, XmRString, XmRXmStringTable,
01352                           (XtTypeConverter)CvtStringToXmStringTable,
01353                           NULL, 0, XtCacheNone, XmStringTableCvtDestroy);
01354 }
01355 
01356 /*
01357  * Function:
01358  *      CONVERT(w, from_string, to_type, to_size, success);
01359  * Description:
01360  *      A converter wrapper for convenience from BuilderXcessory.
01361  * Input:
01362  *      w - Widget : the widget to use for conversion
01363  *      from_string - char * : the string to convert from
01364  *      to_type - char * : the type to convert to
01365  *      to_size - int : the size of the conversion result
01366  *      success - Boolean* : Set to the result value of the conversion
01367  * Output:
01368  *      None
01369  */
01370 #ifndef IGNORE_CONVERT
01371 XtPointer CONVERT
01372     ARGLIST((w, from_string, to_type, to_size, success))
01373         ARG(Widget, w)
01374         ARG(char *, from_string)
01375         ARG(char *, to_type)
01376         ARG(int, to_size)
01377         GRA(Boolean *, success)
01378 {
01379     XrmValue            fromVal, toVal; /* resource holders             */
01380     Boolean             convResult;     /* return value                 */
01381     XtPointer           val;            /* Pointer size return value    */
01382 
01383     to_size = 0;
01384 
01385     /*
01386      * We will assume that the conversion is going to fail and change this
01387      * value later if the conversion is a success.
01388      */
01389     *success = False;
01390 
01391     /*
01392      * Since we are converting from a string to some type we need to
01393      * set the fromVal structure up with the string information that
01394      * the caller passed in.
01395      */
01396     fromVal.size = strlen(from_string) + 1;
01397     fromVal.addr = from_string;
01398 
01399     /*
01400      * Since we are not sure what type and size of data we are going to
01401      * get back we will set this up so that the converter will point us
01402      * at a block of valid data.
01403      */
01404     toVal.size = 0;
01405     toVal.addr = NULL;
01406 
01407     /*
01408      * Now lets try to convert this data by calling this handy-dandy Xt
01409      * routine.
01410      */
01411     convResult = XtConvertAndStore(w, XmRString, &fromVal, to_type, &toVal);
01412     
01413 
01414     /*
01415      * Now we have two conditions here.  One the conversion was a success
01416      * and two the conversion failed.
01417      */
01418     if(!convResult)
01419     {
01420         /*
01421          * If this conversion failed that we can pretty much return right
01422          * here because there is nothing else we can do.
01423          */
01424         return((XtPointer) NULL);
01425     }
01426 
01427     /*
01428      * If we get this far that means we did the conversion and all is
01429      * well.  Now we have to handle the special cases for type and
01430      * size constraints.
01431      */
01432     if(!strcmp(to_type, "String"))
01433     {
01434         /*
01435          * Since strings are handled different in Xt we have to deal with
01436          * the conversion from a string to a string.  When this happens the
01437          * toVal.size will hold the strlen of the string so generic
01438          * conversion code can't handle it.  It is possible for a string to
01439          * string conversion to happen so we do have to watch for it.
01440          */
01441         val = (XTPOINTER)toVal.addr;
01442     }
01443     else if(!strcmp(to_type, "Double"))
01444     {
01445         val = (XTPOINTER)((double*)toVal.addr);
01446     }
01447     else if(!strcmp(to_type, "Float"))
01448     {
01449         val = (XTPOINTER)((float*)toVal.addr);
01450     }
01451     else
01452     {
01453         /*
01454          * Here is the generic conversion return value handler.  This 
01455          * just does some size specific casting so that value that we
01456          * return is in the correct bytes of the XtPointer that we
01457          * return.  Here we check all sizes from 1 to 8 bytes.
01458          */
01459         switch(toVal.size)
01460         {
01461         case 1:
01462             val = (XTPOINTER)(*(char*)toVal.addr);
01463             break;
01464         case 2:
01465             val = (XTPOINTER)(*(short*)toVal.addr);
01466             break;
01467         case 4:
01468             val = (XTPOINTER)(*(int*)toVal.addr);
01469             break;
01470         case 8:
01471         default:
01472             val = (XTPOINTER)(*(long*)toVal.addr);
01473             break;
01474         }
01475     }
01476 
01477     /*
01478      * Well everything is done and the conversion was a success so lets
01479      * set the success flag to True.
01480      */
01481     *success = convResult;
01482 
01483     /*
01484      * Finally lets return the converted value.
01485      */
01486     /*SUPPRESS 80*/
01487     return(val);
01488 }
01489 #endif
01490 
01491 /*
01492  * Function:
01493  *      MENU_POST(p, mw, ev, dispatch);
01494  * Description:
01495  *      A converter wrapper for convenience from BuilderXcessory.
01496  * Input:
01497  *      p - Widget : the widget to post
01498  *      mw - XtPointer : the menu widget
01499  *      ev - XEvent* : the event that caused the menu post
01500  *      dispatch - Boolean* : not used
01501  * Output:
01502  *      None
01503  */
01504 
01505 #ifndef IGNORE_MENU_POST
01506 
01507 void MENU_POST
01508     ARGLIST((p, mw, ev, dispatch))
01509         UARG(Widget, p)
01510         ARG(XtPointer, mw)
01511         ARG(XEvent *, ev)
01512         GRAU(Boolean *, dispatch)
01513 {
01514     Arg args[2];
01515     int argcnt;
01516     int button;
01517     Widget m = (Widget)mw;
01518     XButtonEvent *e = (XButtonEvent *)ev;
01519 
01520     argcnt = 0;
01521     XtSetArg(args[argcnt], XmNwhichButton, &button);
01522     argcnt++;
01523     XtGetValues(m, args, argcnt);
01524     if(e->button != button) return;
01525     XmMenuPosition(m, e);
01526     XtManageChild(m);
01527 }
01528 #endif
01529 
01530 /*
01531  * Function:
01532  *      SET_BACKGROUND_COLOR(w, args, argcnt, bg_color);
01533  * Description:
01534  *      Sets the background color and shadows of a widget.
01535  * Input:
01536  *      w - The widget to set the background color on.
01537  *      args, argcnt - The argument list so far.
01538  *      bg_color - The new background color as a pixel.
01539  * Output:
01540  *      none
01541  *
01542  *  NOTES:  This assumes that args later in the argument list
01543  *          override those already in the list.  Therfore i f
01544  *          there are shadow colors later in the list they will win.
01545  *        
01546  *          There is no need to use this function when creating a widget
01547  *          only when doing a set values, shadow colors are automatically
01548  *          calculated at creation time.
01549  */
01550 
01551 void SET_BACKGROUND_COLOR
01552     ARGLIST((w, args, argcnt, bg_color))
01553         ARG(Widget, w)
01554         ARG(ArgList, args)
01555         ARG(Cardinal *, argcnt)
01556         GRA(Pixel, bg_color)
01557 {
01558     int         i;
01559     int         topShadowLoc;
01560     int         bottomShadowLoc;
01561     int         selectLoc;
01562     int         fgLoc;
01563 
01564 #if ( (XmVERSION == 1) && (XmREVISION > 0) )
01565 
01566     /*
01567      * Walk through the arglist to see if the user set the top or
01568      * bottom shadow colors.
01569      */
01570     selectLoc = topShadowLoc =  bottomShadowLoc = UNSET;
01571     for (i = 0; i < *argcnt; i++)
01572     {
01573         if ((strcmp(args[i].name, XmNtopShadowColor) == 0) ||
01574             (strcmp(args[i].name, XmNtopShadowPixmap) == 0))
01575         {
01576             topShadowLoc = i;
01577         }
01578         else if ((strcmp(args[i].name, XmNbottomShadowColor) == 0) ||
01579                  (strcmp(args[i].name, XmNbottomShadowPixmap) == 0))
01580         {
01581             bottomShadowLoc = i;
01582         }
01583         else if (strcmp(args[i].name, XmNarmColor) == 0)
01584         {
01585             selectLoc = i;
01586         }
01587         else if (strcmp(args[i].name, XmNforeground) == 0)
01588         {
01589             fgLoc = i;
01590         }
01591     }
01592 
01593     /*
01594      * If either the top or bottom shadow are not set then we
01595      * need to use XmGetColors to get the shadow colors from the backgound
01596      * color and add those that are not already in the arglist to the
01597      * arglist.
01598      * 
01599      */
01600     if ((bottomShadowLoc == UNSET) ||
01601         (topShadowLoc == UNSET) ||
01602         (selectLoc == UNSET) ||
01603         (fgLoc == UNSET))
01604     {
01605         Arg             larg[1];
01606         Colormap        cmap;
01607         Pixel           topShadow;
01608         Pixel           bottomShadow;
01609         Pixel           select;
01610         Pixel           fgColor;
01611 
01612         XtSetArg(larg[0], XmNcolormap, &cmap);
01613         XtGetValues(w, larg, 1);
01614         XmGetColors(XtScreen(w), cmap, bg_color, 
01615                     &fgColor, &topShadow, &bottomShadow, &select);
01616 
01617         if (topShadowLoc == UNSET)
01618         {
01619             XtSetArg(args[*argcnt], XmNtopShadowColor, topShadow); 
01620             (*argcnt)++;
01621         }
01622         
01623         if (bottomShadowLoc == UNSET)
01624         {
01625             XtSetArg(args[*argcnt], XmNbottomShadowColor, bottomShadow); 
01626             (*argcnt)++;
01627         }
01628 
01629         if (selectLoc == UNSET)
01630         {
01631             XtSetArg(args[*argcnt], XmNarmColor, select); 
01632             (*argcnt)++;
01633         }
01634 
01635         if (fgLoc == UNSET)
01636         {
01637             XtSetArg(args[*argcnt], XmNforeground, fgColor); 
01638             (*argcnt)++;
01639         }
01640     }
01641 #endif
01642 
01643     XtSetArg(args[*argcnt], XmNbackground, bg_color); (*argcnt)++;
01644 }
01645 
01646 /*
01647  * Function:
01648  *      w = BxFindTopShell(start);
01649  * Description:
01650  *      Go up the hierarhcy until we find a shell widget.
01651  * Input:
01652  *      start - Widget : the widget to start with.
01653  * Output:
01654  *      w - Widget : the shell widget.
01655  */
01656 #ifndef _BX_FIND_TOP_SHELL
01657 #define _BX_FIND_TOP_SHELL
01658 
01659 Widget BxFindTopShell
01660     ARGLIST((start))
01661         GRA(Widget, start)
01662 {
01663     Widget      p;
01664     
01665     while(p = XtParent(start))
01666     {
01667         start = p;
01668     }
01669     return(start);
01670 }
01671 #endif /* _BX_FIND_TOP_SHELL */
01672 
01673 /*
01674  * Function:
01675  *      BxWidgetIdsFromNames(ref, cbName, stringList)
01676  * Description:
01677  *      Return an array of widget ids from a list of widget names.
01678  * Input:
01679  *      ref - Widget : reference widget.
01680  *      cbName - char* : callback name.
01681  *      stringList - char*: list of widget names.
01682  * Output:
01683  *      WidgetList : array of widget IDs.
01684  */
01685 
01686 #ifndef _BX_WIDGETIDS_FROM_NAMES
01687 #define _BX_WIDGETIDS_FROM_NAMES
01688 
01689 WidgetList BxWidgetIdsFromNames
01690     ARGLIST((ref, cbName, stringList))
01691         ARG(Widget, ref)
01692         ARG(char, *cbName)
01693         GRA(char, *stringList)
01694 {
01695     WidgetList  wgtIds = NULL;
01696     int         wgtCount = 0;
01697     Widget      inst;
01698     Widget      current;
01699     String      tmp;
01700     String      start;
01701     String      widget;
01702     char       *ptr;
01703     
01704     /*
01705      * For backward compatibility, remove [ and ] from the list.
01706      */
01707     tmp = start = XtNewString(stringList);
01708     if((start = strchr(start, '[')) != NULL) start++;
01709     else start = tmp;
01710     
01711     while((start && *start) && isspace(*start))
01712     {
01713         start++;
01714     }
01715     ptr = strrchr(start, ']');
01716     if (ptr)
01717     {
01718         *ptr = '\0';
01719     }
01720     
01721     ptr = start + strlen(start) - 1;
01722     while(ptr && *ptr)
01723     {
01724         if (isspace(*ptr))
01725         {
01726             ptr--;
01727         }
01728         else
01729         {
01730             ptr++;
01731             break;
01732         }
01733     }
01734     if (ptr && *ptr)
01735     {
01736         *ptr = '\0';
01737     }
01738     
01739     /*
01740      * start now points to the first character after the [.
01741      * the list is now either empty, one, or more widget
01742      * instance names.
01743      */
01744     start = strtok(start, ",");
01745     while(start)
01746     {
01747         while((start && *start) && isspace(*start))
01748         {
01749             start++;
01750         }
01751         ptr = start + strlen(start) - 1;
01752         while(ptr && *ptr)
01753         {
01754             if (isspace(*ptr))
01755             {
01756                 ptr--;
01757             }
01758             else
01759             {
01760                 ptr++;
01761                 break;
01762             }
01763         }
01764         if (ptr && *ptr)
01765         {
01766             *ptr = '\0';
01767         }
01768 
01769         /*
01770          * Form a string to use with XtNameToWidget().
01771          */
01772         widget = (char *)XtMalloc((strlen(start) + 2) * sizeof(char));
01773         sprintf(widget, "*%s", start);
01774         
01775         /*
01776          * Start at this level and continue up until the widget is found 
01777          * or until the top of the hierarchy is reached.
01778          */
01779         current = ref;
01780         while (current != NULL)
01781         {
01782             inst = XtNameToWidget(current, widget);
01783             if (inst != NULL )
01784             {
01785                 wgtCount++;
01786                 wgtIds = (WidgetList)XtRealloc((char *)wgtIds, 
01787                                                wgtCount * sizeof(Widget));
01788                 wgtIds[wgtCount - 1] = inst;
01789                 break;
01790             }
01791             current = XtParent(current);
01792         }
01793 
01794         if (current == NULL)
01795         {
01796             printf("Callback Error (%s):\n\t\
01797 Cannot find widget %s\n", cbName, widget);
01798         }
01799         XtFree(widget);
01800         start = strtok(NULL, ",");
01801     }
01802 
01803     /*
01804      * NULL terminate the list.
01805      */
01806     wgtIds = (WidgetList)XtRealloc((char *)wgtIds, 
01807                                    (wgtCount + 1) * sizeof(Widget));
01808     wgtIds[wgtCount] = NULL;
01809 
01810     XtFree((char *)tmp);
01811     return(wgtIds);
01812 }
01813 #endif /* _BX_WIDGETIDS_FROM_NAMES */
01814 
01815 XtPointer SINGLE
01816     ARGLIST((val))
01817     GRA(float, val)
01818 {
01819     XtPointer pointer;
01820     
01821     pointer = (XtPointer)XtMalloc(sizeof(float));
01822     if ( pointer != NULL ) *((float *)pointer) = val;
01823     return(pointer);
01824 }
01825 
01826 XtPointer DOUBLE
01827     ARGLIST((val))
01828     GRA(double, val)
01829 {
01830     XtPointer   pointer;
01831     
01832     pointer = (XtPointer)XtMalloc(sizeof(double));
01833     if ( pointer != NULL ) *((double *)pointer) = val;
01834     return(pointer);
01835 }
01836 
01837 
01838 /****************************************************************************
01839  *
01840  * Big chunk of code inserted from Bull (based on modified 3.3)
01841  *
01842  ****************************************************************************/
01843 
01844 #ifndef IGNORE_XPM_PIXMAP
01845 
01846 #ifndef USE_XPM_LIBRARY
01847 
01848 #ifdef SYSV
01849 #include <memory.h>
01850 #endif
01851 
01852 /*
01853  * Copyright 1990, 1991 GROUPE BULL
01854  *
01855  * Permission to use, copy, modify, and distribute this software and its
01856  * documentation for any purpose and without fee is hereby granted, provided
01857  * that the above copyright notice appear in all copies and that both that
01858  * copyright notice and this permission notice appear in supporting
01859  * documentation, and that the name of GROUPE BULL not be used in advertising
01860  * or publicity pertaining to distribution of the software without specific,
01861  * written prior permission.  GROUPE BULL makes no representations about the
01862  * suitability of this software for any purpose.  It is provided "as is"
01863  * without express or implied warranty.
01864  *
01865  * GROUPE BULL disclaims all warranties with regard to this software,
01866  * including all implied warranties of merchantability and fitness,
01867  * in no event shall GROUPE BULL be liable for any special,
01868  * indirect or consequential damages or any damages
01869  * whatsoever resulting from loss of use, data or profits,
01870  * whether in an action of contract, negligence or other tortious
01871  * action, arising out of or in connection with the use 
01872  * or performance of this software.
01873  *
01874  */
01875 
01876 /* Return ErrorStatus codes:
01877  * null     if full success
01878  * positive if partial success
01879  * negative if failure
01880  */
01881 
01882 #define BxXpmColorError    1
01883 #define BxXpmSuccess       0
01884 #define BxXpmOpenFailed   -1
01885 #define BxXpmFileInvalid  -2
01886 #define BxXpmNoMemory     -3
01887 #define BxXpmColorFailed  -4
01888 
01889 typedef struct {
01890     char *name;                         /* Symbolic color name */
01891     char *value;                        /* Color value */
01892     Pixel pixel;                        /* Color pixel */
01893 }       BxXpmColorSymbol;
01894 
01895 typedef struct {
01896     unsigned long valuemask;            /* Specifies which attributes are
01897                                          * defined */
01898 
01899     Visual *visual;                     /* Specifies the visual to use */
01900     Colormap colormap;                  /* Specifies the colormap to use */
01901     unsigned int depth;                 /* Specifies the depth */
01902     unsigned int width;                 /* Returns the width of the created
01903                                          * pixmap */
01904     unsigned int height;                /* Returns the height of the created
01905                                          * pixmap */
01906     unsigned int x_hotspot;             /* Returns the x hotspot's
01907                                          * coordinate */
01908     unsigned int y_hotspot;             /* Returns the y hotspot's
01909                                          * coordinate */
01910     unsigned int cpp;                   /* Specifies the number of char per
01911                                          * pixel */
01912     Pixel *pixels;                      /* List of used color pixels */
01913     unsigned int npixels;               /* Number of pixels */
01914     BxXpmColorSymbol *colorsymbols;       /* Array of color symbols to
01915                                          * override */
01916     unsigned int numsymbols;            /* Number of symbols */
01917     char *rgb_fname;                    /* RGB text file name */
01918 
01919     /* Infos */
01920     unsigned int ncolors;               /* Number of colors */
01921     char ***colorTable;                 /* Color table pointer */
01922     char *hints_cmt;                    /* Comment of the hints section */
01923     char *colors_cmt;                   /* Comment of the colors section */
01924     char *pixels_cmt;                   /* Comment of the pixels section */
01925     unsigned int mask_pixel;            /* Transparent pixel's color table
01926                                          * index */
01927 }      BxXpmAttributes;
01928 
01929 /* Xpm attribute value masks bits */
01930 #define BxXpmVisual          (1L<<0)
01931 #define BxXpmColormap        (1L<<1)
01932 #define BxXpmDepth           (1L<<2)
01933 #define BxXpmSize            (1L<<3)      /* width & height */
01934 #define BxXpmHotspot         (1L<<4)      /* x_hotspot & y_hotspot */
01935 #define BxXpmCharsPerPixel   (1L<<5)
01936 #define BxXpmColorSymbols    (1L<<6)
01937 #define BxXpmRgbFilename     (1L<<7)
01938 #define BxXpmInfos           (1L<<8)      /* all infos members */
01939 
01940 #define BxXpmReturnPixels    (1L<<9)
01941 #define BxXpmReturnInfos     BxXpmInfos
01942 
01943 /*
01944  * minimal portability layer between ansi and KR C
01945  */
01946 
01947 /* forward declaration of functions with prototypes */
01948 
01949 #ifdef NeedFunctionPrototypes
01950 #define LFUNC(f, t, p) static t f p
01951 #else
01952 #define LFUNC(f, t, p) static t f()
01953 #endif
01954 
01955 /*
01956  * functions declarations
01957  */
01958 LFUNC(BxXpmCreatePixmapFromData, int, (Display * display,
01959                                        Drawable d,
01960                                        char **data,
01961                                        Pixmap * pixmap_return,
01962                                        Pixmap * shapemask_return,
01963                                        BxXpmAttributes * attributes));
01964 
01965 LFUNC(BxXpmCreateImageFromData, int, (Display * display,
01966                                       char **data,
01967                                       XImage ** image_return,
01968                                       XImage ** shapemask_return,
01969                                       BxXpmAttributes * attributes));
01970 
01971 LFUNC(BxXpmFreeAttributes, void, (BxXpmAttributes * attributes));
01972 
01973 typedef struct {
01974     unsigned int type;
01975     union {
01976         FILE *file;
01977         char **data;
01978     }     stream;
01979     char *cptr;
01980     unsigned int line;
01981     int CommentLength;
01982     char Comment[BUFSIZ];
01983     char *Bcmt, *Ecmt, Bos, Eos;
01984     unsigned int InsideString;          /* used during parsing: 0 or 1
01985                                          * whether we are inside or not */
01986 }      bxxpmData;
01987 
01988 #define BXXPMARRAY 0
01989 #define BXXPMFILE  1
01990 #define BXXPMPIPE  2
01991 
01992 typedef unsigned char byte;
01993 
01994 #define BX_TRANSPARENT_COLOR "None"        /* this must be a string! */
01995 
01996 /* number of BxXpmColorKeys */
01997 #define BXNKEYS 5
01998 
01999 /*
02000  * key numbers for visual type, they must fit along with the number key of
02001  * each corresponding element in BxXpmColorKeys[] defined in xpm.h
02002  */
02003 #define BXMONO    2
02004 #define BXGRAY4   3
02005 #define BXGRAY    4
02006 #define BXCOLOR   5
02007 
02008 /* structure containing data related to an Xpm pixmap */
02009 typedef struct {
02010     char *name;
02011     unsigned int width;
02012     unsigned int height;
02013     unsigned int cpp;
02014     unsigned int ncolors;
02015     char ***colorTable;
02016     unsigned int *pixelindex;
02017     XColor *xcolors;
02018     char **colorStrings;
02019     unsigned int mask_pixel;            /* mask pixel's colorTable index */
02020 }      bxxpmInternAttrib;
02021 
02022 #define BX_UNDEF_PIXEL 0x80000000
02023 
02024 char *BxXpmColorKeys[] =
02025 {
02026  "s",                                   /* key #1: symbol */
02027  "m",                                   /* key #2: mono visual */
02028  "g4",                                  /* key #3: 4 grays visual */
02029  "g",                                   /* key #4: gray visual */
02030  "c",                                   /* key #5: color visual */
02031 };
02032 
02033 /* XPM private routines */
02034 
02035 LFUNC(xpmCreateImage, int, (Display * display,
02036                            bxxpmInternAttrib * attrib,
02037                            XImage ** image_return,
02038                            XImage ** shapeimage_return,
02039                            BxXpmAttributes * attributes));
02040 
02041 LFUNC(xpmParseData, int, (bxxpmData * data,
02042                          bxxpmInternAttrib * attrib_return,
02043                          BxXpmAttributes * attributes));
02044 
02045 LFUNC(BxXpmVisualType, int, (Visual * visual));
02046 LFUNC(xpmFreeColorTable, void, (char ***colorTable, int ncolors));
02047 
02048 LFUNC(xpmInitInternAttrib, void, (bxxpmInternAttrib * xmpdata));
02049 
02050 LFUNC(xpmFreeInternAttrib, void, (bxxpmInternAttrib * xmpdata));
02051 
02052 LFUNC(xpmSetAttributes, void, (bxxpmInternAttrib * attrib,
02053                              BxXpmAttributes * attributes));
02054 
02055 /* I/O utility */
02056 
02057 LFUNC(xpmNextString, void, (bxxpmData * mdata));
02058 LFUNC(xpmNextUI, int, (bxxpmData * mdata, unsigned int *ui_return));
02059 LFUNC(xpmGetC, int, (bxxpmData * mdata));
02060 LFUNC(xpmUngetC, int, (int c, bxxpmData * mdata));
02061 LFUNC(xpmNextWord, unsigned int, (bxxpmData * mdata, char *buf));
02062 LFUNC(xpmGetCmt, void, (bxxpmData * mdata, char **cmt));
02063 LFUNC(xpmOpenArray, int, (char **data, bxxpmData * mdata));
02064 LFUNC(XpmDataClose, void, (bxxpmData * mdata));
02065 
02066 /* RGB utility */
02067 
02068 LFUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp,
02069                                      register XImage * img));
02070 LFUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp,
02071                                     register XImage * img));
02072 
02073 /* Image utility */
02074 
02075 LFUNC(SetColor, int, (Display * display, Colormap colormap, char *colorname,
02076                       unsigned int color_index, Pixel * image_pixel,
02077                       Pixel * mask_pixel, unsigned int *mask_pixel_index));
02078 
02079 LFUNC(CreateXImage, int, (Display * display, Visual * visual,
02080                           unsigned int depth, unsigned int width,
02081                           unsigned int height, XImage ** image_return));
02082 
02083 LFUNC(SetImagePixels, void, (XImage * image, unsigned int width,
02084                             unsigned int height, unsigned int *pixelindex,
02085                             Pixel * pixels));
02086 
02087 LFUNC(SetImagePixels32, void, (XImage * image, unsigned int width,
02088                               unsigned int height, unsigned int *pixelindex,
02089                               Pixel * pixels));
02090 
02091 LFUNC(SetImagePixels16, void, (XImage * image, unsigned int width,
02092                               unsigned int height, unsigned int *pixelindex,
02093                               Pixel * pixels));
02094 
02095 LFUNC(SetImagePixels8, void, (XImage * image, unsigned int width,
02096                              unsigned int height, unsigned int *pixelindex,
02097                              Pixel * pixels));
02098 
02099 LFUNC(SetImagePixels1, void, (XImage * image, unsigned int width,
02100                              unsigned int height, unsigned int *pixelindex,
02101                              Pixel * pixels));
02102 
02103 LFUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return));
02104 
02105 /*
02106  * Macros
02107  *
02108  * The BXXYNORMALIZE macro determines whether XY format data requires
02109  * normalization and calls a routine to do so if needed. The logic in
02110  * this module is designed for LSBFirst byte and bit order, so
02111  * normalization is done as required to present the data in this order.
02112  *
02113  * The BXZNORMALIZE macro performs byte and nibble order normalization if
02114  * required for Z format data.
02115  *
02116  * The BXXYINDEX macro computes the index to the starting byte (char) boundary
02117  * for a bitmap_unit containing a pixel with coordinates x and y for image
02118  * data in XY format.
02119  *
02120  * The BXZINDEX* macros compute the index to the starting byte (char) boundary
02121  * for a pixel with coordinates x and y for image data in ZPixmap format.
02122  *
02123  */
02124 
02125 #define BXXYNORMALIZE(bp, img) \
02126     if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
02127         xpm_xynormalizeimagebits((unsigned char *)(bp), img)
02128 
02129 #define BXZNORMALIZE(bp, img) \
02130     if (img->byte_order == MSBFirst) \
02131         xpm_znormalizeimagebits((unsigned char *)(bp), img)
02132 
02133 #define BXXYINDEX(x, y, img) \
02134     ((y) * img->bytes_per_line) + \
02135     (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
02136 
02137 #define BXZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
02138     (((x) * img->bits_per_pixel) >> 3)
02139 
02140 #define BXZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2)
02141 
02142 #define BXZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1)
02143 
02144 #define BXZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x)
02145 
02146 #define BXZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3)
02147 
02148 #if __STDC__
02149 #define Const const
02150 #else
02151 #define Const
02152 #endif
02153 
02154 
02155 
02156 static unsigned int atoui
02157 ARGLIST((p, l, ui_return))
02158 ARG(register char *, p)
02159 ARG(unsigned int, l)
02160 GRA(unsigned int *, ui_return)
02161 {
02162     register int n, i;
02163 
02164     n = 0;
02165     for (i = 0; i < l; i++)
02166         if (*p >= '0' && *p <= '9')
02167             n = n * 10 + *p++ - '0';
02168         else
02169             break;
02170 
02171     if (i != 0 && i == l) {
02172         *ui_return = n;
02173         return 1;
02174     } else
02175         return 0;
02176 }
02177 
02178 static int BxXpmCreatePixmapFromData
02179 ARGLIST((display, d, data, pixmap_return, shapemask_return, attributes))
02180 ARG(Display *, display)
02181 ARG(Drawable, d)
02182 ARG(char **, data)
02183 ARG(Pixmap *, pixmap_return)
02184 ARG(Pixmap *, shapemask_return)
02185 GRA(BxXpmAttributes *,attributes)
02186 {
02187     XImage *image, **imageptr = NULL;
02188     XImage *shapeimage, **shapeimageptr = NULL;
02189     int ErrorStatus;
02190     XGCValues gcv;
02191     GC gc;
02192 
02193     /*
02194      * initialize return values
02195      */
02196     if (pixmap_return) {
02197         *pixmap_return = (Pixmap) NULL;
02198         imageptr = &image;
02199     }
02200     if (shapemask_return) {
02201         *shapemask_return = (Pixmap) NULL;
02202         shapeimageptr = &shapeimage;
02203     }
02204 
02205     /*
02206      * create the images
02207      */
02208     ErrorStatus = BxXpmCreateImageFromData(display, data, imageptr,
02209                                          shapeimageptr, attributes);
02210     if (ErrorStatus < 0)
02211         return (ErrorStatus);
02212 
02213     /*
02214      * create the pixmaps
02215      */
02216     if (imageptr && image) {
02217         *pixmap_return = XCreatePixmap(display, d, image->width,
02218                                        image->height, image->depth);
02219         gcv.function = GXcopy;
02220         gc = XCreateGC(display, *pixmap_return, GCFunction, &gcv);
02221 
02222         XPutImage(display, *pixmap_return, gc, image, 0, 0, 0, 0,
02223                   image->width, image->height);
02224 
02225         XDestroyImage(image);
02226         XFreeGC(display, gc);
02227     }
02228     if (shapeimageptr && shapeimage) {
02229         *shapemask_return = XCreatePixmap(display, d, shapeimage->width,
02230                                           shapeimage->height,
02231                                           shapeimage->depth);
02232         gcv.function = GXcopy;
02233         gc = XCreateGC(display, *shapemask_return, GCFunction, &gcv);
02234 
02235         XPutImage(display, *shapemask_return, gc, shapeimage, 0, 0, 0, 0,
02236                   shapeimage->width, shapeimage->height);
02237 
02238         XDestroyImage(shapeimage);
02239         XFreeGC(display, gc);
02240     }
02241     return (ErrorStatus);
02242 }
02243 
02244 
02245 static int BxXpmCreateImageFromData
02246 ARGLIST((display, data, image_return, shapeimage_return, attributes))
02247 ARG(Display *,display)
02248 ARG(char **, data)
02249 ARG(XImage **, image_return)
02250 ARG(XImage **, shapeimage_return)
02251 GRA(BxXpmAttributes *, attributes)
02252 {
02253     bxxpmData mdata;
02254     int ErrorStatus;
02255     bxxpmInternAttrib attrib;
02256 
02257     /*
02258      * initialize return values
02259      */
02260     if (image_return)
02261         *image_return = NULL;
02262     if (shapeimage_return)
02263         *shapeimage_return = NULL;
02264 
02265     if ((ErrorStatus = xpmOpenArray(data, &mdata)) != BxXpmSuccess)
02266         return (ErrorStatus);
02267 
02268     xpmInitInternAttrib(&attrib);
02269 
02270     ErrorStatus = xpmParseData(&mdata, &attrib, attributes);
02271 
02272     if (ErrorStatus == BxXpmSuccess)
02273         ErrorStatus = xpmCreateImage(display, &attrib, image_return,
02274                                      shapeimage_return, attributes);
02275 
02276     if (ErrorStatus >= 0)
02277         xpmSetAttributes(&attrib, attributes);
02278     else if (attributes)
02279         BxXpmFreeAttributes(attributes);
02280 
02281     xpmFreeInternAttrib(&attrib);
02282     XpmDataClose(&mdata);
02283 
02284     return (ErrorStatus);
02285 }
02286 
02287 /*
02288  * open the given array to be read or written as an bxxpmData which is returned
02289  */
02290 static int xpmOpenArray
02291 ARGLIST((data, mdata))
02292 ARG(char **,data)
02293 GRA(bxxpmData *,mdata)
02294 {
02295     mdata->type = BXXPMARRAY;
02296     mdata->stream.data = data;
02297     mdata->cptr = *data;
02298     mdata->line = 0;
02299     mdata->CommentLength = 0;
02300     mdata->Bcmt = mdata->Ecmt = NULL;
02301     mdata->Bos = mdata->Eos = '\0';
02302     mdata->InsideString = 0;
02303     return (BxXpmSuccess);
02304 }
02305 
02306 /*
02307  * Intialize the bxxpmInternAttrib pointers to Null to know
02308  * which ones must be freed later on.
02309  */
02310 static void xpmInitInternAttrib
02311 ARGLIST((attrib))
02312 GRA(bxxpmInternAttrib *,attrib)
02313 {
02314     attrib->ncolors = 0;
02315     attrib->colorTable = NULL;
02316     attrib->pixelindex = NULL;
02317     attrib->xcolors = NULL;
02318     attrib->colorStrings = NULL;
02319     attrib->mask_pixel = BX_UNDEF_PIXEL;
02320 }
02321 
02322 /* function call in case of error, frees only localy allocated variables */
02323 #undef RETURN
02324 #define RETURN(status) \
02325   { if (colorTable) xpmFreeColorTable(colorTable, ncolors); \
02326     if (chars) free(chars); \
02327     if (pixelindex) free((char *)pixelindex); \
02328     if (hints_cmt)  free((char *)hints_cmt); \
02329     if (colors_cmt) free((char *)colors_cmt); \
02330     if (pixels_cmt) free((char *)pixels_cmt); \
02331     return(status); }
02332 
02333 /*
02334  * This function parses an Xpm file or data and store the found informations
02335  * in an an bxxpmInternAttrib structure which is returned.
02336  */
02337 static int xpmParseData
02338 ARGLIST((data, attrib_return, attributes))
02339 ARG(bxxpmData *,data)
02340 ARG(bxxpmInternAttrib *, attrib_return)
02341 GRA(BxXpmAttributes *, attributes)
02342 {
02343     /* variables to return */
02344     unsigned int width, height;
02345     unsigned int ncolors = 0;
02346     unsigned int cpp;
02347     unsigned int x_hotspot, y_hotspot, hotspot = 0;
02348     char ***colorTable = NULL;
02349     unsigned int *pixelindex = NULL;
02350     char *hints_cmt = NULL;
02351     char *colors_cmt = NULL;
02352     char *pixels_cmt = NULL;
02353 
02354     /* calculation variables */
02355     unsigned int rncolors = 0;          /* read number of colors, it is
02356                                          * different to ncolors to avoid
02357                                          * problem when freeing the
02358                                          * colorTable in case an error
02359                                          * occurs while reading the hints
02360                                          * line */
02361     unsigned int key;                   /* color key */
02362     char *chars = NULL, buf[BUFSIZ];
02363     unsigned int *iptr;
02364     unsigned int a, b, x, y, l;
02365 
02366     unsigned int curkey;                /* current color key */
02367     unsigned int lastwaskey;            /* key read */
02368     char curbuf[BUFSIZ];                /* current buffer */
02369 
02370     /*
02371      * read hints: width, height, ncolors, chars_per_pixel 
02372      */
02373     if (!(xpmNextUI(data, &width) && xpmNextUI(data, &height)
02374           && xpmNextUI(data, &rncolors) && xpmNextUI(data, &cpp)))
02375         RETURN(BxXpmFileInvalid);
02376 
02377     ncolors = rncolors;
02378 
02379     /*
02380      * read hotspot coordinates if any 
02381      */
02382     hotspot = xpmNextUI(data, &x_hotspot) && xpmNextUI(data, &y_hotspot);
02383 
02384     /*
02385      * store the hints comment line 
02386      */
02387     if (attributes && (attributes->valuemask & BxXpmReturnInfos))
02388         xpmGetCmt(data, &hints_cmt);
02389 
02390     /*
02391      * read colors 
02392      */
02393     colorTable = (char ***) calloc(ncolors, sizeof(char **));
02394     if (!colorTable)
02395         RETURN(BxXpmNoMemory);
02396 
02397     for (a = 0; a < ncolors; a++) {
02398         xpmNextString(data);            /* skip the line */
02399         colorTable[a] = (char **) calloc((BXNKEYS + 1), sizeof(char *));
02400         if (!colorTable[a])
02401             RETURN(BxXpmNoMemory);
02402 
02403         /*
02404          * read pixel value 
02405          */
02406         colorTable[a][0] = (char *) malloc(cpp);
02407         if (!colorTable[a][0])
02408             RETURN(BxXpmNoMemory);
02409         for (b = 0; b < cpp; b++)
02410             colorTable[a][0][b] = xpmGetC(data);
02411 
02412         /*
02413          * read color keys and values 
02414          */
02415         curkey = 0;
02416         lastwaskey = 0;
02417         while (l = xpmNextWord(data, buf)) {
02418             if (!lastwaskey) {
02419                 for (key = 1; key < BXNKEYS + 1; key++)
02420                     if ((strlen(BxXpmColorKeys[key - 1]) == l)
02421                         && (!strncmp(BxXpmColorKeys[key - 1], buf, l)))
02422                         break;
02423             }
02424             if (!lastwaskey && key <= BXNKEYS) {        /* open new key */
02425                 if (curkey) {           /* flush string */
02426                     colorTable[a][curkey] =
02427                         (char *) malloc(strlen(curbuf) + 1);
02428                     if (!colorTable[a][curkey])
02429                         RETURN(BxXpmNoMemory);
02430                     strcpy(colorTable[a][curkey], curbuf);
02431                 }
02432                 curkey = key;           /* set new key  */
02433                 curbuf[0] = '\0';       /* reset curbuf */
02434                 lastwaskey = 1;
02435             } else {
02436                 if (!curkey)
02437                     RETURN(BxXpmFileInvalid);   /* key without value */
02438                 if (!lastwaskey)
02439                     strcat(curbuf, " ");/* append space */
02440                 buf[l] = '\0';
02441                 strcat(curbuf, buf);    /* append buf */
02442                 lastwaskey = 0;
02443             }
02444         }
02445         if (!curkey)
02446             RETURN(BxXpmFileInvalid);   /* key without value */
02447         colorTable[a][curkey] = (char *) malloc(strlen(curbuf) + 1);
02448         if (!colorTable[a][curkey])
02449             RETURN(BxXpmNoMemory);
02450         strcpy(colorTable[a][curkey], curbuf);
02451     }
02452 
02453     /*
02454      * store the colors comment line 
02455      */
02456     if (attributes && (attributes->valuemask & BxXpmReturnInfos))
02457         xpmGetCmt(data, &colors_cmt);
02458 
02459     /*
02460      * read pixels and index them on color number 
02461      */
02462     pixelindex =
02463         (unsigned int *) malloc(sizeof(unsigned int) * width * height);
02464     if (!pixelindex)
02465         RETURN(BxXpmNoMemory);
02466 
02467     iptr = pixelindex;
02468 
02469     chars = (char *) malloc(cpp);
02470     if (!chars)
02471         RETURN(BxXpmNoMemory);
02472 
02473     for (y = 0; y < height; y++) {
02474         xpmNextString(data);
02475         for (x = 0; x < width; x++, iptr++) {
02476             for (a = 0; a < cpp; a++)
02477                 chars[a] = xpmGetC(data);
02478             for (a = 0; a < ncolors; a++)
02479                 if (!strncmp(colorTable[a][0], chars, cpp))
02480                     break;
02481             if (a == ncolors)
02482                 RETURN(BxXpmFileInvalid);       /* no color matches */
02483             *iptr = a;
02484         }
02485     }
02486 
02487     /*
02488      * store the pixels comment line 
02489      */
02490     if (attributes && (attributes->valuemask & BxXpmReturnInfos))
02491         xpmGetCmt(data, &pixels_cmt);
02492 
02493     free(chars);
02494 
02495     /*
02496      * store found informations in the bxxpmInternAttrib structure 
02497      */
02498     attrib_return->width = width;
02499     attrib_return->height = height;
02500     attrib_return->cpp = cpp;
02501     attrib_return->ncolors = ncolors;
02502     attrib_return->colorTable = colorTable;
02503     attrib_return->pixelindex = pixelindex;
02504 
02505     if (attributes) {
02506         if (attributes->valuemask & BxXpmReturnInfos) {
02507             attributes->hints_cmt = hints_cmt;
02508             attributes->colors_cmt = colors_cmt;
02509             attributes->pixels_cmt = pixels_cmt;
02510         }
02511         if (hotspot) {
02512             attributes->x_hotspot = x_hotspot;
02513             attributes->y_hotspot = y_hotspot;
02514             attributes->valuemask |= BxXpmHotspot;
02515         }
02516     }
02517     return (BxXpmSuccess);
02518 }
02519 
02520 /*
02521  * set the color pixel related to the given colorname,
02522  * return 0 if success, 1 otherwise.
02523  */
02524 
02525 static int SetColor
02526 ARGLIST((display, colormap,colorname, color_index, image_pixel, mask_pixel, mask_pixel_index))
02527 ARG(Display *, display)
02528 ARG(Colormap, colormap)
02529 ARG(char *, colorname)
02530 ARG(unsigned int, color_index)
02531 ARG(Pixel *, image_pixel)
02532 ARG(Pixel *, mask_pixel)
02533 GRA(unsigned int *, mask_pixel_index)
02534 {
02535     XColor xcolor;
02536 
02537     if (STRCASECMP(colorname, BX_TRANSPARENT_COLOR)) {
02538         if (!XParseColor(display, colormap, colorname, &xcolor)
02539             || (!XAllocColor(display, colormap, &xcolor)))
02540             return (1);
02541         *image_pixel = xcolor.pixel;
02542         *mask_pixel = 1;
02543     } else {
02544         *image_pixel = 0;
02545         *mask_pixel = 0;
02546         *mask_pixel_index = color_index;/* store the color table index */
02547     }
02548     return (0);
02549 }
02550 
02551 /* function call in case of error, frees only localy allocated variables */
02552 #undef RETURN
02553 #define RETURN(status) \
02554   { if (image) XDestroyImage(image); \
02555     if (shapeimage) XDestroyImage(shapeimage); \
02556     if (image_pixels) free((char *)image_pixels); \
02557     if (mask_pixels) free((char *)mask_pixels); \
02558     return(status); }
02559 
02560 static int xpmCreateImage
02561 ARGLIST((display, attrib, image_return, shapeimage_return, attributes))
02562 ARG(Display *, display)
02563 ARG(bxxpmInternAttrib *, attrib)
02564 ARG(XImage **, image_return)
02565 ARG(XImage **, shapeimage_return)
02566 GRA(BxXpmAttributes *, attributes)
02567 {
02568     /* variables stored in the BxXpmAttributes structure */
02569     Visual *visual;
02570     Colormap colormap;
02571     unsigned int depth;
02572     BxXpmColorSymbol *colorsymbols;
02573     unsigned int numsymbols;
02574 
02575     /* variables to return */
02576     XImage *image = NULL;
02577     XImage *shapeimage = NULL;
02578     unsigned int mask_pixel;
02579     unsigned int ErrorStatus, ErrorStatus2;
02580 
02581     /* calculation variables */
02582     Pixel *image_pixels = NULL;
02583     Pixel *mask_pixels = NULL;
02584     char *colorname;
02585     unsigned int a, b, l;
02586     Boolean pixel_defined;
02587     unsigned int key;
02588 
02589 
02590     /*
02591      * retrieve information from the BxXpmAttributes 
02592      */
02593     if (attributes && attributes->valuemask & BxXpmColorSymbols) {
02594         colorsymbols = attributes->colorsymbols;
02595         numsymbols = attributes->numsymbols;
02596     } else
02597         numsymbols = 0;
02598 
02599     if (attributes && attributes->valuemask & BxXpmVisual)
02600         visual = attributes->visual;
02601     else
02602         visual = DefaultVisual(display, DefaultScreen(display));
02603 
02604     if (attributes && attributes->valuemask & BxXpmColormap)
02605         colormap = attributes->colormap;
02606     else
02607         colormap = DefaultColormap(display, DefaultScreen(display));
02608 
02609     if (attributes && attributes->valuemask & BxXpmDepth)
02610         depth = attributes->depth;
02611     else
02612         depth = DefaultDepth(display, DefaultScreen(display));
02613 
02614 
02615     ErrorStatus = BxXpmSuccess;
02616 
02617     /*
02618      * alloc pixels index tables 
02619      */
02620 
02621     key = BxXpmVisualType(visual);
02622     image_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
02623     if (!image_pixels)
02624         RETURN(BxXpmNoMemory);
02625 
02626     mask_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
02627     if (!mask_pixels)
02628         RETURN(BxXpmNoMemory);
02629 
02630     mask_pixel = BX_UNDEF_PIXEL;
02631 
02632     /*
02633      * get pixel colors, store them in index tables 
02634      */
02635     for (a = 0; a < attrib->ncolors; a++) {
02636         colorname = NULL;
02637         pixel_defined = False;
02638 
02639         /*
02640          * look for a defined symbol 
02641          */
02642         if (numsymbols && attrib->colorTable[a][1]) {
02643             for (l = 0; l < numsymbols; l++)
02644                 if (!strcmp(colorsymbols[l].name, attrib->colorTable[a][1]))
02645                     break;
02646             if (l != numsymbols) {
02647                 if (colorsymbols[l].value)
02648                     colorname = colorsymbols[l].value;
02649                 else
02650                     pixel_defined = True;
02651             }
02652         }
02653         if (!pixel_defined) {           /* pixel not given as symbol value */
02654 
02655             if (colorname) {            /* colorname given as symbol value */
02656                 if (!SetColor(display, colormap, colorname, a,
02657                            &image_pixels[a], &mask_pixels[a], &mask_pixel))
02658                     pixel_defined = True;
02659                 else
02660                     ErrorStatus = BxXpmColorError;
02661             }
02662             b = key;
02663             while (!pixel_defined && b > 1) {
02664                 if (attrib->colorTable[a][b]) {
02665                     if (!SetColor(display, colormap, attrib->colorTable[a][b],
02666                                   a, &image_pixels[a], &mask_pixels[a],
02667                                   &mask_pixel)) {
02668                         pixel_defined = True;
02669                         break;
02670                     } else
02671                         ErrorStatus = BxXpmColorError;
02672                 }
02673                 b--;
02674             }
02675 
02676             b = key + 1;
02677             while (!pixel_defined && b < BXNKEYS + 1) {
02678                 if (attrib->colorTable[a][b]) {
02679                     if (!SetColor(display, colormap, attrib->colorTable[a][b],
02680                                   a, &image_pixels[a], &mask_pixels[a],
02681                                   &mask_pixel)) {
02682                         pixel_defined = True;
02683                         break;
02684                     } else
02685                         ErrorStatus = BxXpmColorError;
02686                 }
02687                 b++;
02688             }
02689 
02690             if (!pixel_defined)
02691                 RETURN(BxXpmColorFailed);
02692 
02693         } else {
02694             image_pixels[a] = colorsymbols[l].pixel;
02695             mask_pixels[a] = 1;
02696         }
02697     }
02698 
02699     /*
02700      * create the image 
02701      */
02702     if (image_return) {
02703         ErrorStatus2 = CreateXImage(display, visual, depth,
02704                                     attrib->width, attrib->height, &image);
02705         if (ErrorStatus2 != BxXpmSuccess)
02706             RETURN(ErrorStatus2);
02707 
02708         /*
02709          * set the image data 
02710          *
02711          * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use
02712          * optimized functions, otherwise use slower but sure general one. 
02713          *
02714          */
02715 
02716         if (image->depth == 1)
02717             SetImagePixels1(image, attrib->width, attrib->height,
02718                             attrib->pixelindex, image_pixels);
02719         else if (image->bits_per_pixel == 8)
02720             SetImagePixels8(image, attrib->width, attrib->height,
02721                             attrib->pixelindex, image_pixels);
02722         else if (image->bits_per_pixel == 16)
02723             SetImagePixels16(image, attrib->width, attrib->height,
02724                              attrib->pixelindex, image_pixels);
02725         else if (image->bits_per_pixel == 32)
02726             SetImagePixels32(image, attrib->width, attrib->height,
02727                              attrib->pixelindex, image_pixels);
02728         else
02729             SetImagePixels(image, attrib->width, attrib->height,
02730                            attrib->pixelindex, image_pixels);
02731     }
02732 
02733     /*
02734      * create the shape mask image 
02735      */
02736     if (mask_pixel != BX_UNDEF_PIXEL && shapeimage_return) {
02737         ErrorStatus2 = CreateXImage(display, visual, 1, attrib->width,
02738                                     attrib->height, &shapeimage);
02739         if (ErrorStatus2 != BxXpmSuccess)
02740             RETURN(ErrorStatus2);
02741 
02742         SetImagePixels1(shapeimage, attrib->width, attrib->height,
02743                         attrib->pixelindex, mask_pixels);
02744     }
02745     free((char *)mask_pixels);
02746 
02747     /*
02748      * if requested store allocated pixels in the BxXpmAttributes structure 
02749      */
02750     if (attributes &&
02751         (attributes->valuemask & BxXpmReturnInfos
02752          || attributes->valuemask & BxXpmReturnPixels)) {
02753         if (mask_pixel != BX_UNDEF_PIXEL) {
02754             Pixel *pixels, *p1, *p2;
02755 
02756             attributes->npixels = attrib->ncolors - 1;
02757             pixels = (Pixel *) malloc(sizeof(Pixel) * attributes->npixels);
02758             if (pixels) {
02759                 p1 = image_pixels;
02760                 p2 = pixels;
02761                 for (a = 0; a < attrib->ncolors; a++, p1++)
02762                     if (a != mask_pixel)
02763                         *p2++ = *p1;
02764                 attributes->pixels = pixels;
02765             } else {
02766                 /* if error just say we can't return requested data */
02767                 attributes->valuemask &= ~BxXpmReturnPixels;
02768                 attributes->valuemask &= ~BxXpmReturnInfos;
02769                 attributes->pixels = NULL;
02770                 attributes->npixels = 0;
02771             }
02772             free((char *)image_pixels);
02773         } else {
02774             attributes->pixels = image_pixels;
02775             attributes->npixels = attrib->ncolors;
02776         }
02777         attributes->mask_pixel = mask_pixel;
02778     } else
02779         free((char *)image_pixels);
02780 
02781 
02782     /*
02783      * return created images 
02784      */
02785     if (image_return)
02786         *image_return = image;
02787 
02788     if (shapeimage_return)
02789         *shapeimage_return = shapeimage;
02790 
02791     return (ErrorStatus);
02792 }
02793 
02794 
02795 /*
02796  * Create an XImage
02797  */
02798 static int CreateXImage
02799 ARGLIST((display, visual, depth, width, height, image_return))
02800 ARG(Display *, display)
02801 ARG(Visual *, visual)
02802 ARG(unsigned int, depth)
02803 ARG(unsigned int, width)
02804 ARG(unsigned int, height)
02805 GRA(XImage **, image_return)
02806 {
02807     int bitmap_pad;
02808 
02809     /* first get bitmap_pad */
02810     if (depth > 16)
02811         bitmap_pad = 32;
02812     else if (depth > 8)
02813         bitmap_pad = 16;
02814     else
02815         bitmap_pad = 8;
02816 
02817     /* then create the XImage with data = NULL and bytes_per_line = 0 */
02818 
02819     *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0,
02820                                  width, height, bitmap_pad, 0);
02821     if (!*image_return)
02822         return (BxXpmNoMemory);
02823 
02824     /* now that bytes_per_line must have been set properly alloc data */
02825 
02826     (*image_return)->data =
02827         (char *) malloc((*image_return)->bytes_per_line * height);
02828 
02829     if (!(*image_return)->data) {
02830         XDestroyImage(*image_return);
02831         *image_return = NULL;
02832         return (BxXpmNoMemory);
02833     }
02834     return (BxXpmSuccess);
02835 }
02836 
02837 
02838 /*
02839  * The functions below are written from X11R5 MIT's code (XImUtil.c)
02840  *
02841  * The idea is to have faster functions than the standard XPutPixel function
02842  * to build the image data. Indeed we can speed up things by supressing tests
02843  * performed for each pixel. We do exactly the same tests but at the image
02844  * level. Assuming that we use only ZPixmap images. 
02845  */
02846 
02847 LFUNC(_putbits, void, (register char *src, int dstoffset,
02848                       register int numbits, register char *dst));
02849 
02850 LFUNC(_XReverse_Bytes, void, (register unsigned char *bpt, register int nb));
02851 
02852 static unsigned char Const _reverse_byte[0x100] = {
02853                             0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
02854                             0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
02855                             0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
02856                             0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
02857                             0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
02858                             0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
02859                             0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
02860                             0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
02861                             0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
02862                             0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
02863                             0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
02864                             0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
02865                             0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
02866                             0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
02867                             0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
02868                             0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
02869                             0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
02870                             0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
02871                             0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
02872                             0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
02873                             0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
02874                             0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
02875                             0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
02876                             0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
02877                             0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
02878                             0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
02879                             0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
02880                             0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
02881                             0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
02882                             0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
02883                             0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
02884                              0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
02885 };
02886 
02887 static void _XReverse_Bytes
02888 ARGLIST((bpt, nb))
02889 ARG(register unsigned char *, bpt)
02890 GRA(register int, nb)
02891 {
02892     do {
02893         *bpt = _reverse_byte[*bpt];
02894         bpt++;
02895     } while (--nb > 0);
02896 }
02897 
02898 static void xpm_xynormalizeimagebits
02899 ARGLIST((bp,img))
02900 ARG(register unsigned char *, bp)
02901 GRA(register XImage *, img)
02902 {
02903     register unsigned char c;
02904 
02905     if (img->byte_order != img->bitmap_bit_order) {
02906         switch (img->bitmap_unit) {
02907 
02908         case 16:
02909             c = *bp;
02910             *bp = *(bp + 1);
02911             *(bp + 1) = c;
02912             break;
02913 
02914         case 32:
02915             c = *(bp + 3);
02916             *(bp + 3) = *bp;
02917             *bp = c;
02918             c = *(bp + 2);
02919             *(bp + 2) = *(bp + 1);
02920             *(bp + 1) = c;
02921             break;
02922         }
02923     }
02924     if (img->bitmap_bit_order == MSBFirst)
02925         _XReverse_Bytes(bp, img->bitmap_unit >> 3);
02926 }
02927 
02928 static void xpm_znormalizeimagebits
02929 ARGLIST((bp,img))
02930 ARG(register unsigned char *, bp)
02931 GRA(register XImage *, img)
02932 {
02933     register unsigned char c;
02934 
02935     switch (img->bits_per_pixel) {
02936 
02937     case 4:
02938         *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
02939         break;
02940 
02941     case 16:
02942         c = *bp;
02943         *bp = *(bp + 1);
02944         *(bp + 1) = c;
02945         break;
02946 
02947     case 24:
02948         c = *(bp + 2);
02949         *(bp + 2) = *bp;
02950         *bp = c;
02951         break;
02952 
02953     case 32:
02954         c = *(bp + 3);
02955         *(bp + 3) = *bp;
02956         *bp = c;
02957         c = *(bp + 2);
02958         *(bp + 2) = *(bp + 1);
02959         *(bp + 1) = c;
02960         break;
02961     }
02962 }
02963 
02964 static unsigned char Const _lomask[0x09] = {
02965                      0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
02966 static unsigned char Const _himask[0x09] = {
02967                      0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
02968 
02969 static void _putbits
02970 ARGLIST((src, dstoffset, numbits, dst))
02971 ARG(register char *, src)               /* address of source bit string */
02972 ARG(int, dstoffset)                     /* bit offset into destination;
02973                                          * range is 0-31 */
02974 ARG(register int, numbits)              /* number of bits to copy to
02975                                          * destination */
02976 GRA(register char *, dst)               /* address of destination bit string */
02977 {
02978     register unsigned char chlo, chhi;
02979     int hibits;
02980 
02981     dst = dst + (dstoffset >> 3);
02982     dstoffset = dstoffset & 7;
02983     hibits = 8 - dstoffset;
02984     chlo = *dst & _lomask[dstoffset];
02985     for (;;) {
02986         chhi = (*src << dstoffset) & _himask[dstoffset];
02987         if (numbits <= hibits) {
02988             chhi = chhi & _lomask[dstoffset + numbits];
02989             *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
02990             break;
02991         }
02992         *dst = chhi | chlo;
02993         dst++;
02994         numbits = numbits - hibits;
02995         chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
02996         src++;
02997         if (numbits <= dstoffset) {
02998             chlo = chlo & _lomask[numbits];
02999             *dst = (*dst & _himask[numbits]) | chlo;
03000             break;
03001         }
03002         numbits = numbits - dstoffset;
03003     }
03004 }
03005 
03006 /*
03007  * Default method to write pixels into a Z image data structure.
03008  * The algorithm used is:
03009  *
03010  *      copy the destination bitmap_unit or Zpixel to temp
03011  *      normalize temp if needed
03012  *      copy the pixel bits into the temp
03013  *      renormalize temp if needed
03014  *      copy the temp back into the destination image data
03015  */
03016 
03017 static void SetImagePixels
03018 ARGLIST((image, width, height, pixelindex, pixels))
03019 ARG(XImage *, image)
03020 ARG(unsigned int, width)
03021 ARG(unsigned int, height)
03022 ARG(unsigned int *, pixelindex)
03023 GRA(Pixel *, pixels)
03024 {
03025     Pixel pixel;
03026     unsigned long px;
03027     register char *src;
03028     register char *dst;
03029     int nbytes;
03030     register unsigned int *iptr;
03031     register int x, y, i;
03032 
03033     iptr = pixelindex;
03034     if (image->depth == 1) {
03035         for (y = 0; y < height; y++)
03036             for (x = 0; x < width; x++, iptr++) {
03037                 pixel = pixels[*iptr];
03038                 for (i = 0, px = pixel;
03039                      i < sizeof(unsigned long); i++, px >>= 8)
03040                     ((unsigned char *) &pixel)[i] = (unsigned char)px;
03041                 src = &image->data[BXXYINDEX(x, y, image)];
03042                 dst = (char *) &px;
03043                 px = 0;
03044                 nbytes = image->bitmap_unit >> 3;
03045                 for (i = nbytes; --i >= 0;)
03046                     *dst++ = *src++;
03047                 BXXYNORMALIZE(&px, image);
03048                 i = ((x + image->xoffset) % image->bitmap_unit);
03049                 _putbits((char *) &pixel, i, 1, (char *) &px);
03050                 BXXYNORMALIZE(&px, image);
03051                 src = (char *) &px;
03052                 dst = &image->data[BXXYINDEX(x, y, image)];
03053                 for (i = nbytes; --i >= 0;)
03054                     *dst++ = *src++;
03055             }
03056     } else {
03057         for (y = 0; y < height; y++)
03058             for (x = 0; x < width; x++, iptr++) {
03059                 pixel = pixels[*iptr];
03060                 if (image->depth == 4)
03061                     pixel &= 0xf;
03062                 for (i = 0, px = pixel;
03063                      i < sizeof(unsigned long); i++, px >>= 8)
03064                     ((unsigned char *) &pixel)[i] = (unsigned char)px;
03065                 src = &image->data[BXZINDEX(x, y, image)];
03066                 dst = (char *) &px;
03067                 px = 0;
03068                 nbytes = (image->bits_per_pixel + 7) >> 3;
03069                 for (i = nbytes; --i >= 0;)
03070                     *dst++ = *src++;
03071                 BXZNORMALIZE(&px, image);
03072                 _putbits((char *) &pixel,
03073                          (x * image->bits_per_pixel) & 7,
03074                          image->bits_per_pixel, (char *) &px);
03075                 BXZNORMALIZE(&px, image);
03076                 src = (char *) &px;
03077                 dst = &image->data[BXZINDEX(x, y, image)];
03078                 for (i = nbytes; --i >= 0;)
03079                     *dst++ = *src++;
03080             }
03081     }
03082 }
03083 
03084 /*
03085  * write pixels into a 32-bits Z image data structure
03086  */
03087 
03088 #ifndef WORD64
03089 static unsigned long byteorderpixel = MSBFirst << 24;
03090 
03091 #endif
03092 
03093 static void SetImagePixels32
03094 ARGLIST((image, width, height, pixelindex, pixels))
03095 ARG(XImage *, image)
03096 ARG(unsigned int, width)
03097 ARG(unsigned int, height)
03098 ARG(unsigned int *, pixelindex)
03099 GRA(Pixel *, pixels)
03100 {
03101     register unsigned char *addr;
03102     register unsigned int *paddr;
03103     register unsigned int *iptr;
03104     register int x, y;
03105 
03106     iptr = pixelindex;
03107 #ifndef WORD64
03108     if (*((char *) &byteorderpixel) == image->byte_order) {
03109         for (y = 0; y < height; y++)
03110             for (x = 0; x < width; x++, iptr++) {
03111                 paddr =
03112                     (unsigned int *)(&(image->data[BXZINDEX32(x, y, image)]));
03113                 *paddr = (unsigned int)pixels[*iptr];
03114             }
03115     } else
03116 #endif
03117     if (image->byte_order == MSBFirst)
03118         for (y = 0; y < height; y++)
03119             for (x = 0; x < width; x++, iptr++) {
03120                 addr = &((unsigned char *) image->data)[BXZINDEX32(x, y, image)];
03121                 addr[0] = (unsigned char)(pixels[*iptr] >> 24);
03122                 addr[1] = (unsigned char)(pixels[*iptr] >> 16);
03123                 addr[2] = (unsigned char)(pixels[*iptr] >> 8);
03124                 addr[3] = (unsigned char)(pixels[*iptr]);
03125             }
03126     else
03127         for (y = 0; y < height; y++)
03128             for (x = 0; x < width; x++, iptr++) {
03129                 addr = &((unsigned char *) image->data)[BXZINDEX32(x, y, image)];
03130                 addr[3] = (unsigned char)(pixels[*iptr] >> 24);
03131                 addr[2] = (unsigned char)(pixels[*iptr] >> 16);
03132                 addr[1] = (unsigned char)(pixels[*iptr] >> 8);
03133                 addr[0] = (unsigned char)(pixels[*iptr]);
03134             }
03135 }
03136 
03137 /*
03138  * write pixels into a 16-bits Z image data structure
03139  */
03140 
03141 static void SetImagePixels16
03142 ARGLIST((image, width, height, pixelindex, pixels))
03143 ARG(XImage *, image)
03144 ARG(unsigned int, width)
03145 ARG(unsigned int, height)
03146 ARG(unsigned int *, pixelindex)
03147 GRA(Pixel *, pixels)
03148 {
03149     register unsigned char *addr;
03150     register unsigned int *iptr;
03151     register int x, y;
03152 
03153     iptr = pixelindex;
03154     if (image->byte_order == MSBFirst)
03155         for (y = 0; y < height; y++)
03156             for (x = 0; x < width; x++, iptr++) {
03157                 addr = &((unsigned char *) image->data)[BXZINDEX16(x, y, image)];
03158                 addr[0] = (unsigned char)(pixels[*iptr] >> 8);
03159                 addr[1] = (unsigned char)(pixels[*iptr]);
03160             }
03161     else
03162         for (y = 0; y < height; y++)
03163             for (x = 0; x < width; x++, iptr++) {
03164                 addr = &((unsigned char *) image->data)[BXZINDEX16(x, y, image)];
03165                 addr[1] = (unsigned char)(pixels[*iptr] >> 8);
03166                 addr[0] = (unsigned char)(pixels[*iptr]);
03167             }
03168 }
03169 
03170 /*
03171  * write pixels into a 8-bits Z image data structure
03172  */
03173 
03174 static void SetImagePixels8
03175 ARGLIST((image, width, height, pixelindex, pixels))
03176 ARG(XImage *, image)
03177 ARG(unsigned int, width)
03178 ARG(unsigned int, height)
03179 ARG(unsigned int *, pixelindex)
03180 GRA(Pixel *, pixels)
03181 
03182 {
03183     register unsigned int *iptr;
03184     register int x, y;
03185 
03186     iptr = pixelindex;
03187     for (y = 0; y < height; y++)
03188         for (x = 0; x < width; x++, iptr++)
03189             image->data[BXZINDEX8(x, y, image)] = (char)pixels[*iptr];
03190 }
03191 
03192 /*
03193  * write pixels into a 1-bit depth image data structure and **offset null**
03194  */
03195 
03196 static void SetImagePixels1
03197 ARGLIST((image, width, height, pixelindex, pixels))
03198 ARG(XImage *, image)
03199 ARG(unsigned int, width)
03200 ARG(unsigned int, height)
03201 ARG(unsigned int *, pixelindex)
03202 GRA(Pixel *, pixels)
03203 {
03204     unsigned char bit;
03205     int xoff, yoff;
03206     register unsigned int *iptr;
03207     register int x, y;
03208 
03209     if (image->byte_order != image->bitmap_bit_order)
03210         SetImagePixels(image, width, height, pixelindex, pixels);
03211     else {
03212         iptr = pixelindex;
03213         if (image->bitmap_bit_order == MSBFirst)
03214             for (y = 0; y < height; y++)
03215                 for (x = 0; x < width; x++, iptr++) {
03216                     yoff = BXZINDEX1(x, y, image);
03217                     xoff = x & 7;
03218                     bit = 0x80 >> xoff;
03219                     if (pixels[*iptr] & 1)
03220                         image->data[yoff] |= bit;
03221                     else
03222                         image->data[yoff] &= ~bit;
03223                 }
03224         else
03225             for (y = 0; y < height; y++)
03226                 for (x = 0; x < width; x++, iptr++) {
03227                     yoff = BXZINDEX1(x, y, image);
03228                     xoff = x & 7;
03229                     bit = 1 << xoff;
03230                     if (pixels[*iptr] & 1)
03231                         image->data[yoff] |= bit;
03232                     else
03233                         image->data[yoff] &= ~bit;
03234                 }
03235     }
03236 }
03237 
03238 /*
03239  * Store into the BxXpmAttributes structure the required informations stored in
03240  * the bxxpmInternAttrib structure.
03241  */
03242 
03243 static void xpmSetAttributes
03244 ARGLIST((attrib, attributes))
03245 ARG(bxxpmInternAttrib *, attrib)
03246 GRA(BxXpmAttributes *, attributes)
03247 {
03248     if (attributes) {
03249         if (attributes->valuemask & BxXpmReturnInfos) {
03250             attributes->cpp = attrib->cpp;
03251             attributes->ncolors = attrib->ncolors;
03252             attributes->colorTable = attrib->colorTable;
03253 
03254             attrib->ncolors = 0;
03255             attrib->colorTable = NULL;
03256         }
03257         attributes->width = attrib->width;
03258         attributes->height = attrib->height;
03259         attributes->valuemask |= BxXpmSize;
03260     }
03261 }
03262 
03263 /*
03264  * Free the BxXpmAttributes structure members
03265  * but the structure itself
03266  */
03267 
03268 static void BxXpmFreeAttributes
03269 ARGLIST((attributes))
03270 GRA(BxXpmAttributes *, attributes)
03271 {
03272     if (attributes) {
03273         if (attributes->valuemask & BxXpmReturnPixels && attributes->pixels) {
03274             free((char *)attributes->pixels);
03275             attributes->pixels = NULL;
03276             attributes->npixels = 0;
03277         }
03278         if (attributes->valuemask & BxXpmInfos) {
03279             if (attributes->colorTable) {
03280                 xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
03281                 attributes->colorTable = NULL;
03282                 attributes->ncolors = 0;
03283             }
03284             if (attributes->hints_cmt) {
03285                 free(attributes->hints_cmt);
03286                 attributes->hints_cmt = NULL;
03287             }
03288             if (attributes->colors_cmt) {
03289                 free(attributes->colors_cmt);
03290                 attributes->colors_cmt = NULL;
03291             }
03292             if (attributes->pixels_cmt) {
03293                 free(attributes->pixels_cmt);
03294                 attributes->pixels_cmt = NULL;
03295             }
03296             if (attributes->pixels) {
03297                 free((char *)attributes->pixels);
03298                 attributes->pixels = NULL;
03299             }
03300         }
03301         attributes->valuemask = 0;
03302     }
03303 }
03304 
03305 /*
03306  * Free the bxxpmInternAttrib pointers which have been allocated
03307  */
03308 
03309 static void xpmFreeInternAttrib
03310 ARGLIST((attrib))
03311 GRA(bxxpmInternAttrib *, attrib)
03312 {
03313     unsigned int a;
03314 
03315     if (attrib->colorTable)
03316         xpmFreeColorTable(attrib->colorTable, attrib->ncolors);
03317     if (attrib->pixelindex)
03318         free((char *)attrib->pixelindex);
03319     if (attrib->xcolors)
03320         free((char *)attrib->xcolors);
03321     if (attrib->colorStrings) {
03322         for (a = 0; a < attrib->ncolors; a++)
03323             if (attrib->colorStrings[a])
03324                 free((char *)attrib->colorStrings[a]);
03325         free((char *)attrib->colorStrings);
03326     }
03327 }
03328 
03329 /*
03330  * close the file related to the bxxpmData if any
03331  */
03332 static void XpmDataClose
03333 ARGLIST((mdata))
03334 GRA(bxxpmData *, mdata)
03335 {
03336     switch (mdata->type) {
03337     case BXXPMARRAY:
03338         break;
03339     case BXXPMFILE:
03340         if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin))
03341             fclose(mdata->stream.file);
03342         break;
03343 #ifdef ZPIPE
03344     case BXXPMPIPE:
03345         pclose(mdata->stream.file);
03346 #endif
03347     }
03348 }
03349 
03350 /*
03351  * skip whitespace and compute the following unsigned int,
03352  * returns 1 if one is found and 0 if not
03353  */
03354 static int xpmNextUI
03355 ARGLIST((mdata, ui_return))
03356 ARG(bxxpmData *, mdata)
03357 GRA(unsigned int *, ui_return)
03358 {
03359     char buf[BUFSIZ];
03360     int l;
03361 
03362     l = xpmNextWord(mdata, buf);
03363     return atoui(buf, l, ui_return);
03364 }
03365 
03366 /*
03367  * get the current comment line
03368  */
03369 static void xpmGetCmt
03370 ARGLIST((mdata, cmt))
03371 ARG(bxxpmData *, mdata)
03372 GRA(char **, cmt)
03373 {
03374     switch (mdata->type) {
03375     case BXXPMARRAY:
03376         *cmt = NULL;
03377         break;
03378     case BXXPMFILE:
03379     case BXXPMPIPE:
03380         if (mdata->CommentLength) {
03381             *cmt = (char *) malloc(mdata->CommentLength + 1);
03382             strncpy(*cmt, mdata->Comment, mdata->CommentLength);
03383             (*cmt)[mdata->CommentLength] = '\0';
03384             mdata->CommentLength = 0;
03385         } else
03386             *cmt = NULL;
03387         break;
03388     }
03389 }
03390 
03391 /*
03392  * skip to the end of the current string and the beginning of the next one
03393  */
03394 static void xpmNextString
03395 ARGLIST((mdata))
03396 GRA(bxxpmData *, mdata)
03397 {
03398     int c;
03399 
03400     switch (mdata->type) {
03401     case BXXPMARRAY:
03402         mdata->cptr = (mdata->stream.data)[++mdata->line];
03403         break;
03404     case BXXPMFILE:
03405     case BXXPMPIPE:
03406         if (mdata->Eos)
03407             while ((c = xpmGetC(mdata)) != mdata->Eos && c != EOF);
03408         if (mdata->Bos)                 /* if not natural XPM2 */
03409             while ((c = xpmGetC(mdata)) != mdata->Bos && c != EOF);
03410         break;
03411     }
03412 }
03413 
03414 /*
03415  * return the current character, skipping comments
03416  */
03417 static int xpmGetC
03418 ARGLIST((mdata))
03419 GRA(bxxpmData *, mdata)
03420 {
03421     int c;
03422     register unsigned int n = 0, a;
03423     unsigned int notend;
03424 
03425     switch (mdata->type) {
03426     case BXXPMARRAY:
03427         return (*mdata->cptr++);
03428     case BXXPMFILE:
03429     case BXXPMPIPE:
03430         c = getc(mdata->stream.file);
03431 
03432         if (mdata->Bos && mdata->Eos
03433             && (c == mdata->Bos || c == mdata->Eos)) {
03434             /* if not natural XPM2 */
03435             mdata->InsideString = !mdata->InsideString;
03436             return (c);
03437         }
03438         if (!mdata->InsideString && mdata->Bcmt && c == mdata->Bcmt[0]) {
03439             mdata->Comment[0] = c;
03440 
03441             /*
03442              * skip the string begining comment
03443              */
03444             do {
03445                 c = getc(mdata->stream.file);
03446                 mdata->Comment[++n] = c;
03447             } while (c == mdata->Bcmt[n] && mdata->Bcmt[n] != '\0'
03448                      && c != EOF);
03449 
03450             if (mdata->Bcmt[n] != '\0') {
03451                 /* this wasn't the begining of a comment */
03452                 /* put characters back in the order that we got them */
03453                 for (a = n; a > 0; a--)
03454                     xpmUngetC(mdata->Comment[a], mdata);
03455                 return (mdata->Comment[0]);
03456             }
03457 
03458             /*
03459              * store comment
03460              */
03461             mdata->Comment[0] = mdata->Comment[n];
03462             notend = 1;
03463             n = 0;
03464             while (notend) {
03465                 while (mdata->Comment[n] != mdata->Ecmt[0] && c != EOF) {
03466                     c = getc(mdata->stream.file);
03467                     mdata->Comment[++n] = c;
03468                 }
03469                 mdata->CommentLength = n;
03470                 a = 0;
03471                 do {
03472                     c = getc(mdata->stream.file);
03473                     n++;
03474                     a++;
03475                     mdata->Comment[n] = c;
03476                 } while (c == mdata->Ecmt[a] && mdata->Ecmt[a] != '\0'
03477                          && c != EOF);
03478                 if (mdata->Ecmt[a] == '\0') {
03479                     /* this is the end of the comment */
03480                     notend = 0;
03481                     xpmUngetC(mdata->Comment[n], mdata);
03482                 }
03483             }
03484             c = xpmGetC(mdata);
03485         }
03486         return (c);
03487     }
03488     return('\0');
03489 }
03490 
03491 
03492 /*
03493  * push the given character back
03494  */
03495 static int xpmUngetC
03496 ARGLIST((c, mdata))
03497 ARG(int, c)
03498 GRA(bxxpmData *, mdata)
03499 {
03500     switch (mdata->type) {
03501     case BXXPMARRAY:
03502         return (*--mdata->cptr = c);
03503     case BXXPMFILE:
03504     case BXXPMPIPE:
03505         if (mdata->Bos && (c == mdata->Bos || c == mdata->Eos))
03506             /* if not natural XPM2 */
03507             mdata->InsideString = !mdata->InsideString;
03508         return (ungetc(c, mdata->stream.file));
03509     }
03510     return('\0');
03511 }
03512 
03513 /*
03514  * skip whitespace and return the following word
03515  */
03516 static unsigned int xpmNextWord
03517 ARGLIST((mdata, buf))
03518 ARG(bxxpmData *, mdata)
03519 GRA(char *, buf)
03520 {
03521     register unsigned int n = 0;
03522     int c;
03523 
03524     switch (mdata->type) {
03525     case BXXPMARRAY:
03526         while (isspace(c = *mdata->cptr) && c != mdata->Eos)
03527             mdata->cptr++;
03528         do {
03529             c = *mdata->cptr++;
03530             buf[n++] = c;
03531         } while (!isspace(c) && c != mdata->Eos && c != '\0');
03532         n--;
03533         mdata->cptr--;
03534         break;
03535     case BXXPMFILE:
03536     case BXXPMPIPE:
03537         while (isspace(c = xpmGetC(mdata)) && c != mdata->Eos);
03538         while (!isspace(c) && c != mdata->Eos && c != EOF) {
03539             buf[n++] = c;
03540             c = xpmGetC(mdata);
03541         }
03542         xpmUngetC(c, mdata);
03543         break;
03544     }
03545     return (n);
03546 }
03547 
03548 static int BxXpmVisualType
03549 ARGLIST((visual))
03550 GRA(Visual *, visual)
03551 {
03552 #if ( defined(__cplusplus) || defined(c_plusplus) )
03553     switch ( visual->c_class )
03554 #else
03555     switch ( visual->class )
03556 #endif
03557     {
03558     case StaticGray:
03559     case GrayScale:
03560         switch (visual->map_entries)
03561         {
03562         case 2:
03563             return (BXMONO);
03564         case 4:
03565             return (BXGRAY4);
03566         default:
03567             return (BXGRAY);
03568         }
03569     default:
03570         return (BXCOLOR);
03571     }
03572 }
03573 
03574 /*
03575  * Free the computed color table
03576  */
03577 
03578 static void xpmFreeColorTable
03579 ARGLIST((colorTable, ncolors))
03580 ARG(char ***, colorTable)
03581 GRA(int, ncolors)
03582 {
03583     int a, b;
03584 
03585     if (colorTable) {
03586         for (a = 0; a < ncolors; a++)
03587             if (colorTable[a]) {
03588                 for (b = 0; b < (BXNKEYS + 1); b++)
03589                     if (colorTable[a][b])
03590                         free(colorTable[a][b]);
03591                 free((char *)colorTable[a]);
03592             }
03593         free((char *)colorTable);
03594     }
03595 }
03596 
03597 #else /* USE_XPM_LIBRARY */
03598 
03599 #include <xpm.h>
03600 
03601 #define BxXpmColorError                 XpmColorError
03602 #define BxXpmSuccess                    XpmSuccess
03603 #define BxXpmOpenFailed                 XpmOpenFailed
03604 #define BxXpmFileInvalid                XpmFileInvalid
03605 #define BxXpmNoMemory                   XpmNoMemory
03606 #define BxXpmColorFailed                XpmColorFailed
03607 
03608 #define BxXpmVisual                     XpmVisual
03609 #define BxXpmColormap                   XpmColormap
03610 #define BxXpmDepth                      XpmDepth
03611 #define BxXpmSize                       XpmSize
03612 #define BxXpmHotspot                    XpmHotspot
03613 #define BxXpmCharsPerPixel              XpmCharsPerPixel
03614 #define BxXpmColorSymbols               XpmColorSymbols
03615 #define BxXpmRgbFilename                XpmRgbFilename
03616 #define BxXpmInfos                      XpmInfos
03617 
03618 #define BxXpmReturnPixels               XpmReturnPixels
03619 #define BxXpmReturnInfos                XpmReturnInfos
03620 
03621 #define BxXpmCreatePixmapFromData       XpmCreatePixmapFromData
03622 #define BxXpmCreateImageFromData        XpmCreateImageFromData
03623 #define BxXpmFreeAttributes             XpmFreeAttributes
03624 
03625 typedef XpmAttributes                   BxXpmAttributes;
03626 
03627 #endif /* USE_XPM_LIBRARY */
03628     
03629 Pixmap XPM_PIXMAP
03630 ARGLIST((w, pixmapName))
03631 ARG(Widget, w)
03632 GRA(char **, pixmapName)
03633 {
03634     BxXpmAttributes     attributes;
03635     int                 argcnt;
03636     Arg                 args[10];
03637     Pixmap              pixmap;
03638     Pixmap              shape;
03639     int                 returnValue;
03640     
03641     argcnt = 0;
03642     XtSetArg(args[argcnt], XmNdepth, &(attributes.depth)); argcnt++;
03643     XtSetArg(args[argcnt], XmNcolormap, &(attributes.colormap)); argcnt++;
03644     XtGetValues(w, args, argcnt);
03645 
03646     attributes.visual = DefaultVisual(XtDisplay(w),
03647                                       DefaultScreen(XtDisplay(w)));
03648     attributes.valuemask = (BxXpmDepth | BxXpmColormap | BxXpmVisual);
03649     
03650     returnValue = BxXpmCreatePixmapFromData(XtDisplay(w),
03651                                           DefaultRootWindow(XtDisplay(w)),
03652                                           pixmapName, &pixmap, &shape,
03653                                           &attributes);
03654     if ( shape )
03655     {
03656         XFreePixmap(XtDisplay(w), shape);
03657     }   
03658 
03659     switch(returnValue)
03660     {
03661     case BxXpmOpenFailed:
03662     case BxXpmFileInvalid:
03663     case BxXpmNoMemory:
03664     case BxXpmColorFailed:
03665         XtWarning("Could not create pixmap.");
03666         return(XmUNSPECIFIED_PIXMAP);
03667     default:
03668         return(pixmap);
03669     }
03670 }
03671 
03672 #endif
03673 
03674 /***************************************************************************
03675  * $RCSfile: bxutilsC.cpp,v $   $Author: adelmann $
03676  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:34 $
03677  * IPPL_VERSION_ID: $Id: bxutilsC.cpp,v 1.1.1.1 2003/01/23 07:40:34 adelmann Exp $ 
03678  ***************************************************************************/

Generated on Fri Nov 2 01:25:53 2007 for IPPL by doxygen 1.3.5