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 }