cmsCmap.c revision 3233502e
11ab64890Smrg
21ab64890Smrg/*
31ab64890Smrg * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
41ab64890Smrg * 	All Rights Reserved
561b2299dSmrg *
61ab64890Smrg * This file is a component of an X Window System-specific implementation
71ab64890Smrg * of Xcms based on the TekColor Color Management System.  Permission is
81ab64890Smrg * hereby granted to use, copy, modify, sell, and otherwise distribute this
91ab64890Smrg * software and its documentation for any purpose and without fee, provided
101ab64890Smrg * that this copyright, permission, and disclaimer notice is reproduced in
111ab64890Smrg * all copies of this software and in supporting documentation.  TekColor
121ab64890Smrg * is a trademark of Tektronix, Inc.
1361b2299dSmrg *
141ab64890Smrg * Tektronix makes no representation about the suitability of this software
151ab64890Smrg * for any purpose.  It is provided "as is" and with all faults.
1661b2299dSmrg *
171ab64890Smrg * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
181ab64890Smrg * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
191ab64890Smrg * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
201ab64890Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
211ab64890Smrg * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
221ab64890Smrg * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
231ab64890Smrg * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg *
251ab64890Smrg *
261ab64890Smrg *	NAME
271ab64890Smrg *		XcmsCmap.c - Client Colormap Management Routines
281ab64890Smrg *
291ab64890Smrg *	DESCRIPTION
301ab64890Smrg *		Routines that store additional information about
311ab64890Smrg *		colormaps being used by the X Client.
321ab64890Smrg *
331ab64890Smrg *
341ab64890Smrg */
351ab64890Smrg
361ab64890Smrg#ifdef HAVE_CONFIG_H
371ab64890Smrg#include <config.h>
381ab64890Smrg#endif
391ab64890Smrg#include "Xlibint.h"
401ab64890Smrg#include "Xcmsint.h"
411ab64890Smrg#include "Xutil.h"
421ab64890Smrg#include "Cmap.h"
431ab64890Smrg#include "Cv.h"
441ab64890Smrg
451ab64890Smrg/*
461ab64890Smrg *      FORWARD DECLARATIONS
471ab64890Smrg */
481ab64890Smrgstatic void _XcmsFreeClientCmaps(Display *dpy);
491ab64890Smrg
501ab64890Smrg
511ab64890Smrg/************************************************************************
521ab64890Smrg *									*
531ab64890Smrg *			PRIVATE INTERFACES				*
541ab64890Smrg *									*
551ab64890Smrg ************************************************************************/
561ab64890Smrg
571ab64890Smrg/*
581ab64890Smrg *	NAME
591ab64890Smrg *		CmapRecForColormap
601ab64890Smrg *
611ab64890Smrg *	SYNOPSIS
621ab64890Smrg */
631ab64890Smrgstatic XcmsCmapRec *
641ab64890SmrgCmapRecForColormap(
651ab64890Smrg    Display *dpy,
661ab64890Smrg    Colormap cmap)
671ab64890Smrg/*
681ab64890Smrg *	DESCRIPTION
691ab64890Smrg *		Find the corresponding XcmsCmapRec for cmap.  In not found
701ab64890Smrg *		this routines attempts to create one.
711ab64890Smrg *
721ab64890Smrg *	RETURNS
731ab64890Smrg *		Returns NULL if failed; otherwise the address to
741ab64890Smrg *		the corresponding XcmsCmapRec.
751ab64890Smrg *
761ab64890Smrg */
771ab64890Smrg{
781ab64890Smrg    XcmsCmapRec *pRec;
791ab64890Smrg    int nScrn;
801ab64890Smrg    int i, j;
811ab64890Smrg    XVisualInfo visualTemplate;	/* Template of the visual we want */
821ab64890Smrg    XVisualInfo *visualList;	/* List for visuals that match */
831ab64890Smrg    int nVisualsMatched;	/* Number of visuals that match */
841ab64890Smrg    Window tmpWindow;
851ab64890Smrg    Visual *vp;
861ab64890Smrg    unsigned long border = 0;
871ab64890Smrg    _XAsyncHandler async;
881ab64890Smrg    _XAsyncErrorState async_state;
891ab64890Smrg
901ab64890Smrg    for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
911ab64890Smrg	    pRec = pRec->pNext) {
921ab64890Smrg	if (pRec->cmapID == cmap) {
931ab64890Smrg	    return(pRec);
941ab64890Smrg	}
951ab64890Smrg    }
961ab64890Smrg
971ab64890Smrg    /*
981ab64890Smrg     * Can't find an XcmsCmapRec associated with cmap in our records.
991ab64890Smrg     * Let's try to see if its a default colormap
1001ab64890Smrg     */
1011ab64890Smrg    nScrn = ScreenCount(dpy);
1021ab64890Smrg    for (i = 0; i < nScrn; i++) {
1031ab64890Smrg	if (cmap == DefaultColormap(dpy, i)) {
1041ab64890Smrg	    /* It is ... lets go ahead and store that info */
1051ab64890Smrg	    if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
1061ab64890Smrg		    DefaultVisual(dpy, i))) == NULL) {
1071ab64890Smrg		return((XcmsCmapRec *)NULL);
1081ab64890Smrg	    }
1091ab64890Smrg	    pRec->ccc = XcmsCreateCCC(
1101ab64890Smrg		    dpy,
1111ab64890Smrg		    i,			/* screenNumber */
1121ab64890Smrg		    DefaultVisual(dpy, i),
1131ab64890Smrg		    (XcmsColor *)NULL,	/* clientWhitePt */
1141ab64890Smrg		    (XcmsCompressionProc)NULL,  /* gamutCompProc */
1151ab64890Smrg		    (XPointer)NULL,	/* gamutCompClientData */
1161ab64890Smrg		    (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
1171ab64890Smrg		    (XPointer)NULL	/* whitePtAdjClientData */
1181ab64890Smrg		    );
1191ab64890Smrg	    return(pRec);
1201ab64890Smrg	}
1211ab64890Smrg    }
1221ab64890Smrg
1231ab64890Smrg    /*
1241ab64890Smrg     * Nope, its not a default colormap, so it's probably a foreign color map
1251ab64890Smrg     * of which we have no specific details.  Let's go through the
1261ab64890Smrg     * rigorous process of finding this colormap:
1271ab64890Smrg     *        for each screen
1281ab64890Smrg     *            for each screen's visual types
1291ab64890Smrg     *                create a window with cmap specified as the colormap
1301ab64890Smrg     *                if successful
1311ab64890Smrg     *                    Add a CmapRec
1321ab64890Smrg     *                    Create an XcmsCCC
1331ab64890Smrg     *                    return the CmapRec
1341ab64890Smrg     *                else
1351ab64890Smrg     *                    continue
1361ab64890Smrg     */
1371ab64890Smrg
1381ab64890Smrg    async_state.error_code = 0; /* don't care */
1391ab64890Smrg    async_state.major_opcode = X_CreateWindow;
1401ab64890Smrg    async_state.minor_opcode = 0;
1411ab64890Smrg    for (i = 0; i < nScrn; i++) {
1421ab64890Smrg	visualTemplate.screen = i;
1431ab64890Smrg	visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate,
1441ab64890Smrg	    &nVisualsMatched);
1451ab64890Smrg	if (visualList == NULL) {
1461ab64890Smrg	    continue;
1471ab64890Smrg	}
1481ab64890Smrg
1491ab64890Smrg	/*
1501ab64890Smrg	 * Attempt to create a window with cmap
1511ab64890Smrg	 */
1521ab64890Smrg	j = 0;
1531ab64890Smrg	do {
1541ab64890Smrg	    vp = (visualList+j)->visual;
1551ab64890Smrg	    LockDisplay(dpy);
1561ab64890Smrg	    {
1571ab64890Smrg		register xCreateWindowReq *req;
1581ab64890Smrg
1591ab64890Smrg		GetReq(CreateWindow, req);
1601ab64890Smrg		async_state.min_sequence_number = dpy->request;
1611ab64890Smrg		async_state.max_sequence_number = dpy->request;
1621ab64890Smrg		async_state.error_count = 0;
1631ab64890Smrg		async.next = dpy->async_handlers;
1641ab64890Smrg		async.handler = _XAsyncErrorHandler;
1651ab64890Smrg		async.data = (XPointer)&async_state;
1661ab64890Smrg		dpy->async_handlers = &async;
1671ab64890Smrg		req->parent = RootWindow(dpy, i);
1681ab64890Smrg		req->x = 0;
1691ab64890Smrg		req->y = 0;
1701ab64890Smrg		req->width = 1;
1711ab64890Smrg		req->height = 1;
1721ab64890Smrg		req->borderWidth = 0;
1731ab64890Smrg		req->depth = (visualList+j)->depth;
1741ab64890Smrg		req->class = CopyFromParent;
1751ab64890Smrg		req->visual = vp->visualid;
1761ab64890Smrg		tmpWindow = req->wid = XAllocID(dpy);
1771ab64890Smrg		req->mask = CWBorderPixel | CWColormap;
1781ab64890Smrg		req->length += 2;
1791ab64890Smrg		Data32 (dpy, (long *) &border, 4);
1801ab64890Smrg		Data32 (dpy, (long *) &cmap, 4);
1811ab64890Smrg	    }
1821ab64890Smrg	    {
1831ab64890Smrg		xGetInputFocusReply rep;
1843233502eSmrg		_X_UNUSED register xReq *req;
1851ab64890Smrg
1861ab64890Smrg		GetEmptyReq(GetInputFocus, req);
1871ab64890Smrg		(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
1881ab64890Smrg	    }
1891ab64890Smrg	    DeqAsyncHandler(dpy, &async);
1901ab64890Smrg	    UnlockDisplay(dpy);
1911ab64890Smrg	    SyncHandle();
1921ab64890Smrg	} while (async_state.error_count > 0 && ++j < nVisualsMatched);
1931ab64890Smrg
194818534a1Smrg	Xfree(visualList);
1951ab64890Smrg
1961ab64890Smrg	/*
1971ab64890Smrg	 * if successful
1981ab64890Smrg	 */
1991ab64890Smrg	if (j < nVisualsMatched) {
2001ab64890Smrg	    if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
2011ab64890Smrg		return((XcmsCmapRec *)NULL);
2021ab64890Smrg	    pRec->ccc = XcmsCreateCCC(
2031ab64890Smrg		    dpy,
2041ab64890Smrg		    i,			/* screenNumber */
2051ab64890Smrg		    vp,
2061ab64890Smrg		    (XcmsColor *)NULL,	/* clientWhitePt */
2071ab64890Smrg		    (XcmsCompressionProc)NULL,  /* gamutCompProc */
2081ab64890Smrg		    (XPointer)NULL,	/* gamutCompClientData */
2091ab64890Smrg		    (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
2101ab64890Smrg		    (XPointer)NULL	/* whitePtAdjClientData */
2111ab64890Smrg		    );
2121ab64890Smrg	    XDestroyWindow(dpy, tmpWindow);
2131ab64890Smrg	    return(pRec);
2141ab64890Smrg	}
2151ab64890Smrg    }
2161ab64890Smrg
2171ab64890Smrg    return(NULL);
2181ab64890Smrg}
2191ab64890Smrg
2201ab64890Smrg
2211ab64890Smrg
2221ab64890Smrg/************************************************************************
2231ab64890Smrg *									*
2241ab64890Smrg *			API PRIVATE INTERFACES				*
2251ab64890Smrg *									*
2261ab64890Smrg ************************************************************************/
2271ab64890Smrg
2281ab64890Smrg/*
2291ab64890Smrg *	NAME
2301ab64890Smrg *		_XcmsAddCmapRec
2311ab64890Smrg *
2321ab64890Smrg *	SYNOPSIS
2331ab64890Smrg */
2341ab64890SmrgXcmsCmapRec *
2351ab64890Smrg_XcmsAddCmapRec(
2361ab64890Smrg    Display *dpy,
2371ab64890Smrg    Colormap cmap,
2381ab64890Smrg    Window windowID,
2391ab64890Smrg    Visual *visual)
2401ab64890Smrg/*
2411ab64890Smrg *	DESCRIPTION
2421ab64890Smrg *		Create an XcmsCmapRec for the specified cmap, windowID,
2431ab64890Smrg *		and visual, then adds it to its list of CmapRec's.
2441ab64890Smrg *
2451ab64890Smrg *	RETURNS
2461ab64890Smrg *		Returns NULL if failed; otherwise the address to
2471ab64890Smrg *		the added XcmsCmapRec.
2481ab64890Smrg *
2491ab64890Smrg */
2501ab64890Smrg{
2511ab64890Smrg    XcmsCmapRec *pNew;
2521ab64890Smrg
253818534a1Smrg    if ((pNew = Xcalloc(1, sizeof(XcmsCmapRec))) == NULL) {
2541ab64890Smrg	return((XcmsCmapRec *)NULL);
2551ab64890Smrg    }
2561ab64890Smrg
2571ab64890Smrg    pNew->cmapID = cmap;
2581ab64890Smrg    pNew->dpy = dpy;
2591ab64890Smrg    pNew->windowID = windowID;
2601ab64890Smrg    pNew->visual = visual;
2611ab64890Smrg    pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
2621ab64890Smrg    dpy->cms.clientCmaps = (XPointer)pNew;
2631ab64890Smrg    dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
2641ab64890Smrg
2651ab64890Smrg    /*
2661ab64890Smrg     * Note, we don't create the XcmsCCC for pNew->ccc here because
2671ab64890Smrg     * it may require the use of XGetWindowAttributes (a round trip request)
2681ab64890Smrg     * to determine the screen.
2691ab64890Smrg     */
2701ab64890Smrg    return(pNew);
2711ab64890Smrg}
2721ab64890Smrg
2731ab64890Smrg
2741ab64890Smrg/*
2751ab64890Smrg *	NAME
2761ab64890Smrg *		_XcmsCopyCmapRecAndFree
2771ab64890Smrg *
2781ab64890Smrg *	SYNOPSIS
2791ab64890Smrg */
2801ab64890SmrgXcmsCmapRec *
2811ab64890Smrg_XcmsCopyCmapRecAndFree(
2821ab64890Smrg    Display *dpy,
2831ab64890Smrg    Colormap src_cmap,
2841ab64890Smrg    Colormap copy_cmap)
2851ab64890Smrg/*
2861ab64890Smrg *	DESCRIPTION
2871ab64890Smrg *		Augments Xlib's XCopyColormapAndFree() to copy
2881ab64890Smrg *		XcmsCmapRecs.
2891ab64890Smrg *
2901ab64890Smrg *	RETURNS
2911ab64890Smrg *		Returns NULL if failed; otherwise the address to
2921ab64890Smrg *		the copy XcmsCmapRec.
2931ab64890Smrg *
2941ab64890Smrg */
2951ab64890Smrg{
2961ab64890Smrg    XcmsCmapRec *pRec_src;
2971ab64890Smrg    XcmsCmapRec *pRec_copy;
2981ab64890Smrg
2991ab64890Smrg    if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) {
3001ab64890Smrg	pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID,
3011ab64890Smrg		pRec_src->visual);
3021ab64890Smrg	if (pRec_copy != NULL && pRec_src->ccc) {
303818534a1Smrg	    pRec_copy->ccc = Xcalloc(1, sizeof(XcmsCCCRec));
3041ab64890Smrg	    memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc,
3051ab64890Smrg		   sizeof(XcmsCCCRec));
3061ab64890Smrg	}
3071ab64890Smrg	return(pRec_copy);
3081ab64890Smrg    }
3091ab64890Smrg    return((XcmsCmapRec *)NULL);
3101ab64890Smrg}
3111ab64890Smrg
3121ab64890Smrg
3131ab64890Smrg/*
3141ab64890Smrg *	NAME
3151ab64890Smrg *		_XcmsDeleteCmapRec
3161ab64890Smrg *
3171ab64890Smrg *	SYNOPSIS
3181ab64890Smrg */
3191ab64890Smrgvoid
3201ab64890Smrg_XcmsDeleteCmapRec(
3211ab64890Smrg    Display *dpy,
3221ab64890Smrg    Colormap cmap)
3231ab64890Smrg/*
3241ab64890Smrg *	DESCRIPTION
3251ab64890Smrg *		Removes and frees the specified XcmsCmapRec structure
3261ab64890Smrg *		from the linked list of structures.
3271ab64890Smrg *
3281ab64890Smrg *	RETURNS
3291ab64890Smrg *		void
3301ab64890Smrg *
3311ab64890Smrg */
3321ab64890Smrg{
3331ab64890Smrg    XcmsCmapRec **pPrevPtr;
3341ab64890Smrg    XcmsCmapRec *pRec;
3351ab64890Smrg    int scr;
3361ab64890Smrg
3371ab64890Smrg    /* If it is the default cmap for a screen, do not delete it,
3381ab64890Smrg     * because the server will not actually free it */
3391ab64890Smrg    for (scr = ScreenCount(dpy); --scr >= 0; ) {
3401ab64890Smrg	if (cmap == DefaultColormap(dpy, scr))
3411ab64890Smrg	    return;
3421ab64890Smrg    }
3431ab64890Smrg
3441ab64890Smrg    /* search for it in the list */
3451ab64890Smrg    pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
3461ab64890Smrg    while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
3471ab64890Smrg	pPrevPtr = &pRec->pNext;
3481ab64890Smrg    }
3491ab64890Smrg
3501ab64890Smrg    if (pRec) {
3511ab64890Smrg	if (pRec->ccc) {
3521ab64890Smrg	    XcmsFreeCCC(pRec->ccc);
3531ab64890Smrg	}
3541ab64890Smrg	*pPrevPtr = pRec->pNext;
355818534a1Smrg	Xfree(pRec);
3561ab64890Smrg    }
3571ab64890Smrg}
3581ab64890Smrg
3591ab64890Smrg
3601ab64890Smrg/*
3611ab64890Smrg *	NAME
3621ab64890Smrg *		_XcmsFreeClientCmaps
3631ab64890Smrg *
3641ab64890Smrg *	SYNOPSIS
3651ab64890Smrg */
3661ab64890Smrgstatic void
3671ab64890Smrg_XcmsFreeClientCmaps(
3681ab64890Smrg    Display *dpy)
3691ab64890Smrg/*
3701ab64890Smrg *	DESCRIPTION
3711ab64890Smrg *		Frees all XcmsCmapRec structures in the linked list
3721ab64890Smrg *		and sets dpy->cms.clientCmaps to NULL.
3731ab64890Smrg *
3741ab64890Smrg *	RETURNS
3751ab64890Smrg *		void
3761ab64890Smrg *
3771ab64890Smrg */
3781ab64890Smrg{
3791ab64890Smrg    XcmsCmapRec *pRecNext, *pRecFree;
3801ab64890Smrg
3811ab64890Smrg    pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
3821ab64890Smrg    while (pRecNext != NULL) {
3831ab64890Smrg	pRecFree = pRecNext;
3841ab64890Smrg	pRecNext = pRecNext->pNext;
3851ab64890Smrg	if (pRecFree->ccc) {
3861ab64890Smrg	    /* Free the XcmsCCC structure */
3871ab64890Smrg	    XcmsFreeCCC(pRecFree->ccc);
3881ab64890Smrg	}
3891ab64890Smrg	/* Now free the XcmsCmapRec structure */
390818534a1Smrg	Xfree(pRecFree);
3911ab64890Smrg    }
3921ab64890Smrg    dpy->cms.clientCmaps = (XPointer)NULL;
3931ab64890Smrg}
3941ab64890Smrg
3951ab64890Smrg
3961ab64890Smrg
3971ab64890Smrg/************************************************************************
3981ab64890Smrg *									*
3991ab64890Smrg *			PUBLIC INTERFACES				*
4001ab64890Smrg *									*
4011ab64890Smrg ************************************************************************/
4021ab64890Smrg
4031ab64890Smrg/*
4041ab64890Smrg *	NAME
4051ab64890Smrg *		XcmsCCCOfColormap
4061ab64890Smrg *
4071ab64890Smrg *	SYNOPSIS
4081ab64890Smrg */
40961b2299dSmrgXcmsCCC
4101ab64890SmrgXcmsCCCOfColormap(
4111ab64890Smrg    Display *dpy,
4121ab64890Smrg    Colormap cmap)
4131ab64890Smrg/*
4141ab64890Smrg *	DESCRIPTION
4151ab64890Smrg *		Finds the XcmsCCC associated with the specified colormap.
4161ab64890Smrg *
4171ab64890Smrg *	RETURNS
4181ab64890Smrg *		Returns NULL if failed; otherwise the address to
4191ab64890Smrg *		the associated XcmsCCC structure.
4201ab64890Smrg *
4211ab64890Smrg */
4221ab64890Smrg{
4231ab64890Smrg    XWindowAttributes windowAttr;
4241ab64890Smrg    XcmsCmapRec *pRec;
4251ab64890Smrg    int nScrn = ScreenCount(dpy);
4261ab64890Smrg    int i;
4271ab64890Smrg
4281ab64890Smrg    if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
4291ab64890Smrg	if (pRec->ccc) {
4301ab64890Smrg	    /* XcmsCmapRec already has a XcmsCCC */
4311ab64890Smrg	    return(pRec->ccc);
4321ab64890Smrg	}
4331ab64890Smrg
4341ab64890Smrg	/*
4351ab64890Smrg	 * The XcmsCmapRec does not have a XcmsCCC yet, so let's create
4361ab64890Smrg	 * one.  But first, we need to know the screen associated with
4371ab64890Smrg	 * cmap, so use XGetWindowAttributes() to extract that
4381ab64890Smrg	 * information.  Unless, of course there is only one screen!!
4391ab64890Smrg	 */
4401ab64890Smrg	if (nScrn == 1) {
4411ab64890Smrg	    /* Assume screenNumber == 0 */
4421ab64890Smrg	    return(pRec->ccc = XcmsCreateCCC(
4431ab64890Smrg		    dpy,
4441ab64890Smrg		    0,			/* screenNumber */
4451ab64890Smrg		    pRec->visual,
4461ab64890Smrg		    (XcmsColor *)NULL,	/* clientWhitePt */
4471ab64890Smrg		    (XcmsCompressionProc)NULL,  /* gamutCompProc */
4481ab64890Smrg		    (XPointer)NULL,	/* gamutCompClientData */
4491ab64890Smrg		    (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
4501ab64890Smrg		    (XPointer)NULL	/* whitePtAdjClientData */
4511ab64890Smrg		    ));
4521ab64890Smrg	} else {
4531ab64890Smrg	    if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) {
4541ab64890Smrg		for (i = 0; i < nScrn; i++) {
4551ab64890Smrg		    if (ScreenOfDisplay(dpy, i) == windowAttr.screen) {
4561ab64890Smrg			return(pRec->ccc = XcmsCreateCCC(
4571ab64890Smrg				dpy,
4581ab64890Smrg				i,		   /* screenNumber */
4591ab64890Smrg				pRec->visual,
4601ab64890Smrg				(XcmsColor *)NULL, /* clientWhitePt */
4611ab64890Smrg				(XcmsCompressionProc)NULL, /* gamutCompProc */
4621ab64890Smrg				(XPointer)NULL,	   /* gamutCompClientData */
4631ab64890Smrg				(XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
4641ab64890Smrg				(XPointer)NULL	   /* whitePtAdjClientData */
4651ab64890Smrg				));
4661ab64890Smrg		    }
4671ab64890Smrg		}
4681ab64890Smrg	    }
4691ab64890Smrg	}
4701ab64890Smrg    }
4711ab64890Smrg
4721ab64890Smrg    /*
4731ab64890Smrg     * No such cmap
4741ab64890Smrg     */
4751ab64890Smrg    return(NULL);
4761ab64890Smrg}
4771ab64890Smrg
4781ab64890SmrgXcmsCCC XcmsSetCCCOfColormap(
4791ab64890Smrg    Display *dpy,
4801ab64890Smrg    Colormap cmap,
4811ab64890Smrg    XcmsCCC ccc)
4821ab64890Smrg{
4831ab64890Smrg    XcmsCCC prev_ccc = NULL;
4841ab64890Smrg    XcmsCmapRec *pRec;
4851ab64890Smrg
4861ab64890Smrg    pRec = CmapRecForColormap(dpy, cmap);
4871ab64890Smrg    if (pRec) {
4881ab64890Smrg	prev_ccc = pRec->ccc;
4891ab64890Smrg	pRec->ccc = ccc;
4901ab64890Smrg    }
4911ab64890Smrg    return prev_ccc;
4921ab64890Smrg}
493