Merge commit 'origin/gallium-0.1'
[mesa.git] / src / glut / glx / glut_cindex.c
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 */
14 void GLUTAPIENTRY
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)
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
129 GLfloat GLUTAPIENTRY
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)
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 GLUTAPIENTRY
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)
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 */