cmsCmap.c revision 3b4ba46c
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
903b4ba46cSmrg    LockDisplay(dpy);
911ab64890Smrg    for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
921ab64890Smrg	    pRec = pRec->pNext) {
931ab64890Smrg	if (pRec->cmapID == cmap) {
943b4ba46cSmrg            UnlockDisplay(dpy);
953b4ba46cSmrg            SyncHandle();
961ab64890Smrg	    return(pRec);
971ab64890Smrg	}
981ab64890Smrg    }
993b4ba46cSmrg    UnlockDisplay(dpy);
1003b4ba46cSmrg    SyncHandle();
1011ab64890Smrg
1021ab64890Smrg    /*
1031ab64890Smrg     * Can't find an XcmsCmapRec associated with cmap in our records.
1041ab64890Smrg     * Let's try to see if its a default colormap
1051ab64890Smrg     */
1061ab64890Smrg    nScrn = ScreenCount(dpy);
1071ab64890Smrg    for (i = 0; i < nScrn; i++) {
1081ab64890Smrg	if (cmap == DefaultColormap(dpy, i)) {
1091ab64890Smrg	    /* It is ... lets go ahead and store that info */
1101ab64890Smrg	    if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
1111ab64890Smrg		    DefaultVisual(dpy, i))) == NULL) {
1121ab64890Smrg		return((XcmsCmapRec *)NULL);
1131ab64890Smrg	    }
1141ab64890Smrg	    pRec->ccc = XcmsCreateCCC(
1151ab64890Smrg		    dpy,
1161ab64890Smrg		    i,			/* screenNumber */
1171ab64890Smrg		    DefaultVisual(dpy, i),
1181ab64890Smrg		    (XcmsColor *)NULL,	/* clientWhitePt */
1191ab64890Smrg		    (XcmsCompressionProc)NULL,  /* gamutCompProc */
1201ab64890Smrg		    (XPointer)NULL,	/* gamutCompClientData */
1211ab64890Smrg		    (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
1221ab64890Smrg		    (XPointer)NULL	/* whitePtAdjClientData */
1231ab64890Smrg		    );
1241ab64890Smrg	    return(pRec);
1251ab64890Smrg	}
1261ab64890Smrg    }
1271ab64890Smrg
1281ab64890Smrg    /*
1291ab64890Smrg     * Nope, its not a default colormap, so it's probably a foreign color map
1301ab64890Smrg     * of which we have no specific details.  Let's go through the
1311ab64890Smrg     * rigorous process of finding this colormap:
1321ab64890Smrg     *        for each screen
1331ab64890Smrg     *            for each screen's visual types
1341ab64890Smrg     *                create a window with cmap specified as the colormap
1351ab64890Smrg     *                if successful
1361ab64890Smrg     *                    Add a CmapRec
1371ab64890Smrg     *                    Create an XcmsCCC
1381ab64890Smrg     *                    return the CmapRec
1391ab64890Smrg     *                else
1401ab64890Smrg     *                    continue
1411ab64890Smrg     */
1421ab64890Smrg
1431ab64890Smrg    async_state.error_code = 0; /* don't care */
1441ab64890Smrg    async_state.major_opcode = X_CreateWindow;
1451ab64890Smrg    async_state.minor_opcode = 0;
1461ab64890Smrg    for (i = 0; i < nScrn; i++) {
1471ab64890Smrg	visualTemplate.screen = i;
1481ab64890Smrg	visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate,
1491ab64890Smrg	    &nVisualsMatched);
1501ab64890Smrg	if (visualList == NULL) {
1511ab64890Smrg	    continue;
1521ab64890Smrg	}
1531ab64890Smrg
1541ab64890Smrg	/*
1551ab64890Smrg	 * Attempt to create a window with cmap
1561ab64890Smrg	 */
1571ab64890Smrg	j = 0;
1581ab64890Smrg	do {
1591ab64890Smrg	    vp = (visualList+j)->visual;
1601ab64890Smrg	    LockDisplay(dpy);
1611ab64890Smrg	    {
1621ab64890Smrg		register xCreateWindowReq *req;
1631ab64890Smrg
1641ab64890Smrg		GetReq(CreateWindow, req);
1651ab64890Smrg		async_state.min_sequence_number = dpy->request;
1661ab64890Smrg		async_state.max_sequence_number = dpy->request;
1671ab64890Smrg		async_state.error_count = 0;
1681ab64890Smrg		async.next = dpy->async_handlers;
1691ab64890Smrg		async.handler = _XAsyncErrorHandler;
1701ab64890Smrg		async.data = (XPointer)&async_state;
1711ab64890Smrg		dpy->async_handlers = &async;
1721ab64890Smrg		req->parent = RootWindow(dpy, i);
1731ab64890Smrg		req->x = 0;
1741ab64890Smrg		req->y = 0;
1751ab64890Smrg		req->width = 1;
1761ab64890Smrg		req->height = 1;
1771ab64890Smrg		req->borderWidth = 0;
1781ab64890Smrg		req->depth = (visualList+j)->depth;
1791ab64890Smrg		req->class = CopyFromParent;
1801ab64890Smrg		req->visual = vp->visualid;
1811ab64890Smrg		tmpWindow = req->wid = XAllocID(dpy);
1821ab64890Smrg		req->mask = CWBorderPixel | CWColormap;
1831ab64890Smrg		req->length += 2;
1841ab64890Smrg		Data32 (dpy, (long *) &border, 4);
1851ab64890Smrg		Data32 (dpy, (long *) &cmap, 4);
1861ab64890Smrg	    }
1871ab64890Smrg	    {
1881ab64890Smrg		xGetInputFocusReply rep;
1893233502eSmrg		_X_UNUSED register xReq *req;
1901ab64890Smrg
1911ab64890Smrg		GetEmptyReq(GetInputFocus, req);
1921ab64890Smrg		(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
1931ab64890Smrg	    }
1941ab64890Smrg	    DeqAsyncHandler(dpy, &async);
1951ab64890Smrg	    UnlockDisplay(dpy);
1961ab64890Smrg	    SyncHandle();
1971ab64890Smrg	} while (async_state.error_count > 0 && ++j < nVisualsMatched);
1981ab64890Smrg
199818534a1Smrg	Xfree(visualList);
2001ab64890Smrg
2011ab64890Smrg	/*
2021ab64890Smrg	 * if successful
2031ab64890Smrg	 */
2041ab64890Smrg	if (j < nVisualsMatched) {
2051ab64890Smrg	    if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
2061ab64890Smrg		return((XcmsCmapRec *)NULL);
2071ab64890Smrg	    pRec->ccc = XcmsCreateCCC(
2081ab64890Smrg		    dpy,
2091ab64890Smrg		    i,			/* screenNumber */
2101ab64890Smrg		    vp,
2111ab64890Smrg		    (XcmsColor *)NULL,	/* clientWhitePt */
2121ab64890Smrg		    (XcmsCompressionProc)NULL,  /* gamutCompProc */
2131ab64890Smrg		    (XPointer)NULL,	/* gamutCompClientData */
2141ab64890Smrg		    (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
2151ab64890Smrg		    (XPointer)NULL	/* whitePtAdjClientData */
2161ab64890Smrg		    );
2171ab64890Smrg	    XDestroyWindow(dpy, tmpWindow);
2181ab64890Smrg	    return(pRec);
2191ab64890Smrg	}
2201ab64890Smrg    }
2211ab64890Smrg
2221ab64890Smrg    return(NULL);
2231ab64890Smrg}
2241ab64890Smrg
2251ab64890Smrg
2261ab64890Smrg
2271ab64890Smrg/************************************************************************
2281ab64890Smrg *									*
2291ab64890Smrg *			API PRIVATE INTERFACES				*
2301ab64890Smrg *									*
2311ab64890Smrg ************************************************************************/
2321ab64890Smrg
2331ab64890Smrg/*
2341ab64890Smrg *	NAME
2351ab64890Smrg *		_XcmsAddCmapRec
2361ab64890Smrg *
2371ab64890Smrg *	SYNOPSIS
2381ab64890Smrg */
2391ab64890SmrgXcmsCmapRec *
2401ab64890Smrg_XcmsAddCmapRec(
2411ab64890Smrg    Display *dpy,
2421ab64890Smrg    Colormap cmap,
2431ab64890Smrg    Window windowID,
2441ab64890Smrg    Visual *visual)
2451ab64890Smrg/*
2461ab64890Smrg *	DESCRIPTION
2471ab64890Smrg *		Create an XcmsCmapRec for the specified cmap, windowID,
2481ab64890Smrg *		and visual, then adds it to its list of CmapRec's.
2491ab64890Smrg *
2501ab64890Smrg *	RETURNS
2511ab64890Smrg *		Returns NULL if failed; otherwise the address to
2521ab64890Smrg *		the added XcmsCmapRec.
2531ab64890Smrg *
2541ab64890Smrg */
2551ab64890Smrg{
2561ab64890Smrg    XcmsCmapRec *pNew;
2571ab64890Smrg
258818534a1Smrg    if ((pNew = Xcalloc(1, sizeof(XcmsCmapRec))) == NULL) {
2591ab64890Smrg	return((XcmsCmapRec *)NULL);
2601ab64890Smrg    }
2611ab64890Smrg
2621ab64890Smrg    pNew->cmapID = cmap;
2631ab64890Smrg    pNew->dpy = dpy;
2641ab64890Smrg    pNew->windowID = windowID;
2651ab64890Smrg    pNew->visual = visual;
2663b4ba46cSmrg    LockDisplay(dpy);
2671ab64890Smrg    pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
2681ab64890Smrg    dpy->cms.clientCmaps = (XPointer)pNew;
2691ab64890Smrg    dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
2703b4ba46cSmrg    UnlockDisplay(dpy);
2713b4ba46cSmrg    SyncHandle();
2721ab64890Smrg
2731ab64890Smrg    /*
2741ab64890Smrg     * Note, we don't create the XcmsCCC for pNew->ccc here because
2751ab64890Smrg     * it may require the use of XGetWindowAttributes (a round trip request)
2761ab64890Smrg     * to determine the screen.
2771ab64890Smrg     */
2781ab64890Smrg    return(pNew);
2791ab64890Smrg}
2801ab64890Smrg
2811ab64890Smrg
2821ab64890Smrg/*
2831ab64890Smrg *	NAME
2841ab64890Smrg *		_XcmsCopyCmapRecAndFree
2851ab64890Smrg *
2861ab64890Smrg *	SYNOPSIS
2871ab64890Smrg */
2881ab64890SmrgXcmsCmapRec *
2891ab64890Smrg_XcmsCopyCmapRecAndFree(
2901ab64890Smrg    Display *dpy,
2911ab64890Smrg    Colormap src_cmap,
2921ab64890Smrg    Colormap copy_cmap)
2931ab64890Smrg/*
2941ab64890Smrg *	DESCRIPTION
2951ab64890Smrg *		Augments Xlib's XCopyColormapAndFree() to copy
2961ab64890Smrg *		XcmsCmapRecs.
2971ab64890Smrg *
2981ab64890Smrg *	RETURNS
2991ab64890Smrg *		Returns NULL if failed; otherwise the address to
3001ab64890Smrg *		the copy XcmsCmapRec.
3011ab64890Smrg *
3021ab64890Smrg */
3031ab64890Smrg{
3041ab64890Smrg    XcmsCmapRec *pRec_src;
3051ab64890Smrg    XcmsCmapRec *pRec_copy;
3061ab64890Smrg
3071ab64890Smrg    if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) {
3081ab64890Smrg	pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID,
3091ab64890Smrg		pRec_src->visual);
3101ab64890Smrg	if (pRec_copy != NULL && pRec_src->ccc) {
311818534a1Smrg	    pRec_copy->ccc = Xcalloc(1, sizeof(XcmsCCCRec));
3121ab64890Smrg	    memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc,
3131ab64890Smrg		   sizeof(XcmsCCCRec));
3141ab64890Smrg	}
3151ab64890Smrg	return(pRec_copy);
3161ab64890Smrg    }
3171ab64890Smrg    return((XcmsCmapRec *)NULL);
3181ab64890Smrg}
3191ab64890Smrg
3201ab64890Smrg
3211ab64890Smrg/*
3221ab64890Smrg *	NAME
3231ab64890Smrg *		_XcmsDeleteCmapRec
3241ab64890Smrg *
3251ab64890Smrg *	SYNOPSIS
3261ab64890Smrg */
3271ab64890Smrgvoid
3281ab64890Smrg_XcmsDeleteCmapRec(
3291ab64890Smrg    Display *dpy,
3301ab64890Smrg    Colormap cmap)
3311ab64890Smrg/*
3321ab64890Smrg *	DESCRIPTION
3331ab64890Smrg *		Removes and frees the specified XcmsCmapRec structure
3341ab64890Smrg *		from the linked list of structures.
3351ab64890Smrg *
3361ab64890Smrg *	RETURNS
3371ab64890Smrg *		void
3381ab64890Smrg *
3391ab64890Smrg */
3401ab64890Smrg{
3411ab64890Smrg    XcmsCmapRec **pPrevPtr;
3421ab64890Smrg    XcmsCmapRec *pRec;
3431ab64890Smrg    int scr;
3441ab64890Smrg
3451ab64890Smrg    /* If it is the default cmap for a screen, do not delete it,
3461ab64890Smrg     * because the server will not actually free it */
3471ab64890Smrg    for (scr = ScreenCount(dpy); --scr >= 0; ) {
3481ab64890Smrg	if (cmap == DefaultColormap(dpy, scr))
3491ab64890Smrg	    return;
3501ab64890Smrg    }
3511ab64890Smrg
3521ab64890Smrg    /* search for it in the list */
3533b4ba46cSmrg    LockDisplay(dpy);
3541ab64890Smrg    pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
3551ab64890Smrg    while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
3561ab64890Smrg	pPrevPtr = &pRec->pNext;
3571ab64890Smrg    }
3581ab64890Smrg
3591ab64890Smrg    if (pRec) {
3601ab64890Smrg	if (pRec->ccc) {
3611ab64890Smrg	    XcmsFreeCCC(pRec->ccc);
3621ab64890Smrg	}
3631ab64890Smrg	*pPrevPtr = pRec->pNext;
364818534a1Smrg	Xfree(pRec);
3651ab64890Smrg    }
3663b4ba46cSmrg    UnlockDisplay(dpy);
3673b4ba46cSmrg    SyncHandle();
3681ab64890Smrg}
3691ab64890Smrg
3701ab64890Smrg
3711ab64890Smrg/*
3721ab64890Smrg *	NAME
3731ab64890Smrg *		_XcmsFreeClientCmaps
3741ab64890Smrg *
3751ab64890Smrg *	SYNOPSIS
3761ab64890Smrg */
3771ab64890Smrgstatic void
3781ab64890Smrg_XcmsFreeClientCmaps(
3791ab64890Smrg    Display *dpy)
3801ab64890Smrg/*
3811ab64890Smrg *	DESCRIPTION
3821ab64890Smrg *		Frees all XcmsCmapRec structures in the linked list
3831ab64890Smrg *		and sets dpy->cms.clientCmaps to NULL.
3841ab64890Smrg *
3851ab64890Smrg *	RETURNS
3861ab64890Smrg *		void
3871ab64890Smrg *
3881ab64890Smrg */
3891ab64890Smrg{
3901ab64890Smrg    XcmsCmapRec *pRecNext, *pRecFree;
3911ab64890Smrg
3923b4ba46cSmrg    LockDisplay(dpy);
3931ab64890Smrg    pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
3941ab64890Smrg    while (pRecNext != NULL) {
3951ab64890Smrg	pRecFree = pRecNext;
3961ab64890Smrg	pRecNext = pRecNext->pNext;
3971ab64890Smrg	if (pRecFree->ccc) {
3981ab64890Smrg	    /* Free the XcmsCCC structure */
3991ab64890Smrg	    XcmsFreeCCC(pRecFree->ccc);
4001ab64890Smrg	}
4011ab64890Smrg	/* Now free the XcmsCmapRec structure */
402818534a1Smrg	Xfree(pRecFree);
4031ab64890Smrg    }
4041ab64890Smrg    dpy->cms.clientCmaps = (XPointer)NULL;
4053b4ba46cSmrg    UnlockDisplay(dpy);
4063b4ba46cSmrg    SyncHandle();
4071ab64890Smrg}
4081ab64890Smrg
4091ab64890Smrg
4101ab64890Smrg
4111ab64890Smrg/************************************************************************
4121ab64890Smrg *									*
4131ab64890Smrg *			PUBLIC INTERFACES				*
4141ab64890Smrg *									*
4151ab64890Smrg ************************************************************************/
4161ab64890Smrg
4171ab64890Smrg/*
4181ab64890Smrg *	NAME
4191ab64890Smrg *		XcmsCCCOfColormap
4201ab64890Smrg *
4211ab64890Smrg *	SYNOPSIS
4221ab64890Smrg */
42361b2299dSmrgXcmsCCC
4241ab64890SmrgXcmsCCCOfColormap(
4251ab64890Smrg    Display *dpy,
4261ab64890Smrg    Colormap cmap)
4271ab64890Smrg/*
4281ab64890Smrg *	DESCRIPTION
4291ab64890Smrg *		Finds the XcmsCCC associated with the specified colormap.
4301ab64890Smrg *
4311ab64890Smrg *	RETURNS
4321ab64890Smrg *		Returns NULL if failed; otherwise the address to
4331ab64890Smrg *		the associated XcmsCCC structure.
4341ab64890Smrg *
4351ab64890Smrg */
4361ab64890Smrg{
4371ab64890Smrg    XWindowAttributes windowAttr;
4381ab64890Smrg    XcmsCmapRec *pRec;
4391ab64890Smrg    int nScrn = ScreenCount(dpy);
4401ab64890Smrg    int i;
4411ab64890Smrg
4421ab64890Smrg    if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
4431ab64890Smrg	if (pRec->ccc) {
4441ab64890Smrg	    /* XcmsCmapRec already has a XcmsCCC */
4451ab64890Smrg	    return(pRec->ccc);
4461ab64890Smrg	}
4471ab64890Smrg
4481ab64890Smrg	/*
4491ab64890Smrg	 * The XcmsCmapRec does not have a XcmsCCC yet, so let's create
4501ab64890Smrg	 * one.  But first, we need to know the screen associated with
4511ab64890Smrg	 * cmap, so use XGetWindowAttributes() to extract that
4521ab64890Smrg	 * information.  Unless, of course there is only one screen!!
4531ab64890Smrg	 */
4541ab64890Smrg	if (nScrn == 1) {
4551ab64890Smrg	    /* Assume screenNumber == 0 */
4561ab64890Smrg	    return(pRec->ccc = XcmsCreateCCC(
4571ab64890Smrg		    dpy,
4581ab64890Smrg		    0,			/* 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	} else {
4671ab64890Smrg	    if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) {
4681ab64890Smrg		for (i = 0; i < nScrn; i++) {
4691ab64890Smrg		    if (ScreenOfDisplay(dpy, i) == windowAttr.screen) {
4701ab64890Smrg			return(pRec->ccc = XcmsCreateCCC(
4711ab64890Smrg				dpy,
4721ab64890Smrg				i,		   /* screenNumber */
4731ab64890Smrg				pRec->visual,
4741ab64890Smrg				(XcmsColor *)NULL, /* clientWhitePt */
4751ab64890Smrg				(XcmsCompressionProc)NULL, /* gamutCompProc */
4761ab64890Smrg				(XPointer)NULL,	   /* gamutCompClientData */
4771ab64890Smrg				(XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
4781ab64890Smrg				(XPointer)NULL	   /* whitePtAdjClientData */
4791ab64890Smrg				));
4801ab64890Smrg		    }
4811ab64890Smrg		}
4821ab64890Smrg	    }
4831ab64890Smrg	}
4841ab64890Smrg    }
4851ab64890Smrg
4861ab64890Smrg    /*
4871ab64890Smrg     * No such cmap
4881ab64890Smrg     */
4891ab64890Smrg    return(NULL);
4901ab64890Smrg}
4911ab64890Smrg
4921ab64890SmrgXcmsCCC XcmsSetCCCOfColormap(
4931ab64890Smrg    Display *dpy,
4941ab64890Smrg    Colormap cmap,
4951ab64890Smrg    XcmsCCC ccc)
4961ab64890Smrg{
4971ab64890Smrg    XcmsCCC prev_ccc = NULL;
4981ab64890Smrg    XcmsCmapRec *pRec;
4991ab64890Smrg
5001ab64890Smrg    pRec = CmapRecForColormap(dpy, cmap);
5011ab64890Smrg    if (pRec) {
5021ab64890Smrg	prev_ccc = pRec->ccc;
5031ab64890Smrg	pRec->ccc = ccc;
5041ab64890Smrg    }
5051ab64890Smrg    return prev_ccc;
5061ab64890Smrg}
507