Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
glut_cindex.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <GL/glut.h>
00010 #include "glutint.h"
00011 #include "layerutil.h"
00012
00013 GLUTcolormap *__glutColormapList = NULL;
00014
00015 static GLUTcolormap *
00016 associateNewColormap(XVisualInfo * vis)
00017 {
00018 GLUTcolormap *cmap;
00019 int transparentPixel, i;
00020 unsigned long pixels[255];
00021
00022 cmap = (GLUTcolormap *) malloc(sizeof(GLUTcolormap));
00023 if (!cmap)
00024 __glutFatalError("out of memory.");
00025 cmap->visual = vis->visual;
00026 cmap->refcnt = 1;
00027 cmap->size = vis->visual->map_entries;
00028 cmap->cells = (GLUTcolorcell *)
00029 malloc(sizeof(GLUTcolorcell) * cmap->size);
00030
00031 for (i = cmap->size - 1; i >= 0; i--) {
00032 cmap->cells[i].component[GLUT_RED] = -1.0;
00033 cmap->cells[i].component[GLUT_GREEN] = -1.0;
00034 cmap->cells[i].component[GLUT_BLUE] = -1.0;
00035 }
00036 if (!cmap->cells)
00037 __glutFatalError("out of memory.");
00038 transparentPixel = __glutGetTransparentPixel(__glutDisplay, vis);
00039 if (transparentPixel == -1 || transparentPixel >= vis->visual->map_entries) {
00040
00041
00042
00043
00044
00045
00046
00047 cmap->cmap = XCreateColormap(__glutDisplay,
00048 __glutRoot, vis->visual, AllocAll);
00049 } else {
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 cmap->cmap = XCreateColormap(__glutDisplay,
00061 __glutRoot, vis->visual, AllocNone);
00062 XAllocColorCells(__glutDisplay, cmap->cmap, False, 0, 0,
00063 pixels, vis->visual->map_entries - 1);
00064 }
00065 cmap->next = __glutColormapList;
00066 __glutColormapList = cmap;
00067 return cmap;
00068 }
00069
00070 GLUTcolormap *
00071 __glutAssociateColormap(XVisualInfo * vis)
00072 {
00073 GLUTcolormap *cmap = __glutColormapList;
00074
00075 while (cmap != NULL) {
00076
00077 if (cmap->visual->visualid == vis->visual->visualid) {
00078
00079 cmap->refcnt++;
00080 return cmap;
00081 }
00082 cmap = cmap->next;
00083 }
00084 return associateNewColormap(vis);
00085 }
00086
00087 #define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
00088
00089 void
00090 glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
00091 {
00092 GLUTcolormap *cmap, *newcmap;
00093 XVisualInfo *vis;
00094 XColor color;
00095 int i;
00096
00097 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
00098 cmap = __glutCurrentWindow->colormap;
00099 vis = __glutCurrentWindow->vis;
00100 } else {
00101 cmap = __glutCurrentWindow->overlay->colormap;
00102 vis = __glutCurrentWindow->overlay->vis;
00103 if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
00104 __glutWarning(
00105 "glutSetColor: cannot set color of overlay transparent index %d\n",
00106 ndx);
00107 return;
00108 }
00109 }
00110
00111 if (!cmap) {
00112 __glutWarning("glutSetColor: current window is RGBA");
00113 return;
00114 }
00115 if (ndx >= vis->visual->map_entries ||
00116 ndx < 0) {
00117 __glutWarning("glutSetColor: index %d out of range", ndx);
00118 return;
00119 }
00120 if (cmap->refcnt > 1) {
00121 GLUTwindow *toplevel;
00122
00123 newcmap = associateNewColormap(vis);
00124 cmap->refcnt--;
00125
00126
00127 for (i = cmap->size - 1; i >= 0; i--) {
00128 if (i == ndx) {
00129
00130 continue;
00131 }
00132 if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
00133 color.pixel = i;
00134 newcmap->cells[i].component[GLUT_RED] =
00135 cmap->cells[i].component[GLUT_RED];
00136 color.red = (GLfloat) 0xffff *
00137 cmap->cells[i].component[GLUT_RED];
00138 newcmap->cells[i].component[GLUT_GREEN] =
00139 cmap->cells[i].component[GLUT_GREEN];
00140 color.green = (GLfloat) 0xffff *
00141 cmap->cells[i].component[GLUT_GREEN];
00142 newcmap->cells[i].component[GLUT_BLUE] =
00143 cmap->cells[i].component[GLUT_BLUE];
00144 color.blue = (GLfloat) 0xffff *
00145 cmap->cells[i].component[GLUT_BLUE];
00146 color.flags = DoRed | DoGreen | DoBlue;
00147 XStoreColor(__glutDisplay, newcmap->cmap, &color);
00148 } else {
00149
00150 }
00151 }
00152 cmap = newcmap;
00153 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
00154 __glutCurrentWindow->colormap = cmap;
00155 __glutCurrentWindow->cmap = cmap->cmap;
00156 } else {
00157 __glutCurrentWindow->overlay->colormap = cmap;
00158 __glutCurrentWindow->overlay->cmap = cmap->cmap;
00159 }
00160 XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin, cmap->cmap);
00161
00162 toplevel = __glutToplevelOf(__glutCurrentWindow);
00163 if (toplevel->cmap != cmap->cmap) {
00164 __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
00165 }
00166 }
00167 color.pixel = ndx;
00168 red = CLAMP(red);
00169 cmap->cells[ndx].component[GLUT_RED] = red;
00170 color.red = (GLfloat) 0xffff *red;
00171 green = CLAMP(green);
00172 cmap->cells[ndx].component[GLUT_GREEN] = green;
00173 color.green = (GLfloat) 0xffff *green;
00174 blue = CLAMP(blue);
00175 cmap->cells[ndx].component[GLUT_BLUE] = blue;
00176 color.blue = (GLfloat) 0xffff *blue;
00177 color.flags = DoRed | DoGreen | DoBlue;
00178 XStoreColor(__glutDisplay, cmap->cmap, &color);
00179 }
00180
00181 GLfloat
00182 glutGetColor(int ndx, int comp)
00183 {
00184 GLUTcolormap *colormap;
00185 XVisualInfo *vis;
00186
00187 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
00188 colormap = __glutCurrentWindow->colormap;
00189 vis = __glutCurrentWindow->vis;
00190 } else {
00191 colormap = __glutCurrentWindow->overlay->colormap;
00192 vis = __glutCurrentWindow->overlay->vis;
00193 if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
00194 __glutWarning("glutGetColor: requesting overlay transparent index %d\n",
00195 ndx);
00196 return -1.0;
00197 }
00198 }
00199
00200 if (!colormap) {
00201 __glutWarning("glutGetColor: current window is RGBA");
00202 return -1.0;
00203 }
00204 if (ndx >= vis->visual->map_entries || ndx < 0) {
00205 __glutWarning("glutGetColor: index %d out of range", ndx);
00206 return -1.0;
00207 }
00208 return colormap->cells[ndx].component[comp];
00209 }
00210
00211 void
00212 __glutFreeColormap(GLUTcolormap * cmap)
00213 {
00214 GLUTcolormap *cur, **prev;
00215
00216 cmap->refcnt--;
00217 if (cmap->refcnt == 0) {
00218
00219 cur = __glutColormapList;
00220 prev = &__glutColormapList;
00221 while (cur) {
00222 if (cur == cmap) {
00223 *prev = cmap->next;
00224 break;
00225 }
00226 prev = &(cur->next);
00227 cur = cur->next;
00228 }
00229
00230 XFreeColormap(__glutDisplay, cmap->cmap);
00231 free(cmap->cells);
00232 free(cmap);
00233 }
00234 }
00235
00236 void
00237 glutCopyColormap(int winnum)
00238 {
00239 GLUTwindow *window = __glutWindowList[winnum - 1];
00240 GLUTcolormap *oldcmap, *newcmap, *copycmap;
00241 XVisualInfo *dstvis;
00242 XColor color;
00243 int i, last;
00244
00245 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
00246 oldcmap = __glutCurrentWindow->colormap;
00247 dstvis = __glutCurrentWindow->vis;
00248 newcmap = window->colormap;
00249 } else {
00250 oldcmap = __glutCurrentWindow->overlay->colormap;
00251 dstvis = __glutCurrentWindow->overlay->vis;
00252 if (!window->overlay) {
00253 __glutWarning("glutCopyColormap: window %d has no overlay", winnum);
00254 return;
00255 }
00256 newcmap = window->overlay->colormap;
00257 }
00258
00259 if (!oldcmap) {
00260 __glutWarning("glutCopyColormap: destination colormap must be color index");
00261 return;
00262 }
00263 if (!newcmap) {
00264 __glutWarning(
00265 "glutCopyColormap: source colormap of window %d must be color index",
00266 winnum);
00267 return;
00268 }
00269 if (newcmap == oldcmap) {
00270
00271 return;
00272 }
00273
00274 if (newcmap->visual->visualid == oldcmap->visual->visualid) {
00275
00276 __glutFreeColormap(oldcmap);
00277 newcmap->refcnt++;
00278 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
00279 __glutCurrentWindow->colormap = newcmap;
00280 __glutCurrentWindow->cmap = newcmap->cmap;
00281 } else {
00282 __glutCurrentWindow->overlay->colormap = newcmap;
00283 __glutCurrentWindow->overlay->cmap = newcmap->cmap;
00284 }
00285 XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
00286 newcmap->cmap);
00287 __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
00288 } else {
00289
00290 copycmap = associateNewColormap(dstvis);
00291
00292
00293 last = newcmap->size;
00294 if (last > copycmap->size) {
00295 last = copycmap->size;
00296 }
00297 for (i = last - 1; i >= 0; i--) {
00298 if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
00299 color.pixel = i;
00300 copycmap->cells[i].component[GLUT_RED] =
00301 newcmap->cells[i].component[GLUT_RED];
00302 color.red = (GLfloat) 0xffff *
00303 newcmap->cells[i].component[GLUT_RED];
00304 copycmap->cells[i].component[GLUT_GREEN] =
00305 newcmap->cells[i].component[GLUT_GREEN];
00306 color.green = (GLfloat) 0xffff *
00307 newcmap->cells[i].component[GLUT_GREEN];
00308 copycmap->cells[i].component[GLUT_BLUE] =
00309 newcmap->cells[i].component[GLUT_BLUE];
00310 color.blue = (GLfloat) 0xffff *
00311 newcmap->cells[i].component[GLUT_BLUE];
00312 color.flags = DoRed | DoGreen | DoBlue;
00313 XStoreColor(__glutDisplay, copycmap->cmap, &color);
00314 }
00315 }
00316 }
00317 }