comparison src/video/x11/SDL_x11gamma.c @ 2214:e7164a4dac62

Added gamma table support to X11. Also now supports DirectColor visuals.
author Bob Pendleton <bob@pendleton.com>
date Wed, 25 Jul 2007 21:22:55 +0000
parents 59a667370c57
children 82a133b784c9
comparison
equal deleted inserted replaced
2213:59a667370c57 2214:e7164a4dac62
27 27
28 typedef struct 28 typedef struct
29 { 29 {
30 Display *display; 30 Display *display;
31 int scrNum; 31 int scrNum;
32 Colormap colormap;
32 XStandardColormap cmap; 33 XStandardColormap cmap;
33 Visual visual; 34 Visual visual;
34 } cmapTableEntry; 35 } cmapTableEntry;
35 36
36 cmapTableEntry *cmapTable = NULL; 37 cmapTableEntry *cmapTable = NULL;
37 38
38 void 39 /* To reduce the overhead as much as possible lets do as little as
39 X11_TrackColormap(Display * display, int scrNum, 40 possible. When we do have to create a colormap keep track of it and
40 XStandardColormap * cmap, Visual * visual) 41 reuse it. We're going to do this for both DirectColor and
41 { 42 PseudoColor colormaps. */
42 int i; 43
43 cmapTableEntry *newTable = NULL; 44 Colormap
44 45 X11_LookupColormap(Display * display, int scrNum, VisualID vid)
45 /* only tracking DirectColor colormaps because they're the only ones 46 {
46 with gamma ramps */ 47 int i;
47 if (DirectColor != visual->class) { 48
48 return;
49 }
50
51 /* search the table to find out if we already have this one. We only
52 want one entry for each display, screen number, visualid
53 combination */
54 for (i = 0; i < numCmaps; i++) { 49 for (i = 0; i < numCmaps; i++) {
55 if (cmapTable[i].display == display && 50 if (cmapTable[i].display == display &&
56 cmapTable[i].scrNum == scrNum && 51 cmapTable[i].scrNum == scrNum &&
57 cmapTable[i].cmap.visualid == cmap->visualid) { 52 cmapTable[i].cmap.visualid == vid) {
53 return cmapTable[i].cmap.colormap;
54 }
55 }
56
57 return 0;
58 }
59
60
61 void
62 X11_TrackColormap(Display * display, int scrNum, Colormap colormap,
63 XStandardColormap * cmap, Visual * visual)
64 {
65 int i;
66 cmapTableEntry *newTable = NULL;
67
68 /* search the table to find out if we already have this one. We
69 only want one entry for each display, screen number, visualid,
70 and colormap combination */
71 for (i = 0; i < numCmaps; i++) {
72 if (cmapTable[i].display == display &&
73 cmapTable[i].scrNum == scrNum &&
74 cmapTable[i].cmap.visualid == cmap->visualid &&
75 cmapTable[i].cmap.colormap == colormap) {
58 return; 76 return;
59 } 77 }
60 } 78 }
61 79
62 /* increase the table by one entry. If the table is NULL create the 80 /* increase the table by one entry. If the table is NULL create the
73 } 91 }
74 cmapTable = newTable; 92 cmapTable = newTable;
75 93
76 cmapTable[numCmaps].display = display; 94 cmapTable[numCmaps].display = display;
77 cmapTable[numCmaps].scrNum = scrNum; 95 cmapTable[numCmaps].scrNum = scrNum;
96 cmapTable[numCmaps].colormap = colormap;
78 SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap)); 97 SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap));
79 SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual)); 98 SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
80 99
81 numCmaps++; 100 numCmaps++;
82 } 101 }
83 102
103 /* The problem is that you have to have at least one DirectColor
104 colormap before you can set the gamma ramps or read the gamma
105 ramps. If the application has created a DirectColor window then the
106 cmapTable will have at least one colormap in it and everything is
107 cool. If not, then we just fail */
108
84 int 109 int
85 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp) 110 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
86 { 111 {
87 return -1; 112 Display *display;
113 Colormap colormap;
114 XColor *colorcells;
115 int ncolors;
116 int i;
117 int j;
118
119 int rmax, gmax, bmax;
120 int rmul, gmul, bmul;
121
122 for (j = 0; j < numCmaps; j++) {
123 if (cmapTable[j].visual.class == DirectColor) {
124 display = cmapTable[j].display;
125 colormap = cmapTable[j].colormap;
126 ncolors = cmapTable[j].visual.map_entries;
127
128 colorcells = SDL_malloc(ncolors * sizeof(XColor));
129 if (NULL == colorcells) {
130 SDL_SetError("out of memory in X11_SetDisplayGammaRamp");
131 return -1;
132 }
133
134 rmax = cmapTable[j].cmap.red_max + 1;
135 gmax = cmapTable[j].cmap.blue_max + 1;
136 bmax = cmapTable[j].cmap.green_max + 1;
137
138 rmul = cmapTable[j].cmap.red_mult;
139 gmul = cmapTable[j].cmap.blue_mult;
140 bmul = cmapTable[j].cmap.green_mult;
141
142 /* build the color table pixel values */
143 for (i = 0; i < ncolors; i++) {
144 Uint32 red = (rmax * i) / ncolors;
145 Uint32 green = (gmax * i) / ncolors;
146 Uint32 blue = (bmax * i) / ncolors;
147
148 colorcells[i].pixel =
149 (red * rmul) | (green * gmul) | (blue * bmul);
150 colorcells[i].flags = DoRed | DoGreen | DoBlue;
151
152 colorcells[i].red = ramp[(0 * 256) + i];
153 colorcells[i].green = ramp[(1 * 256) + i];
154 colorcells[i].blue = ramp[(2 * 256) + i];
155 }
156
157 XStoreColors(display, colormap, colorcells, ncolors);
158 XFlush(display);
159 SDL_free(colorcells);
160 }
161 }
162
163 return 0;
88 } 164 }
89 165
90 int 166 int
91 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp) 167 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
92 { 168 {
93 return -1; 169 Display *display;
94 } 170 Colormap colormap;
171 XColor *colorcells;
172 int ncolors;
173 int dc;
174 int i;
175
176 int rmax, gmax, bmax;
177 int rmul, gmul, bmul;
178
179 /* find the first DirectColor colormap and use it to get the gamma
180 ramp */
181
182 dc = -1;
183 for (i = 0; i < numCmaps; i++) {
184 if (cmapTable[i].visual.class == DirectColor) {
185 dc = i;
186 break;
187 }
188 }
189
190 if (dc < 0) {
191 return -1;
192 }
193
194 /* there is at least one DirectColor colormap in the cmapTable,
195 let's just get the entries from that colormap */
196
197 display = cmapTable[dc].display;
198 colormap = cmapTable[dc].colormap;
199 ncolors = cmapTable[dc].visual.map_entries;
200 colorcells = SDL_malloc(ncolors * sizeof(XColor));
201 if (NULL == colorcells) {
202 SDL_SetError("out of memory in X11_GetDisplayGammaRamp");
203 return -1;
204 }
205
206 rmax = cmapTable[dc].cmap.red_max + 1;
207 gmax = cmapTable[dc].cmap.blue_max + 1;
208 bmax = cmapTable[dc].cmap.green_max + 1;
209
210 rmul = cmapTable[dc].cmap.red_mult;
211 gmul = cmapTable[dc].cmap.blue_mult;
212 bmul = cmapTable[dc].cmap.green_mult;
213
214 /* build the color table pixel values */
215 for (i = 0; i < ncolors; i++) {
216 Uint32 red = (rmax * i) / ncolors;
217 Uint32 green = (gmax * i) / ncolors;
218 Uint32 blue = (bmax * i) / ncolors;
219
220 colorcells[i].pixel = (red * rmul) | (green * gmul) | (blue * bmul);
221 }
222
223 XQueryColors(display, colormap, colorcells, ncolors);
224
225 /* prepare the values to be returned. Note that SDL assumes that
226 gamma ramps are always 3 * 256 entries long with the red entries
227 in the first 256 elements, the green in the second 256 elements
228 and the blue in the last 256 elements */
229
230 for (i = 0; i < ncolors; i++) {
231 ramp[(0 * 256) + i] = colorcells[i].red;
232 ramp[(1 * 256) + i] = colorcells[i].green;
233 ramp[(2 * 256) + i] = colorcells[i].blue;
234 }
235
236 SDL_free(colorcells);
237 return 0;
238 }