BSD 4_4_Lite2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 17 Apr 1993 13:23:28 +0000 (05:23 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 17 Apr 1993 13:23:28 +0000 (05:23 -0800)
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XCnvWCToMB.c
Work on file usr/src/contrib/X11R5-lib/lib/X/XcmsLRGB.c
Work on file usr/src/contrib/X11R5-lib/lib/X/XcmsInt.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/TextPerBd.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XConnIM.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XCrIC.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XICSetVal.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XOpenIM.c
Work on file usr/src/contrib/X11R5-lib/lib/X/Xsi/XIMlibint.h

Synthesized-from: CSRG/cd3/4.4BSD-Lite2

usr/src/contrib/X11R5-lib/lib/X/XcmsInt.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/XcmsLRGB.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/TextPerBd.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XCnvWCToMB.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XConnIM.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XCrIC.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XICSetVal.c [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XIMlibint.h [new file with mode: 0644]
usr/src/contrib/X11R5-lib/lib/X/Xsi/XOpenIM.c [new file with mode: 0644]

diff --git a/usr/src/contrib/X11R5-lib/lib/X/XcmsInt.c b/usr/src/contrib/X11R5-lib/lib/X/XcmsInt.c
new file mode 100644 (file)
index 0000000..5fab739
--- /dev/null
@@ -0,0 +1,421 @@
+/* $XConsortium: XcmsInt.c,v 1.9 92/01/02 19:27:32 rws Exp $" */
+
+/*
+ * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
+ *     All Rights Reserved
+ * 
+ * This file is a component of an X Window System-specific implementation
+ * of Xcms based on the TekColor Color Management System.  Permission is
+ * hereby granted to use, copy, modify, sell, and otherwise distribute this
+ * software and its documentation for any purpose and without fee, provided
+ * that this copyright, permission, and disclaimer notice is reproduced in
+ * all copies of this software and in supporting documentation.  TekColor
+ * is a trademark of Tektronix, Inc.
+ * 
+ * Tektronix makes no representation about the suitability of this software
+ * for any purpose.  It is provided "as is" and with all faults.
+ * 
+ * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
+ * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
+ *
+ *
+ *     NAME
+ *             XcmsInt.c - Xcms API utility routines
+ *
+ *     DESCRIPTION
+ *             Xcms Application Program Interface (API) utility
+ *             routines for hanging information directly onto
+ *             the Display structure.
+ *
+ *
+ */
+
+
+/* #define NEED_EVENTS */
+#include <stdio.h>
+#include "Xlibint.h"
+#include "Xcmsint.h"
+
+#ifndef XCMSCOMPPROC
+#  define XCMSCOMPPROC XcmsTekHVCClipC
+#endif
+
+/*
+ *      EXTERNS
+ */
+extern XcmsColorSpace **_XcmsDIColorSpaces;
+extern XcmsFunctionSet **_XcmsSCCFuncSets;
+
+static void _XcmsFreeDefaultCCCs();
+
+/*
+ *      GLOBALS
+ */
+
+
+\f
+/************************************************************************
+ *                                                                     *
+ *                        API PRIVATE ROUTINES                         *
+ *                                                                     *
+ ************************************************************************/
+
+/*
+ *     NAME
+ *             _XcmsCopyPointerArray
+ *
+ *     SYNOPSIS
+ */
+XPointer *
+_XcmsCopyPointerArray(pap)
+    XPointer *pap;
+/*
+ *     DESCRIPTION
+ *             Copies an array of NULL terminated pointers.
+ *
+ *     RETURNS
+ *             Returns NULL if failed; otherwise the address to
+ *             the copy.
+ *
+ */
+{
+    XPointer *newArray;
+    char **tmp;
+    int n;
+
+    for (tmp = pap, n = 0; *tmp != NULL; tmp++, n++);
+    n++; /* add 1 to include the NULL pointer */
+
+    if (newArray = (XPointer *)Xmalloc(n * sizeof(XPointer))) {
+       bcopy((char *)pap, (char *)newArray, (unsigned)(n * sizeof(XPointer)));
+    }
+    return((XPointer *)newArray);
+}
+
+/*
+ *     NAME
+ *             _XcmsFreePointerArray
+ *
+ *     SYNOPSIS
+ */
+void
+_XcmsFreePointerArray(pap)
+    XPointer *pap;
+/*
+ *     DESCRIPTION
+ *             Frees an array of NULL terminated pointers.
+ *
+ *     RETURNS
+ *             void
+ *
+ */
+{
+    Xfree(pap);
+}
+
+/*
+ *     NAME
+ *             _XcmsPushPointerArray
+ *
+ *     SYNOPSIS
+ */
+XPointer *
+_XcmsPushPointerArray(pap, p, papNoFree)
+    XPointer *pap;
+    XPointer p;
+    XPointer *papNoFree;
+/*
+ *     DESCRIPTION
+ *             Places the specified pointer at the head of an array of NULL
+ *             terminated pointers.
+ *
+ *     RETURNS
+ *             Returns NULL if failed; otherwise the address to
+ *             the head of the array.
+ *
+ */
+{
+    XPointer *newArray;
+    char **tmp;
+    int n;
+
+    for (tmp = pap, n = 0; *tmp != NULL; tmp++, n++);
+
+    /* add 2: 1 for the new pointer and another for the NULL pointer */
+    n += 2;
+
+    if (newArray = (XPointer *)Xmalloc(n * sizeof(XPointer))) {
+       bcopy((char *)pap, (char *)(newArray+1),
+               (unsigned)((n-1) * sizeof(XPointer)));
+       *newArray = p;
+    }
+    if (pap != papNoFree) {
+        _XcmsFreePointerArray(pap);
+    }
+    return((XPointer *)newArray);
+}
+
+/*
+ *     NAME
+ *             _XcmsInitDefaultCCCs
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsInitDefaultCCCs(dpy)
+    Display *dpy;
+/*
+ *     DESCRIPTION
+ *             Initializes the Xcms per Display Info structure
+ *             (XcmsPerDpyInfo).
+ *
+ *     RETURNS
+ *             Returns 0 if failed; otherwise non-zero.
+ *
+ */
+{
+    int nScrn = ScreenCount(dpy);
+    int i;
+    XcmsCCC ccc;
+
+    if (nScrn <= 0) {
+       return(0);
+    }
+
+    /*
+     * Create an array of XcmsCCC structures, one for each screen.
+     * They serve as the screen's default CCC.
+     */
+    if (!(ccc = (XcmsCCC)
+           Xcalloc((unsigned)nScrn, (unsigned) sizeof(XcmsCCCRec)))) {
+       return(0);
+    } 
+    dpy->cms.defaultCCCs = (XPointer)ccc;
+    dpy->free_funcs->defaultCCCs = _XcmsFreeDefaultCCCs;
+
+    for (i = 0; i < nScrn; i++, ccc++) {
+       ccc->dpy = dpy;
+       ccc->screenNumber = i;
+       ccc->visual = DefaultVisual(dpy, i);
+       /*
+        * Used calloc to allocate memory so:
+        *      ccc->clientWhitePt->format == XcmsUndefinedFormat
+        *      ccc->gamutCompProc == NULL
+        *      ccc->whitePtAdjProc == NULL
+        *      ccc->pPerScrnInfo = NULL
+        *
+        * Don't need to create XcmsPerScrnInfo and its functionSet and
+        * pScreenData components until the default CCC is accessed.
+        * Note that the XcmsDefaultCCC routine calls _XcmsInitScrnInto
+        * to do this.
+        */
+       ccc->gamutCompProc = XCMSCOMPPROC;
+    }
+
+    return(1);
+}
+
+\f
+/*
+ *     NAME
+ *             _XcmsFreeDefaultCCCs - Free Default CCCs and its PerScrnInfo
+ *
+ *     SYNOPSIS
+ */
+static void
+_XcmsFreeDefaultCCCs(dpy)
+    Display *dpy;
+/*
+ *     DESCRIPTION
+ *             This routine frees the default XcmsCCC's associated with
+ *             each screen and its associated substructures as neccessary.
+ *
+ *     RETURNS
+ *             void
+ *
+ *
+ */
+{
+    int nScrn = ScreenCount(dpy);
+    XcmsCCC ccc;
+    int i;
+
+    /*
+     * Free Screen data in each DefaultCCC
+     *         Do not use XcmsFreeCCC here because it will not free
+     *         DefaultCCC's.
+     */
+    ccc = (XcmsCCC)dpy->cms.defaultCCCs;
+    for (i = nScrn; i--; ccc++) {
+       /*
+        * Check if XcmsPerScrnInfo exists.
+        *
+        * This is the only place where XcmsPerScrnInfo structures
+        * are freed since there is only one allocated per Screen.
+        * It just so happens that we place its reference in the
+        * default CCC.
+        */
+       if (ccc->pPerScrnInfo) {
+           /* Check if SCCData exists */
+           if ((ccc->pPerScrnInfo->state == XcmsInitSuccess ||
+                   ccc->pPerScrnInfo->state == XcmsInitDefault)
+                   && ccc->pPerScrnInfo->screenData) {
+               (*((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->screenFreeProc)
+                       (ccc->pPerScrnInfo->screenData);
+           }
+           Xfree(ccc->pPerScrnInfo);
+       }
+    }
+
+    /*
+     * Free the array of XcmsCCC structures
+     */
+    Xfree(dpy->cms.defaultCCCs);
+    dpy->cms.defaultCCCs = (XPointer)NULL;
+}
+
+
+\f
+/*
+ *     NAME
+ *             _XcmsInitScrnInfo
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsInitScrnInfo(dpy, screenNumber)
+    register Display *dpy;
+    int screenNumber;
+/*
+ *     DESCRIPTION
+ *             Given a display and screen number, this routine attempts
+ *             to initialize the Xcms per Screen Info structure
+ *             (XcmsPerScrnInfo).
+ *
+ *     RETURNS
+ *             Returns zero if initialization failed; non-zero otherwise.
+ */
+{
+    XcmsFunctionSet **papSCCFuncSet = _XcmsSCCFuncSets;
+    XcmsCCC defaultccc;
+
+    /*
+     * Check if the XcmsCCC's for each screen has been created.
+     * Really dont need to be created until some routine uses the Xcms
+     * API routines.
+     */
+    if ((XcmsCCC)dpy->cms.defaultCCCs == NULL) {
+       if (!_XcmsInitDefaultCCCs(dpy)) {
+           return(0);
+       }
+    }
+
+    defaultccc = (XcmsCCC)dpy->cms.defaultCCCs + screenNumber;
+
+    /*
+     * For each SCCFuncSet, try its pInitScrnFunc.
+     * If the function succeeds, then we got it!
+     */
+
+    if (!defaultccc->pPerScrnInfo) {
+       /*
+        * This is one of two places where XcmsPerScrnInfo structures
+        * are allocated.  There is one allocated per Screen that is
+        * shared among visuals that do not have specific intensity
+        * tables.  Other XcmsPerScrnInfo structures are created
+        * for the latter (see XcmsCreateCCC).  The ones created
+        * here are referenced by the default CCC.
+        */
+       if (!(defaultccc->pPerScrnInfo = (XcmsPerScrnInfo *)
+               Xcalloc(1, (unsigned) sizeof(XcmsPerScrnInfo)))) {
+           return(0);
+       } 
+       defaultccc->pPerScrnInfo->state = XcmsInitNone;
+    }
+
+    while (*papSCCFuncSet != NULL) {
+       if ((*(*papSCCFuncSet)->screenInitProc)(dpy, screenNumber,
+               defaultccc->pPerScrnInfo)) {
+           defaultccc->pPerScrnInfo->state = XcmsInitSuccess;
+           return(1);
+       }
+       papSCCFuncSet++;
+    }
+
+    /*
+     * Use Default SCCData
+     */
+    return(_XcmsLRGB_InitScrnDefault(dpy, screenNumber, defaultccc->pPerScrnInfo));
+}
+
+\f
+/*
+ *     NAME
+ *             _XcmsFreeIntensityMaps
+ *
+ *     SYNOPSIS
+ */
+void
+_XcmsFreeIntensityMaps(dpy)
+    Display *dpy;
+/*
+ *     DESCRIPTION
+ *             Frees all XcmsIntensityMap structures in the linked list
+ *             and sets dpy->cms.perVisualIntensityMaps to NULL.
+ *
+ *     RETURNS
+ *             void
+ *
+ */
+{
+    XcmsIntensityMap *pNext, *pFree;
+
+    pNext = (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
+    while (pNext != NULL) {
+       pFree = pNext;
+       pNext = pNext->pNext;
+       (*pFree->pFreeScreenData)(pFree->screenData);
+       /* Now free the XcmsIntensityMap structure */
+       Xfree(pFree);
+    }
+    dpy->cms.perVisualIntensityMaps = (XPointer)NULL;
+}
+
+\f
+/*
+ *     NAME
+ *             _XcmsGetIntensityMap
+ *
+ *     SYNOPSIS
+ */
+XcmsIntensityMap *
+_XcmsGetIntensityMap(dpy, visual)
+    Display *dpy;
+    Visual *visual;
+/*
+ *     DESCRIPTION
+ *             Attempts to return a per-Visual intensity map.
+ *
+ *     RETURNS
+ *             Pointer to the XcmsIntensityMap structure if found;
+ *             otherwise NULL
+ *
+ */
+{
+    VisualID targetID = visual->visualid;
+    XcmsIntensityMap *pNext;
+
+    pNext = (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
+    while (pNext != NULL) {
+       if (targetID == pNext->visualID) {
+           return(pNext);
+       }
+       pNext = pNext->pNext;
+    }
+    return((XcmsIntensityMap *)NULL);
+}
diff --git a/usr/src/contrib/X11R5-lib/lib/X/XcmsLRGB.c b/usr/src/contrib/X11R5-lib/lib/X/XcmsLRGB.c
new file mode 100644 (file)
index 0000000..7cdec78
--- /dev/null
@@ -0,0 +1,1811 @@
+/* $XConsortium: XcmsLRGB.c,v 1.22 92/01/02 19:28:13 rws Exp $" */
+
+/*
+ * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
+ *     All Rights Reserved
+ * 
+ * This file is a component of an X Window System-specific implementation
+ * of Xcms based on the TekColor Color Management System.  Permission is
+ * hereby granted to use, copy, modify, sell, and otherwise distribute this
+ * software and its documentation for any purpose and without fee, provided
+ * that this copyright, permission, and disclaimer notice is reproduced in
+ * all copies of this software and in supporting documentation.  TekColor
+ * is a trademark of Tektronix, Inc.
+ * 
+ * Tektronix makes no representation about the suitability of this software
+ * for any purpose.  It is provided "as is" and with all faults.
+ * 
+ * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
+ * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
+ *
+ *
+ *     NAME
+ *             XcmsLRGB.c
+ *
+ *     DESCRIPTION
+ *             This file contains the conversion routines:
+ *                 1. CIE XYZ to RGB intensity
+ *                 2. RGB intensity to device RGB
+ *                 3. device RGB to RGB intensity
+ *                 4. RGB intensity to CIE XYZ
+ *
+ */
+
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xcmsint.h"
+
+#if __STDC__
+#define Const const
+#else
+#define Const /**/
+#endif
+
+/*
+ *      EXTERNS
+ *              External declarations required locally to this package
+ *              that are not already declared in any of the included header
+ *             files (external includes or internal includes).
+ */
+extern char XcmsRGB_prefix[];
+extern char XcmsRGBi_prefix[];
+extern unsigned long _XcmsGetElement();
+extern void _XcmsFreeIntensityMaps();
+
+
+/*
+ *      LOCAL DEFINES
+ *             #define declarations local to this package.
+ */
+#define EPS    0.001
+#ifndef MIN
+#define MIN(x,y) ((x) > (y) ? (y) : (x))
+#endif /* MIN */
+#ifndef MAX
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#endif /* MAX */
+#ifndef MIN3
+#define MIN3(x,y,z) (MIN(x, MIN(y, z)))
+#endif /* MIN3 */
+#ifndef MAX3
+#define MAX3(x,y,z) (MAX(x, MAX(y, z)))
+#endif /* MAX3 */
+
+/*
+ *      LOCAL TYPEDEFS
+ *              typedefs local to this package (for use with local vars).
+ *
+ */
+
+/*
+ *      FORWARD DECLARATIONS
+ */
+static void LINEAR_RGB_FreeSCCData();
+static int LINEAR_RGB_InitSCCData();
+int XcmsLRGB_RGB_ParseString();
+int XcmsLRGB_RGBi_ParseString();
+Status _XcmsGetTableType0();
+Status _XcmsGetTableType1();
+
+/*
+ *      LOCALS VARIABLES
+ *             Variables local to this package.
+ *                 Usage example:
+ *                     static int      ExampleLocalVar;
+ */
+
+static unsigned short Const MASK[17] = {
+    0x0000,    /*  0 bitsPerRGB */
+    0x8000,    /*  1 bitsPerRGB */
+    0xc000,    /*  2 bitsPerRGB */
+    0xe000,    /*  3 bitsPerRGB */
+    0xf000,    /*  4 bitsPerRGB */
+    0xf800,    /*  5 bitsPerRGB */
+    0xfc00,    /*  6 bitsPerRGB */
+    0xfe00,    /*  7 bitsPerRGB */
+    0xff00,    /*  8 bitsPerRGB */
+    0xff80,    /*  9 bitsPerRGB */
+    0xffc0,    /* 10 bitsPerRGB */
+    0xffe0,    /* 11 bitsPerRGB */
+    0xfff0,    /* 12 bitsPerRGB */
+    0xfff8,    /* 13 bitsPerRGB */
+    0xfffc,    /* 14 bitsPerRGB */
+    0xfffe,    /* 15 bitsPerRGB */
+    0xffff     /* 16 bitsPerRGB */
+};
+
+
+    /*
+     * A NULL terminated array of function pointers that when applied
+     * in series will convert an XcmsColor structure from XcmsRGBFormat
+     * to XcmsCIEXYZFormat.
+     */
+static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
+    XcmsRGBToRGBi,
+    XcmsRGBiToCIEXYZ,
+    NULL
+};
+
+    /*
+     * A NULL terminated array of function pointers that when applied
+     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
+     * to XcmsRGBFormat.
+     */
+static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
+    XcmsCIEXYZToRGBi,
+    XcmsRGBiToRGB,
+    NULL
+};
+
+    /*
+     * A NULL terminated array of function pointers that when applied
+     * in series will convert an XcmsColor structure from XcmsRGBiFormat
+     * to XcmsCIEXYZFormat.
+     */
+static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
+    XcmsRGBiToCIEXYZ,
+    NULL
+};
+
+    /*
+     * A NULL terminated array of function pointers that when applied
+     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
+     * to XcmsRGBiFormat.
+     */
+static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
+    XcmsCIEXYZToRGBi,
+    NULL
+};
+
+    /*
+     * RGBi Color Spaces
+     */
+XcmsColorSpace XcmsRGBiColorSpace =
+    {
+       XcmsRGBi_prefix,        /* prefix */
+       XcmsRGBiFormat,         /* id */
+       XcmsLRGB_RGBi_ParseString,      /* parseString */
+       Fl_RGBi_to_CIEXYZ,      /* to_CIEXYZ */
+       Fl_CIEXYZ_to_RGBi,      /* from_CIEXYZ */
+       1
+    };
+
+    /*
+     * RGB Color Spaces
+     */
+XcmsColorSpace XcmsRGBColorSpace =
+    {
+       XcmsRGB_prefix,         /* prefix */
+       XcmsRGBFormat,          /* id */
+       XcmsLRGB_RGB_ParseString,       /* parseString */
+       Fl_RGB_to_CIEXYZ,       /* to_CIEXYZ */
+       Fl_CIEXYZ_to_RGB,       /* from_CIEXYZ */
+       1
+    };
+
+    /*
+     * Device-Independent Color Spaces known to the 
+     * LINEAR_RGB Screen Color Characteristics Function Set.
+     */
+static XcmsColorSpace  *DDColorSpaces[] = {
+    &XcmsRGBColorSpace,
+    &XcmsRGBiColorSpace,
+    NULL
+};
+
+
+/*
+ *      GLOBALS
+ *              Variables declared in this package that are allowed
+ *             to be used globally.
+ */
+
+    /*
+     * LINEAR_RGB Screen Color Characteristics Function Set.
+     */
+XcmsFunctionSet        XcmsLinearRGBFunctionSet =
+    {
+       &DDColorSpaces[0],      /* pDDColorSpaces */
+       LINEAR_RGB_InitSCCData, /* pInitScrnFunc */
+       LINEAR_RGB_FreeSCCData  /* pFreeSCCData */
+    };
+
+/*
+ *     DESCRIPTION
+ *             Contents of Default SCCData should be replaced if other
+ *             data should be used as default.
+ *
+ *
+ */
+
+/*
+ * NAME                Tektronix 19" (Sony) CRT
+ * PART_NUMBER         119-2451-00
+ * MODEL               Tek4300, Tek4800
+ */
+
+static IntensityRec Const Default_RGB_RedTuples[] = {
+    /* {unsigned short value, XcmsFloat intensity} */
+            0x0000,    0.000000,
+            0x0909,    0.000000,
+            0x0a0a,    0.000936,
+            0x0f0f,    0.001481,
+            0x1414,    0.002329,
+            0x1919,    0.003529,
+            0x1e1e,    0.005127,
+            0x2323,    0.007169,
+            0x2828,    0.009699,
+            0x2d2d,    0.012759,
+            0x3232,    0.016392,
+            0x3737,    0.020637,
+            0x3c3c,    0.025533,
+            0x4141,    0.031119,
+            0x4646,    0.037431,
+            0x4b4b,    0.044504,
+            0x5050,    0.052373,
+            0x5555,    0.061069,
+            0x5a5a,    0.070624,
+            0x5f5f,    0.081070,
+            0x6464,    0.092433,
+            0x6969,    0.104744,
+            0x6e6e,    0.118026,
+            0x7373,    0.132307,
+            0x7878,    0.147610,
+            0x7d7d,    0.163958,
+            0x8282,    0.181371,
+            0x8787,    0.199871,
+            0x8c8c,    0.219475,
+            0x9191,    0.240202,
+            0x9696,    0.262069,
+            0x9b9b,    0.285089,
+            0xa0a0,    0.309278,
+            0xa5a5,    0.334647,
+            0xaaaa,    0.361208,
+            0xafaf,    0.388971,
+            0xb4b4,    0.417945,
+            0xb9b9,    0.448138,
+            0xbebe,    0.479555,
+            0xc3c3,    0.512202,
+            0xc8c8,    0.546082,
+            0xcdcd,    0.581199,
+            0xd2d2,    0.617552,
+            0xd7d7,    0.655144,
+            0xdcdc,    0.693971,
+            0xe1e1,    0.734031,
+            0xe6e6,    0.775322,
+            0xebeb,    0.817837,
+            0xf0f0,    0.861571,
+            0xf5f5,    0.906515,
+            0xfafa,    0.952662,
+            0xffff,    1.000000
+};
+
+static IntensityRec Const Default_RGB_GreenTuples[] = {
+    /* {unsigned short value, XcmsFloat intensity} */
+            0x0000,    0.000000,
+            0x1313,    0.000000,
+            0x1414,    0.000832,
+            0x1919,    0.001998,
+            0x1e1e,    0.003612,
+            0x2323,    0.005736,
+            0x2828,    0.008428,
+            0x2d2d,    0.011745,
+            0x3232,    0.015740,
+            0x3737,    0.020463,
+            0x3c3c,    0.025960,
+            0x4141,    0.032275,
+            0x4646,    0.039449,
+            0x4b4b,    0.047519,
+            0x5050,    0.056520,
+            0x5555,    0.066484,
+            0x5a5a,    0.077439,
+            0x5f5f,    0.089409,
+            0x6464,    0.102418,
+            0x6969,    0.116485,
+            0x6e6e,    0.131625,
+            0x7373,    0.147853,
+            0x7878,    0.165176,
+            0x7d7d,    0.183604,
+            0x8282,    0.203140,
+            0x8787,    0.223783,
+            0x8c8c,    0.245533,
+            0x9191,    0.268384,
+            0x9696,    0.292327,
+            0x9b9b,    0.317351,
+            0xa0a0,    0.343441,
+            0xa5a5,    0.370580,
+            0xaaaa,    0.398747,
+            0xafaf,    0.427919,
+            0xb4b4,    0.458068,
+            0xb9b9,    0.489165,
+            0xbebe,    0.521176,
+            0xc3c3,    0.554067,
+            0xc8c8,    0.587797,
+            0xcdcd,    0.622324,
+            0xd2d2,    0.657604,
+            0xd7d7,    0.693588,
+            0xdcdc,    0.730225,
+            0xe1e1,    0.767459,
+            0xe6e6,    0.805235,
+            0xebeb,    0.843491,
+            0xf0f0,    0.882164,
+            0xf5f5,    0.921187,
+            0xfafa,    0.960490,
+            0xffff,    1.000000
+};
+
+static IntensityRec Const Default_RGB_BlueTuples[] = {
+    /* {unsigned short value, XcmsFloat intensity} */
+            0x0000,    0.000000,
+            0x0e0e,    0.000000,
+            0x0f0f,    0.001341,
+            0x1414,    0.002080,
+            0x1919,    0.003188,
+            0x1e1e,    0.004729,
+            0x2323,    0.006766,
+            0x2828,    0.009357,
+            0x2d2d,    0.012559,
+            0x3232,    0.016424,
+            0x3737,    0.021004,
+            0x3c3c,    0.026344,
+            0x4141,    0.032489,
+            0x4646,    0.039481,
+            0x4b4b,    0.047357,
+            0x5050,    0.056154,
+            0x5555,    0.065903,
+            0x5a5a,    0.076634,
+            0x5f5f,    0.088373,
+            0x6464,    0.101145,
+            0x6969,    0.114968,
+            0x6e6e,    0.129862,
+            0x7373,    0.145841,
+            0x7878,    0.162915,
+            0x7d7d,    0.181095,
+            0x8282,    0.200386,
+            0x8787,    0.220791,
+            0x8c8c,    0.242309,
+            0x9191,    0.264937,
+            0x9696,    0.288670,
+            0x9b9b,    0.313499,
+            0xa0a0,    0.339410,
+            0xa5a5,    0.366390,
+            0xaaaa,    0.394421,
+            0xafaf,    0.423481,
+            0xb4b4,    0.453547,
+            0xb9b9,    0.484592,
+            0xbebe,    0.516587,
+            0xc3c3,    0.549498,
+            0xc8c8,    0.583291,
+            0xcdcd,    0.617925,
+            0xd2d2,    0.653361,
+            0xd7d7,    0.689553,
+            0xdcdc,    0.726454,
+            0xe1e1,    0.764013,
+            0xe6e6,    0.802178,
+            0xebeb,    0.840891,
+            0xf0f0,    0.880093,
+            0xf5f5,    0.919723,
+            0xfafa,    0.959715,
+            0xffff,    1.00000
+};
+
+static IntensityTbl Default_RGB_RedTbl = {
+    /* IntensityRec *pBase */
+       (IntensityRec *) Default_RGB_RedTuples,
+    /* unsigned int nEntries */
+       52
+};
+
+static IntensityTbl Default_RGB_GreenTbl = {
+    /* IntensityRec *pBase */
+       (IntensityRec *)Default_RGB_GreenTuples,
+    /* unsigned int nEntries */
+       50
+};
+
+static IntensityTbl Default_RGB_BlueTbl = {
+    /* IntensityRec *pBase */
+       (IntensityRec *)Default_RGB_BlueTuples,
+    /* unsigned int nEntries */
+       51
+};
+
+static LINEAR_RGB_SCCData Default_RGB_SCCData = {
+
+    /* XcmsFloat XYZtoRGBmatrix[3][3] */
+       3.48340481253539000, -1.52176374927285200, -0.55923133354049780,
+      -1.07152751306193600,  1.96593795204372400,  0.03673691339553462,
+       0.06351179790497788, -0.20020501000496480,  0.81070942031648220,
+
+    /* XcmsFloat RGBtoXYZmatrix[3][3] */
+       0.38106149108714790, 0.32025712365352110, 0.24834578525933100,
+       0.20729745115140850, 0.68054638776373240, 0.11215616108485920,
+       0.02133944350088028, 0.14297193020246480, 1.24172892629665500,
+
+    /* IntensityTbl *pRedTbl */
+       &Default_RGB_RedTbl,
+
+    /* IntensityTbl *pGreenTbl */
+       &Default_RGB_GreenTbl,
+
+    /* IntensityTbl *pBlueTbl */
+       &Default_RGB_BlueTbl
+};
+\f
+/************************************************************************
+ *                                                                     *
+ *                     PRIVATE ROUTINES                                *
+ *                                                                     *
+ ************************************************************************/
+
+/*
+ *     NAME
+ *             LINEAR_RGB_InitSCCData()
+ *
+ *     SYNOPSIS
+ */
+static Status
+LINEAR_RGB_InitSCCData(dpy, screenNumber, pPerScrnInfo)
+    Display *dpy;
+    int screenNumber;
+    XcmsPerScrnInfo *pPerScrnInfo;
+/*
+ *     DESCRIPTION
+ *
+ *     RETURNS
+ *             XcmsFailure if failed.
+ *             XcmsSuccess if succeeded.
+ *
+ */
+{
+    Atom  CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
+    Atom  MatrixAtom  = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
+    int          format_return, count, cType, nTables;
+    unsigned long nitems, nbytes_return;
+    char *property_return, *pChar;
+    XcmsFloat *pValue;
+#ifdef ALLDEBUG
+    IntensityRec *pIRec;
+#endif /* ALLDEBUG */
+    VisualID visualID;
+
+    LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
+    XcmsIntensityMap *pNewMap;
+
+    /*
+     * Allocate memory for pScreenData
+     */
+    if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) 
+                     Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
+       return(XcmsFailure);
+    }
+
+    /* 
+     *  1. Get the XYZ->RGB and RGB->XYZ matrices
+     */
+
+    if (MatrixAtom == None ||
+       !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, 
+          &format_return, &nitems, &nbytes_return, &property_return) ||
+          nitems != 18 || format_return != 32) {
+       /*
+        * As per the XDCCC, there must be 18 data items and each must be
+        * in 32 bits !
+        */
+       goto FreeSCCData;
+
+    } else {
+
+       /*
+        * RGBtoXYZ and XYZtoRGB matrices
+        */
+       pValue = (XcmsFloat *) pScreenData;
+       pChar = property_return;
+       for (count = 0; count < 18; count++) {
+           *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
+                   &nitems) / (XcmsFloat)XDCCC_NUMBER;
+       }
+       XFree (property_return);
+       pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
+               pScreenData->RGBtoXYZmatrix[0][0] +
+               pScreenData->RGBtoXYZmatrix[0][1] +
+               pScreenData->RGBtoXYZmatrix[0][2];
+       pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
+               pScreenData->RGBtoXYZmatrix[1][0] +
+               pScreenData->RGBtoXYZmatrix[1][1] +
+               pScreenData->RGBtoXYZmatrix[1][2];
+       pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
+               pScreenData->RGBtoXYZmatrix[2][0] +
+               pScreenData->RGBtoXYZmatrix[2][1] +
+               pScreenData->RGBtoXYZmatrix[2][2];
+
+       /*
+        * Compute the Screen White Point
+        */
+       if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
+               || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
+           goto FreeSCCData;
+       } else {
+           pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
+       }
+       pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
+       pPerScrnInfo->screenWhitePt.pixel = 0;
+
+#ifdef PDEBUG
+       printf ("RGB to XYZ Matrix values:\n");
+       printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
+               pScreenData->RGBtoXYZmatrix[0][0],
+               pScreenData->RGBtoXYZmatrix[0][1],
+               pScreenData->RGBtoXYZmatrix[0][2],
+               pScreenData->RGBtoXYZmatrix[1][0],
+               pScreenData->RGBtoXYZmatrix[1][1],
+               pScreenData->RGBtoXYZmatrix[1][2],
+               pScreenData->RGBtoXYZmatrix[2][0],
+               pScreenData->RGBtoXYZmatrix[2][1],
+               pScreenData->RGBtoXYZmatrix[2][2]);
+       printf ("XYZ to RGB Matrix values:\n");
+       printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
+               pScreenData->XYZtoRGBmatrix[0][0],
+               pScreenData->XYZtoRGBmatrix[0][1],
+               pScreenData->XYZtoRGBmatrix[0][2],
+               pScreenData->XYZtoRGBmatrix[1][0],
+               pScreenData->XYZtoRGBmatrix[1][1],
+               pScreenData->XYZtoRGBmatrix[1][2],
+               pScreenData->XYZtoRGBmatrix[2][0],
+               pScreenData->XYZtoRGBmatrix[2][1],
+               pScreenData->XYZtoRGBmatrix[2][2]);
+       printf ("Screen White Pt value: %f %f %f\n",
+               pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
+               pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
+               pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
+#endif /* PDEBUG */
+    }
+
+    /*
+     * 2. Get the Intensity Profile
+     */
+    if (CorrectAtom == None ||
+       !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
+          &format_return, &nitems, &nbytes_return, &property_return)) {
+       XFree (property_return);
+       goto FreeSCCData;
+    }
+
+    pChar = property_return;
+
+    while (nitems) {
+       switch (format_return) {
+         case 8:
+           /*
+            * Must have at least:
+            *          VisualID0
+            *          VisualID1
+            *          VisualID2
+            *          VisualID3
+            *          type
+            *          count
+            *          length
+            *          intensity1
+            *          intensity2
+            */
+           if (nitems < 9) {
+               XFree (property_return);
+               goto FreeSCCData;
+           }
+           count = 3;
+           break;
+         case 16:
+           /*
+            * Must have at least:
+            *          VisualID0
+            *          VisualID3
+            *          type
+            *          count
+            *          length
+            *          intensity1
+            *          intensity2
+            */
+           if (nitems < 7) {
+               XFree (property_return);
+               goto FreeSCCData;
+           }
+           count = 1;
+           break;
+         case 32:
+           /*
+            * Must have at least:
+            *          VisualID0
+            *          type
+            *          count
+            *          length
+            *          intensity1
+            *          intensity2
+            */
+           if (nitems < 6) {
+               XFree (property_return);
+               goto FreeSCCData;
+           }
+           count = 0;
+           break;
+         default:
+           XFree (property_return);
+           goto FreeSCCData;
+       }
+
+       /*
+        * Get VisualID
+        */
+       visualID = _XcmsGetElement(format_return, &pChar, &nitems);
+       while (count--) {
+           visualID = visualID << format_return;
+           visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
+       }
+
+       if (visualID == 0) {
+           /*
+            * This is a shared intensity table
+            */
+           pScreenData = pScreenDefaultData;
+       } else {
+           /*
+            * This is a per-Visual intensity table
+            */
+           if (!(pScreenData = (LINEAR_RGB_SCCData *) 
+                             Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
+               return(XcmsFailure);
+           }
+           /* copy matrices */
+           bcopy((char *)pScreenDefaultData, (char *)pScreenData,
+                   18 * sizeof(XcmsFloat));
+
+           /* Create, initialize, and add map */
+           if (!(pNewMap = (XcmsIntensityMap *) 
+                             Xcalloc (1, sizeof(XcmsIntensityMap)))) {
+               Xfree(pScreenData);
+               return(XcmsFailure);
+           }
+           pNewMap->visualID = visualID;
+           pNewMap->screenData = (XPointer)pScreenData;
+           pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
+           pNewMap->pNext =
+                   (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
+           dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
+           dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
+       }
+
+       cType = _XcmsGetElement(format_return, &pChar, &nitems);
+       nTables = _XcmsGetElement(format_return, &pChar, &nitems);
+
+       if (cType == 0) {
+
+           /* Red Intensity Table */
+           if (!(pScreenData->pRedTbl = (IntensityTbl *)
+                   Xcalloc (1, sizeof(IntensityTbl)))) {
+               goto FreeSCCData;
+           }
+           if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
+                   &nitems) == XcmsFailure) {
+               goto FreeRedTbl;
+           }
+
+           if (nTables == 1) {
+               /* Green Intensity Table */
+               pScreenData->pGreenTbl = pScreenData->pRedTbl;
+               /* Blue Intensity Table */
+               pScreenData->pBlueTbl = pScreenData->pRedTbl;
+           } else {
+               /* Green Intensity Table */
+               if (!(pScreenData->pGreenTbl = (IntensityTbl *)
+                       Xcalloc (1, sizeof(IntensityTbl)))) {
+                   goto FreeRedTblElements;
+               }
+               if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
+                       &nitems) == XcmsFailure) {
+                   goto FreeGreenTbl;
+               }
+
+               /* Blue Intensity Table */
+               if (!(pScreenData->pBlueTbl = (IntensityTbl *)
+                       Xcalloc (1, sizeof(IntensityTbl)))) {
+                   goto FreeGreenTblElements;
+               }
+               if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
+                       &nitems) == XcmsFailure) {
+                   goto FreeBlueTbl;
+               }
+           }       
+       } else if (cType == 1) {
+           /* Red Intensity Table */
+           if (!(pScreenData->pRedTbl = (IntensityTbl *)
+                   Xcalloc (1, sizeof(IntensityTbl)))) {
+               goto FreeSCCData;
+           }
+           if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
+                   &nitems) == XcmsFailure) {
+               goto FreeRedTbl;
+           }
+
+           if (nTables == 1) {
+
+               /* Green Intensity Table */
+               pScreenData->pGreenTbl = pScreenData->pRedTbl;
+               /* Blue Intensity Table */
+               pScreenData->pBlueTbl = pScreenData->pRedTbl;
+
+           } else {
+
+               /* Green Intensity Table */
+               if (!(pScreenData->pGreenTbl = (IntensityTbl *)
+                       Xcalloc (1, sizeof(IntensityTbl)))) {
+                   goto FreeRedTblElements;
+               }
+               if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
+                       &nitems) == XcmsFailure) {
+                   goto FreeGreenTbl;
+               }
+
+               /* Blue Intensity Table */
+               if (!(pScreenData->pBlueTbl = (IntensityTbl *)
+                       Xcalloc (1, sizeof(IntensityTbl)))) {
+                   goto FreeBlueTblElements;
+               }
+               if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
+                       &nitems) == XcmsFailure) {
+                   goto FreeBlueTbl;
+               }
+           }
+       } else {
+           XFree (property_return);
+           goto FreeSCCData;
+       }
+
+#ifdef ALLDEBUG
+       printf ("Intensity Table  RED    %d\n", pScreenData->pRedTbl->nEntries);
+       pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
+       for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
+           printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+       }
+       if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
+           printf ("Intensity Table  GREEN  %d\n", pScreenData->pGreenTbl->nEntries);
+           pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
+           for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
+               printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+           }
+       }
+       if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
+           printf ("Intensity Table  BLUE   %d\n", pScreenData->pBlueTbl->nEntries);
+           pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
+           for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
+               printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+           }
+       }
+#endif /* ALLDEBUG */
+    }
+
+    XFree (property_return);
+
+    /* Free the old memory and use the new structure created. */
+    LINEAR_RGB_FreeSCCData((LINEAR_RGB_SCCData *) pPerScrnInfo->screenData);
+
+    pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
+
+    pPerScrnInfo->screenData = (XPointer) pScreenData;
+
+    pPerScrnInfo->state = XcmsInitSuccess;
+
+    return(XcmsSuccess);
+
+FreeBlueTblElements:
+    free(pScreenData->pBlueTbl->pBase);
+
+FreeBlueTbl:
+    free(pScreenData->pBlueTbl);
+
+FreeGreenTblElements:
+    free(pScreenData->pBlueTbl->pBase);
+
+FreeGreenTbl:
+    free(pScreenData->pGreenTbl);
+
+FreeRedTblElements:
+    free(pScreenData->pRedTbl->pBase);
+
+FreeRedTbl:
+    free(pScreenData->pRedTbl);
+
+FreeSCCData:
+    free(pScreenData);
+    pPerScrnInfo->state = XcmsInitNone;
+    return(XcmsFailure);
+}
+
+\f
+/*
+ *     NAME
+ *             LINEAR_RGB_FreeSCCData()
+ *
+ *     SYNOPSIS
+ */
+static void
+LINEAR_RGB_FreeSCCData(pScreenDataTemp)
+    XPointer pScreenDataTemp;
+/*
+ *     DESCRIPTION
+ *
+ *     RETURNS
+ *             0 if failed.
+ *             1 if succeeded with no modifications.
+ *
+ */
+{
+    LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
+
+    if (pScreenData && pScreenData != &Default_RGB_SCCData) {
+       if (pScreenData->pRedTbl) {
+           if (pScreenData->pGreenTbl) {
+               if (pScreenData->pRedTbl->pBase != 
+                   pScreenData->pGreenTbl->pBase) {
+                   if (pScreenData->pGreenTbl->pBase) {
+                       free (pScreenData->pGreenTbl->pBase);
+                   }
+               }
+               if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
+                   free (pScreenData->pGreenTbl);
+               }
+           }
+           if (pScreenData->pBlueTbl) {
+               if (pScreenData->pRedTbl->pBase != 
+                   pScreenData->pBlueTbl->pBase) {
+                   if (pScreenData->pBlueTbl->pBase) {
+                       free (pScreenData->pBlueTbl->pBase);
+                   }
+               }
+               if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
+                   free (pScreenData->pBlueTbl);
+               }
+           }
+           if (pScreenData->pRedTbl->pBase) {
+               free (pScreenData->pRedTbl->pBase);
+           }
+           free (pScreenData->pRedTbl);
+       }
+       free (pScreenData);
+    }
+}
+
+
+\f
+/************************************************************************
+ *                                                                     *
+ *                     API PRIVATE ROUTINES                            *
+ *                                                                     *
+ ************************************************************************/
+
+/*
+ *     NAME
+ *             _XcmsGetTableType0
+ *
+ *     SYNOPSIS
+ */
+Status
+_XcmsGetTableType0(pTbl, format, pChar, pCount)
+    IntensityTbl *pTbl;
+    int          format;
+    char **pChar;
+    unsigned long *pCount;
+/*
+ *     DESCRIPTION
+ *
+ *     RETURNS
+ *             XcmsFailure if failed.
+ *             XcmsSuccess if succeeded.
+ *
+ */
+{
+    unsigned int nElements;
+    IntensityRec *pIRec;
+
+    nElements = pTbl->nEntries =
+           _XcmsGetElement(format, pChar, pCount) + 1;
+    if (!(pIRec = pTbl->pBase = (IntensityRec *)
+         Xcalloc (nElements, sizeof(IntensityRec)))) {
+       return(XcmsFailure);
+    }
+
+    switch (format) {
+      case 8: 
+       for (; nElements--; pIRec++) {
+           /* 0xFFFF/0xFF = 0x101 */
+           pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
+           pIRec->intensity =
+                   _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
+       }
+       break;
+      case 16: 
+       for (; nElements--; pIRec++) {
+           pIRec->value = _XcmsGetElement (format, pChar, pCount);
+           pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+                   / (XcmsFloat)65535.0;
+       }
+       break;
+      case 32: 
+       for (; nElements--; pIRec++) {
+           pIRec->value = _XcmsGetElement (format, pChar, pCount);
+           pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+                   / (XcmsFloat)4294967295.0;
+       }
+       break;
+      default:
+       return(XcmsFailure);
+    }
+    return(XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             _XcmsGetTableType1
+ *
+ *     SYNOPSIS
+ */
+Status
+_XcmsGetTableType1(pTbl, format, pChar, pCount)
+    IntensityTbl *pTbl;
+    int          format;
+    char **pChar;
+    unsigned long *pCount;
+/*
+ *     DESCRIPTION
+ *
+ *     RETURNS
+ *             XcmsFailure if failed.
+ *             XcmsSuccess if succeeded.
+ *
+ */
+{
+    int count;
+    unsigned int max_index;
+    IntensityRec *pIRec;
+
+    max_index = _XcmsGetElement(format, pChar, pCount);
+    pTbl->nEntries = max_index + 1;
+    if (!(pIRec = pTbl->pBase = (IntensityRec *)
+         Xcalloc (max_index+1, sizeof(IntensityRec)))) {
+       return(XcmsFailure);
+    }
+
+    switch (format) {
+      case 8: 
+       for (count = 0; count < max_index+1; count++, pIRec++) {
+           pIRec->value = (count * 65535) / max_index;
+           pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+                   / (XcmsFloat)255.0;
+       }
+       break;
+      case 16: 
+       for (count = 0; count < max_index+1; count++, pIRec++) {
+           pIRec->value = (count * 65535) / max_index;
+           pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+                   / (XcmsFloat)65535.0;
+       }
+       break;
+      case 32: 
+       for (count = 0; count < max_index+1; count++, pIRec++) {
+           pIRec->value = (count * 65535) / max_index;
+           pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+                   / (XcmsFloat)4294967295.0;
+       }
+       break;
+      default:
+       return(XcmsFailure);
+    }
+
+    return(XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             ValueCmp
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsValueCmp (p1, p2)
+    IntensityRec *p1, *p2;
+/*
+ *     DESCRIPTION
+ *             Compares the value component of two IntensityRec
+ *             structures.
+ *
+ *     RETURNS
+ *             0 if p1->value is equal to p2->value
+ *             < 0 if p1->value is less than p2->value
+ *             > 0 if p1->value is greater than p2->value
+ *
+ */
+{
+    return (p1->value - p2->value);
+}
+
+\f
+/*
+ *     NAME
+ *             IntensityCmp
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsIntensityCmp (p1, p2)
+    IntensityRec *p1, *p2;
+/*
+ *     DESCRIPTION
+ *             Compares the intensity component of two IntensityRec
+ *             structures.
+ *
+ *     RETURNS
+ *             0 if equal;
+ *             < 0 if first precedes second
+ *             > 0 if first succeeds second
+ *
+ */
+{
+    if (p1->intensity < p2->intensity) {
+       return (-1);
+    }
+    if (p1->intensity > p2->intensity) {
+       return (XcmsSuccess);
+    }
+    return (XcmsFailure);
+}
+\f
+/*
+ *     NAME
+ *             ValueInterpolation
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+int
+_XcmsValueInterpolation (key, lo, hi, answer, bitsPerRGB)
+    IntensityRec *key, *lo, *hi, *answer;
+    int bitsPerRGB;
+/*
+ *     DESCRIPTION
+ *             Based on a given value, performs a linear interpolation
+ *             on the intensities between two IntensityRec structures.
+ *             Note that the bitsPerRGB parameter is ignored.
+ *
+ *     RETURNS
+ *             Returns 0 if failed; otherwise non-zero.
+ */
+{
+    XcmsFloat ratio;
+
+    ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / 
+       ((XcmsFloat)hi->value - (XcmsFloat)lo->value);
+    answer->value = key->value;
+    answer->intensity = (hi->intensity - lo->intensity) * ratio;
+    answer->intensity += lo->intensity;
+    return (XcmsSuccess);
+}
+\f
+/*
+ *     NAME
+ *             IntensityInterpolation
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsIntensityInterpolation (key, lo, hi, answer, bitsPerRGB)
+    IntensityRec *key, *lo, *hi, *answer;
+    int bitsPerRGB;
+/*
+ *     DESCRIPTION
+ *             Based on a given intensity, performs a linear interpolation
+ *             on the values between two IntensityRec structures.
+ *             The bitsPerRGB parameter is necessary to perform rounding
+ *             to the correct number of significant bits.
+ *
+ *     RETURNS
+ *             Returns 0 if failed; otherwise non-zero.
+ */
+{
+    XcmsFloat ratio;
+    long target, up, down;
+    int shift = 16 - bitsPerRGB;
+    int max_color = (1 << bitsPerRGB) - 1;
+
+    ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
+    answer->intensity = key->intensity;
+    target = hi->value - lo->value;
+    target *= ratio;
+    target += lo->value;
+
+    /*
+     * Ok now, lets find the closest in respects to bits per RGB
+     */
+    up = ((target >> shift) * 0xFFFF) / max_color;
+    if (up < target) {
+       down = up;
+       up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
+    } else {
+       down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
+    }
+    answer->value = ((up - target) < (target - down) ? up : down);
+    answer->value &= MASK[bitsPerRGB];
+    return (XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             _XcmsTableSearch
+ *
+ *     SYNOPSIS
+ */
+int
+_XcmsTableSearch (key, bitsPerRGB, base, nel, nKeyPtrSize, compar, interpol, answer)
+    char *key;
+    int bitsPerRGB;
+    char *base;
+    unsigned nel;
+    unsigned nKeyPtrSize;
+    int (*compar)();
+    int (*interpol)();
+    char *answer;
+
+/*
+ *     DESCRIPTION
+ *             A binary search through the specificied table.
+ *
+ *     RETURNS
+ *             Returns 0 if failed; otherwise non-zero.
+ *
+ */
+{
+    char *hi, *lo, *mid, *last;
+    int result;
+
+    last = hi = base + ((nel - 1) * nKeyPtrSize);
+    mid = lo = base;
+
+    /* use only the significants bits, then scale into 16 bits */
+    ((IntensityRec *)key)->value = ((unsigned long)
+           (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
+           / ((1 << bitsPerRGB) - 1);
+
+    /* Special case so that zero intensity always maps to zero value */
+    if ((*compar) (key,lo) == 0) {
+       bcopy (lo, answer, nKeyPtrSize);
+       ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
+       return XcmsSuccess;
+    }
+    while (mid != last) {
+       last = mid;
+       mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
+       result = (*compar) (key, mid);
+       if (result == 0) {
+
+           bcopy(mid, answer, nKeyPtrSize);
+           ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
+           return (XcmsSuccess);
+       } else if (result < 0) {
+           hi = mid;
+       } else {
+           lo = mid;
+       }
+    }
+
+    /*
+     * If we got to here, we didn't find a solution, so we
+     * need to apply interpolation.
+     */
+    return ((*interpol)(key, lo, hi, answer, bitsPerRGB));
+}
+
+\f
+/*
+ *      NAME
+ *             _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
+ *
+ *     SYNOPSIS
+ */
+void _XcmsMatVec(pMat, pIn, pOut)
+    XcmsFloat *pMat, *pIn, *pOut;
+/*
+ *      DESCRIPTION
+ *             Multiply the passed vector by the passed matrix to return a 
+ *             vector. Matrix is 3x3, vectors are of length 3.
+ *
+ *     RETURNS
+ *             void
+ */
+{
+    int i, j;
+
+    for (i = 0; i < 3; i++) {
+       pOut[i] = 0.0;
+       for (j = 0; j < 3; j++)
+           pOut[i] += *(pMat+(i*3)+j) * pIn[j];
+    }
+}
+
+\f
+/************************************************************************
+ *                                                                     *
+ *                      PUBLIC ROUTINES                                *
+ *                                                                     *
+ ************************************************************************/
+
+
+/*
+ *     NAME
+ *             XcmsLRGB_RGB_ParseString
+ *
+ *     SYNOPSIS
+ */
+int
+XcmsLRGB_RGB_ParseString(spec, pColor)
+    register char *spec;
+    XcmsColor *pColor;
+/*
+ *     DESCRIPTION
+ *             This routines takes a string and attempts to convert
+ *             it into a XcmsColor structure with XcmsRGBFormat.
+ *
+ *     RETURNS
+ *             0 if failed, non-zero otherwise.
+ */
+{
+    register int n, i;
+    unsigned short r, g, b;
+    char c;
+    char *pchar;
+    unsigned short *pShort;
+
+    /*
+     * Check for old # format
+     */
+    if (*spec == '#') {
+       /*
+        * Attempt to parse the value portion.
+        */
+       spec++;
+       n = strlen(spec);
+       if (n != 3 && n != 6 && n != 9 && n != 12) {
+           return(XcmsFailure);
+       }
+
+       n /= 3;
+       g = b = 0;
+       do {
+           r = g;
+           g = b;
+           b = 0;
+           for (i = n; --i >= 0; ) {
+               c = *spec++;
+               b <<= 4;
+               if (c >= '0' && c <= '9')
+                   b |= c - '0';
+               /* assume string in lowercase
+               else if (c >= 'A' && c <= 'F')
+                   b |= c - ('A' - 10);
+               */
+               else if (c >= 'a' && c <= 'f')
+                   b |= c - ('a' - 10);
+               else return (XcmsFailure);
+           }
+       } while (*spec != '\0');
+
+       /*
+        * Succeeded !
+        */
+       n <<= 2;
+       n = 16 - n;
+       /* shift instead of scale, to match old broken semantics */
+       pColor->spec.RGB.red = r << n;
+       pColor->spec.RGB.green = g << n;
+       pColor->spec.RGB.blue =  b << n;
+    } else {
+       if ((pchar = strchr(spec, ':')) == NULL) {
+           return(XcmsFailure);
+       }
+       n = (int)(pchar - spec);
+
+       /*
+        * Check for proper prefix.
+        */
+       if (strncmp(spec, XcmsRGB_prefix, n) != 0) {
+           return(XcmsFailure);
+       }
+
+       /*
+        * Attempt to parse the value portion.
+        */
+       spec += (n + 1);
+       pShort = &pColor->spec.RGB.red;
+       for (i = 0; i < 3; i++, pShort++, spec++) {
+           n = 0;
+           *pShort = 0;
+           while (*spec != '/' && *spec != '\0') {
+               if (++n > 4) {
+                   return(XcmsFailure);
+               }
+               c = *spec++;
+               *pShort <<= 4;
+               if (c >= '0' && c <= '9')
+                   *pShort |= c - '0';
+               /* assume string in lowercase
+               else if (c >= 'A' && c <= 'F')
+                   *pShort |= c - ('A' - 10);
+               */
+               else if (c >= 'a' && c <= 'f')
+                   *pShort |= c - ('a' - 10);
+               else return (XcmsFailure);
+           }
+           if (n < 4) {
+               *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
+           }
+       }
+    }
+    pColor->format = XcmsRGBFormat;
+    pColor->pixel = 0;
+    return (XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             XcmsLRGB_RGBi_ParseString
+ *
+ *     SYNOPSIS
+ */
+int
+XcmsLRGB_RGBi_ParseString(spec, pColor)
+    register char *spec;
+    XcmsColor *pColor;
+/*
+ *     DESCRIPTION
+ *             This routines takes a string and attempts to convert
+ *             it into a XcmsColor structure with XcmsRGBiFormat.
+ *             The assumed RGBi string syntax is:
+ *                 RGBi:<r>/<g>/<b>
+ *             Where r, g, and b are in string input format for floats
+ *             consisting of:
+ *                 a. an optional sign
+ *                 b. a string of numbers possibly containing a decimal point,
+ *                 c. an optional exponent field containing an 'E' or 'e'
+ *                     followed by a possibly signed integer string.
+ *
+ *     RETURNS
+ *             0 if failed, non-zero otherwise.
+ */
+{
+    int n;
+    char *pchar;
+
+    if ((pchar = strchr(spec, ':')) == NULL) {
+       return(XcmsFailure);
+    }
+    n = (int)(pchar - spec);
+
+    /*
+     * Check for proper prefix.
+     */
+    if (strncmp(spec, XcmsRGBi_prefix, n) != 0) {
+       return(XcmsFailure);
+    }
+
+    /*
+     * Attempt to parse the value portion.
+     */
+    if (sscanf(spec + n + 1, "%lf/%lf/%lf",
+           &pColor->spec.RGBi.red,
+           &pColor->spec.RGBi.green,
+           &pColor->spec.RGBi.blue) != 3) {
+       return(XcmsFailure);
+    }
+
+    /*
+     * Succeeded !
+     */
+    pColor->format = XcmsRGBiFormat;
+    pColor->pixel = 0;
+    return (XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+Status 
+XcmsCIEXYZToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
+    XcmsCCC ccc;
+    XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert  */
+    unsigned int nColors;      /* Number of colors                     */
+    Bool *pCompressed;         /* pointer to an array of Bool          */
+/*
+ *     DESCRIPTION
+ *             Converts color specifications in an array of XcmsColor
+ *             structures from RGB format to RGBi format.
+ *
+ *     RETURNS
+ *             XcmsFailure if failed,
+ *             XcmsSuccess if succeeded without gamut compression.
+ *             XcmsSuccessWithCompression if succeeded with gamut
+ *                     compression.
+ */
+{
+    LINEAR_RGB_SCCData *pScreenData;
+    XcmsFloat tmp[3];
+    int hasCompressed = 0;
+    unsigned int i;
+    XcmsColor *pColor = pXcmsColors_in_out;
+
+    if (ccc == NULL) {
+       return(XcmsFailure);
+    }
+
+    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+    /*
+     * XcmsColors should be White Point Adjusted, if necessary, by now!
+     */
+
+    /*
+     * NEW!!! for extended gamut compression
+     *
+     * 1. Need to zero out pCompressed
+     *
+     * 2. Need to save initial address of pColor
+     *
+     * 3. Need to save initial address of pCompressed
+     */
+
+    for (i = 0; i < nColors; i++) {
+
+       /* Make sure format is XcmsCIEXYZFormat */
+       if (pColor->format != XcmsCIEXYZFormat) {
+           return(XcmsFailure);
+       }
+
+       /* Multiply [A]-1 * [XYZ] to get RGB intensity */
+       _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
+               (XcmsFloat *) &pColor->spec, tmp);
+
+       if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
+           (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
+
+           /*
+            * RGBi out of screen's gamut
+            */
+
+           if (ccc->gamutCompProc == NULL) {
+               /*
+                * Aha!! Here's that little trick that will allow
+                * gamut compression routines to get the out of bound
+                * RGBi.  
+                */
+               bcopy((char *)tmp, (char *)&pColor->spec, sizeof(tmp));
+               pColor->format = XcmsRGBiFormat;
+               return(XcmsFailure);
+           } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
+                   i, pCompressed) == 0) {
+               return(XcmsFailure);
+           }
+
+           /*
+            * The gamut compression function should return colors in CIEXYZ
+            *  Also check again to if the new color is within gamut.
+            */
+           if (pColor->format != XcmsCIEXYZFormat) {
+               return(XcmsFailure);
+           }
+           _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
+                   (XcmsFloat *) &pColor->spec, tmp);
+           if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
+               (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
+               return(XcmsFailure);
+           }
+           hasCompressed++;
+       }
+       bcopy((char *)tmp, (char *)&pColor->spec, sizeof(tmp));
+       /* These if statements are done to ensure the fudge factor is */
+       /* is taken into account. */
+       if (pColor->spec.RGBi.red < 0.0) {
+               pColor->spec.RGBi.red = 0.0;
+       } else if (pColor->spec.RGBi.red > 1.0) {
+               pColor->spec.RGBi.red = 1.0;
+       }
+       if (pColor->spec.RGBi.green < 0.0) {
+               pColor->spec.RGBi.green = 0.0;
+       } else if (pColor->spec.RGBi.green > 1.0) {
+               pColor->spec.RGBi.green = 1.0;
+       }
+       if (pColor->spec.RGBi.blue < 0.0) {
+               pColor->spec.RGBi.blue = 0.0;
+       } else if (pColor->spec.RGBi.blue > 1.0) {
+               pColor->spec.RGBi.blue = 1.0;
+       }
+       (pColor++)->format = XcmsRGBiFormat;
+    }
+    return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+Status 
+XcmsRGBiToCIEXYZ(ccc, pXcmsColors_in_out, nColors, pCompressed)
+    XcmsCCC ccc;
+    XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert  */
+    unsigned int nColors;      /* Number of colors                     */
+    Bool *pCompressed;         /* pointer to a bit array               */
+/*
+ *     DESCRIPTION
+ *             Converts color specifications in an array of XcmsColor
+ *             structures from RGBi format to CIEXYZ format.
+ *
+ *     RETURNS
+ *             XcmsFailure if failed,
+ *             XcmsSuccess if succeeded.
+ */
+{
+    LINEAR_RGB_SCCData *pScreenData;
+    XcmsFloat tmp[3];
+
+    /*
+     * pCompressed ignored in this function.
+     */
+
+    if (ccc == NULL) {
+       return(XcmsFailure);
+    }
+
+    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+    /*
+     * XcmsColors should be White Point Adjusted, if necessary, by now!
+     */
+
+    while (nColors--) {
+
+       /* Multiply [A]-1 * [XYZ] to get RGB intensity */
+       _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
+               (XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
+
+       bcopy((char *)tmp, (char *)&pXcmsColors_in_out->spec, sizeof(tmp));
+       (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
+    }
+    return(XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             XcmsRGBiToRGB
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+Status 
+XcmsRGBiToRGB(ccc, pXcmsColors_in_out, nColors, pCompressed)
+    XcmsCCC ccc;
+    XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert  */
+    unsigned int nColors;      /* Number of colors                     */
+    Bool *pCompressed;         /* pointer to a bit array               */
+/*
+ *     DESCRIPTION
+ *             Converts color specifications in an array of XcmsColor
+ *             structures from RGBi format to RGB format.
+ *
+ *     RETURNS
+ *             XcmsFailure if failed,
+ *             XcmsSuccess if succeeded without gamut compression.
+ *             XcmsSuccessWithCompression if succeeded with gamut
+ *                     compression.
+ */
+{
+    LINEAR_RGB_SCCData *pScreenData;
+    XcmsRGB tmpRGB;
+    IntensityRec keyIRec, answerIRec;
+
+    /*
+     * pCompressed ignored in this function.
+     */
+
+    if (ccc == NULL) {
+       return(XcmsFailure);
+    }
+
+    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+    while (nColors--) {
+
+       /* Make sure format is XcmsRGBiFormat */
+       if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
+           return(XcmsFailure);
+       }
+
+       keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pRedTbl->pBase,
+               (unsigned)pScreenData->pRedTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGB.red = answerIRec.value;
+
+       keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pGreenTbl->pBase,
+               (unsigned)pScreenData->pGreenTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGB.green = answerIRec.value;
+
+       keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pBlueTbl->pBase,
+               (unsigned)pScreenData->pBlueTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGB.blue = answerIRec.value;
+
+       bcopy((char *)&tmpRGB, (char *)&pXcmsColors_in_out->spec, sizeof(XcmsRGB));
+       (pXcmsColors_in_out++)->format = XcmsRGBFormat;
+    }
+    return(XcmsSuccess);
+}
+
+\f
+/*
+ *     NAME
+ *             XcmsRGBToRGBi
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+Status 
+XcmsRGBToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
+    XcmsCCC ccc;
+    XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert  */
+    unsigned int nColors;      /* Number of colors                     */
+    Bool *pCompressed;         /* pointer to a bit array               */
+/*
+ *     DESCRIPTION
+ *             Converts color specifications in an array of XcmsColor
+ *             structures from RGB format to RGBi format.
+ *
+ *     RETURNS
+ *             XcmsFailure if failed,
+ *             XcmsSuccess if succeeded.
+ */
+{
+    LINEAR_RGB_SCCData *pScreenData;
+    XcmsRGBi tmpRGBi;
+    IntensityRec keyIRec, answerIRec;
+
+    /*
+     * pCompressed ignored in this function.
+     */
+
+    if (ccc == NULL) {
+       return(XcmsFailure);
+    }
+
+    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+    while (nColors--) {
+
+       /* Make sure format is XcmsRGBFormat */
+       if (pXcmsColors_in_out->format != XcmsRGBFormat) {
+           return(XcmsFailure);
+       }
+
+       keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pRedTbl->pBase,
+               (unsigned)pScreenData->pRedTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGBi.red = answerIRec.intensity;
+
+       keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pGreenTbl->pBase,
+               (unsigned)pScreenData->pGreenTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGBi.green = answerIRec.intensity;
+
+       keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
+       if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+               (char *)pScreenData->pBlueTbl->pBase,
+               (unsigned)pScreenData->pBlueTbl->nEntries,
+               (unsigned)sizeof(IntensityRec),
+               _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
+           return(XcmsFailure);
+       }
+       tmpRGBi.blue = answerIRec.intensity;
+
+       bcopy((char *)&tmpRGBi, (char *)&pXcmsColors_in_out->spec, sizeof(XcmsRGBi));
+       (pXcmsColors_in_out++)->format = XcmsRGBiFormat;
+    }
+    return(XcmsSuccess);
+}
+\f
+/*
+ *     NAME
+ *             _XcmsInitScrnDefaultInfo
+ *
+ *     SYNOPSIS
+ */
+/* ARGSUSED */
+int
+_XcmsLRGB_InitScrnDefault(dpy, screenNumber, pPerScrnInfo)
+    Display *dpy;
+    int screenNumber;
+    XcmsPerScrnInfo *pPerScrnInfo;
+/*
+ *     DESCRIPTION
+ *             Given a display and screen number, this routine attempts
+ *             to initialize the TekCMS per Screen Info structure
+ *             (XcmsPerScrnInfo) with defaults.
+ *
+ *     RETURNS
+ *             Returns zero if initialization failed; non-zero otherwise.
+ */
+{
+    pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
+    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
+               Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
+    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
+               Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
+    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
+               Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
+               Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
+    if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
+           || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
+       pPerScrnInfo->screenData = (XPointer)NULL;
+       pPerScrnInfo->state = XcmsInitNone;
+       return(0);
+    }
+    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
+    pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
+    pPerScrnInfo->screenWhitePt.pixel = 0;
+    pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
+    pPerScrnInfo->state = XcmsInitDefault;
+    return(1);
+}
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/TextPerBd.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/TextPerBd.c
new file mode 100644 (file)
index 0000000..40f12fa
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * $XConsortium: TextPerBd.c,v 1.16 92/07/29 11:39:57 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
+ *                      and Nippon Telegraph and Telephone Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON, NTT Software, NTT, and M.I.T.
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. OMRON, NTT Software,
+ * NTT, and M.I.T. make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OMRON, NTT SOFTWARE, NTT, AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, NTT, OR M.I.T. BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ *     Authors: Li Yuhong      OMRON Corporation
+ *   
+ */
+
+/*************************************************************************
+ *                                                                       *
+ *     TextPerExtBody.c -- body of functions:                            *
+ *                           XmbTextPerCharExtents()                     *
+ *                           XwcTextPerCharExtents()                     *
+ *                                                                       *
+ *************************************************************************/
+/*--------------------------- BEGIN -------------------------------------*/
+#ifdef DecomposeGlyphCharset
+
+    XLocale        xlocale = ((XsiFontSet)font_set)->xlc;
+    XFontStruct    *fnt;
+    unsigned char  gstr[BUFSIZ];
+    int                    ctid;
+    int             glen;
+    int             scanned, ret;
+    int             count, i;
+    XCharStruct     overall;
+    int             max_ascent, max_descent;
+    XCharStruct     *onechar;
+
+#define MAX(a, b)           ((a > b)? a : b)
+#define MIN(a, b)           ((a < b)? a : b)
+
+#ifdef XML
+    if (!xlocale)
+       xlocale = _XFallBackConvert();
+#endif
+    overall.ascent = 0;
+    overall.descent = 0;
+    overall.width = 0;
+    overall.lbearing = 0;
+    overall.rbearing = 0;
+    max_ascent = 0;
+    max_descent = 0;
+    count = 0;
+    _Xmbinit(xlocale);
+    _Xctinit(xlocale);
+    while (text_len > 0 && count < buffer_size) {
+        /* buffer size */
+        glen = BUFSIZ;
+        scanned = 0;
+        ret = DecomposeGlyphCharset(xlocale, text, text_len,
+                                   gstr, &glen, &scanned, &ctid);
+        /*
+         * if ret is BadEncoding, uncovered wrong codepoint, must stop!
+         */
+        if (ret == BadEncoding || scanned == 0)
+            break;
+        /* 
+         * if missing font, no drawing or measuring
+         */
+        if ((fnt = _XsiQueryFontSetFromId(font_set, ctid)) != NULL) {
+            /*
+             * only 1 or 2 byte-encoding font supported by X.
+             */
+            if (!count) {
+                max_ascent = fnt->ascent;
+                max_descent = fnt->descent;
+            } else {
+                max_ascent = MAX(max_ascent, fnt->ascent);
+                max_descent = MAX(max_descent, fnt->descent);
+            }
+            if (fnt->min_byte1 != 0 || fnt->max_byte1 != 0)
+                glen &= ~1;
+            for (i = 0; i < glen && count < buffer_size; i++, count++) {
+                int ind, d, byte1, byte2;
+                /*
+                 * get index of glyph of font.
+                 */
+                if (fnt->min_byte1 == 0 && fnt->max_byte1 == 0) {
+                    byte2 = gstr[i];
+                    if (byte2 > fnt->max_char_or_byte2)
+                        ind = 0;
+                    else 
+                        ind = byte2 - fnt->min_char_or_byte2;
+                } else {
+                    d = fnt->max_char_or_byte2 - fnt->min_char_or_byte2 + 1;
+                    byte1 = gstr[i++];
+                    byte2 = gstr[i];
+                    if (byte1 > fnt->max_byte1 ||
+                        byte2 > fnt->max_char_or_byte2)
+                        ind = 0;
+                    else
+                        ind  = (byte1 - fnt->min_byte1) * d
+                            + (byte2 - fnt->min_char_or_byte2);
+                }
+                if (fnt->per_char != NULL)
+                    onechar = fnt->per_char + ind;
+                else
+                    onechar = &(fnt->max_bounds);
+                /*
+                 * set ink & logical extent.
+                 */
+                ink_extents_buffer[count].x = overall.width + onechar->lbearing;
+                ink_extents_buffer[count].y = - onechar->ascent;
+                ink_extents_buffer[count].width = 
+                                onechar->rbearing - onechar->lbearing;
+                ink_extents_buffer[count].height = 
+                                onechar->ascent + onechar->descent;
+
+                logical_extents_buffer[count].x = overall.width;
+                logical_extents_buffer[count].y = - fnt->ascent;
+                logical_extents_buffer[count].width = onechar->width;
+                logical_extents_buffer[count].height =
+                                fnt->ascent + fnt->descent;
+                /*
+                 * get min and max of ink/logical extent.
+                 */
+                if (!count) {
+                    overall = *onechar;
+                } else {
+                    overall.ascent = MAX(overall.ascent, onechar->ascent);
+                    overall.descent = MAX(overall.descent, onechar->descent);
+                    overall.lbearing = MIN(overall.lbearing,
+                                           overall.width + onechar->lbearing);
+                    overall.rbearing = MAX(overall.rbearing,
+                                           overall.width + onechar->rbearing);
+                    overall.width += onechar->width;
+                }
+            }
+        }
+        if (ret == BadTerminate)
+            /* The passed string "text" is terminated unexpectly, stop!*/
+            break;
+        text += scanned;
+        text_len -= scanned;
+    }
+    if (max_ink_extents) {
+       max_ink_extents->x = overall.lbearing;
+       max_ink_extents->y = - overall.ascent;
+       max_ink_extents->width = overall.rbearing - overall.lbearing;
+       max_ink_extents->height = overall.ascent + overall.descent;
+    }
+
+    if (max_logical_extents) {
+       max_logical_extents->x = 0;
+       max_logical_extents->y = - max_ascent;
+       max_logical_extents->width = overall.width;
+       max_logical_extents->height = max_ascent + max_descent;
+    }
+
+    *num_chars = count;
+    return (count <= buffer_size);
+
+#endif
+/*--------------------------- END ---------------------------------------*/
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XCnvWCToMB.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XCnvWCToMB.c
new file mode 100644 (file)
index 0000000..be4354c
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * $XConsortium: XCnvWCToMB.c,v 1.24 92/07/29 11:44:21 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
+ *                      and Nippon Telegraph and Telephone Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON, NTT Software, NTT, and M.I.T.
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. OMRON, NTT Software,
+ * NTT, and M.I.T. make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OMRON, NTT SOFTWARE, NTT, AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, NTT, OR M.I.T. BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *     Authors: Li Yuhong              OMRON Corporation
+ *              Hiroshi Kuribayashi    OMRON Coproration
+ *   
+ */
+
+/*
+ * Functions:
+ *  _XConvertMBToWC()
+ *  _XConvertWCToMB()
+ * 
+ */
+#include "Xlibint.h"
+#include "Xlocaleint.h"
+#include <X11/Xos.h>
+#include <X11/Xutil.h>
+
+#define ESC 0x1b
+#define CSI 0x9b
+
+/*
+  _IsValidEscSequence()
+  if str is valid escape sequence returns length of it in bytes.
+  else if str is not valid escape sequence returns BadEncoding.
+  else if str has not enough data returns BadTerminate.
+
+  ISO 2022
+    6.3.3 Categories of escape sequence
+    6.3.3.1 Two-character escape sequence
+    ESC Fs     Fs : 06/00 to 07/15
+    ESC Fe     Fe : 04/00 to 05/15
+    ESC Fp     Fp : 03/00 to 03/14
+
+    6.3.3.2 Three-character escape sequence
+    ESC I F    I  : 02/00 to 02/15
+    ESC I Ft   Ft : 04/00 to 07/14
+    ESC I Fp   Fp : 03/00 to 03/15
+
+    6.3.3.3 Escape sequence having four or more characters
+    ESC I...I F
+
+  ISO 2375 : (I will rewrite this function after reading ISO 2375 :-)
+
+  ISO 6429
+    5.5 Control sequence (C1 & CSI)
+    CSI P...P I...I F
+    CSI : 01/11 05/11 or 09/11
+    P...P Paramer Bytes, if present, consist from 03/00 to 03/15
+    I...I Intermediate Bytes, if present, consist from 02/00 to 02/15
+    F Final Byte, from 04/00 to 07/14
+
+    5.6 Independent control function
+    ESC Fs (same as ISO 2022)
+*/
+static int
+_IsValidEscSequence(str, len)
+unsigned char *str;
+int len;
+{
+    int i;
+
+    if (len <= 0)
+       return (BadTerminate);
+
+    if (*str == ESC) {
+       if (len == 1)   /* Only ESC */
+           return (1);
+       len--; i = 1; str++;
+       if (*str == '[') {
+           /* 7bit CSI */
+           len--; i++; str++;
+       } else if (*str >= 0x30 && *str <= 0x7e) {
+           return (2);
+       } else if (*str >= 0x20 && *str <= 0x2f) {
+           for (i++, len--, str++; len > 0; str++,i++, len--) {
+               if (*str >= 0x30 && *str <= 0x7e)
+                   return(i);
+               if (*str < 0x20 || *str >= 0x7f)
+                   return (BadEncoding); /* Not valid Escape seqence */
+           }
+           return (BadTerminate);
+       } else {
+           return (BadEncoding);
+       }
+    } else if (*str == CSI) {
+       len--; i = 1; str++;
+    } else {
+       return (BadEncoding);   /* Not Escape sequence */
+    }
+
+    if (len == 0)
+       return (i);     /* Only CSI */
+
+    for (i++; len > 0; str++,i++, len--) {
+       if (*str >= 0x40 && *str <= 0x7e)
+           return(i);
+       if (*str < 0x20 || *str >= 0x7f)
+           return (BadEncoding); /* Not valid Escape seqence */
+    }
+    return (BadTerminate);
+}
+
+
+#define Return(result) {                                                \
+        *wc_len = wccnt;                                                \
+        *scanned_bytes = mbcnt;                                         \
+       if (state) *state = xlocale->mb_state;                          \
+       if (wccnt < limit)                                              \
+           *wc_str = WNULL;                                            \
+        if (error != 0) return(error);                                  \
+        return(result);                                                 \
+    }
+         
+#define SaveStore(wc) {                                                 \
+        if (wccnt >= limit) Return(BadBuffer);                          \
+        *wc_str++ = wc;                                                 \
+        wccnt++;                                                        \
+    }
+    
+            
+/*
+ * _XConvertMBToWC()
+ *   convert string encoded in the current locale to wchar string.
+ *   if the codeset of locale is state-dependent, the _Xmbcsid()
+ *   will keep the current state, so need not the argument, such as isostate
+ *   to remember it. 
+ * Return Valur:
+ *   Success
+ *   BadBuffer
+ *   BadTerminate
+ *   > 0        number of wrong codepoints, but recovered by function
+ * 
+*/
+int
+_XConvertMBToWC(xlocale, mb_str, mb_bytes, wc_str, wc_len, scanned_bytes, state)
+    XLocale         xlocale;
+    unsigned char   *mb_str;
+    int                     mb_bytes;
+    wchar          *wc_str;
+    int                    *wc_len;
+    int                    *scanned_bytes;
+    _State         *state;
+{
+    unsigned char c;
+    _CSID      csid_sv, newcsid;
+    int         mbcnt, wccnt, deslen, codelen, code;
+    int         error, limit;
+    wchar       woffset;
+
+    if (!xlocale)
+       xlocale = _XFallBackConvert();
+
+    if (state && *state != XDEFAULT_STATE) {
+       xlocale->mb_state = *state;
+       if (_XmbCheck(xlocale) == False)
+           _Xmbinit(xlocale);
+    } else
+       _Xmbinit(xlocale);
+    _Xctinit(xlocale);
+
+    limit = *wc_len;
+    mbcnt = wccnt = error = 0;
+    csid_sv = mbGetid(xlocale);
+    codelen = _Xmblen(xlocale);
+    woffset = _Xmbfswf(xlocale, csid_sv);
+    while (mb_bytes > 0 && (c = *mb_str) != 0) {
+        if ((newcsid = _Xmbcsid(xlocale, mb_str)) == ND) {
+           int len;
+           if ((len = _IsValidEscSequence(mb_str, mb_bytes)) > 0) {
+               for ( ; len > 0; len--) {
+                   SaveStore(_Xatowc(*mb_str));
+                   mb_str++, mbcnt++, mb_bytes--;
+               }
+               continue;
+           }
+           Return(len);
+       }
+        /*
+         * filter control characters.
+         */
+        if (newcsid == C0 || newcsid == C1) {
+            SaveStore(_Xatowc(c)); 
+            mb_str++, mbcnt++, mb_bytes--;
+            continue;
+        }
+        /*
+         * skip designation sequence of state-dependent codeset.
+         * Warning: cannot recover the error of BadTerminate in this case.
+         */
+        if (_Xmbtype(xlocale) == CDS_STATEFUL &&
+             (deslen = _Xmbdlen(xlocale, mb_str)) > 0) {
+            mb_str += deslen, mbcnt += deslen, mb_bytes -= deslen;
+            continue;
+        }
+        if (csid_sv != newcsid) {
+            codelen = _Xmblen(xlocale);
+            woffset = _Xmbfswf(xlocale, newcsid);
+            csid_sv = newcsid;
+        }
+        if (codelen > mb_bytes)
+            Return(BadTerminate);
+        if (_Xmbctocsc(xlocale, mb_str, &code) < 0)
+            error++;
+        SaveStore((code & 0x7f7f) | woffset);
+        mb_str += codelen, mbcnt += codelen, mb_bytes -= codelen;
+    }
+    Return(Success);
+}
+
+#undef  Return
+#undef  SaveStore
+
+#define Return(result) {                                                \
+        *mb_bytes = mbcnt;                                              \
+        *scanned_len = wccnt;                                           \
+       if (mbcnt < limit)                                              \
+           *mb_str = 0;                                                \
+        if (error != 0) return(error);                                  \
+        return(result);                                                 \
+    }
+
+#define SaveStore(c) {                                                  \
+        if (mbcnt >= limit) Return(BadBuffer);                          \
+        *mb_str++ = c;                                                  \
+        mbcnt++;                                                        \
+    }
+
+/*
+ * _XConvertWCToMB()
+ *   convert wchar string to the string encoded in the current locale.
+ * 
+ * Return Valur:
+ *   Success
+ *   BadBuffer
+ *   > 0        number of wrong codepoints, but recovered by function
+ *
+*/
+int
+_XConvertWCToMB(xlocale, wc_str, wc_len, mb_str, mb_bytes, scanned_len)
+    XLocale            xlocale;
+    wchar             *wc_str;
+    int                        wc_len;
+    unsigned char      *mb_str;
+    int                       *mb_bytes;
+    int                       *scanned_len;
+{
+    int     limit, mbcnt, wccnt;
+    _CSID   csid_sv, newcsid;
+    int     code, codelen, error, i;
+    _State  state_sv;
+    wchar   wc, woffset, newwoffset;
+    extern void _XmbSetCsid();
+    char *defstr = XDefaultString();
+   
+    if (!xlocale)
+       xlocale = _XFallBackConvert();
+
+    _Xmbinit(xlocale);
+    _Xctinit(xlocale);
+    limit = *mb_bytes;
+    mbcnt = wccnt = error = 0;
+    csid_sv = mbGetid(xlocale);
+    codelen = _Xmblen(xlocale);
+    woffset = _Xmbfswf(xlocale, csid_sv);
+    state_sv = xlocale->mb_state;
+    while (wc_len > 0 && ((wc = *wc_str) != WNULL)) {
+       _CSID ctid;
+        if (_Xiswcntrl(wc)) {
+            SaveStore(_Xwctoa(wc));
+            wc_str++, wccnt++, wc_len--;
+            continue;
+        }
+       ctid = _XcwGetWoffsetFromLocale(xlocale, *wc_str, &newwoffset);
+       if (ctid == ND || (newcsid = _Xmbctidtocsid(xlocale, ctid)) == ND) {
+           /* XXX BUG: if stateful encoding, need to check/add
+                       designate sequence of default string.
+              But current default string is NULL, so OK. :-) */
+           for (i = 0; *(defstr + i) != 0; i++) {
+               SaveStore(*(defstr + i))
+           }
+           error++;
+           wc_str++, wccnt++, wc_len--;
+           continue;
+       }
+       _XmbSetCsid(xlocale, newcsid);
+        if (csid_sv != newcsid) {
+           int mbGLorGR;
+           if (_Xmbtype(xlocale) == CDS_STATEFUL &&
+               ((mbGLorGR = mbGetGLorGR(xlocale)) == GL &&
+                mbGetGLid(xlocale) != (state_sv & 0xff) ||
+               mbGLorGR == GR &&
+                mbGetGRid(xlocale) != (state_sv >> 8 & 0xff))) {
+                /*
+                 * add designation sequence.
+                 */
+                char    *dsg;
+                int     dsglen;
+
+                dsg = _Xmbdsg(xlocale);
+                dsglen = strlen(dsg);
+                if (mbcnt + dsglen > limit)
+                    Return(BadBuffer);
+                strncpy((char *)mb_str, dsg, dsglen);
+                mb_str += dsglen, mbcnt += dsglen;
+               state_sv = xlocale->mb_state;
+            }
+            codelen = _Xmblen(xlocale);
+            csid_sv = newcsid;
+            woffset = newwoffset;
+        }
+        if (_Xcsctombc(xlocale, (int)(*wc_str - woffset), &code) < 0)
+            error++;
+        for (i = codelen - 1; i >= 0; i--)
+            SaveStore((code >> (i * 8)) & 0x00FF);
+        wc_str++, wccnt++, wc_len--;
+    }
+    if (_Xmbtype(xlocale) == CDS_STATEFUL) {
+       /*
+        * add designation sequence.
+        */
+       char    dsg[64];
+       int     dsglen;
+
+       _XmbGetDefaultEncoding(xlocale, dsg);
+       dsglen = strlen(dsg);
+       if (mbcnt + dsglen > limit)
+           Return(BadBuffer);
+       strncpy((char *)mb_str, dsg, dsglen);
+       mb_str += dsglen, mbcnt += dsglen;
+       _Xmbinit(xlocale);
+    }
+    Return(Success);
+}
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XConnIM.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XConnIM.c
new file mode 100644 (file)
index 0000000..c510686
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * $XConsortium: XConnIM.c,v 1.18 92/07/29 13:55:35 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON and MIT not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  OMRON and MIT make no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE. 
+ *
+ *     Author: Seiji Kuwari    OMRON Corporation
+ *                             kuwa@omron.co.jp
+ *                             kuwa%omron.co.jp@uunet.uu.net
+ */                            
+
+/*
+ * This is an OS dependent file. this should work on 4.3BSD.
+ */
+#include "Xlibint.h"
+#include "Xlibnet.h"
+#include "Xi18nint.h"
+#include "XIMlibint.h"
+#include <X11/Xos.h>
+#ifdef TCPCONN
+#include <sys/socket.h>
+#endif
+
+#ifdef UNIXCONN
+#include <sys/un.h>
+#ifndef        XIM_UNIX_PATH
+#define        XIM_UNIX_PATH   "/tmp/.X11-unix/XIM"
+#endif /* XIM_UNIX_PATH */
+#endif /* UNIXCONN */
+
+/*
+ * Attempts to connect to an input manager, given atom id.
+ */
+Bool
+_XipConnectIM (im, im_atom, displaybuf)
+    XipIM im;
+    Atom im_atom;
+    char *displaybuf;
+{
+#ifdef STREAMSCONN
+    im->fd = -1;
+    return(False);
+#else
+    char               im_hostname[256];/* Input manager host name buffer */
+    Atom               actual_type;
+    int                        actual_format;
+    unsigned long      nitems;
+    unsigned long      byte_after;
+    unsigned char      *prop;
+#ifdef UNIXCONN
+    struct sockaddr_un saddr;          /* UNIX domain socket address */
+#endif /* UNIXCONN */
+#ifdef TCPCONN
+    struct sockaddr_in saddr_in;       /* INET domain socket address */
+    struct hostent     *hp;
+    unsigned short     port;
+#endif
+    int                        sd = -1;        /* File disclipter */
+    int                        indian;
+    ximConnClient      client;
+    ximNormalReply     reply;
+    unsigned long      i;
+    unsigned short     s;
+    int                        inet_ok = 0;
+
+    im->fd = -1;
+    /*
+     * Get a property of input manager. Format of the property is
+     *         char hostname[128] ( host name )
+     *         unsigned short portnumber    ( port number )
+     *         long major_version    ( major version of protocol )
+     *         long minor_version    ( minor version of protocol )
+     */
+    XGetWindowProperty(im->core.display, DefaultRootWindow(im->core.display),
+                      im_atom, 0L, 256L, 0, AnyPropertyType,
+                      &actual_type, &actual_format, &nitems,
+                      &byte_after, &prop);
+    bcopy((char *)prop, im_hostname, hname_size);
+    bcopy((char *)(prop + offset_of_portnumber), (char *)&s, portnumber_size);
+#ifdef TCPCONN
+    port = ntohs(s);
+#endif
+    bcopy((char *)(prop + offset_of_version), (char *)&i, version_size);
+    im->major_version = (long)ntohl(i);
+    bcopy((char *)(prop + offset_of_minor_version), (char *)&i, version_size);
+    im->minor_version = (long)ntohl(i);
+    Xfree((char *)prop);
+    if (im->major_version != XIM_MAJOR_VERSION) return(False);
+    if (!(im->minor_version >= XIM_MINOR_VERSION)) return(False);
+
+#ifdef TCPCONN
+    /*
+     * Attempts to open INET domain socket.
+     */
+    if (hp = gethostbyname(im_hostname)) {
+       bzero((char *)&saddr_in, (int)sizeof(saddr_in));
+       bcopy(hp->h_addr, (char *)&saddr_in.sin_addr, hp->h_length);
+       saddr_in.sin_family = AF_INET;
+       saddr_in.sin_port = htons(port);
+       if ((sd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
+           if (connect(sd, &saddr_in, sizeof(saddr_in)) >= 0) {
+               inet_ok = 1;
+           } else {
+               close(sd);
+               sd = -1;
+           }
+       }
+    }
+#endif
+#ifdef UNIXCONN
+    /*
+     * Attempts to open UNIX domain socket.
+     */
+    if (inet_ok == 0) {
+       saddr.sun_family = AF_UNIX;
+       strcpy(saddr.sun_path, XIM_UNIX_PATH);
+       if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+           return(False);
+       }
+       if (connect(sd, &saddr, strlen(saddr.sun_path)+sizeof(saddr.sun_family)) < 0) {
+           close(sd);
+           return(False);
+       }
+    }
+#endif /* UNIXCONN */
+    if (sd == -1) return(False);
+
+    /*
+     * Send the display name to the input manager. 
+     */
+    indian = 1;
+    if (*(char *) &indian) {
+       client.byteOrder = 'l';
+    } else {
+       client.byteOrder = 'B';
+    }
+    client.length = strlen(displaybuf);
+
+    im->fd = sd;
+    if ((_XipWriteToIM(im, (char *)&client, sizeof(ximConnClient)) < 0) ||
+       (_XipWriteToIM(im, (char *)displaybuf, (int)client.length) < 0) ||
+       (_XipFlushToIM(im) < 0)) {
+       return(False);
+    }
+
+
+    /*
+     * Now see, if connection was accepted.
+     */
+    if (_XipReadFromIM(im, (char *)&reply, sz_ximNormalReply) < 0) {
+       return(False);
+    }
+    if (reply.state != 0) {
+       close(sd);
+       return(False);
+    }
+    return(True);
+#endif
+}
+
+/*
+ * Disconnect from the input manager.
+ */
+
+void
+_XipDisconnectIM(server)
+    int server;
+{
+    (void) close(server);
+}
+
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XCrIC.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XCrIC.c
new file mode 100644 (file)
index 0000000..2e40ef0
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ * $XConsortium: XCrIC.c,v 1.34 92/07/29 13:54:58 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON and MIT not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  OMRON and MIT make no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE. 
+ *
+ *     Author: Seiji Kuwari    OMRON Corporation
+ *                             kuwa@omron.co.jp
+ *                             kuwa%omron.co.jp@uunet.uu.net
+ */                            
+
+#include <stdio.h>
+#include "Xlibint.h"
+#include "Xi18nint.h"
+#include "XIMlibint.h"
+#if NeedVarargsPrototypes
+# include <stdarg.h>
+# define Va_start(a,b) va_start(a,b)
+#else
+# include <varargs.h>
+# define Va_start(a,b) va_start(a)
+#endif
+
+#if __STDC__ && !defined(NORCONST)
+#define RConst const
+#else
+#define RConst /**/
+#endif
+
+/*
+ * Free the input context.
+ */
+void
+_XipDestroyIC(supic)
+    XIC supic;
+{
+    XipIC ic = (XipIC)supic;
+    XipIM im = (XipIM)ic->core.im;
+    /* check xim and ic*/
+    if (im->fd >= 0) {
+       ximDestroyICReq req;
+       ximEventReply   reply;
+
+       req.reqType = XIM_DestroyIC;
+       req.length = sz_ximDestroyICReq;
+       req.xic = ic->icid;
+       if ((_XipWriteToIM(im, (char *)&req, sz_ximDestroyICReq) >= 0) &&
+           (_XipFlushToIM(im) >= 0)) {
+           for (;;) {
+               if ((_XipReadFromIM(im, (char *)&reply, sz_ximEventReply) < 0)
+                   || (reply.state == 0xffff)) {
+                   return;
+               }
+               if (reply.detail == XIM_CALLBACK) {
+                   /*
+                    * Call the callback routines.
+                    */
+                   if (_XipCallCallbacks(ic) < 0) {
+                       return;
+                   }
+               } else {
+                   break;
+               }
+           }
+       }
+    }
+
+    _XUnregisterFilter(im->core.display, ic->core.focus_window,
+                      ic->prototype_filter, (XPointer)ic);
+
+    if (ic->mb) _XlcFreeLocale(ic->mb);
+    if (ic->wc) _XlcFreeLocale(ic->wc);
+#ifdef XML
+    if (ic->xlc_num > 0) {
+       int i;
+
+       for (i = 0; i < ic->xlc_num; i++) {
+           _XlcFreeLocale(ic->mb_temp[i]);
+           _XlcFreeLocale(ic->wc_temp[i]);
+       }
+    }
+    if (ic->mb_temp) Xfree(ic->mb_temp);
+    if (ic->wc_temp) Xfree(ic->wc_temp);
+    if (ic->values.using_language) Xfree(ic->values.using_language);
+    if (ic->values.current_language) Xfree(ic->values.current_language);
+#endif /* XML */
+    if (ic->ct_buf) Xfree(ic->ct_buf);
+    if (ic->wc_buf) Xfree(ic->wc_buf);
+    (void) _XipFreeAllICQueue(ic);
+}
+
+static RConst XICMethodsRec ic_methods = {
+    _XipDestroyIC,
+    _XipSetICFocus,
+    _XipUnsetICFocus,
+    _XipSetICValues,
+    _XipGetICValues,
+    _XipmbResetIC,
+    _XipwcResetIC,
+    _XipmbLookupString,
+    _XipwcLookupString
+};
+
+static Status
+_StringToPixel(display, colormap, name, pixel)
+    Display *display;
+    Colormap colormap;
+    char *name;
+    unsigned long *pixel;
+{
+    XColor c, e_c;
+    Status status;
+
+    if (name[0] == '#') {
+       status = XParseColor(display, colormap, name, &c);
+       if (status != 0) {
+           status = XAllocColor(display, colormap, &c);
+       }
+    } else {
+       status = XAllocNamedColor(display, colormap, name, &c, &e_c);
+    }
+    if (status == 0) {
+       return(-1);
+    } else {
+       *pixel = c.pixel;
+       return(0);
+    }
+}
+
+unsigned long
+_XipReadRdb(display, ic, mask, rdb, res_name, res_class)
+    Display *display;
+    XipIC ic;
+    unsigned long mask;
+    XrmDatabase rdb;
+    char *res_name;
+    char *res_class;
+{
+    XipIM im = ipIMofIC(ic);
+    unsigned long ret_mask = 0;
+    char name_prefix[256], class_prefix[256];
+    char res_name_buf[256], res_class_buf[256];
+    /*
+    char def_fontset[256];
+    */
+#ifdef XML
+    char def_language[256];
+#endif /* XML */
+    char def_fg_name[256], def_bg_name[256];
+    unsigned long def_fg, def_bg;
+    char *str_type[20];
+    XrmValue value;
+    XIMArg args[8], pre_args[4], st_args[4];
+    int count = 0, pre_count = 0, st_count = 0;
+    Colormap colormap, def_colormap;
+    XWindowAttributes win_info;
+
+    if (rdb == NULL) {
+       return(0);
+    }
+    if (ic->core.client_window) {
+       XGetWindowAttributes(display, ic->core.client_window, &win_info);
+    } else {
+       XGetWindowAttributes(display,
+                            RootWindow(display, DefaultScreen(display)),
+                            &win_info);
+    }
+    def_colormap = win_info.colormap;
+    if (res_name == NULL || *res_name == '\0'
+       || res_class == NULL || *res_class == '\0') {
+       strcpy(name_prefix, "*.");
+       strcpy(class_prefix, "*.");
+    } else {
+       strcpy(name_prefix, res_name);
+       strcpy(class_prefix, res_class);
+       strcat(name_prefix, ".");
+       strcat(class_prefix, ".");
+    }
+    if (!(mask & ((1 << ICForeground) | (1 << (ICForeground + StatusOffset))))){
+       strcpy(res_name_buf, name_prefix);
+       strcpy(res_class_buf, class_prefix);
+       strcat(res_name_buf, "foreground");
+       strcat(res_class_buf, "Foreground");
+       if (XrmGetResource(rdb, res_name_buf, res_class_buf,
+                          str_type, &value) == True) {
+           strncpy(def_fg_name, value.addr, (int)value.size);
+           if (ic->core.preedit_attr.colormap) {
+               colormap = ic->core.preedit_attr.colormap;
+           } else {
+               colormap = def_colormap;
+           }
+           if (_StringToPixel(display, colormap, def_fg_name, &def_fg) == 0) {
+               if (!(mask & (1 << ICForeground))) {
+                   pre_args[pre_count].name = (char *)XNForeground;
+                   pre_args[pre_count].value = (XPointer)def_fg;
+                   pre_count++;
+               }
+               if (!(mask & (1 << (ICForeground + StatusOffset)))) {
+                   st_args[st_count].name = (char *)XNForeground;
+                   st_args[st_count].value = (XPointer)def_fg;
+                   st_count++;
+               }
+           } else {
+               fprintf(stderr, "XIM: Could not Alloc color \"%s\".",
+                       def_fg_name);
+           }
+       }
+    }
+    if (!(mask & ((1 << ICBackground) | (1 << (ICBackground + StatusOffset))))){
+       strcpy(res_name_buf, name_prefix);
+       strcpy(res_class_buf, class_prefix);
+       strcat(res_name_buf, "background");
+       strcat(res_class_buf, "Background");
+       if (XrmGetResource(rdb, res_name_buf, res_class_buf,
+                          str_type, &value) == True) { 
+           strncpy(def_bg_name, value.addr, (int)value.size);  
+           if (ic->core.preedit_attr.colormap) {
+               colormap = ic->core.preedit_attr.colormap;
+           } else {
+               colormap = def_colormap;
+           }
+           if (_StringToPixel(display, colormap, def_bg_name, &def_bg) == 0) {
+               if (!(mask & (1 << ICBackground))) {
+                   pre_args[pre_count].name = (char *)XNBackground;
+                   pre_args[pre_count].value = (XPointer)def_bg;
+                   pre_count++;
+               }
+               if (!(mask & (1 << (ICBackground + StatusOffset)))) {
+                   st_args[st_count].name = (char *)XNBackground;
+                   st_args[st_count].value = (XPointer)def_bg;
+                   st_count++;
+               }
+           } else {
+               fprintf(stderr, "XIM: Could not Alloc color \"%s\".",
+                       def_bg_name);
+           }   
+       }       
+    }
+    /*
+    if (!(mask & ((1 << ICFontSet) | (1 << (ICFontSet + StatusOffset))))) {
+       strcpy(res_name_buf, name_prefix);      
+       strcpy(res_class_buf, class_prefix);
+       strcat(res_name_buf, "fontSet");
+       strcat(res_class_buf, "FontSet");
+       if (XrmGetResource(rdb, res_name_buf, res_class_buf,
+                          str_type, &value) == True) {
+           strncpy(def_fontset, value.addr, value.size);
+           if (!(mask & (1 << ICFontSet))) {
+               pre_args[pre_count].name = (char *)XNFontSet;
+               pre_args[pre_count].value = (XPointer)def_fontset;
+               pre_count++;
+           }
+           if (!(mask & (1 << (ICFontSet + StatusOffset)))) {
+               st_args[st_count].name = (char *)XNForeground;
+               st_args[st_count].value = (XPointer)def_fg;
+               st_count++;
+           }
+       }
+    }
+    */
+#ifdef XML
+    if (!(mask & (1 << ICUsingLanguage))) {
+       strcpy(res_name_buf, name_prefix);      
+       strcpy(res_class_buf, class_prefix);
+       strcat(res_name_buf, "usingLanguage");
+       strcat(res_class_buf, "usingLanguage");
+       if (XrmGetResource(rdb, res_name_buf, res_class_buf,
+                          str_type, &value) == True) {
+           strncpy(def_language, value.addr, (int)value.size);
+           args[count].name = (char *)XNUsingLanguage;
+           args[count].value = (XPointer)def_language;
+           count++;
+       }
+    }
+#endif /* XML */
+    if(pre_count) {
+       pre_args[pre_count].name = (char *)NULL;
+       (void)_XipICSetAttrValues(im, pre_args, &ic->core.preedit_attr,
+                                 &ret_mask, 0);
+    }
+    if(st_count) {
+       st_args[st_count].name = (char *)NULL;
+       (void)_XipICSetAttrValues(im, st_args, &ic->core.status_attr,
+                                 &ret_mask, StatusOffset);
+    }
+    if (count) {
+       args[count].name = (char *)NULL;
+       (void)_XipICSetValues(ic, args, &ret_mask);
+    }
+    return(ret_mask);
+}
+
+Bool
+_XipCreateDefIC(im)
+    XipIM im;
+{
+    im->default_ic = (XipIC)Xcalloc(1, sizeof(XipICRec));
+    if (im->default_ic == NULL) {
+       return False;
+    }
+    im->default_ic->core.im = (XIM)im;
+
+    im->default_mask = _XipReadRdb(im->core.display, im->default_ic,
+                               (unsigned long)0,
+                               im->core.rdb, im->core.res_name,
+                               im->core.res_class);
+    return True;
+}
+
+
+/*
+ * Create an input context within the input method, 
+ * and return a pointer the input context ti the caller.
+ */
+XIC
+_XipCreateIC(supim, args)
+    XIM supim;
+    XIMArg *args;
+{
+    XipIM              im = (XipIM)supim;
+    XipIC              ic;
+    ximCreateICReq     req;
+    ximCreateICReply   reply;
+    ximEventReply      reply1;
+    unsigned long      mask;
+    extern Bool                _XipBackEndFilter();
+#ifdef XML
+    char               *p, **nls_list, **l;
+    unsigned int       i, n = 0;
+    XLocale            xlc;
+#endif /* XML */
+
+    /*
+     * If im is not specified or the file descripter is not available,
+     * return NULL.
+     */
+    if (im->fd < 0) {
+       return(NULL);
+    }
+
+    if ((ic = (XipIC)Xcalloc(1, sizeof(XipICRec))) == NULL) {
+       return(NULL);
+    }
+
+    mask = im->default_mask;
+    if (mask)
+       bcopy((char *)&im->default_ic->values, (char *)&ic->values,
+             sizeof(struct _ICValues));
+
+    ic->methods = (XICMethods) &ic_methods;
+    ic->prototype_filter = _XipBackEndFilter;
+    ic->core.im = supim;
+    (void)_XipICSetValues(ic, args, &mask);
+
+    req.reqType = XIM_CreateIC;
+    req.length = sz_ximCreateICReq + strlen(im->client_data);
+
+    if ((_XipWriteToIM(im, (char *)&req, sz_ximCreateICReq) < 0) ||
+       (_XipWriteToIM(im, im->client_data, strlen(im->client_data)) < 0) ||
+       (_XipFlushToIM(im) < 0)) {
+       return(NULL);
+    }
+
+    if (im->core.rdb && ic->values.res_name && ic->values.res_class) {
+       mask |= _XipReadRdb(im->core.display, ic, mask, im->core.rdb,
+                        ic->values.res_name, ic->values.res_class);
+    }
+       
+#ifdef XML
+    if (im->xlc != NULL) {
+#endif /* XML */
+       ic->mb = _XlcDupLocale(im->xlc);
+       ic->wc = _XlcDupLocale(im->xlc);
+#ifdef XML
+       ic->xlc_num = 0;
+       ic->mb_temp = NULL;
+       ic->wc_temp = NULL;
+       n = strlen(im->xlc->xlc_db->lc_name) + 1;
+       if ((p = Xmalloc(n)) == NULL) return(NULL);
+       strcpy(p, im->xlc->xlc_db->lc_name);
+       p[n - 1] = 0;
+       ic->values.using_language = p;
+       mask |= (1 << ICUsingLanguage);
+    } else {
+       ic->mb = NULL;
+       ic->wc = NULL;
+       ic->xlc_num = 0;
+       if ((ic->mb_temp = (XLocale*)Xmalloc(sizeof(XLocale) * 32)) == NULL) {
+           return(NULL);
+       }
+       if ((ic->wc_temp = (XLocale*)Xmalloc(sizeof(XLocale) * 32)) == NULL) {
+           return(NULL);
+       }
+       _XlcListLocale(&nls_list);
+       for (l = nls_list; *l; l++) {
+           xlc = _XlcMakeLocale(*l);
+           if (!xlc)
+               continue;
+           ic->mb_temp[ic->xlc_num] = xlc;
+           ic->wc_temp[ic->xlc_num] = _XlcDupLocale(xlc);
+           n += strlen(ic->mb_temp[ic->xlc_num]->xlc_db->lc_name) + 1;
+           ic->xlc_num++;
+       }
+       Xfree((char *)nls_list);
+       if ((p = Xmalloc(n)) == NULL) return(NULL);
+       p[0] = '\0';
+       for (i = 0; i < ic->xlc_num; i++) {
+           strcat(p, ic->mb_temp[i]->xlc_db->lc_name);
+           strcat(p, ";");
+       }
+       p[n - 1] = '\0';
+       ic->values.using_language = p;
+       mask |= (1 << ICUsingLanguage);
+    }
+#endif /* XML */
+
+
+    /*
+     * Attempt to send IC data to the input manager. If sending failed,
+     * free IC structure and return NULL.
+     */
+    _XipSendICValues(ic, mask);
+    ic->max_of_ct = ic->max_of_wc = 0;
+    ic->ct_buf = NULL;
+    ic->wc_buf = NULL;
+    for (;;) {
+       if ((_XipReadFromIM(im, (char *)&reply1, sz_ximEventReply) < 0) ||
+           (reply1.state == 0xffff)) {
+           goto _err_ret;
+       }
+       if (reply1.detail == XIM_CALLBACK) {
+           /*
+            * Call the callback routines.
+            */
+           if (_XipCallCallbacks(ic) < 0) {
+               goto _err_ret;
+           }
+       } else if (reply1.detail == XIM_IC) {
+           if (_XipReadFromIM(im, (char *)&reply, sz_ximCreateICReply) < 0) {
+               goto _err_ret;
+           }
+           if (reply.state != 0) {
+               goto _err_ret;
+           }
+           ic->icid = reply.xic;
+           break;
+       } else {
+           break;
+       }
+    }
+
+    /*
+     * Attempt to get current IC data from the input manager.
+     */
+    _XipReceiveICValues(ic, (unsigned long)ICAllMask);
+
+#ifdef XML
+    if (ic->xlc_num > 0) {
+       for (i = 0; i < ic->xlc_num; i++) {
+           if (!strcmp(ic->values.current_language,
+                       ic->mb_temp[i]->xlc_db->lc_name)) {
+               ic->mb = ic->mb_temp[i];
+               ic->wc = ic->wc_temp[i];
+               break;
+           }
+       }
+       if (ic->mb == NULL) {
+           ic->mb = ic->mb_temp[0];
+           ic->wc = ic->wc_temp[0];
+       }
+    }
+#endif /* XML */
+    return((XIC)ic);
+
+_err_ret:
+    if (ic->mb) _XlcFreeLocale(ic->mb);
+    if (ic->wc) _XlcFreeLocale(ic->wc);
+#ifdef  XML
+    if (ic->xlc_num > 0) {
+       for (i = 0; i < ic->xlc_num; i++) {
+           _XlcFreeLocale(ic->mb_temp[i]);
+           _XlcFreeLocale(ic->wc_temp[i]);
+       }
+    }
+    if (ic->mb_temp) Xfree(ic->mb_temp);
+    if (ic->wc_temp) Xfree(ic->wc_temp);
+    if (ic->values.using_language) Xfree(ic->values.using_language);
+#endif  /* XML */
+    Xfree((char *)ic);
+    return(NULL);
+}
+
+/*
+ * Reset the input context. 
+ */
+wchar_t *
+_XipwcResetIC(ic)
+    XIC ic;            /* specified the input context to reset*/
+{
+    XipIM im = ipIMofIC((XipIC)ic);
+    ximResetICReq      req;
+    ximEventReply      reply;
+
+    /*
+     * If im is not specified or the file descripter is not available,
+     * return NULL.
+     */
+    if (im->fd < 0) {
+       return((wchar_t *)NULL);
+    }
+    req.reqType = XIM_ResetIC;
+    req.length = sz_ximResetICReq;
+    req.xic = ((XipIC)ic)->icid;
+    if ((_XipWriteToIM(im, (char *)&req, sz_ximResetICReq) >= 0) &&
+       (_XipFlushToIM(im) >= 0)) {
+       for (;;) {
+           if ((_XipReadFromIM(im, (char *)&reply, sz_ximEventReply) < 0) ||
+               (reply.state == 0xffff)) {
+               return((wchar_t *)NULL);
+           }
+           if (reply.detail == XIM_CALLBACK) {
+               /*
+                * Call the callback routines.
+                */
+               if (_XipCallCallbacks(ic) < 0) {
+                   return((wchar_t *)NULL);
+               }
+           } else {
+               break;
+           }
+       }
+    }
+    return((wchar_t *)NULL);
+}
+
+char *
+_XipmbResetIC(ic)
+    XIC ic;            /* specified the input context to reset*/
+{
+    XipIM im = ipIMofIC((XipIC)ic);
+    ximResetICReq      req;
+    ximEventReply      reply;
+
+    /*
+     * If im is not specified or the file descripter is not available,
+     * return NULL.
+     */
+    if (im->fd < 0) {
+       return(NULL);
+    }
+    req.reqType = XIM_ResetIC;
+    req.length = sz_ximResetICReq;
+    req.xic = ((XipIC)ic)->icid;
+    if ((_XipWriteToIM(im, (char *)&req, sz_ximResetICReq) >= 0) &&
+       (_XipFlushToIM(im) >= 0)) {
+       for (;;) {
+           if ((_XipReadFromIM(im, (char *)&reply, sz_ximEventReply) < 0) ||
+               (reply.state == 0xffff)) {
+               return(NULL);
+           }
+           if (reply.detail == XIM_CALLBACK) {
+               /*
+                * Call the callback routines.
+                */
+               if (_XipCallCallbacks(ic) < 0) {
+                   return(NULL);
+               }
+           } else {
+               break;
+           }
+       }
+    }
+    return(NULL);
+}
+
+#ifdef XML
+void
+_XipChangeLocale(ic, lc_name)
+    XipIC ic;
+    char *lc_name;
+{
+    XLocale xlc;
+    int i;
+
+    for (i = 0; i < ic->xlc_num; i++) {
+       if ((!strcmp(lc_name, ic->mb_temp[i]->lc_lang)) ||
+           (!strcmp(lc_name, ic->mb_temp[i]->xlc_db->lc_name))) {
+           ic->mb = ic->mb_temp[i];
+           ic->wc = ic->wc_temp[i];
+           return;
+       }
+    }
+    xlc = _XlcMakeLocale(lc_name);
+    if (xlc) {
+       ic->mb = ic->mb_temp[ic->xlc_num] = xlc;
+       ic->wc = ic->wc_temp[ic->xlc_num] = _XlcDupLocale(xlc);
+       ic->xlc_num++;
+    }
+}
+#endif /* XML */
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XICSetVal.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XICSetVal.c
new file mode 100644 (file)
index 0000000..e2310a2
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * $XConsortium: XICSetVal.c,v 1.29 92/07/28 17:54:11 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON and MIT not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  OMRON and MIT make no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE. 
+ *
+ *     Author: Seiji Kuwari    OMRON Corporation
+ *                             kuwa@omron.co.jp
+ *                             kuwa%omron.co.jp@uunet.uu.net
+ */                            
+
+#include "Xlibint.h"
+#include "Xi18nint.h"
+#include "XIMlibint.h"
+#include <X11/Xos.h>
+#if NeedVarargsPrototypes
+# include <stdarg.h>
+# define Va_start(a,b) va_start(a,b)
+#else
+# include <varargs.h>
+# define Va_start(a,b) va_start(a)
+#endif
+
+static void
+CopyFromArg(src, dst, size)
+    XPointer src;
+    XPointer *dst;
+    register unsigned int size;
+{
+    if (size > sizeof(XPointer))
+      bcopy((char *)src, (char *)dst, (int)size);
+    else {
+       union {
+           long        longval;
+           short       shortval;
+           char        charval;
+           char*       charptr;
+           XPointer    ptr;
+       } u;
+       char *p = (char*)&u;
+       if (size == sizeof(long))               u.longval = (long)src;
+       else if (size == sizeof(short))         u.shortval = (short)src;
+       else if (size == sizeof(char))          u.charval = (char)src;
+       else if (size == sizeof(XPointer))      u.ptr = (XPointer)src;
+       else if (size == sizeof(char *))        u.charptr = (char *)src;
+       else                                    p = (char*)&src;
+
+       bcopy(p, (char *) dst, (int) size);
+    }
+}
+
+/*
+ * Up date a attributes of input context depended on the nested list.
+ */
+char *
+_XipICSetAttrValues(im, args, attr, mask, offset)
+    register XipIM im;
+    register XIMArg *args;
+    ICAttributes *attr;
+    unsigned long *mask;
+    int offset;
+{
+    register XIMArg            *arg;
+    register int               i;
+    register XrmName           Name;
+    register XIMrmResourceList xrmres;
+    register unsigned int      num_resources = im->core.ic_num_attr_resources;
+    XrmQuark                   spot_name =
+                                   XrmPermStringToQuark(XNSpotLocation);
+
+    for (arg = args; arg && arg->name && *(arg->name) ; arg++) {
+       Name = XrmStringToName(arg->name);
+       for (xrmres = im->core.ic_attr_resources, i = 0;
+            i < num_resources; i++, xrmres++) {
+           if (Name == xrmres->xrm_name) {
+               if (!(xrmres->mode & IMResourceWrite)) {
+                   return(arg->name);
+               }
+               /*
+                * Size of XPoint is not bigger than XPointer, so
+                * could not call CopyFromArg();
+                */
+               if (Name == spot_name) {
+                  XPoint *p = (XPoint*)arg->value;
+                  attr->spot_location.x = p->x;
+                  attr->spot_location.y = p->y;
+               } else {
+                   (void) CopyFromArg(arg->value,
+                                      (char *)attr - xrmres->xrm_offset - 1,
+                                      (unsigned int)xrmres->xrm_size);
+               }
+               if (xrmres->mask >= 0) {
+                   *mask |= (1L << (xrmres->mask + offset));
+               }
+               break;
+           }
+       }
+    }
+    return(NULL);
+}
+
+/*
+ * Up date input context depended on the argument list.
+ */
+char *
+_XipICSetValues(ic, args, mask)
+    register XipIC ic;
+    register XIMArg *args;
+    unsigned long *mask;
+{
+    XipIM                      im = ipIMofIC(ic);
+    register XIMArg            *arg;
+    register int               i;
+    register XrmName           Name;
+    register XIMrmResourceList xrmres;
+    register unsigned int      num_resources = im->core.ic_num_resources;
+    char                       *err;
+    XrmQuark                   preedit_name =
+                                   XrmPermStringToQuark(XNPreeditAttributes);
+    XrmQuark                   status_name =
+                                   XrmPermStringToQuark(XNStatusAttributes);
+#ifdef XML
+    XrmQuark                   use_lang =
+                                   XrmPermStringToQuark(XNUsingLanguage);
+    XrmQuark                   cur_lang =
+                                   XrmPermStringToQuark(XNCurrentLanguage);
+    int len;
+    char *p;
+#endif /* XML */
+
+    for (arg = args; arg && arg->name && *(arg->name); arg++) {
+       Name = XrmStringToName(arg->name);
+       for (xrmres = im->core.ic_resources, i = 0;
+            i < num_resources; i++, xrmres++) {
+           if (Name == xrmres->xrm_name) {
+               if (Name == preedit_name) {
+                   if ((err = _XipICSetAttrValues(im, (XIMArg *)arg->value,
+                                                  &ic->core.preedit_attr,
+                                                  mask, 0)) != NULL) {
+                       return(err);
+                   }
+               } else if (Name == status_name) {
+                   if ((err = _XipICSetAttrValues(im, (XIMArg *)arg->value,
+                                                  &ic->core.status_attr,
+                                                  mask, StatusOffset)) != NULL) {
+                       return(err);
+                   }
+               } else {
+                   if (!(xrmres->mode & IMResourceWrite)) {
+                       return(arg->name);
+                   }
+#ifdef XML
+                   if (Name == use_lang || Name == cur_lang) {
+                      len = strlen((char *)arg->value);
+                      p = Xmalloc(len + 1);
+                      strcpy(p, (char *)arg->value);
+                      arg->value = (XPointer)p;
+                   }
+#endif /* XML */
+                   (void) CopyFromArg(arg->value,
+                                      (char *)ic - xrmres->xrm_offset - 1,
+                                      (unsigned int)xrmres->xrm_size);
+                   if (xrmres->mask >= 0) {
+                       *mask |= (1L << (xrmres->mask));
+                   }
+               }
+               break;
+           }
+       }
+       if (i >= num_resources) return(arg->name);
+    }
+    return(NULL);
+}
+
+static int
+_XipSendICAttributes(im, attr, mask, offset)
+    XipIM im;
+    register ICAttributes *attr;
+    unsigned long mask;
+    int offset;
+{
+    ximICAttributesReq req;
+    register int i;
+    register char *p = NULL;
+    register char **font_name_list;
+
+    req.area_x = attr->area.x;
+    req.area_y = attr->area.y;
+    req.area_width = attr->area.width;
+    req.area_height = attr->area.height;
+    req.spot_x = attr->spot_location.x;
+    req.spot_y = attr->spot_location.y;
+    req.colormap = attr->colormap;
+    req.std_colormap = attr->std_colormap;
+    req.foreground = attr->foreground;
+    req.background = attr->background;
+    req.pixmap = attr->background_pixmap;
+    req.line_space = attr->line_space;
+    req.cursor = attr->cursor;
+    if (mask & (1 << (ICFontSet + offset))) {
+       font_name_list = attr->fontset->core.font_name_list;
+       req.nfonts = attr->fontset->core.num_of_fonts;
+       req.nbytes = 0;
+       for (i = 0; i < (int)req.nfonts; i++) {
+           req.nbytes += (strlen(font_name_list[i]) + 1);
+       }
+       if ((p = Xmalloc((unsigned)(req.nbytes + 1))) == NULL) return(-1);
+       p[0] = '\0';
+       for (i = 0; i < (int)req.nfonts; i++) {
+           strcat(p, font_name_list[i]);
+           strcat(p, ",");
+       }
+       p[req.nbytes - 1] = '\0';
+    } else {
+       req.nfonts = 0;
+       req.nbytes = 0;
+    }
+
+    if (_XipWriteToIM(im, (char *)&req, sz_ximICAttributesReq) < 0) {
+       return(-1);
+    }
+    if (req.nbytes > 0) {
+       if (_XipWriteToIM(im, p, req.nbytes) < 0) {
+           return(-1);
+       }
+       Xfree(p);
+    }
+    return(0);
+}
+
+int
+_XipSendICValues(ic, mask)
+    register XipIC ic;
+    unsigned long mask;
+{
+    XipIM im = ipIMofIC(ic);
+    ximICValuesReq req;
+    register char *p, *p2;
+#ifdef XML
+    register int i;
+#endif /* XML */
+    register unsigned int n = 0;
+
+    req.mask = mask;
+    req.c_window = ic->core.client_window;
+    req.input_style = ic->core.input_style;
+    req.focus_window = ic->core.focus_window;
+    req.filter_events = ic->core.filter_events;
+    req.max_keycode = 0;       /* noused */
+#ifdef XML
+    if (mask & (1 << ICUsingLanguage)) {
+       if (ic->xlc_num == 0) {
+#endif /* XML */
+           n = strlen(ic->mb->xlc_db->lc_name) + strlen(ic->mb->lc_lang) + 2;
+           if ((p = Xmalloc(n)) == NULL) return(-1);
+           strcpy(p, ic->mb->xlc_db->lc_name);
+           strcat(p, ",");
+           strcat(p, ic->mb->lc_lang);
+           p[n - 1] = '\0';
+           req.nbytes = strlen(p);
+#ifdef XML
+       } else {
+           for (i = 0; i < ic->xlc_num; i++) {
+               n += (strlen(ic->mb_temp[i]->xlc_db->lc_name)
+                     + strlen(ic->mb_temp[i]->lc_lang) + 2);
+           }
+           if (n > 0) {
+               if ((p = Xmalloc(n)) == NULL) return(-1);
+               p[0] = '\0';
+               for (i = 0; i < ic->xlc_num; i++) {
+                   strcat(p, ic->mb_temp[i]->xlc_db->lc_name);
+                   strcat(p, ",");
+                   strcat(p, ic->mb_temp[i]->lc_lang);
+                   strcat(p, ";");
+               }
+               p[n - 1] = '\0';
+               req.nbytes = strlen(p);
+           } else {
+               p = NULL;
+               req.nbytes = 0;
+           }
+       }
+    } else {
+       p = NULL;
+       req.nbytes = 0;
+    }
+#endif /* XML */
+
+#ifdef XML
+    if (mask & (1 << ICCurrentLanguage)) {
+       p2 = ic->values.current_language;
+       req.nbytes2 = strlen(p2);
+    } else {
+       p2 = NULL;
+       req.nbytes2 = 0;
+    }
+#else  /* XML */
+    req.nbytes2 = strlen(ic->mb->xlc_db->lc_name);
+    p2 = ic->mb->xlc_db->lc_name;
+#endif /* XML */
+
+    if (_XipWriteToIM(im, (char *)&req, sz_ximICValuesReq) < 0) {
+       return(-1);
+    }
+    if (req.nbytes > 0) {
+       if (_XipWriteToIM(im, (char *)p, req.nbytes) < 0) {
+           return(-1);
+       }
+    }
+    if (req.nbytes2 > 0) {
+       if (_XipWriteToIM(im, (char *)p2, req.nbytes2) < 0) {
+           return(-1);
+       }
+    }
+    if ((_XipSendICAttributes(im, &ic->core.preedit_attr, mask, 0) < 0) ||
+       (_XipSendICAttributes(im, &ic->core.status_attr, mask,
+                           StatusOffset) < 0) ||
+       (_XipFlushToIM(im) < 0)) {
+       return(-1);
+    }
+    return(0);
+}
+
+char *
+_XipSetICValues(supic, args)
+    XIC supic;
+    XIMArg *args;
+{
+    XipIC              ic = (XipIC)supic;
+    XipIM              im = ipIMofIC(ic);
+    unsigned long      mask = 0L;
+    Window             old_focus_window;
+    ximChangeICReq     req;
+    ximEventReply      reply;
+    char               *err = NULL;
+
+    if (im->fd < 0) return(NULL);
+    old_focus_window = ic->core.focus_window;
+
+    err = _XipICSetValues(ic, args, &mask);
+    if (err)
+       return(err);
+    if (im->core.rdb &&
+       (mask & (1L << ICResourceClass | 1L << ICResourceName))) {
+       mask |= _XipReadRdb(im->core.display, ic, mask, im->core.rdb,
+                           ic->values.res_name, ic->values.res_class);
+    }
+    
+    if (mask & (1L << ICFocusWindow)) {
+       _XUnregisterFilter(im->core.display, old_focus_window,
+                          ic->prototype_filter, (XPointer)ic);
+       _XRegisterFilterByMask(im->core.display, ic->core.focus_window,
+                              KeyPressMask,
+                              ic->prototype_filter, (XPointer)ic);
+    }
+#ifdef XML
+    if (mask & (1L << ICCurrentLanguage)) {
+       _XipChangeLocale(ic, ic->values.current_language);
+    }
+#endif /* XML */
+
+    /*
+     * Attempt to send IC data to the input manager. If sending failed,
+     * generate -1.
+     */
+    req.reqType = XIM_ChangeIC;
+    req.length = sz_ximChangeICReq;
+    req.xic = ic->icid;
+
+    if ((_XipWriteToIM(im, (char *)&req, sz_ximChangeICReq) >= 0) &&
+       (_XipSendICValues(ic, mask) >= 0)) {
+       for (;;) {
+           if ((_XipReadFromIM(im, (char *)&reply, sz_ximEventReply) < 0)
+               || (reply.state == 0xffff)) {
+               return("unknownError"); /* XXX */
+           }
+           if (reply.detail == XIM_CALLBACK) {
+               /*
+                * Call the callback routines.
+                */
+               if (_XipCallCallbacks(ic) < 0) {
+                   return(NULL);
+               }
+           } else {
+               break;
+           }
+       }
+    }
+    return(NULL);
+}
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XIMlibint.h b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XIMlibint.h
new file mode 100644 (file)
index 0000000..42b0977
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * $XConsortium: XIMlibint.h,v 1.13 92/07/29 13:55:45 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON and MIT not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  OMRON and MIT make no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE. 
+ *
+ *     Author: Seiji Kuwari    OMRON Corporation
+ *                             kuwa@omron.co.jp
+ *                             kuwa%omron.co.jp@uunet.uu.net
+ */                            
+
+#ifndef        _XIMLIBINT_H_
+#define        _XIMLIBINT_H_
+
+#include "XIMproto.h"
+
+#define        XIM_INPUTMETHOD         "_XIM_INPUTMETHOD"
+
+#ifndef        ESC
+#define        ESC                     0x1b
+#endif /* ESC */
+#define        ASCII_DESIGNATE         "\033\050\102"
+
+#define hname_size             128
+#define offset_of_portnumber   hname_size
+#define portnumber_size                2
+#define offset_of_version      (offset_of_portnumber + portnumber_size)
+#define version_size           4
+#define offset_of_minor_version        (offset_of_version + version_size)
+
+#define ipIMofIC(ic) ((XipIM)ic->core.im)
+#ifndef        NO_LOCAL_IM
+#define ipLocalIMofIC(ic) ((XipLocalIM)ic->core.im)
+#endif
+
+extern short   _XipTypeOfNextICQueue();
+extern KeySym  _XipKeySymOfNextICQueue();
+extern unsigned int    _XipStateOfNextICQueue();
+extern char *  _XipStringOfNextICQueue();
+extern void    _XipFreeNextICQueue();
+extern int     _XipPutICQueue();
+extern void    _XipGetNextICQueue();
+extern void    _XipFreeAllICQueue();
+extern void    _XipSaveOverflowICQueue();
+extern void    _XipGetOverflowICQueue();
+extern int     _XipWriteToIM();
+extern int     _XipReadFromIM();
+extern int     _XipFlushToIM();
+extern void    _XipSetCurSock();
+extern void    _XipSetCurIM();
+extern Bool    _XipConnectIM();
+extern void    _XipDisconnectIM();
+extern int     _XipCallCallbacks();
+extern Bool    _XipBackEndFilter();
+extern Status  _XipReceiveICValues();
+extern int     _XipSendICValues();
+extern Bool    _XipCreateDefIC();
+extern char *  _XipICSetAttrValues();
+extern char *  _XipICSetValues();
+extern char *  _XipICGetValues();
+#ifndef        NO_LOCAL_IM
+extern Bool    _XipBackEndFilter();
+#endif
+#ifdef XML
+extern void    _XipChangeLocale();
+#endif /* XML */
+
+#endif /* _XIMLIBINT_H_ */
diff --git a/usr/src/contrib/X11R5-lib/lib/X/Xsi/XOpenIM.c b/usr/src/contrib/X11R5-lib/lib/X/Xsi/XOpenIM.c
new file mode 100644 (file)
index 0000000..3765795
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * $XConsortium: XOpenIM.c,v 1.19 92/07/28 17:52:13 rws Exp $
+ */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation
+ * Copyright 1991 by the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of OMRON and MIT not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  OMRON and MIT make no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE. 
+ *
+ *     Author: Seiji Kuwari    OMRON Corporation
+ *                             kuwa@omron.co.jp
+ *                             kuwa%omron.co.jp@uunet.uu.net
+ */                            
+
+#include "Xlibint.h"
+#include "Xi18nint.h"
+#include "XIMlibint.h"
+#include <X11/Xos.h>
+#include <pwd.h>
+#ifdef X_NOT_STDC_ENV
+extern char *getenv();
+#endif
+#ifdef X_NOT_POSIX
+extern int getuid();
+#endif
+
+#if __STDC__ && !defined(NORCONST)
+#define RConst const
+#else
+#define RConst /**/
+#endif
+
+#define        offset(field)   XOffsetOf(XipIMRec, field)
+
+static int compiled_resources;
+
+static XIMResource im_resources[] = {
+    { XNQueryInputStyle, sizeof(XIMStyles *), offset(values.input_styles),
+      (unsigned short)IMResourceRead, (int)IMQueryInputStyle },
+#ifdef XML
+    { XNQueryLanguage, sizeof(char *), offset(values.supported_language),
+      (unsigned short)IMResourceRead, (int)IMQueryLanguage }
+#endif /* XML */
+};
+
+#undef offset
+
+#define        offset(field)   XOffsetOf(XipICRec, field)
+
+static XIMResource ic_resources[] = {
+    { XNInputStyle, sizeof(XIMStyle), offset(core.input_style),
+      (unsigned short)IMResourceReadWrite, ICInputStyle },
+    { XNClientWindow, sizeof(Window), offset(core.client_window),
+      (unsigned short)IMResourceReadWrite, ICClientWindow },
+    { XNFocusWindow, sizeof(Window), offset(core.focus_window),
+      (unsigned short)IMResourceReadWrite, ICFocusWindow },
+    { XNResourceName, sizeof(char *), offset(values.res_name),
+      (unsigned short)IMResourceReadWrite, ICResourceName },
+    { XNResourceClass, sizeof(char *), offset(values.res_class),
+      (unsigned short)IMResourceReadWrite, ICResourceClass },
+    { XNFilterEvents, sizeof(long), offset(core.filter_events),
+      (unsigned short)IMResourceRead, ICFilterEvents },
+    { XNPreeditAttributes, sizeof(ICAttributes *), offset(core.preedit_attr),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNStatusAttributes, sizeof(ICAttributes *), offset(core.status_attr),
+      (unsigned short)IMResourceReadWrite, -1 }
+#ifdef XML
+    ,
+    { XNUsingLanguage, sizeof(char *), offset(values.using_language),
+      (unsigned short)IMResourceReadWrite, ICUsingLanguage },
+    { XNCurrentLanguage, sizeof(char *), offset(values.current_language),
+      (unsigned short)IMResourceReadWrite, ICCurrentLanguage },
+    { XNChangeLocaleCB, sizeof(char **), offset(values.ch_locale_cb),
+      (unsigned short)IMResourceReadWrite, ICChangeLocaleCB },
+#endif /* XML */
+};
+
+#undef offset
+
+#define        attroffset(field)       XOffsetOf(ICAttributes, field)
+
+static XIMResource attr_resources[] = {
+    { XNArea, sizeof(XRectangle), attroffset(area),
+      (unsigned short)IMResourceReadWrite, ICArea },
+    { XNAreaNeeded, sizeof(XRectangle), attroffset(area_needed),
+      (unsigned short)IMResourceReadWrite, ICAreaNeeded },
+    { XNSpotLocation, sizeof(XPoint), attroffset(spot_location),
+      (unsigned short)IMResourceReadWrite, ICSpotLocation },
+    { XNColormap, sizeof(Colormap), attroffset(colormap),
+      (unsigned short)IMResourceReadWrite, ICColormap },
+    { XNStdColormap, sizeof(Atom), attroffset(std_colormap),
+      (unsigned short)IMResourceReadWrite, ICStdColormap },
+    { XNForeground, sizeof(long), attroffset(foreground),
+      (unsigned short)IMResourceReadWrite, ICForeground },
+    { XNBackground, sizeof(long), attroffset(background),
+      (unsigned short)IMResourceReadWrite, ICBackground },
+    { XNBackgroundPixmap, sizeof(Pixmap), attroffset(background_pixmap),
+      (unsigned short)IMResourceReadWrite, ICBackgroundPixmap },
+    { XNFontSet, sizeof(XFontSet *), attroffset(fontset),
+      (unsigned short)IMResourceReadWrite, ICFontSet },
+    { XNLineSpace, sizeof(int), attroffset(line_space),
+      (unsigned short)IMResourceReadWrite, ICLineSpace },
+    { XNCursor, sizeof(Cursor), attroffset(cursor),
+      (unsigned short)IMResourceReadWrite, ICCursor },
+    { XNPreeditStartCallback, sizeof(XIMCallback), attroffset(callbacks.start),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNPreeditDoneCallback, sizeof(XIMCallback), attroffset(callbacks.done),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNPreeditDrawCallback, sizeof(XIMCallback), attroffset(callbacks.draw),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNPreeditCaretCallback, sizeof(XIMCallback), attroffset(callbacks.caret),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNStatusStartCallback, sizeof(XIMCallback), attroffset(callbacks.start),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNStatusDoneCallback, sizeof(XIMCallback), attroffset(callbacks.done),
+      (unsigned short)IMResourceReadWrite, -1 },
+    { XNStatusDrawCallback, sizeof(XIMCallback), attroffset(callbacks.draw),
+      (unsigned short)IMResourceReadWrite, -1 }
+};
+
+#undef attroffset
+
+
+/*
+ * Close the connection to the input manager, and free the private data
+ */
+static Status
+_XipCloseIM(supim)
+    XIM supim;
+{
+    XipIM im = (XipIM)supim;
+    if (im->fd >= 0)
+       _XipDisconnectIM(im->fd);
+    _XlcFreeLocale(im->xlc);
+    Xfree(im->client_data);
+    if (im->default_ic) Xfree((char *)im->default_ic);
+    return(Success);
+}
+
+static RConst XIMMethodsRec im_methods = {
+    _XipCloseIM,
+    _XipGetIMValues,
+    _XipCreateIC
+};
+
+/*
+ * Connects to an input method matching current locale specification, creates
+ * a XIM object and return a pointer the newly created XIM back to the caller.
+ */
+XIM 
+_XipOpenIM(lcd, display, rdb, res_name, res_class)
+    XLCd lcd;
+    Display *display;
+    XrmDatabase rdb;
+    char *res_name;
+    char *res_class;
+{
+    Atom               atom_im;
+    XipIM              xim;
+    char               strbuf[128];
+    char               *str, *prop_im, *p;
+    XLocale            xlc = ((XsiLCd)lcd)->xlc;
+#ifdef uniosu
+    extern struct passwd *getpwuid();
+#endif
+
+    str = lcd->core.modifiers;
+    while (str && strncmp(str+1, "im=", 3))
+       str = index(str+1, '@');
+    if (!str)
+       strbuf[0] = '\0';
+    else {
+       str += 4;
+       p = index(str, '@');
+       if (p) {
+           strncpy(strbuf, str, p - str);
+           strbuf[p - str] = '\0';
+       } else {
+           strcpy(strbuf, str);
+       }
+    }
+    if (strbuf[0] == '\0')
+       prop_im = XIM_INPUTMETHOD;
+    else if (!strcmp(strbuf, "None") || !strcmp(strbuf, "NONE"))
+       return(NULL);
+#ifndef        NO_LOCAL_IM
+    else if (!strcmp(strbuf, "Local"))
+       return(_XipLocalOpenIM(lcd, display, rdb, res_name, res_class));
+#endif
+    else
+       prop_im = strbuf;
+
+    /*
+     * Check whether an input manager is running or not. If the input manager
+     * isn't running, return NULL.
+     */
+    if ((atom_im = XInternAtom(display, prop_im, True)) == None) {
+       return(NULL);
+    }
+    if (XGetSelectionOwner (display, atom_im) == None) {
+       return(NULL);
+    }
+
+    /*
+     * Gets display name from the display structure. If the display name is
+     * NULL, gets from the DISPLAY variable.
+     */
+    if (DisplayString(display)) {
+      strcpy(strbuf, DisplayString(display));
+    } else if (str = getenv("DISPLAY")) {
+       /* If the display string is NULL, read the DISPLAY variable. */
+       strcpy(strbuf, str);
+    } else {
+       /* No display name - error. */
+       return(NULL);
+    }
+
+    /*
+     * Attempt to allocate a XIM structure. Return NULL if allocation
+     * failed.
+     */
+    if ((xim = (XipIM)Xmalloc(sizeof(XipIMRec))) == NULL) {
+       return(NULL);
+    }
+    xim->methods = (XIMMethods)&im_methods;
+    xim->sp = 0;
+    xim->rp = 0;
+    xim->rc = 0;
+    xim->core.lcd = lcd;
+    xim->core.ic_chain = NULL;
+    xim->core.display = display;
+    xim->core.rdb = rdb;
+    xim->core.res_name = res_name;
+    xim->core.res_class = res_class;
+    xim->values.input_styles.supported_styles = NULL;
+    xim->values.input_styles.count_styles = 0;
+#ifdef XML
+    xim->values.supported_language = NULL;
+#endif /* XML */
+
+    /*
+     * Get user name.
+     */
+    if ((str = getenv("USER")) == NULL)
+       str = getpwuid(getuid())->pw_name;
+    xim->client_data = Xmalloc(strlen(str) + 1);
+    if (!xim->client_data) {
+       Xfree((char *)xim);
+       return NULL;
+    }
+    (void)strcpy(xim->client_data, str);
+
+    if (!compiled_resources) {
+       _XIMCompileResourceList(im_resources, XIMNumber(im_resources));
+       _XIMCompileResourceList(ic_resources, XIMNumber(ic_resources));
+       _XIMCompileResourceList(attr_resources, XIMNumber(attr_resources));
+       compiled_resources = 1;
+    }
+    xim->resources = (XIMrmResourceList)im_resources;
+    xim->num_resources = XIMNumber(im_resources);
+    xim->core.ic_resources = (XIMrmResourceList)ic_resources;
+    xim->core.ic_num_resources = XIMNumber(ic_resources);
+    xim->core.ic_attr_resources = (XIMrmResourceList)attr_resources;
+    xim->core.ic_num_attr_resources = XIMNumber(attr_resources);
+
+    /*
+     * Call the Connect routine to get the network socket. If a value less
+     * than 0 is returned, the connection failed. 
+     */
+    if ((_XipConnectIM(xim, atom_im, strbuf)) != True) {
+       Xfree(xim->client_data);
+       Xfree((char *)xim);
+       return(NULL);
+    }
+
+    xim->xlc = _XlcDupLocale(xlc);
+
+    /*
+     * Create a default IC.
+     */
+    if (!_XipCreateDefIC(xim)) {
+       XCloseIM((XIM)xim);
+       return(NULL);
+    }
+
+    return((XIM)xim);
+}
+
+#ifdef XML
+XIM 
+XmlOpenIM(display, rdb, res_name, res_class)
+Display *display;
+XrmDatabase rdb;
+char *res_name;
+char *res_class;
+{
+    XIM                supim;
+    XipIM      im;
+
+    if ((supim = XOpenIM(display, rdb, res_name, res_class)) == NULL) {
+       return(NULL);
+    }
+    im = (XipIM)supim;
+    if (im->xlc) {
+       _XlcFreeLocale(im->xlc);
+       im->xlc = NULL;
+    }
+    return(supim);
+}
+#endif /* XML */