home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
evbl0627.zip
/
everblue_20010627.zip
/
x11
/
Xcms_Cmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-02
|
13KB
|
505 lines
/* $XConsortium: cmsCmap.c,v 1.17 95/04/27 18:28:37 converse 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
* 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
#include "Xlib_private.h"
#include "Xcmsint.h"
#include "Xutil.h"
/*
* FORWARD DECLARATIONS
*/
XcmsCmapRec *_XcmsAddCmapRec();
static void _XcmsFreeClientCmaps();
/************************************************************************
* *
* PRIVATE INTERFACES *
* *
************************************************************************/
/*
* NAME
* CmapRecForColormap
*
* SYNOPSIS
*/
static XcmsCmapRec *
CmapRecForColormap(dpy, cmap)
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.
*
*/
{
DBUG_ENTER("CmapRecForColormap")
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;
#if 0
_XAsyncHandler async;
_XAsyncErrorState async_state;
#endif
for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
pRec = pRec->pNext) {
if (pRec->cmapID == cmap) {
DBUG_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) {
DBUG_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 */
);
DBUG_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
*/
#if 0
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 (nVisualsMatched == 0) {
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)
DBUG_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);
DBUG_RETURN(pRec);
}
}
#endif
DBUG_RETURN(NULL);
}
/************************************************************************
* *
* API PRIVATE INTERFACES *
* *
************************************************************************/
/*
* NAME
* _XcmsAddCmapRec
*
* SYNOPSIS
*/
XcmsCmapRec *
_XcmsAddCmapRec(dpy, cmap, windowID, visual)
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.
*
*/
{
DBUG_ENTER("_XcmsAddCmapRec")
XcmsCmapRec *pNew;
if ((pNew = (XcmsCmapRec *) Xcalloc(1, (unsigned) sizeof(XcmsCmapRec)))
== NULL) {
DBUG_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.
*/
DBUG_RETURN(pNew);
}
/*
* NAME
* _XcmsCopyCmapRecAndFree
*
* SYNOPSIS
*/
XcmsCmapRec *
_XcmsCopyCmapRecAndFree(dpy, src_cmap, copy_cmap)
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.
*
*/
{
DBUG_ENTER("_XcmsCopyCmapRecAndFree")
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));
}
DBUG_RETURN(pRec_copy);
}
DBUG_RETURN((XcmsCmapRec *)NULL);
}
/*
* NAME
* _XcmsDeleteCmapRec
*
* SYNOPSIS
*/
void
_XcmsDeleteCmapRec(dpy, cmap)
Display *dpy;
Colormap cmap;
/*
* DESCRIPTION
* Removes and frees the specified XcmsCmapRec structure
* from the linked list of structures.
*
* RETURNS
* void
*
*/
{
DBUG_ENTER("_XcmsDeleteCmapRec")
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))
DBUG_VOID_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);
}
DBUG_VOID_RETURN;
}
/*
* NAME
* _XcmsFreeClientCmaps
*
* SYNOPSIS
*/
static void
_XcmsFreeClientCmaps(dpy)
Display *dpy;
/*
* DESCRIPTION
* Frees all XcmsCmapRec structures in the linked list
* and sets dpy->cms.clientCmaps to NULL.
*
* RETURNS
* void
*
*/
{
DBUG_ENTER("_XcmsFreeClientCmaps")
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;
DBUG_VOID_RETURN;
}
/************************************************************************
* *
* PUBLIC INTERFACES *
* *
************************************************************************/
/*
* NAME
* XcmsCCCOfColormap
*
* SYNOPSIS
*/
XcmsCCC
XcmsCCCOfColormap(dpy, cmap)
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.
*
*/
{
DBUG_ENTER("XcmsCCCOfColormap")
XWindowAttributes windowAttr;
XcmsCmapRec *pRec;
int nScrn;
int i;
nScrn = ScreenCount(dpy);
if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
if (pRec->ccc) {
/* XcmsCmapRec already has a XcmsCCC */
DBUG_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 */
DBUG_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) {
DBUG_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
*/
DBUG_RETURN(NULL);
}
XcmsCCC XcmsSetCCCOfColormap(dpy, cmap, ccc)
Display *dpy;
Colormap cmap;
XcmsCCC ccc;
{
DBUG_ENTER("XcmsSetCCCOfColormap")
XcmsCCC prev_ccc = NULL;
XcmsCmapRec *pRec;
pRec = CmapRecForColormap(dpy, cmap);
if (pRec) {
prev_ccc = pRec->ccc;
pRec->ccc = ccc;
}
DBUG_RETURN(prev_ccc);
}