diff options
Diffstat (limited to 'libX11/src/xcms/cmsInt.c')
-rw-r--r-- | libX11/src/xcms/cmsInt.c | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/libX11/src/xcms/cmsInt.c b/libX11/src/xcms/cmsInt.c new file mode 100644 index 000000000..68cfebd74 --- /dev/null +++ b/libX11/src/xcms/cmsInt.c @@ -0,0 +1,415 @@ +/* $Xorg: cmsInt.c,v 1.4 2000/08/17 19:45:09 cpqbld 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. + * + * + */ +/* $XFree86: xc/lib/X11/cmsInt.c,v 1.4 2003/04/13 19:22:20 dawes Exp $ */ + +/* #define NEED_EVENTS */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" +#include "Cv.h" + +#ifndef XCMSCOMPPROC +# define XCMSCOMPPROC XcmsTekHVCClipC +#endif + +/* forward/static */ +static void _XcmsFreeDefaultCCCs(Display *dpy); + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCopyPointerArray + * + * SYNOPSIS + */ +XPointer * +_XcmsCopyPointerArray( + 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)))) { + memcpy((char *)newArray, (char *)pap, + (unsigned)(n * sizeof(XPointer))); + } + return((XPointer *)newArray); +} + +/* + * NAME + * _XcmsFreePointerArray + * + * SYNOPSIS + */ +void +_XcmsFreePointerArray( + XPointer *pap) +/* + * DESCRIPTION + * Frees an array of NULL terminated pointers. + * + * RETURNS + * void + * + */ +{ + Xfree(pap); +} + +/* + * NAME + * _XcmsPushPointerArray + * + * SYNOPSIS + */ +XPointer * +_XcmsPushPointerArray( + 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)))) { + memcpy((char *)(newArray+1),(char *)pap, + (unsigned)((n-1) * sizeof(XPointer))); + *newArray = p; + } + if (pap != papNoFree) { + _XcmsFreePointerArray(pap); + } + return((XPointer *)newArray); +} + +/* + * NAME + * _XcmsInitDefaultCCCs + * + * SYNOPSIS + */ +int +_XcmsInitDefaultCCCs( + 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); +} + + +/* + * NAME + * _XcmsFreeDefaultCCCs - Free Default CCCs and its PerScrnInfo + * + * SYNOPSIS + */ +static void +_XcmsFreeDefaultCCCs( + 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 != XcmsInitNone + && 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; +} + + + +/* + * NAME + * _XcmsInitScrnInfo + * + * SYNOPSIS + */ +int +_XcmsInitScrnInfo( + 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)); +} + + +/* + * NAME + * _XcmsFreeIntensityMaps + * + * SYNOPSIS + */ +void +_XcmsFreeIntensityMaps( + 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; +} + + +/* + * NAME + * _XcmsGetIntensityMap + * + * SYNOPSIS + */ +XcmsIntensityMap * +_XcmsGetIntensityMap( + 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); +} |