#define NEED_EVENTS
#define NEED_REPLIES
#include "Xlibint.h"
#include "Xcmsint.h"
#include "Xutil.h"
#include "Cmap.h"
#include "Cv.h"
static void _XcmsFreeClientCmaps(Display *dpy);
static XcmsCmapRec *
CmapRecForColormap(
Display *dpy,
Colormap cmap)
{
XcmsCmapRec *pRec;
int nScrn;
int i, j;
XVisualInfo visualTemplate;
XVisualInfo *visualList;
int nVisualsMatched;
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);
}
}
nScrn = ScreenCount(dpy);
for (i = 0; i < nScrn; i++) {
if (cmap == DefaultColormap(dpy, i)) {
if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
DefaultVisual(dpy, i))) == NULL) {
return((XcmsCmapRec *)NULL);
}
pRec->ccc = XcmsCreateCCC(
dpy,
i,
DefaultVisual(dpy, i),
(XcmsColor *)NULL,
(XcmsCompressionProc)NULL,
(XPointer)NULL,
(XcmsWhiteAdjustProc)NULL,
(XPointer)NULL
);
return(pRec);
}
}
async_state.error_code = 0;
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;
}
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 (j < nVisualsMatched) {
if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
return((XcmsCmapRec *)NULL);
pRec->ccc = XcmsCreateCCC(
dpy,
i,
vp,
(XcmsColor *)NULL,
(XcmsCompressionProc)NULL,
(XPointer)NULL,
(XcmsWhiteAdjustProc)NULL,
(XPointer)NULL
);
XDestroyWindow(dpy, tmpWindow);
return(pRec);
}
}
return(NULL);
}
XcmsCmapRec *
_XcmsAddCmapRec(dpy, cmap, windowID, visual)
Display *dpy;
Colormap cmap;
Window windowID;
Visual *visual;
{
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;
return(pNew);
}
XcmsCmapRec *
_XcmsCopyCmapRecAndFree(
Display *dpy,
Colormap src_cmap,
Colormap copy_cmap)
{
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);
}
void
_XcmsDeleteCmapRec(
Display *dpy,
Colormap cmap)
{
XcmsCmapRec **pPrevPtr;
XcmsCmapRec *pRec;
int scr;
for (scr = ScreenCount(dpy); --scr >= 0; ) {
if (cmap == DefaultColormap(dpy, scr))
return;
}
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);
}
}
static void
_XcmsFreeClientCmaps(
Display *dpy)
{
XcmsCmapRec *pRecNext, *pRecFree;
pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
while (pRecNext != NULL) {
pRecFree = pRecNext;
pRecNext = pRecNext->pNext;
if (pRecFree->ccc) {
XcmsFreeCCC(pRecFree->ccc);
}
Xfree((char *)pRecFree);
}
dpy->cms.clientCmaps = (XPointer)NULL;
}
XcmsCCC
XcmsCCCOfColormap(dpy, cmap)
Display *dpy;
Colormap cmap;
{
XWindowAttributes windowAttr;
XcmsCmapRec *pRec;
int nScrn = ScreenCount(dpy);
int i;
if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
if (pRec->ccc) {
return(pRec->ccc);
}
if (nScrn == 1) {
return(pRec->ccc = XcmsCreateCCC(
dpy,
0,
pRec->visual,
(XcmsColor *)NULL,
(XcmsCompressionProc)NULL,
(XPointer)NULL,
(XcmsWhiteAdjustProc)NULL,
(XPointer)NULL
));
} 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,
pRec->visual,
(XcmsColor *)NULL,
(XcmsCompressionProc)NULL,
(XPointer)NULL,
(XcmsWhiteAdjustProc)NULL,
(XPointer)NULL
));
}
}
}
}
}
return(NULL);
}
XcmsCCC XcmsSetCCCOfColormap(dpy, cmap, ccc)
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;
}