Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

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 /* Copyright (c) Mark J. Kilgard, 1994, 1996. */
00003 
00004 /* This program is freely distributable without licensing fees 
00005    and is provided without guarantee or warrantee expressed or 
00006    implied. This program is -not- in the public domain. */
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   /* make all color cell entries be invalid */
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     /* If there is no transparent pixel or if the transparent
00042        pixel is outside the range of valid colormap cells (HP
00043        can implement their overlays this smart way since their
00044        transparent pixel is 255), we can AllocAll the colormap.
00045        See note below.  */
00046 
00047     cmap->cmap = XCreateColormap(__glutDisplay,
00048       __glutRoot, vis->visual, AllocAll);
00049   } else {
00050 
00051     /* On machines where zero (or some other value in the range
00052        of 0 through map_entries-1), BadAlloc may be generated
00053        when an AllocAll overlay colormap is allocated since the
00054        transparent pixel precludes all the cells in the colormap
00055        being allocated (the transparent pixel is pre-allocated).
00056        So in this case, use XAllocColorCells to allocate
00057        map_entries-1 pixels (that is, all but the transparent
00058        pixel.  */
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     /* Play safe: compare visual IDs, not Visual*'s */
00077     if (cmap->visual->visualid == vis->visual->visualid) {
00078       /* already have created colormap for the visual */
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     /* Wouldn't it be nice if XCopyColormapAndFree could be
00126        told not to free the old colormap's entries! */
00127     for (i = cmap->size - 1; i >= 0; i--) {
00128       if (i == ndx) {
00129         /* We are going to set this cell shortly! */
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         /* leave unallocated entries unallocated */
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     /* remove from colormap list */
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     /* actually free colormap */
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     /* Source and destination are the same; now copy needed. */
00271     return;
00272   }
00273   /* Play safe: compare visual IDs, not Visual*'s */
00274   if (newcmap->visual->visualid == oldcmap->visual->visualid) {
00275     /* Visuals match!  "Copy" by reference...  */
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     /* Visuals different - need a distinct X colormap! */
00290     copycmap = associateNewColormap(dstvis);
00291     /* Wouldn't it be nice if XCopyColormapAndFree could be
00292        told not to free the old colormap's entries! */
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 }
 

Powered by Plone

This site conforms to the following standards: