comparison src/video/x11/SDL_x11gamma.c @ 3010:a6694a812119

Modified and totally untested code to load the color tables for DirectColor and PseudoColor windows.
author Bob Pendleton <bob@pendleton.com>
date Fri, 09 Jan 2009 20:41:31 +0000
parents 99210400e8b9
children b36579172f27
comparison
equal deleted inserted replaced
3009:546c022a9ae5 3010:a6694a812119
28 typedef struct 28 typedef struct
29 { 29 {
30 Display *display; 30 Display *display;
31 int scrNum; 31 int scrNum;
32 Colormap colormap; 32 Colormap colormap;
33 XStandardColormap cmap;
34 Visual visual; 33 Visual visual;
34 Uint16 *ramp;
35 } cmapTableEntry; 35 } cmapTableEntry;
36 36
37 cmapTableEntry *cmapTable = NULL; 37 cmapTableEntry *cmapTable = NULL;
38 38
39 /* To reduce the overhead as much as possible lets do as little as 39 /* To reduce the overhead as much as possible lets do as little as
47 int i; 47 int i;
48 48
49 for (i = 0; i < numCmaps; i++) { 49 for (i = 0; i < numCmaps; i++) {
50 if (cmapTable[i].display == display && 50 if (cmapTable[i].display == display &&
51 cmapTable[i].scrNum == scrNum && 51 cmapTable[i].scrNum == scrNum &&
52 cmapTable[i].cmap.visualid == vid) { 52 cmapTable[i].visual.visualid == vid) {
53 return cmapTable[i].cmap.colormap; 53 return cmapTable[i].colormap;
54 } 54 }
55 } 55 }
56 56
57 return 0; 57 return 0;
58 } 58 }
59 59
60 60
61 void 61 void
62 X11_TrackColormap(Display * display, int scrNum, Colormap colormap, 62 X11_TrackColormap(Display * display, int scrNum, Colormap colormap,
63 XStandardColormap * cmap, Visual * visual) 63 Visual * visual, XColor * ramp)
64 { 64 {
65 int i; 65 int i;
66 Uint16 *newramp;
67 int ncolors;
66 68
67 /* search the table to find out if we already have this one. We 69 /* search the table to find out if we already have this one. We
68 only want one entry for each display, screen number, visualid, 70 only want one entry for each display, screen number, visualid,
69 and colormap combination */ 71 and colormap combination */
70 for (i = 0; i < numCmaps; i++) { 72 for (i = 0; i < numCmaps; i++) {
71 if (cmapTable[i].display == display && 73 if (cmapTable[i].display == display &&
72 cmapTable[i].scrNum == scrNum && 74 cmapTable[i].scrNum == scrNum &&
73 cmapTable[i].cmap.visualid == cmap->visualid && 75 cmapTable[i].visual.visualid == visual->visualid &&
74 cmapTable[i].cmap.colormap == colormap) { 76 cmapTable[i].colormap == colormap) {
75 return; 77 return;
76 } 78 }
77 } 79 }
78 80
79 /* increase the table by one entry. If the table is NULL create the 81 /* increase the table by one entry. If the table is NULL create the
86 } 88 }
87 89
88 cmapTable[numCmaps].display = display; 90 cmapTable[numCmaps].display = display;
89 cmapTable[numCmaps].scrNum = scrNum; 91 cmapTable[numCmaps].scrNum = scrNum;
90 cmapTable[numCmaps].colormap = colormap; 92 cmapTable[numCmaps].colormap = colormap;
91 SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap));
92 SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual)); 93 SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
94 cmapTable[numCmaps].ramp = NULL;
95
96 newramp = SDL_malloc(3 * 256 * sizeof(Uint16)); /* The size of *all* SDL gamma ramps */
97 if (NULL == newramp) {
98 SDL_SetError("Out of memory in X11_TrackColormap()");
99 return;
100 }
101 SDL_memset(newramp, 0, sizeof(*newramp));
102 cmapTable[numCmaps].ramp = newramp;
103
104 ncolors = cmapTable[numCmaps].visual.map_entries;
105
106 for (i = 0; i < ncolors; i++) {
107 newramp[(0 * 256) + i] = ramp[i].red;
108 newramp[(1 * 256) + i] = ramp[i].green;
109 newramp[(2 * 256) + i] = ramp[i].blue;
110 }
93 111
94 numCmaps++; 112 numCmaps++;
95 } 113 }
96 114
97 /* The problem is that you have to have at least one DirectColor 115 /* The problem is that you have to have at least one DirectColor
101 cool. If not, then we just fail */ 119 cool. If not, then we just fail */
102 120
103 int 121 int
104 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp) 122 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
105 { 123 {
124 Visual *visual;
106 Display *display; 125 Display *display;
107 Colormap colormap; 126 Colormap colormap;
108 XColor *colorcells; 127 XColor *colorcells;
109 int ncolors; 128 int ncolors;
129 int rmask, gmask, bmask;
130 int rshift, gshift, bshift;
110 int i; 131 int i;
111 int j; 132 int j;
112
113 int rmax, gmax, bmax;
114 int rmul, gmul, bmul;
115 133
116 for (j = 0; j < numCmaps; j++) { 134 for (j = 0; j < numCmaps; j++) {
117 if (cmapTable[j].visual.class == DirectColor) { 135 if (cmapTable[j].visual.class == DirectColor) {
118 display = cmapTable[j].display; 136 display = cmapTable[j].display;
119 colormap = cmapTable[j].colormap; 137 colormap = cmapTable[j].colormap;
120 ncolors = cmapTable[j].visual.map_entries; 138 ncolors = cmapTable[j].visual.map_entries;
139 visual = &cmapTable[j].visual;
121 140
122 colorcells = SDL_malloc(ncolors * sizeof(XColor)); 141 colorcells = SDL_malloc(ncolors * sizeof(XColor));
123 if (NULL == colorcells) { 142 if (NULL == colorcells) {
124 SDL_SetError("out of memory in X11_SetDisplayGammaRamp"); 143 SDL_SetError("out of memory in X11_SetDisplayGammaRamp");
125 return -1; 144 return -1;
126 } 145 }
127 146 /* remember the new ramp */
128 rmax = cmapTable[j].cmap.red_max + 1; 147 SDL_memcpy(cmapTable[j].ramp, ramp, sizeof(*cmapTable[j].ramp));
129 gmax = cmapTable[j].cmap.blue_max + 1; 148
130 bmax = cmapTable[j].cmap.green_max + 1; 149 rshift = 0;
131 150 rmask = visual->red_mask;
132 rmul = cmapTable[j].cmap.red_mult; 151 while (0 == (rmask & 1)) {
133 gmul = cmapTable[j].cmap.blue_mult; 152 rshift++;
134 bmul = cmapTable[j].cmap.green_mult; 153 rmask >>= 1;
154 }
155
156 /* printf("rmask = %4x rshift = %4d\n", rmask, rshift); */
157
158 gshift = 0;
159 gmask = visual->green_mask;
160 while (0 == (gmask & 1)) {
161 gshift++;
162 gmask >>= 1;
163 }
164
165 /* printf("gmask = %4x gshift = %4d\n", gmask, gshift); */
166
167 bshift = 0;
168 bmask = visual->blue_mask;
169 while (0 == (bmask & 1)) {
170 bshift++;
171 bmask >>= 1;
172 }
173
174 /* printf("bmask = %4x bshift = %4d\n", bmask, bshift); */
135 175
136 /* build the color table pixel values */ 176 /* build the color table pixel values */
137 for (i = 0; i < ncolors; i++) { 177 for (i = 0; i < ncolors; i++) {
138 Uint32 red = (rmax * i) / ncolors; 178 Uint32 rbits = (rmask * i) / (ncolors - 1);
139 Uint32 green = (gmax * i) / ncolors; 179 Uint32 gbits = (gmask * i) / (ncolors - 1);
140 Uint32 blue = (bmax * i) / ncolors; 180 Uint32 bbits = (bmask * i) / (ncolors - 1);
141 181
142 colorcells[i].pixel = 182 Uint32 pix =
143 (red * rmul) | (green * gmul) | (blue * bmul); 183 (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
184
185 colorcells[i].pixel = pix;
186
144 colorcells[i].flags = DoRed | DoGreen | DoBlue; 187 colorcells[i].flags = DoRed | DoGreen | DoBlue;
145 188
146 colorcells[i].red = ramp[(0 * 256) + i]; 189 colorcells[i].red = ramp[(0 * 256) + i];
147 colorcells[i].green = ramp[(1 * 256) + i]; 190 colorcells[i].green = ramp[(1 * 256) + i];
148 colorcells[i].blue = ramp[(2 * 256) + i]; 191 colorcells[i].blue = ramp[(2 * 256) + i];
158 } 201 }
159 202
160 int 203 int
161 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp) 204 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
162 { 205 {
163 Display *display; 206 int i;
164 Colormap colormap;
165 XColor *colorcells;
166 int ncolors;
167 int dc;
168 int i;
169
170 int rmax, gmax, bmax;
171 int rmul, gmul, bmul;
172 207
173 /* find the first DirectColor colormap and use it to get the gamma 208 /* find the first DirectColor colormap and use it to get the gamma
174 ramp */ 209 ramp */
175 210
176 dc = -1;
177 for (i = 0; i < numCmaps; i++) { 211 for (i = 0; i < numCmaps; i++) {
178 if (cmapTable[i].visual.class == DirectColor) { 212 if (cmapTable[i].visual.class == DirectColor) {
179 dc = i; 213 SDL_memcpy(ramp, cmapTable[i].ramp, sizeof(*cmapTable[i].ramp));
180 break; 214 return 0;
181 } 215 }
182 } 216 }
183 217
184 if (dc < 0) { 218 return -1;
185 return -1; 219 }
186 }
187
188 /* there is at least one DirectColor colormap in the cmapTable,
189 let's just get the entries from that colormap */
190
191 display = cmapTable[dc].display;
192 colormap = cmapTable[dc].colormap;
193 ncolors = cmapTable[dc].visual.map_entries;
194 colorcells = SDL_malloc(ncolors * sizeof(XColor));
195 if (NULL == colorcells) {
196 SDL_SetError("out of memory in X11_GetDisplayGammaRamp");
197 return -1;
198 }
199
200 rmax = cmapTable[dc].cmap.red_max + 1;
201 gmax = cmapTable[dc].cmap.blue_max + 1;
202 bmax = cmapTable[dc].cmap.green_max + 1;
203
204 rmul = cmapTable[dc].cmap.red_mult;
205 gmul = cmapTable[dc].cmap.blue_mult;
206 bmul = cmapTable[dc].cmap.green_mult;
207
208 /* build the color table pixel values */
209 for (i = 0; i < ncolors; i++) {
210 Uint32 red = (rmax * i) / ncolors;
211 Uint32 green = (gmax * i) / ncolors;
212 Uint32 blue = (bmax * i) / ncolors;
213
214 colorcells[i].pixel = (red * rmul) | (green * gmul) | (blue * bmul);
215 }
216
217 XQueryColors(display, colormap, colorcells, ncolors);
218
219 /* prepare the values to be returned. Note that SDL assumes that
220 gamma ramps are always 3 * 256 entries long with the red entries
221 in the first 256 elements, the green in the second 256 elements
222 and the blue in the last 256 elements */
223
224 for (i = 0; i < ncolors; i++) {
225 ramp[(0 * 256) + i] = colorcells[i].red;
226 ramp[(1 * 256) + i] = colorcells[i].green;
227 ramp[(2 * 256) + i] = colorcells[i].blue;
228 }
229
230 SDL_free(colorcells);
231 return 0;
232 }