mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
5.8 KiB
223 lines
5.8 KiB
|
|
/* Copyright (c) Mark J. Kilgard, 1994. */
|
|
|
|
/* This program is freely distributable without licensing fees
|
|
and is provided without guarantee or warrantee expressed or
|
|
implied. This program is -not- in the public domain. */
|
|
|
|
#include <stdlib.h>
|
|
#include "gltint.h"
|
|
|
|
GLUTcolormap *__glutColormapList = NULL;
|
|
|
|
static GLUTcolormap *
|
|
associateNewColormap(GLUTosSurface osurf)
|
|
{
|
|
GLUTcolormap *cmap;
|
|
int i;
|
|
|
|
cmap = (GLUTcolormap *) malloc(sizeof(GLUTcolormap));
|
|
if (!cmap)
|
|
__glutFatalError("out of memory.");
|
|
cmap->osurf = osurf;
|
|
cmap->size = __glutOsColormapSize(osurf);
|
|
cmap->refcnt = 1;
|
|
cmap->cells = (GLUTcolorcell *)
|
|
malloc(sizeof(GLUTcolorcell) * cmap->size);
|
|
if (!cmap->cells)
|
|
__glutFatalError("out of memory.");
|
|
/* make all color cell entries be invalid */
|
|
for (i = cmap->size - 1; i >= 0; i--) {
|
|
cmap->cells[i].component[GLUT_RED] = (GLfloat) -1.0;
|
|
cmap->cells[i].component[GLUT_GREEN] = (GLfloat) -1.0;
|
|
cmap->cells[i].component[GLUT_BLUE] = (GLfloat) -1.0;
|
|
}
|
|
cmap->ocmap = __glutOsCreateEmptyColormap(osurf);
|
|
if (cmap->ocmap == GLUT_OS_INVALID_COLORMAP)
|
|
{
|
|
__glutFatalError("Unable to create emtpy colormap.");
|
|
}
|
|
cmap->next = __glutColormapList;
|
|
__glutColormapList = cmap;
|
|
return cmap;
|
|
}
|
|
|
|
GLUTcolormap *
|
|
__glutAssociateColormap(GLUTosSurface osurf)
|
|
{
|
|
GLUTcolormap *cmap = __glutColormapList;
|
|
|
|
while (cmap != NULL) {
|
|
if (__glutOsSurfaceEq(cmap->osurf, osurf)) {
|
|
/* already have created colormap for the surface */
|
|
cmap->refcnt++;
|
|
return cmap;
|
|
}
|
|
cmap = cmap->next;
|
|
}
|
|
return associateNewColormap(osurf);
|
|
}
|
|
|
|
static void
|
|
copyColormapCells(GLUTcolormap *dest, GLUTcolormap *src, int n)
|
|
{
|
|
int i;
|
|
|
|
/* Only copy cells that are set */
|
|
for (i = n - 1; i >= 0; i--) {
|
|
if (src->cells[i].component[GLUT_RED] >= 0.0) {
|
|
dest->cells[i].component[GLUT_RED] =
|
|
src->cells[i].component[GLUT_RED];
|
|
dest->cells[i].component[GLUT_GREEN] =
|
|
src->cells[i].component[GLUT_GREEN];
|
|
dest->cells[i].component[GLUT_BLUE] =
|
|
src->cells[i].component[GLUT_BLUE];
|
|
__glutOsSetColor(dest->ocmap, i,
|
|
src->cells[i].component[GLUT_RED],
|
|
src->cells[i].component[GLUT_GREEN],
|
|
src->cells[i].component[GLUT_BLUE]);
|
|
}
|
|
}
|
|
}
|
|
|
|
#define CLAMP(i) \
|
|
((i) > (GLfloat) 1.0 ? \
|
|
(GLfloat) 1.0 : \
|
|
((i) < (GLfloat) 0.0 ? \
|
|
(GLfloat) 0.0 : \
|
|
(i)))
|
|
|
|
/* CENTRY */
|
|
void
|
|
glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
|
|
{
|
|
GLUTcolormap *cmap;
|
|
GLUTcolormap *newcmap;
|
|
|
|
cmap = __glutCurrentWindow->colormap;
|
|
if (!cmap) {
|
|
__glutWarning("glutSetColor: current window is RGBA");
|
|
return;
|
|
}
|
|
if (ndx >= __glutCurrentWindow->colormap->size ||
|
|
ndx < 0) {
|
|
__glutWarning("glutSetColor: index %d out of range", ndx);
|
|
return;
|
|
}
|
|
if (cmap->refcnt > 1) {
|
|
GLUTwindow *toplevel;
|
|
|
|
newcmap = associateNewColormap(__glutCurrentWindow->osurf);
|
|
cmap->refcnt--;
|
|
copyColormapCells(newcmap, cmap, cmap->size);
|
|
__glutCurrentWindow->colormap = newcmap;
|
|
__glutCurrentWindow->ocmap = newcmap->ocmap;
|
|
__glutOsSetWindowColormap(__glutCurrentWindow->owin,
|
|
__glutCurrentWindow->ocmap);
|
|
toplevel = __glutToplevelOf(__glutCurrentWindow);
|
|
if (toplevel->ocmap != __glutCurrentWindow->ocmap) {
|
|
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
|
|
}
|
|
cmap = newcmap;
|
|
}
|
|
|
|
red = CLAMP(red);
|
|
cmap->cells[ndx].component[GLUT_RED] = red;
|
|
green = CLAMP(green);
|
|
cmap->cells[ndx].component[GLUT_GREEN] = green;
|
|
blue = CLAMP(blue);
|
|
cmap->cells[ndx].component[GLUT_BLUE] = blue;
|
|
__glutOsSetColor(cmap->ocmap, ndx, red, green, blue);
|
|
}
|
|
|
|
GLfloat
|
|
glutGetColor(int ndx, int comp)
|
|
{
|
|
if (!__glutCurrentWindow->colormap) {
|
|
__glutWarning("glutGetColor: current window is RGBA");
|
|
return (GLfloat) -1.0;
|
|
}
|
|
if (ndx >= __glutCurrentWindow->colormap->size ||
|
|
ndx < 0) {
|
|
__glutWarning("glutGetColor: index %d out of range", ndx);
|
|
return (GLfloat) -1.0;
|
|
}
|
|
return
|
|
__glutCurrentWindow->colormap->cells[ndx].component[comp];
|
|
}
|
|
/* ENDCENTRY */
|
|
|
|
void
|
|
__glutFreeColormap(GLUTcolormap * cmap)
|
|
{
|
|
GLUTcolormap *cur, **prev;
|
|
|
|
cmap->refcnt--;
|
|
if (cmap->refcnt == 0) {
|
|
/* remove from colormap list */
|
|
cur = __glutColormapList;
|
|
prev = &__glutColormapList;
|
|
while (cur) {
|
|
if (cur == cmap) {
|
|
*prev = cmap->next;
|
|
break;
|
|
}
|
|
prev = &(cur->next);
|
|
cur = cur->next;
|
|
}
|
|
/* actually free colormap */
|
|
__glutOsDestroyColormap(cmap->ocmap);
|
|
free(cmap->cells);
|
|
free(cmap);
|
|
}
|
|
}
|
|
|
|
/* CENTRY */
|
|
void
|
|
glutCopyColormap(int winnum)
|
|
{
|
|
GLUTwindow *window = __glutWindowList[winnum];
|
|
GLUTcolormap *oldcmap, *newcmap, *copycmap;
|
|
int last;
|
|
|
|
if (!__glutCurrentWindow->colormap) {
|
|
__glutWarning("glutCopyColormap: current window is RGBA");
|
|
return;
|
|
}
|
|
if (!window->colormap) {
|
|
__glutWarning("glutCopyColormap: window %d is RGBA", winnum);
|
|
return;
|
|
}
|
|
oldcmap = __glutCurrentWindow->colormap;
|
|
newcmap = window->colormap;
|
|
|
|
if (newcmap == oldcmap)
|
|
return;
|
|
|
|
if (__glutOsSurfaceEq(newcmap->osurf, oldcmap->osurf)) {
|
|
GLUTwindow *toplevel;
|
|
|
|
/* Surfaces match! "Copy" by reference... */
|
|
__glutFreeColormap(oldcmap);
|
|
newcmap->refcnt++;
|
|
__glutCurrentWindow->colormap = newcmap;
|
|
__glutCurrentWindow->ocmap = newcmap->ocmap;
|
|
__glutOsSetWindowColormap(__glutCurrentWindow->owin,
|
|
__glutCurrentWindow->ocmap);
|
|
toplevel = __glutToplevelOf(window);
|
|
if (toplevel->ocmap != window->ocmap) {
|
|
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Surfaces different - need a distinct colormap! */
|
|
copycmap = associateNewColormap(__glutCurrentWindow->osurf);
|
|
last = newcmap->size;
|
|
if (last > copycmap->size) {
|
|
last = copycmap->size;
|
|
}
|
|
copyColormapCells(copycmap, newcmap, last);
|
|
}
|
|
}
|
|
/* ENDCENTRY */
|