| 1 | /* $Id: glut_cindex.c,v 1.2 2000-02-09 08:46:08 jeroen Exp $ */
|
|---|
| 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 */
|
|---|
| 14 | void APIENTRY
|
|---|
| 15 | glutSetColor(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) || defined(__WIN32OS2__)
|
|---|
| 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) && !defined(__WIN32OS2__)
|
|---|
| 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 |
|
|---|
| 129 | GLfloat APIENTRY
|
|---|
| 130 | glutGetColor(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) || defined(__WIN32OS2__)
|
|---|
| 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 |
|
|---|
| 164 | void APIENTRY
|
|---|
| 165 | glutCopyColormap(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) && !defined(__WIN32OS2__)
|
|---|
| 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) && !defined(__WIN32OS2__)
|
|---|
| 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 */
|
|---|