1 2/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */ 3 4/* This program is freely distributable without licensing fees 5 and is provided without guarantee or warrantee expressed or 6 implied. This program is -not- in the public domain. */ 7 8#include <stdlib.h> 9#include "glutint.h" 10 11#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i))) 12 13/* CENTRY */ 14void GLUTAPIENTRY 15glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue) 16{ 17 GLUTcolormap *cmap, *newcmap; 18 XVisualInfo *vis; 19 XColor color; 20 int i; 21 22 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { 23 cmap = __glutCurrentWindow->colormap; 24 vis = __glutCurrentWindow->vis; 25 } else { 26 cmap = __glutCurrentWindow->overlay->colormap; 27 vis = __glutCurrentWindow->overlay->vis; 28 if (ndx == __glutCurrentWindow->overlay->transparentPixel) { 29 __glutWarning( 30 "glutSetColor: cannot set color of overlay transparent index %d\n", 31 ndx); 32 return; 33 } 34 } 35 36 if (!cmap) { 37 __glutWarning("glutSetColor: current window is RGBA"); 38 return; 39 } 40#if defined(_WIN32) 41 if (ndx >= 256 || /* always assume 256 colors on Win32 */ 42#else 43 if (ndx >= vis->visual->map_entries || 44#endif 45 ndx < 0) { 46 __glutWarning("glutSetColor: index %d out of range", ndx); 47 return; 48 } 49 if (cmap->refcnt > 1) { 50 newcmap = __glutAssociateNewColormap(vis); 51 cmap->refcnt--; 52 /* Wouldn't it be nice if XCopyColormapAndFree could be 53 told not to free the old colormap's entries! */ 54 for (i = cmap->size - 1; i >= 0; i--) { 55 if (i == ndx) { 56 /* We are going to set this cell shortly! */ 57 continue; 58 } 59 if (cmap->cells[i].component[GLUT_RED] >= 0.0) { 60 color.pixel = i; 61 newcmap->cells[i].component[GLUT_RED] = 62 cmap->cells[i].component[GLUT_RED]; 63 color.red = (GLfloat) 0xffff * 64 cmap->cells[i].component[GLUT_RED]; 65 newcmap->cells[i].component[GLUT_GREEN] = 66 cmap->cells[i].component[GLUT_GREEN]; 67 color.green = (GLfloat) 0xffff * 68 cmap->cells[i].component[GLUT_GREEN]; 69 newcmap->cells[i].component[GLUT_BLUE] = 70 cmap->cells[i].component[GLUT_BLUE]; 71 color.blue = (GLfloat) 0xffff * 72 cmap->cells[i].component[GLUT_BLUE]; 73 color.flags = DoRed | DoGreen | DoBlue; 74#if defined(_WIN32) 75 if (IsWindowVisible(__glutCurrentWindow->win)) { 76 XHDC = __glutCurrentWindow->hdc; 77 } else { 78 XHDC = 0; 79 } 80#endif 81 XStoreColor(__glutDisplay, newcmap->cmap, &color); 82 } else { 83 /* Leave unallocated entries unallocated. */ 84 } 85 } 86 cmap = newcmap; 87 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { 88 __glutCurrentWindow->colormap = cmap; 89 __glutCurrentWindow->cmap = cmap->cmap; 90 } else { 91 __glutCurrentWindow->overlay->colormap = cmap; 92 __glutCurrentWindow->overlay->cmap = cmap->cmap; 93 } 94 XSetWindowColormap(__glutDisplay, 95 __glutCurrentWindow->renderWin, cmap->cmap); 96 97#if !defined(_WIN32) 98 { 99 GLUTwindow *toplevel; 100 101 toplevel = __glutToplevelOf(__glutCurrentWindow); 102 if (toplevel->cmap != cmap->cmap) { 103 __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK); 104 } 105 } 106#endif 107 } 108 color.pixel = ndx; 109 red = CLAMP(red); 110 cmap->cells[ndx].component[GLUT_RED] = red; 111 color.red = (GLfloat) 0xffff *red; 112 green = CLAMP(green); 113 cmap->cells[ndx].component[GLUT_GREEN] = green; 114 color.green = (GLfloat) 0xffff *green; 115 blue = CLAMP(blue); 116 cmap->cells[ndx].component[GLUT_BLUE] = blue; 117 color.blue = (GLfloat) 0xffff *blue; 118 color.flags = DoRed | DoGreen | DoBlue; 119#if defined(_WIN32) 120 if (IsWindowVisible(__glutCurrentWindow->win)) { 121 XHDC = __glutCurrentWindow->hdc; 122 } else { 123 XHDC = 0; 124 } 125#endif 126 XStoreColor(__glutDisplay, cmap->cmap, &color); 127} 128 129GLfloat GLUTAPIENTRY 130glutGetColor(int ndx, int comp) 131{ 132 GLUTcolormap *colormap; 133 XVisualInfo *vis; 134 135 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { 136 colormap = __glutCurrentWindow->colormap; 137 vis = __glutCurrentWindow->vis; 138 } else { 139 colormap = __glutCurrentWindow->overlay->colormap; 140 vis = __glutCurrentWindow->overlay->vis; 141 if (ndx == __glutCurrentWindow->overlay->transparentPixel) { 142 __glutWarning("glutGetColor: requesting overlay transparent index %d\n", 143 ndx); 144 return -1.0; 145 } 146 } 147 148 if (!colormap) { 149 __glutWarning("glutGetColor: current window is RGBA"); 150 return -1.0; 151 } 152#if defined(_WIN32) 153#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0) 154#else 155#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0) 156#endif 157 if (OUT_OF_RANGE_NDX(ndx)) { 158 __glutWarning("glutGetColor: index %d out of range", ndx); 159 return -1.0; 160 } 161 return colormap->cells[ndx].component[comp]; 162} 163 164void GLUTAPIENTRY 165glutCopyColormap(int winnum) 166{ 167 GLUTwindow *window = __glutWindowList[winnum - 1]; 168 GLUTcolormap *oldcmap, *newcmap; 169 XVisualInfo *dstvis; 170 171 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { 172 oldcmap = __glutCurrentWindow->colormap; 173 dstvis = __glutCurrentWindow->vis; 174 newcmap = window->colormap; 175 } else { 176 oldcmap = __glutCurrentWindow->overlay->colormap; 177 dstvis = __glutCurrentWindow->overlay->vis; 178 if (!window->overlay) { 179 __glutWarning("glutCopyColormap: window %d has no overlay", winnum); 180 return; 181 } 182 newcmap = window->overlay->colormap; 183 } 184 185 if (!oldcmap) { 186 __glutWarning("glutCopyColormap: destination colormap must be color index"); 187 return; 188 } 189 if (!newcmap) { 190 __glutWarning( 191 "glutCopyColormap: source colormap of window %d must be color index", 192 winnum); 193 return; 194 } 195 if (newcmap == oldcmap) { 196 /* Source and destination are the same; now copy needed. */ 197 return; 198 } 199#if !defined(_WIN32) 200 /* Play safe: compare visual IDs, not Visual*'s. */ 201 if (newcmap->visual->visualid == oldcmap->visual->visualid) { 202#endif 203 /* Visuals match! "Copy" by reference... */ 204 __glutFreeColormap(oldcmap); 205 newcmap->refcnt++; 206 if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { 207 __glutCurrentWindow->colormap = newcmap; 208 __glutCurrentWindow->cmap = newcmap->cmap; 209 } else { 210 __glutCurrentWindow->overlay->colormap = newcmap; 211 __glutCurrentWindow->overlay->cmap = newcmap->cmap; 212 } 213 XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin, 214 newcmap->cmap); 215#if !defined(_WIN32) 216 __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK); 217 } else { 218 GLUTcolormap *copycmap; 219 XColor color; 220 int i, last; 221 222 /* Visuals different - need a distinct X colormap! */ 223 copycmap = __glutAssociateNewColormap(dstvis); 224 /* Wouldn't it be nice if XCopyColormapAndFree could be 225 told not to free the old colormap's entries! */ 226 last = newcmap->size; 227 if (last > copycmap->size) { 228 last = copycmap->size; 229 } 230 for (i = last - 1; i >= 0; i--) { 231 if (newcmap->cells[i].component[GLUT_RED] >= 0.0) { 232 color.pixel = i; 233 copycmap->cells[i].component[GLUT_RED] = 234 newcmap->cells[i].component[GLUT_RED]; 235 color.red = (GLfloat) 0xffff * 236 newcmap->cells[i].component[GLUT_RED]; 237 copycmap->cells[i].component[GLUT_GREEN] = 238 newcmap->cells[i].component[GLUT_GREEN]; 239 color.green = (GLfloat) 0xffff * 240 newcmap->cells[i].component[GLUT_GREEN]; 241 copycmap->cells[i].component[GLUT_BLUE] = 242 newcmap->cells[i].component[GLUT_BLUE]; 243 color.blue = (GLfloat) 0xffff * 244 newcmap->cells[i].component[GLUT_BLUE]; 245 color.flags = DoRed | DoGreen | DoBlue; 246 XStoreColor(__glutDisplay, copycmap->cmap, &color); 247 } 248 } 249 } 250#endif 251} 252/* ENDCENTRY */ 253