aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/xcms/cmsCmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/xcms/cmsCmap.c')
-rw-r--r--libX11/src/xcms/cmsCmap.c988
1 files changed, 493 insertions, 495 deletions
diff --git a/libX11/src/xcms/cmsCmap.c b/libX11/src/xcms/cmsCmap.c
index f93a25b1f..2f14cdb25 100644
--- a/libX11/src/xcms/cmsCmap.c
+++ b/libX11/src/xcms/cmsCmap.c
@@ -1,495 +1,493 @@
-
-/*
- * 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
- * XcmsCmap.c - Client Colormap Management Routines
- *
- * DESCRIPTION
- * Routines that store additional information about
- * colormaps being used by the X Client.
- *
- *
- */
-
-#define NEED_EVENTS
-#define NEED_REPLIES
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "Xcmsint.h"
-#include "Xutil.h"
-#include "Cmap.h"
-#include "Cv.h"
-
-/*
- * FORWARD DECLARATIONS
- */
-static void _XcmsFreeClientCmaps(Display *dpy);
-
-
-/************************************************************************
- * *
- * PRIVATE INTERFACES *
- * *
- ************************************************************************/
-
-/*
- * NAME
- * CmapRecForColormap
- *
- * SYNOPSIS
- */
-static XcmsCmapRec *
-CmapRecForColormap(
- Display *dpy,
- Colormap cmap)
-/*
- * DESCRIPTION
- * Find the corresponding XcmsCmapRec for cmap. In not found
- * this routines attempts to create one.
- *
- * RETURNS
- * Returns NULL if failed; otherwise the address to
- * the corresponding XcmsCmapRec.
- *
- */
-{
- XcmsCmapRec *pRec;
- int nScrn;
- int i, j;
- XVisualInfo visualTemplate; /* Template of the visual we want */
- XVisualInfo *visualList; /* List for visuals that match */
- int nVisualsMatched; /* Number of visuals that match */
- Window tmpWindow;
- Visual *vp;
- unsigned long border = 0;
- _XAsyncHandler async;
- _XAsyncErrorState async_state;
-
- for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
- pRec = pRec->pNext) {
- if (pRec->cmapID == cmap) {
- return(pRec);
- }
- }
-
- /*
- * Can't find an XcmsCmapRec associated with cmap in our records.
- * Let's try to see if its a default colormap
- */
- nScrn = ScreenCount(dpy);
- for (i = 0; i < nScrn; i++) {
- if (cmap == DefaultColormap(dpy, i)) {
- /* It is ... lets go ahead and store that info */
- if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
- DefaultVisual(dpy, i))) == NULL) {
- return((XcmsCmapRec *)NULL);
- }
- pRec->ccc = XcmsCreateCCC(
- dpy,
- i, /* screenNumber */
- DefaultVisual(dpy, i),
- (XcmsColor *)NULL, /* clientWhitePt */
- (XcmsCompressionProc)NULL, /* gamutCompProc */
- (XPointer)NULL, /* gamutCompClientData */
- (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
- (XPointer)NULL /* whitePtAdjClientData */
- );
- return(pRec);
- }
- }
-
- /*
- * Nope, its not a default colormap, so it's probably a foreign color map
- * of which we have no specific details. Let's go through the
- * rigorous process of finding this colormap:
- * for each screen
- * for each screen's visual types
- * create a window with cmap specified as the colormap
- * if successful
- * Add a CmapRec
- * Create an XcmsCCC
- * return the CmapRec
- * else
- * continue
- */
-
- async_state.error_code = 0; /* don't care */
- async_state.major_opcode = X_CreateWindow;
- async_state.minor_opcode = 0;
- for (i = 0; i < nScrn; i++) {
- visualTemplate.screen = i;
- visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate,
- &nVisualsMatched);
- if (visualList == NULL) {
- continue;
- }
-
- /*
- * Attempt to create a window with cmap
- */
- j = 0;
- do {
- vp = (visualList+j)->visual;
- LockDisplay(dpy);
- {
- register xCreateWindowReq *req;
-
- GetReq(CreateWindow, req);
- async_state.min_sequence_number = dpy->request;
- async_state.max_sequence_number = dpy->request;
- async_state.error_count = 0;
- async.next = dpy->async_handlers;
- async.handler = _XAsyncErrorHandler;
- async.data = (XPointer)&async_state;
- dpy->async_handlers = &async;
- req->parent = RootWindow(dpy, i);
- req->x = 0;
- req->y = 0;
- req->width = 1;
- req->height = 1;
- req->borderWidth = 0;
- req->depth = (visualList+j)->depth;
- req->class = CopyFromParent;
- req->visual = vp->visualid;
- tmpWindow = req->wid = XAllocID(dpy);
- req->mask = CWBorderPixel | CWColormap;
- req->length += 2;
- Data32 (dpy, (long *) &border, 4);
- Data32 (dpy, (long *) &cmap, 4);
- }
- {
- xGetInputFocusReply rep;
- register xReq *req;
-
- GetEmptyReq(GetInputFocus, req);
- (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
- }
- DeqAsyncHandler(dpy, &async);
- UnlockDisplay(dpy);
- SyncHandle();
- } while (async_state.error_count > 0 && ++j < nVisualsMatched);
-
- Xfree((char *)visualList);
-
- /*
- * if successful
- */
- if (j < nVisualsMatched) {
- if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
- return((XcmsCmapRec *)NULL);
- pRec->ccc = XcmsCreateCCC(
- dpy,
- i, /* screenNumber */
- vp,
- (XcmsColor *)NULL, /* clientWhitePt */
- (XcmsCompressionProc)NULL, /* gamutCompProc */
- (XPointer)NULL, /* gamutCompClientData */
- (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
- (XPointer)NULL /* whitePtAdjClientData */
- );
- XDestroyWindow(dpy, tmpWindow);
- return(pRec);
- }
- }
-
- return(NULL);
-}
-
-
-
-/************************************************************************
- * *
- * API PRIVATE INTERFACES *
- * *
- ************************************************************************/
-
-/*
- * NAME
- * _XcmsAddCmapRec
- *
- * SYNOPSIS
- */
-XcmsCmapRec *
-_XcmsAddCmapRec(
- Display *dpy,
- Colormap cmap,
- Window windowID,
- Visual *visual)
-/*
- * DESCRIPTION
- * Create an XcmsCmapRec for the specified cmap, windowID,
- * and visual, then adds it to its list of CmapRec's.
- *
- * RETURNS
- * Returns NULL if failed; otherwise the address to
- * the added XcmsCmapRec.
- *
- */
-{
- XcmsCmapRec *pNew;
-
- if ((pNew = (XcmsCmapRec *) Xcalloc(1, (unsigned) sizeof(XcmsCmapRec)))
- == NULL) {
- return((XcmsCmapRec *)NULL);
- }
-
- pNew->cmapID = cmap;
- pNew->dpy = dpy;
- pNew->windowID = windowID;
- pNew->visual = visual;
- pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
- dpy->cms.clientCmaps = (XPointer)pNew;
- dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
-
- /*
- * Note, we don't create the XcmsCCC for pNew->ccc here because
- * it may require the use of XGetWindowAttributes (a round trip request)
- * to determine the screen.
- */
- return(pNew);
-}
-
-
-/*
- * NAME
- * _XcmsCopyCmapRecAndFree
- *
- * SYNOPSIS
- */
-XcmsCmapRec *
-_XcmsCopyCmapRecAndFree(
- Display *dpy,
- Colormap src_cmap,
- Colormap copy_cmap)
-/*
- * DESCRIPTION
- * Augments Xlib's XCopyColormapAndFree() to copy
- * XcmsCmapRecs.
- *
- * RETURNS
- * Returns NULL if failed; otherwise the address to
- * the copy XcmsCmapRec.
- *
- */
-{
- XcmsCmapRec *pRec_src;
- XcmsCmapRec *pRec_copy;
-
- if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) {
- pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID,
- pRec_src->visual);
- if (pRec_copy != NULL && pRec_src->ccc) {
- pRec_copy->ccc = (XcmsCCC)Xcalloc(1, (unsigned) sizeof(XcmsCCCRec));
- memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc,
- sizeof(XcmsCCCRec));
- }
- return(pRec_copy);
- }
- return((XcmsCmapRec *)NULL);
-}
-
-
-/*
- * NAME
- * _XcmsDeleteCmapRec
- *
- * SYNOPSIS
- */
-void
-_XcmsDeleteCmapRec(
- Display *dpy,
- Colormap cmap)
-/*
- * DESCRIPTION
- * Removes and frees the specified XcmsCmapRec structure
- * from the linked list of structures.
- *
- * RETURNS
- * void
- *
- */
-{
- XcmsCmapRec **pPrevPtr;
- XcmsCmapRec *pRec;
- int scr;
-
- /* If it is the default cmap for a screen, do not delete it,
- * because the server will not actually free it */
- for (scr = ScreenCount(dpy); --scr >= 0; ) {
- if (cmap == DefaultColormap(dpy, scr))
- return;
- }
-
- /* search for it in the list */
- pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
- while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
- pPrevPtr = &pRec->pNext;
- }
-
- if (pRec) {
- if (pRec->ccc) {
- XcmsFreeCCC(pRec->ccc);
- }
- *pPrevPtr = pRec->pNext;
- Xfree((char *)pRec);
- }
-}
-
-
-/*
- * NAME
- * _XcmsFreeClientCmaps
- *
- * SYNOPSIS
- */
-static void
-_XcmsFreeClientCmaps(
- Display *dpy)
-/*
- * DESCRIPTION
- * Frees all XcmsCmapRec structures in the linked list
- * and sets dpy->cms.clientCmaps to NULL.
- *
- * RETURNS
- * void
- *
- */
-{
- XcmsCmapRec *pRecNext, *pRecFree;
-
- pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
- while (pRecNext != NULL) {
- pRecFree = pRecNext;
- pRecNext = pRecNext->pNext;
- if (pRecFree->ccc) {
- /* Free the XcmsCCC structure */
- XcmsFreeCCC(pRecFree->ccc);
- }
- /* Now free the XcmsCmapRec structure */
- Xfree((char *)pRecFree);
- }
- dpy->cms.clientCmaps = (XPointer)NULL;
-}
-
-
-
-/************************************************************************
- * *
- * PUBLIC INTERFACES *
- * *
- ************************************************************************/
-
-/*
- * NAME
- * XcmsCCCOfColormap
- *
- * SYNOPSIS
- */
-XcmsCCC
-XcmsCCCOfColormap(
- Display *dpy,
- Colormap cmap)
-/*
- * DESCRIPTION
- * Finds the XcmsCCC associated with the specified colormap.
- *
- * RETURNS
- * Returns NULL if failed; otherwise the address to
- * the associated XcmsCCC structure.
- *
- */
-{
- XWindowAttributes windowAttr;
- XcmsCmapRec *pRec;
- int nScrn = ScreenCount(dpy);
- int i;
-
- if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
- if (pRec->ccc) {
- /* XcmsCmapRec already has a XcmsCCC */
- return(pRec->ccc);
- }
-
- /*
- * The XcmsCmapRec does not have a XcmsCCC yet, so let's create
- * one. But first, we need to know the screen associated with
- * cmap, so use XGetWindowAttributes() to extract that
- * information. Unless, of course there is only one screen!!
- */
- if (nScrn == 1) {
- /* Assume screenNumber == 0 */
- return(pRec->ccc = XcmsCreateCCC(
- dpy,
- 0, /* screenNumber */
- pRec->visual,
- (XcmsColor *)NULL, /* clientWhitePt */
- (XcmsCompressionProc)NULL, /* gamutCompProc */
- (XPointer)NULL, /* gamutCompClientData */
- (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
- (XPointer)NULL /* whitePtAdjClientData */
- ));
- } else {
- if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) {
- for (i = 0; i < nScrn; i++) {
- if (ScreenOfDisplay(dpy, i) == windowAttr.screen) {
- return(pRec->ccc = XcmsCreateCCC(
- dpy,
- i, /* screenNumber */
- pRec->visual,
- (XcmsColor *)NULL, /* clientWhitePt */
- (XcmsCompressionProc)NULL, /* gamutCompProc */
- (XPointer)NULL, /* gamutCompClientData */
- (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
- (XPointer)NULL /* whitePtAdjClientData */
- ));
- }
- }
- }
- }
- }
-
- /*
- * No such cmap
- */
- return(NULL);
-}
-
-XcmsCCC XcmsSetCCCOfColormap(
- Display *dpy,
- Colormap cmap,
- XcmsCCC ccc)
-{
- XcmsCCC prev_ccc = NULL;
- XcmsCmapRec *pRec;
-
- pRec = CmapRecForColormap(dpy, cmap);
- if (pRec) {
- prev_ccc = pRec->ccc;
- pRec->ccc = ccc;
- }
- return prev_ccc;
-}
+
+/*
+ * 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
+ * XcmsCmap.c - Client Colormap Management Routines
+ *
+ * DESCRIPTION
+ * Routines that store additional information about
+ * colormaps being used by the X Client.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xcmsint.h"
+#include "Xutil.h"
+#include "Cmap.h"
+#include "Cv.h"
+
+/*
+ * FORWARD DECLARATIONS
+ */
+static void _XcmsFreeClientCmaps(Display *dpy);
+
+
+/************************************************************************
+ * *
+ * PRIVATE INTERFACES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * CmapRecForColormap
+ *
+ * SYNOPSIS
+ */
+static XcmsCmapRec *
+CmapRecForColormap(
+ Display *dpy,
+ Colormap cmap)
+/*
+ * DESCRIPTION
+ * Find the corresponding XcmsCmapRec for cmap. In not found
+ * this routines attempts to create one.
+ *
+ * RETURNS
+ * Returns NULL if failed; otherwise the address to
+ * the corresponding XcmsCmapRec.
+ *
+ */
+{
+ XcmsCmapRec *pRec;
+ int nScrn;
+ int i, j;
+ XVisualInfo visualTemplate; /* Template of the visual we want */
+ XVisualInfo *visualList; /* List for visuals that match */
+ int nVisualsMatched; /* Number of visuals that match */
+ Window tmpWindow;
+ Visual *vp;
+ unsigned long border = 0;
+ _XAsyncHandler async;
+ _XAsyncErrorState async_state;
+
+ for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
+ pRec = pRec->pNext) {
+ if (pRec->cmapID == cmap) {
+ return(pRec);
+ }
+ }
+
+ /*
+ * Can't find an XcmsCmapRec associated with cmap in our records.
+ * Let's try to see if its a default colormap
+ */
+ nScrn = ScreenCount(dpy);
+ for (i = 0; i < nScrn; i++) {
+ if (cmap == DefaultColormap(dpy, i)) {
+ /* It is ... lets go ahead and store that info */
+ if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
+ DefaultVisual(dpy, i))) == NULL) {
+ return((XcmsCmapRec *)NULL);
+ }
+ pRec->ccc = XcmsCreateCCC(
+ dpy,
+ i, /* screenNumber */
+ DefaultVisual(dpy, i),
+ (XcmsColor *)NULL, /* clientWhitePt */
+ (XcmsCompressionProc)NULL, /* gamutCompProc */
+ (XPointer)NULL, /* gamutCompClientData */
+ (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
+ (XPointer)NULL /* whitePtAdjClientData */
+ );
+ return(pRec);
+ }
+ }
+
+ /*
+ * Nope, its not a default colormap, so it's probably a foreign color map
+ * of which we have no specific details. Let's go through the
+ * rigorous process of finding this colormap:
+ * for each screen
+ * for each screen's visual types
+ * create a window with cmap specified as the colormap
+ * if successful
+ * Add a CmapRec
+ * Create an XcmsCCC
+ * return the CmapRec
+ * else
+ * continue
+ */
+
+ async_state.error_code = 0; /* don't care */
+ async_state.major_opcode = X_CreateWindow;
+ async_state.minor_opcode = 0;
+ for (i = 0; i < nScrn; i++) {
+ visualTemplate.screen = i;
+ visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate,
+ &nVisualsMatched);
+ if (visualList == NULL) {
+ continue;
+ }
+
+ /*
+ * Attempt to create a window with cmap
+ */
+ j = 0;
+ do {
+ vp = (visualList+j)->visual;
+ LockDisplay(dpy);
+ {
+ register xCreateWindowReq *req;
+
+ GetReq(CreateWindow, req);
+ async_state.min_sequence_number = dpy->request;
+ async_state.max_sequence_number = dpy->request;
+ async_state.error_count = 0;
+ async.next = dpy->async_handlers;
+ async.handler = _XAsyncErrorHandler;
+ async.data = (XPointer)&async_state;
+ dpy->async_handlers = &async;
+ req->parent = RootWindow(dpy, i);
+ req->x = 0;
+ req->y = 0;
+ req->width = 1;
+ req->height = 1;
+ req->borderWidth = 0;
+ req->depth = (visualList+j)->depth;
+ req->class = CopyFromParent;
+ req->visual = vp->visualid;
+ tmpWindow = req->wid = XAllocID(dpy);
+ req->mask = CWBorderPixel | CWColormap;
+ req->length += 2;
+ Data32 (dpy, (long *) &border, 4);
+ Data32 (dpy, (long *) &cmap, 4);
+ }
+ {
+ xGetInputFocusReply rep;
+ register xReq *req;
+
+ GetEmptyReq(GetInputFocus, req);
+ (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
+ }
+ DeqAsyncHandler(dpy, &async);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ } while (async_state.error_count > 0 && ++j < nVisualsMatched);
+
+ Xfree((char *)visualList);
+
+ /*
+ * if successful
+ */
+ if (j < nVisualsMatched) {
+ if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
+ return((XcmsCmapRec *)NULL);
+ pRec->ccc = XcmsCreateCCC(
+ dpy,
+ i, /* screenNumber */
+ vp,
+ (XcmsColor *)NULL, /* clientWhitePt */
+ (XcmsCompressionProc)NULL, /* gamutCompProc */
+ (XPointer)NULL, /* gamutCompClientData */
+ (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
+ (XPointer)NULL /* whitePtAdjClientData */
+ );
+ XDestroyWindow(dpy, tmpWindow);
+ return(pRec);
+ }
+ }
+
+ return(NULL);
+}
+
+
+
+/************************************************************************
+ * *
+ * API PRIVATE INTERFACES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * _XcmsAddCmapRec
+ *
+ * SYNOPSIS
+ */
+XcmsCmapRec *
+_XcmsAddCmapRec(
+ Display *dpy,
+ Colormap cmap,
+ Window windowID,
+ Visual *visual)
+/*
+ * DESCRIPTION
+ * Create an XcmsCmapRec for the specified cmap, windowID,
+ * and visual, then adds it to its list of CmapRec's.
+ *
+ * RETURNS
+ * Returns NULL if failed; otherwise the address to
+ * the added XcmsCmapRec.
+ *
+ */
+{
+ XcmsCmapRec *pNew;
+
+ if ((pNew = (XcmsCmapRec *) Xcalloc(1, (unsigned) sizeof(XcmsCmapRec)))
+ == NULL) {
+ return((XcmsCmapRec *)NULL);
+ }
+
+ pNew->cmapID = cmap;
+ pNew->dpy = dpy;
+ pNew->windowID = windowID;
+ pNew->visual = visual;
+ pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
+ dpy->cms.clientCmaps = (XPointer)pNew;
+ dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
+
+ /*
+ * Note, we don't create the XcmsCCC for pNew->ccc here because
+ * it may require the use of XGetWindowAttributes (a round trip request)
+ * to determine the screen.
+ */
+ return(pNew);
+}
+
+
+/*
+ * NAME
+ * _XcmsCopyCmapRecAndFree
+ *
+ * SYNOPSIS
+ */
+XcmsCmapRec *
+_XcmsCopyCmapRecAndFree(
+ Display *dpy,
+ Colormap src_cmap,
+ Colormap copy_cmap)
+/*
+ * DESCRIPTION
+ * Augments Xlib's XCopyColormapAndFree() to copy
+ * XcmsCmapRecs.
+ *
+ * RETURNS
+ * Returns NULL if failed; otherwise the address to
+ * the copy XcmsCmapRec.
+ *
+ */
+{
+ XcmsCmapRec *pRec_src;
+ XcmsCmapRec *pRec_copy;
+
+ if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) {
+ pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID,
+ pRec_src->visual);
+ if (pRec_copy != NULL && pRec_src->ccc) {
+ pRec_copy->ccc = (XcmsCCC)Xcalloc(1, (unsigned) sizeof(XcmsCCCRec));
+ memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc,
+ sizeof(XcmsCCCRec));
+ }
+ return(pRec_copy);
+ }
+ return((XcmsCmapRec *)NULL);
+}
+
+
+/*
+ * NAME
+ * _XcmsDeleteCmapRec
+ *
+ * SYNOPSIS
+ */
+void
+_XcmsDeleteCmapRec(
+ Display *dpy,
+ Colormap cmap)
+/*
+ * DESCRIPTION
+ * Removes and frees the specified XcmsCmapRec structure
+ * from the linked list of structures.
+ *
+ * RETURNS
+ * void
+ *
+ */
+{
+ XcmsCmapRec **pPrevPtr;
+ XcmsCmapRec *pRec;
+ int scr;
+
+ /* If it is the default cmap for a screen, do not delete it,
+ * because the server will not actually free it */
+ for (scr = ScreenCount(dpy); --scr >= 0; ) {
+ if (cmap == DefaultColormap(dpy, scr))
+ return;
+ }
+
+ /* search for it in the list */
+ pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
+ while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
+ pPrevPtr = &pRec->pNext;
+ }
+
+ if (pRec) {
+ if (pRec->ccc) {
+ XcmsFreeCCC(pRec->ccc);
+ }
+ *pPrevPtr = pRec->pNext;
+ Xfree((char *)pRec);
+ }
+}
+
+
+/*
+ * NAME
+ * _XcmsFreeClientCmaps
+ *
+ * SYNOPSIS
+ */
+static void
+_XcmsFreeClientCmaps(
+ Display *dpy)
+/*
+ * DESCRIPTION
+ * Frees all XcmsCmapRec structures in the linked list
+ * and sets dpy->cms.clientCmaps to NULL.
+ *
+ * RETURNS
+ * void
+ *
+ */
+{
+ XcmsCmapRec *pRecNext, *pRecFree;
+
+ pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
+ while (pRecNext != NULL) {
+ pRecFree = pRecNext;
+ pRecNext = pRecNext->pNext;
+ if (pRecFree->ccc) {
+ /* Free the XcmsCCC structure */
+ XcmsFreeCCC(pRecFree->ccc);
+ }
+ /* Now free the XcmsCmapRec structure */
+ Xfree((char *)pRecFree);
+ }
+ dpy->cms.clientCmaps = (XPointer)NULL;
+}
+
+
+
+/************************************************************************
+ * *
+ * PUBLIC INTERFACES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * XcmsCCCOfColormap
+ *
+ * SYNOPSIS
+ */
+XcmsCCC
+XcmsCCCOfColormap(
+ Display *dpy,
+ Colormap cmap)
+/*
+ * DESCRIPTION
+ * Finds the XcmsCCC associated with the specified colormap.
+ *
+ * RETURNS
+ * Returns NULL if failed; otherwise the address to
+ * the associated XcmsCCC structure.
+ *
+ */
+{
+ XWindowAttributes windowAttr;
+ XcmsCmapRec *pRec;
+ int nScrn = ScreenCount(dpy);
+ int i;
+
+ if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
+ if (pRec->ccc) {
+ /* XcmsCmapRec already has a XcmsCCC */
+ return(pRec->ccc);
+ }
+
+ /*
+ * The XcmsCmapRec does not have a XcmsCCC yet, so let's create
+ * one. But first, we need to know the screen associated with
+ * cmap, so use XGetWindowAttributes() to extract that
+ * information. Unless, of course there is only one screen!!
+ */
+ if (nScrn == 1) {
+ /* Assume screenNumber == 0 */
+ return(pRec->ccc = XcmsCreateCCC(
+ dpy,
+ 0, /* screenNumber */
+ pRec->visual,
+ (XcmsColor *)NULL, /* clientWhitePt */
+ (XcmsCompressionProc)NULL, /* gamutCompProc */
+ (XPointer)NULL, /* gamutCompClientData */
+ (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
+ (XPointer)NULL /* whitePtAdjClientData */
+ ));
+ } else {
+ if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) {
+ for (i = 0; i < nScrn; i++) {
+ if (ScreenOfDisplay(dpy, i) == windowAttr.screen) {
+ return(pRec->ccc = XcmsCreateCCC(
+ dpy,
+ i, /* screenNumber */
+ pRec->visual,
+ (XcmsColor *)NULL, /* clientWhitePt */
+ (XcmsCompressionProc)NULL, /* gamutCompProc */
+ (XPointer)NULL, /* gamutCompClientData */
+ (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
+ (XPointer)NULL /* whitePtAdjClientData */
+ ));
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * No such cmap
+ */
+ return(NULL);
+}
+
+XcmsCCC XcmsSetCCCOfColormap(
+ Display *dpy,
+ Colormap cmap,
+ XcmsCCC ccc)
+{
+ XcmsCCC prev_ccc = NULL;
+ XcmsCmapRec *pRec;
+
+ pRec = CmapRecForColormap(dpy, cmap);
+ if (pRec) {
+ prev_ccc = pRec->ccc;
+ pRec->ccc = ccc;
+ }
+ return prev_ccc;
+}