CCC.c revision 1ab64890
1/* $Xorg: CCC.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */
2
3/*
4 * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
5 * 	All Rights Reserved
6 *
7 * This file is a component of an X Window System-specific implementation
8 * of Xcms based on the TekColor Color Management System.  Permission is
9 * hereby granted to use, copy, modify, sell, and otherwise distribute this
10 * software and its documentation for any purpose and without fee, provided
11 * that this copyright, permission, and disclaimer notice is reproduced in
12 * all copies of this software and in supporting documentation.  TekColor
13 * is a trademark of Tektronix, Inc.
14 *
15 * Tektronix makes no representation about the suitability of this software
16 * for any purpose.  It is provided "as is" and with all faults.
17 *
18 * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
19 * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
21 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
23 * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
24 * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
25 *
26 *
27 *	NAME
28 *		XcmsCCC.c - Color Conversion Context Routines
29 *
30 *	DESCRIPTION
31 *		Routines to create, access, and free Color Conversion
32 *		Context structures.
33 *
34 *
35 */
36/* $XFree86: xc/lib/X11/CCC.c,v 1.4 2001/12/14 19:53:56 dawes Exp $ */
37
38/*
39
40Copyright 1994, 1998  The Open Group
41
42Permission to use, copy, modify, distribute, and sell this software and its
43documentation for any purpose is hereby granted without fee, provided that
44the above copyright notice appear in all copies and that both that
45copyright notice and this permission notice appear in supporting
46documentation.
47
48The above copyright notice and this permission notice shall be included
49in all copies or substantial portions of the Software.
50
51THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
52OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
54IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
55OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
56ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
57OTHER DEALINGS IN THE SOFTWARE.
58
59Except as contained in this notice, the name of The Open Group shall
60not be used in advertising or otherwise to promote the sale, use or
61other dealings in this Software without prior written authorization
62from The Open Group.
63
64*/
65
66#ifdef HAVE_CONFIG_H
67#include <config.h>
68#endif
69#include <stdio.h>
70#include "Xlibint.h"
71#include "Xcmsint.h"
72#include "Cv.h"
73
74
75
76/************************************************************************
77 *									*
78 *			PUBLIC INTERFACES				*
79 *									*
80 ************************************************************************/
81
82/*
83 *	NAME
84 *		XcmsCreateCCC
85 *
86 *	SYNOPSIS
87 */
88
89XcmsCCC
90XcmsCreateCCC(
91    Display *dpy,
92    int screenNumber,
93    Visual *visual,
94    XcmsColor *clientWhitePt,
95    XcmsCompressionProc gamutCompProc,
96    XPointer gamutCompClientData,
97    XcmsWhiteAdjustProc whitePtAdjProc,
98    XPointer whitePtAdjClientData)
99/*
100 *	DESCRIPTION
101 *		Given a Display, Screen, Visual, etc., this routine creates
102 *		an appropriate Color Conversion Context.
103 *
104 *	RETURNS
105 *		Returns NULL if failed; otherwise address of the newly
106 *		created XcmsCCC.
107 *
108 */
109{
110    XcmsCCC pDefaultCCC = XcmsDefaultCCC(dpy, screenNumber);
111    XcmsCCC newccc;
112    XcmsIntensityMap *pIMap;
113    XcmsPerScrnInfo *pNewScrnInfo;
114
115    if (pDefaultCCC == NULL ||
116	    !(newccc = (XcmsCCC) Xcalloc(1, (unsigned) sizeof(XcmsCCCRec)))) {
117	return(NULL);
118    }
119
120    /*
121     * Should inherit the following as result of a memmove():
122     *		dpy
123     *		screenNumber
124     *		pPerScrnInfo
125     */
126    memcpy((char *)newccc, (char *)pDefaultCCC, sizeof(XcmsCCCRec));
127    if (clientWhitePt) {
128	memcpy((char *)&newccc->clientWhitePt, (char *)clientWhitePt,
129		sizeof(XcmsColor));
130    }
131    if (gamutCompProc) {
132	newccc->gamutCompProc = gamutCompProc;
133    }
134    if (gamutCompClientData) {
135	newccc->gamutCompClientData = gamutCompClientData;
136    }
137    if (whitePtAdjProc) {
138	newccc->whitePtAdjProc = whitePtAdjProc;
139    }
140    if (whitePtAdjClientData) {
141	newccc->whitePtAdjClientData = whitePtAdjClientData;
142    }
143
144    /*
145     * Now check our list of per-Visual Intensity tables.
146     * If one exists replace the pPerScrnInfo.
147     */
148    if ((pIMap = _XcmsGetIntensityMap(dpy, visual)) != NULL) {
149	if (!(pNewScrnInfo = (XcmsPerScrnInfo *)
150		Xcalloc(1, (unsigned) sizeof(XcmsPerScrnInfo)))) {
151	    Xfree(newccc);
152	    return(NULL);
153	}
154	memcpy((char *)pNewScrnInfo, (char *)newccc->pPerScrnInfo,
155		sizeof(XcmsPerScrnInfo));
156	pNewScrnInfo->screenData = pIMap->screenData;
157	newccc->pPerScrnInfo = pNewScrnInfo;
158    }
159
160    /*
161     * Set visual component
162     */
163    newccc->visual = visual;
164
165    return(newccc);
166}
167
168
169/*
170 *	NAME
171 *		XcmsDefaultCCC
172 *
173 *	SYNOPSIS
174 */
175XcmsCCC
176XcmsDefaultCCC(
177    Display *dpy,
178    int screenNumber)
179/*
180 *	DESCRIPTION
181 *		Given a Display and Screen, this routine creates
182 *		returns the Screen's default Color Conversion Context.
183 *		Note that a Screen's default CCC is built with the
184 *		screen default visual.
185 *
186 *	RETURNS
187 *		Returns NULL if failed; otherwise address of the
188 *		XcmsCCC for the Screen's default CCC.
189 *
190 */
191{
192    XcmsCCC ccc;
193
194
195    if ((screenNumber < 0) || (screenNumber >= ScreenCount(dpy))) {
196	return((XcmsCCC)NULL);
197    }
198
199    /*
200     * Check if the XcmsCCC's for each screen has been created
201     */
202    if ((XcmsCCC)dpy->cms.defaultCCCs == NULL) {
203	if (!_XcmsInitDefaultCCCs(dpy)) {
204	    return((XcmsCCC)NULL);
205	}
206    }
207
208    ccc = (XcmsCCC)dpy->cms.defaultCCCs + screenNumber;
209
210    if (!ccc->pPerScrnInfo) {
211	/*
212	 * Need to create the XcmsPerScrnInfo structure.  The
213	 * _XcmsInitScrnInfo routine will create the XcmsPerScrnInfo
214	 * structure as well as initialize its functionSet and pScreenData
215	 * components.
216	 */
217	if (!_XcmsInitScrnInfo(dpy, screenNumber)) {
218	    return((XcmsCCC)NULL);
219	}
220	return(ccc);
221    } else {
222	/*
223	 * If ccc->pPerScrnInfo->state == XcmsInitSuccess,
224	 *    then the pPerScrnInfo component has already been initialized
225	 *    therefore, just return ccc.
226	 * If ccc->pPerScrnInfo->state == XcmsInitFailure,
227	 *    then this means that we already attempted to initialize
228	 *    the pPerScrnInfo component but failed therefore stuffing
229	 *    the pPerScrnInfo component with defaults.  Just return ccc.
230	 * If ccc->pPerScrnInfo->state == XcmsInitNone,
231	 *    then attempt to initialize the pPerScrnInfo component.
232	 */
233	switch (ccc->pPerScrnInfo->state) {
234	   case XcmsInitFailure :
235	    /* fall through */
236	   case XcmsInitSuccess :
237	    return(ccc);
238	   case XcmsInitNone :
239	    /* XcmsPerScreenInfo has not been initialized */
240	    if (!_XcmsInitScrnInfo(dpy, screenNumber)) {
241		return((XcmsCCC)NULL);
242	    }
243	    return(ccc);
244	   default :
245	    return((XcmsCCC)NULL);
246	}
247    }
248}
249
250
251/*
252 *	NAME
253 *		XcmsFreeCCC
254 *
255 *	SYNOPSIS
256 */
257void
258XcmsFreeCCC(XcmsCCC ccc)
259/*
260 *	DESCRIPTION
261 *		Frees memory associated with a Color Conversion Context
262 *		that was created with XcmsCreateCCC().
263 *
264 *	RETURNS
265 *		void
266 *
267 */
268{
269    if (ccc->dpy->cms.defaultCCCs &&
270	ccc == ((XcmsCCC)ccc->dpy->cms.defaultCCCs) + ccc->screenNumber) {
271	/* do not allow clients to free DefaultCCC's */
272	return;
273    }
274
275    /*
276     * Note that XcmsPerScrnInfo sub-structures are freed here only if
277     * they are for visuals that have per-Visual intensity tables.
278     * Otherwise the XcmsPerScrnInfo structure is being shared!
279     * For the latter, there is only one allocated per Screen and it just
280     * so happens * that we place its initial reference is placed in the
281     * 	default CCC.  The routine _XcmsFreeDefaultCCCs frees them.
282     */
283    if (_XcmsGetIntensityMap(ccc->dpy, ccc->visual) != NULL) {
284	Xfree(ccc->pPerScrnInfo);
285    }
286
287    Xfree(ccc);
288}
289