1 
2 /*
3  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
4  * 	All Rights Reserved
5  *
6  * This file is a component of an X Window System-specific implementation
7  * of Xcms based on the TekColor Color Management System.  Permission is
8  * hereby granted to use, copy, modify, sell, and otherwise distribute this
9  * software and its documentation for any purpose and without fee, provided
10  * that this copyright, permission, and disclaimer notice is reproduced in
11  * all copies of this software and in supporting documentation.  TekColor
12  * is a trademark of Tektronix, Inc.
13  *
14  * Tektronix makes no representation about the suitability of this software
15  * for any purpose.  It is provided "as is" and with all faults.
16  *
17  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
18  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
20  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
22  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
24  *
25  *
26  *	NAME
27  *		XcmsAddSF.c
28  *
29  *	DESCRIPTION
30  *		Source for XcmsAddFunctionSet
31  *
32  *
33  */
34 
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38 #include "Xlibint.h"
39 #include "Xcmsint.h"
40 #include "Cv.h"
41 
42 /*
43  *      DEFINES
44  */
45 #define NextUnregDdCsID(lastid) \
46 	    (XCMS_UNREG_ID(lastid) ? ++lastid : XCMS_FIRST_UNREG_DD_ID)
47 #define MIN(x,y) ((x) > (y) ? (y) : (x))
48 
49 
50 /*
51  *	NAME
52  *		XcmsAddFunctionSet - Add an Screen Color Characterization
53  *					Function Set
54  *
55  *	SYNOPSIS
56  */
57 Status
XcmsAddFunctionSet(XcmsFunctionSet * pNewFS)58 XcmsAddFunctionSet(XcmsFunctionSet *pNewFS)
59 /*
60  *	DESCRIPTION
61  *		Additional Screen Color Characterization Function Sets are
62  *		managed on a global basis.  This means that with exception
63  *		of the provided DD color spaces:
64  *			    RGB and RGBi
65  *		DD color spaces may have different XcmsColorFormat IDs between
66  *		clients.  So, you must be careful when using XcmsColorFormat
67  *		across clients!  Use the routines XcmsFormatOfPrefix()
68  *		and XcmsPrefixOfFormat() appropriately.
69  *
70  *	RETURNS
71  *		XcmsSuccess if succeeded, otherwise XcmsFailure
72  *
73  *	CAVEATS
74  *		Additional Screen Color Characterization Function Sets
75  *		should be added prior to any use of the routine
76  *		XcmsCreateCCC().  If not, XcmsCCC structures created
77  *		prior to the call of this routines will not have had
78  *		a chance to initialize using the added Screen Color
79  *		Characterization Function Set.
80  */
81 {
82     XcmsFunctionSet **papSCCFuncSets = _XcmsSCCFuncSets;
83     XcmsColorSpace **papNewCSs;
84     XcmsColorSpace *pNewCS, **paptmpCS;
85     XcmsColorFormat lastID = 0;
86 
87 
88     if (papSCCFuncSets != NULL) {
89 	if ((papNewCSs = pNewFS->DDColorSpaces) == NULL) {
90 	    /*
91 	     * Error, new Screen Color Characterization Function Set
92 	     *	missing color spaces
93 	     */
94 	    return(XcmsFailure);
95 	}
96 	while ((pNewCS = *papNewCSs++) != NULL) {
97 	    if ((pNewCS->id = _XcmsRegFormatOfPrefix(pNewCS->prefix)) != 0) {
98 		if (XCMS_DI_ID(pNewCS->id)) {
99 		    /* This is a Device-Independent Color Space */
100 		    return(XcmsFailure);
101 		}
102 		/*
103 		 * REGISTERED DD Color Space
104 		 *    therefore use the registered ID.
105 		 */
106 	    } else {
107 		/*
108 		 * UNREGISTERED DD Color Space
109 		 *    then see if the color space is already in
110 		 *    _XcmsDDColorSpaces.
111 		 *	    a. If same prefix, then use the same ID.
112 		 *	    b. Otherwise, use a new ID.
113 		 */
114 		for (paptmpCS = _XcmsDDColorSpaces; *paptmpCS != NULL;
115 			paptmpCS++){
116 		    lastID = MIN(lastID, (*paptmpCS)->id);
117 		    if (strcmp(pNewCS->prefix, (*paptmpCS)->prefix) == 0) {
118 			pNewCS->id = (*paptmpCS)->id;
119 			break;
120 		    }
121 		}
122 		if (pNewCS->id == 0) {
123 		    /* still haven't found one */
124 		    pNewCS->id = NextUnregDdCsID(lastID);
125 		    if ((paptmpCS = (XcmsColorSpace **)_XcmsPushPointerArray(
126 		   	    (XPointer *) _XcmsDDColorSpaces,
127 			    (XPointer) pNewCS,
128 			    (XPointer *) _XcmsDDColorSpacesInit)) == NULL) {
129 			return(XcmsFailure);
130 		    }
131 		    _XcmsDDColorSpaces = paptmpCS;
132 		}
133 	    }
134 	}
135     }
136     if ((papSCCFuncSets = (XcmsFunctionSet **)
137 	    _XcmsPushPointerArray((XPointer *) _XcmsSCCFuncSets,
138 	    (XPointer) pNewFS,
139 	    (XPointer *)_XcmsSCCFuncSetsInit)) == NULL) {
140 	return(XcmsFailure);
141     }
142     _XcmsSCCFuncSets = papSCCFuncSets;
143 
144     return(XcmsSuccess);
145 }
146