#include <stdlib.h>
#include "glutint.h"
#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
void GLUTAPIENTRY
glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
{
GLUTcolormap *cmap, *newcmap;
XVisualInfo *vis;
XColor color;
int i;
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
cmap = __glutCurrentWindow->colormap;
vis = __glutCurrentWindow->vis;
} else {
cmap = __glutCurrentWindow->overlay->colormap;
vis = __glutCurrentWindow->overlay->vis;
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
__glutWarning(
"glutSetColor: cannot set color of overlay transparent index %d\n",
ndx);
return;
}
}
if (!cmap) {
__glutWarning("glutSetColor: current window is RGBA");
return;
}
#if defined(_WIN32)
if (ndx >= 256 ||
#else
if (ndx >= vis->visual->map_entries ||
#endif
ndx < 0) {
__glutWarning("glutSetColor: index %d out of range", ndx);
return;
}
if (cmap->refcnt > 1) {
newcmap = __glutAssociateNewColormap(vis);
cmap->refcnt--;
for (i = cmap->size - 1; i >= 0; i--) {
if (i == ndx) {
continue;
}
if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
color.pixel = i;
newcmap->cells[i].component[GLUT_RED] =
cmap->cells[i].component[GLUT_RED];
color.red = (GLfloat) 0xffff *
cmap->cells[i].component[GLUT_RED];
newcmap->cells[i].component[GLUT_GREEN] =
cmap->cells[i].component[GLUT_GREEN];
color.green = (GLfloat) 0xffff *
cmap->cells[i].component[GLUT_GREEN];
newcmap->cells[i].component[GLUT_BLUE] =
cmap->cells[i].component[GLUT_BLUE];
color.blue = (GLfloat) 0xffff *
cmap->cells[i].component[GLUT_BLUE];
color.flags = DoRed | DoGreen | DoBlue;
#if defined(_WIN32)
if (IsWindowVisible(__glutCurrentWindow->win)) {
XHDC = __glutCurrentWindow->hdc;
} else {
XHDC = 0;
}
#endif
XStoreColor(__glutDisplay, newcmap->cmap, &color);
} else {
}
}
cmap = newcmap;
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
__glutCurrentWindow->colormap = cmap;
__glutCurrentWindow->cmap = cmap->cmap;
} else {
__glutCurrentWindow->overlay->colormap = cmap;
__glutCurrentWindow->overlay->cmap = cmap->cmap;
}
XSetWindowColormap(__glutDisplay,
__glutCurrentWindow->renderWin, cmap->cmap);
#if !defined(_WIN32)
{
GLUTwindow *toplevel;
toplevel = __glutToplevelOf(__glutCurrentWindow);
if (toplevel->cmap != cmap->cmap) {
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
}
}
#endif
}
color.pixel = ndx;
red = CLAMP(red);
cmap->cells[ndx].component[GLUT_RED] = red;
color.red = (GLfloat) 0xffff *red;
green = CLAMP(green);
cmap->cells[ndx].component[GLUT_GREEN] = green;
color.green = (GLfloat) 0xffff *green;
blue = CLAMP(blue);
cmap->cells[ndx].component[GLUT_BLUE] = blue;
color.blue = (GLfloat) 0xffff *blue;
color.flags = DoRed | DoGreen | DoBlue;
#if defined(_WIN32)
if (IsWindowVisible(__glutCurrentWindow->win)) {
XHDC = __glutCurrentWindow->hdc;
} else {
XHDC = 0;
}
#endif
XStoreColor(__glutDisplay, cmap->cmap, &color);
}
GLfloat GLUTAPIENTRY
glutGetColor(int ndx, int comp)
{
GLUTcolormap *colormap;
XVisualInfo *vis;
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
colormap = __glutCurrentWindow->colormap;
vis = __glutCurrentWindow->vis;
} else {
colormap = __glutCurrentWindow->overlay->colormap;
vis = __glutCurrentWindow->overlay->vis;
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
__glutWarning("glutGetColor: requesting overlay transparent index %d\n",
ndx);
return -1.0;
}
}
if (!colormap) {
__glutWarning("glutGetColor: current window is RGBA");
return -1.0;
}
#if defined(_WIN32)
#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
#else
#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
#endif
if (OUT_OF_RANGE_NDX(ndx)) {
__glutWarning("glutGetColor: index %d out of range", ndx);
return -1.0;
}
return colormap->cells[ndx].component[comp];
}
void GLUTAPIENTRY
glutCopyColormap(int winnum)
{
GLUTwindow *window = __glutWindowList[winnum - 1];
GLUTcolormap *oldcmap, *newcmap;
XVisualInfo *dstvis;
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
oldcmap = __glutCurrentWindow->colormap;
dstvis = __glutCurrentWindow->vis;
newcmap = window->colormap;
} else {
oldcmap = __glutCurrentWindow->overlay->colormap;
dstvis = __glutCurrentWindow->overlay->vis;
if (!window->overlay) {
__glutWarning("glutCopyColormap: window %d has no overlay", winnum);
return;
}
newcmap = window->overlay->colormap;
}
if (!oldcmap) {
__glutWarning("glutCopyColormap: destination colormap must be color index");
return;
}
if (!newcmap) {
__glutWarning(
"glutCopyColormap: source colormap of window %d must be color index",
winnum);
return;
}
if (newcmap == oldcmap) {
return;
}
#if !defined(_WIN32)
if (newcmap->visual->visualid == oldcmap->visual->visualid) {
#endif
__glutFreeColormap(oldcmap);
newcmap->refcnt++;
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
__glutCurrentWindow->colormap = newcmap;
__glutCurrentWindow->cmap = newcmap->cmap;
} else {
__glutCurrentWindow->overlay->colormap = newcmap;
__glutCurrentWindow->overlay->cmap = newcmap->cmap;
}
XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
newcmap->cmap);
#if !defined(_WIN32)
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
} else {
GLUTcolormap *copycmap;
XColor color;
int i, last;
copycmap = __glutAssociateNewColormap(dstvis);
last = newcmap->size;
if (last > copycmap->size) {
last = copycmap->size;
}
for (i = last - 1; i >= 0; i--) {
if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
color.pixel = i;
copycmap->cells[i].component[GLUT_RED] =
newcmap->cells[i].component[GLUT_RED];
color.red = (GLfloat) 0xffff *
newcmap->cells[i].component[GLUT_RED];
copycmap->cells[i].component[GLUT_GREEN] =
newcmap->cells[i].component[GLUT_GREEN];
color.green = (GLfloat) 0xffff *
newcmap->cells[i].component[GLUT_GREEN];
copycmap->cells[i].component[GLUT_BLUE] =
newcmap->cells[i].component[GLUT_BLUE];
color.blue = (GLfloat) 0xffff *
newcmap->cells[i].component[GLUT_BLUE];
color.flags = DoRed | DoGreen | DoBlue;
XStoreColor(__glutDisplay, copycmap->cmap, &color);
}
}
}
#endif
}