comparison src/video/x11/SDL_x11window.c @ 3044:b36579172f27

Changes to hopefully handle the creation of a colormap for 8 bit PseudoColor visuals in X11
author Bob Pendleton <bob@pendleton.com>
date Thu, 15 Jan 2009 21:35:42 +0000
parents 546c022a9ae5
children b7197d7e8566
comparison
equal deleted inserted replaced
3043:9a20287aaed1 3044:b36579172f27
212 } 212 }
213 xattr.background_pixel = 0; 213 xattr.background_pixel = 0;
214 xattr.border_pixel = 0; 214 xattr.border_pixel = 0;
215 215
216 if (visual->class == PseudoColor) { 216 if (visual->class == PseudoColor) {
217 /* printf("asking for PseudoColor\n"); */ 217 printf("asking for PseudoColor\n");
218 int nmaps; 218
219 XStandardColormap cmap;
220 XStandardColormap *stdmaps;
221 XColor *colorcells;
222 Colormap colormap;
223 Bool found = False;
224 int i;
225 int ncolors;
226 int rmax, gmax, bmax;
227 int rmul, gmul, bmul;
228
229 if (colormap =
230 X11_LookupColormap(data->display, displaydata->screen,
231 visual->visualid)) {
232 xattr.colormap = colormap;
233 } else {
234 /* check to see if the colormap we need already exists */
235 if (0 != XGetRGBColormaps(data->display,
236 RootWindow(data->display,
237 displaydata->screen),
238 &stdmaps, &nmaps, XA_RGB_BEST_MAP)) {
239 for (i = 0; i < nmaps; i++) {
240 if (stdmaps[i].visualid == visual->visualid) {
241 SDL_memcpy(&cmap, &stdmaps[i],
242 sizeof(XStandardColormap));
243 found = True;
244 break;
245 }
246 }
247 XFree(stdmaps);
248 }
249
250 /* it doesn't exist, so create it */
251 if (!found) {
252 int max = visual->map_entries - 1;
253 stdmaps =
254 XmuStandardColormap(data->display, displaydata->screen,
255 visual->visualid, depth,
256 XA_RGB_BEST_MAP, None, max, max, max);
257 if (NULL == stdmaps || stdmaps->visualid != visual->visualid) {
258 SDL_SetError
259 ("Couldn't create window:XA_RGB_BEST_MAP not found and could not be created");
260 return -1;
261 }
262 SDL_memcpy(&cmap, stdmaps, sizeof(XStandardColormap));
263 XFree(stdmaps);
264 }
265
266 /* OK, we have the best color map, now copy it for use by the
267 program */
268
269 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
270 if (NULL == colorcells) {
271 SDL_SetError("out of memory in X11_CreateWindow");
272 return -1;
273 }
274 ncolors = visual->map_entries;
275 rmax = cmap.red_max + 1;
276 gmax = cmap.blue_max + 1;
277 bmax = cmap.green_max + 1;
278
279 rmul = cmap.red_mult;
280 gmul = cmap.blue_mult;
281 bmul = cmap.green_mult;
282
283 /* build the color table pixel values */
284 for (i = 0; i < ncolors; i++) {
285 Uint32 red = (rmax * i) / ncolors;
286 Uint32 green = (gmax * i) / ncolors;
287 Uint32 blue = (bmax * i) / ncolors;
288
289 colorcells[i].pixel =
290 (red * rmul) | (green * gmul) | (blue * bmul);
291 }
292 XQueryColors(data->display, cmap.colormap, colorcells, ncolors);
293 colormap = XCreateColormap(data->display,
294 RootWindow(data->display,
295 displaydata->screen),
296 visual, AllocAll);
297 XStoreColors(data->display, colormap, colorcells, ncolors);
298
299 xattr.colormap = colormap;
300 X11_TrackColormap(data->display, displaydata->screen, colormap,
301 visual, colorcells);
302 SDL_free(colorcells);
303 }
304 } else if (visual->class == DirectColor) {
305 Status status; 219 Status status;
306 XStandardColormap cmap; 220 XStandardColormap cmap;
307 XColor *colorcells; 221 XColor *colorcells;
308 Colormap colormap; 222 Colormap colormap;
309 int i; 223 Sint32 pix;
310 int ncolors; 224 Sint32 ncolors;
311 int rmax, gmax, bmax; 225 Sint32 nbits;
312 int rmask, gmask, bmask; 226 Sint32 rmax, gmax, bmax;
313 int rshift, gshift, bshift; 227 Sint32 rwidth, gwidth, bwidth;
228 Sint32 rmask, gmask, bmask;
229 Sint32 rshift, gshift, bshift;
230 Sint32 r, g, b;
314 231
315 /* Is the colormap we need already registered in SDL? */ 232 /* Is the colormap we need already registered in SDL? */
316 if (colormap = 233 if (colormap =
317 X11_LookupColormap(data->display, 234 X11_LookupColormap(data->display,
318 displaydata->screen, visual->visualid)) { 235 displaydata->screen, visual->visualid)) {
327 /* printf("colormap = %x\n", colormap); */ 244 /* printf("colormap = %x\n", colormap); */
328 245
329 /* If we can't create a colormap, then we must die */ 246 /* If we can't create a colormap, then we must die */
330 if (!colormap) { 247 if (!colormap) {
331 SDL_SetError 248 SDL_SetError
332 ("Couldn't create window: Could not create wriatable colormap"); 249 ("Couldn't create window: Could not create writable colormap");
250 return -1;
251 }
252
253 /* OK, we got a colormap, now fill it in as best as we can */
254
255 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
256 if (NULL == colorcells) {
257 SDL_SetError("out of memory in X11_CreateWindow");
258 return -1;
259 }
260
261 ncolors = visual->map_entries;
262 nbits = visual->bits_per_rgb;
263
264 /* printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
265
266 /* what if ncolors != (1 << nbits)? That can happen on a
267 true PseudoColor display. I'm assuming that we will
268 always have ncolors == (1 << nbits)*/
269
270 /* I'm making a lot of assumptions here. */
271
272 /* Compute the width of each field. If there is one extra
273 bit, give it to green. If there are two extra bits give
274 them to red and greed. We can get extra bits when the
275 number of bits per pixel is not a multiple of 3. For
276 example when we have 16 bits per pixel and need a 5/6/5
277 layout for the RGB fields */
278
279 rwidth = (nbits / 3) + (((nbits % 3) == 2) ? 1 : 0);
280 gwidth = (nbits / 3) + (((nbits % 3) >= 1) ? 1 : 0);
281 bwidth = (nbits / 3);
282
283 rshift = gwidth + bwidth;
284 gshift = bwidth;
285 bshift = 0;
286
287 rmax = 1 << rwidth;
288 gmax = 1 << gwidth;
289 bmax = 1 << bwidth;
290
291 rmask = rmax - 1;
292 gmask = gmax - 1;
293 bmask = bmax - 1;
294
295 /* printf("red mask = %4x shift = %4d width = %d\n", rmask, rshift, rwidth); */
296 /* printf("green mask = %4x shift = %4d width = %d\n", gmask, gshift, gwidth); */
297 /* printf("blue mask = %4x shift = %4d width = %d\n", bmask, bshift, bwidth); */
298
299 /* build the color table pixel values */
300 pix = 0;
301 for (r = 0; r < rmax; r++) {
302 for (g = 0; g < gmax; g++) {
303 for (b = 0; b < bmax; b++) {
304 colorcells[pix].pixel = (r << rshift) | (g << gshift) | (b << bshift);
305 colorcells[pix].red = (0xffff * r) / rmask;
306 colorcells[pix].green = (0xffff * g) / gmask;
307 colorcells[pix].blue = (0xffff * b) / bmask;
308 /* printf("%4x:%4x [%4x %4x %4x]\n", */
309 /* pix, */
310 /* colorcells[pix].pixel, */
311 /* colorcells[pix].red, */
312 /* colorcells[pix].green, */
313 /* colorcells[pix].blue); */
314 pix++;
315 }
316 }
317 }
318
319 /* status = */
320 /* XStoreColors(data->display, colormap, colorcells, ncolors); */
321
322 xattr.colormap = colormap;
323 X11_TrackColormap(data->display, displaydata->screen,
324 colormap, visual, NULL);
325
326 SDL_free(colorcells);
327 }
328 } else if (visual->class == DirectColor) {
329 Status status;
330 XStandardColormap cmap;
331 XColor *colorcells;
332 Colormap colormap;
333 int i;
334 int ncolors;
335 int rmax, gmax, bmax;
336 int rmask, gmask, bmask;
337 int rshift, gshift, bshift;
338
339 /* Is the colormap we need already registered in SDL? */
340 if (colormap =
341 X11_LookupColormap(data->display,
342 displaydata->screen, visual->visualid)) {
343 xattr.colormap = colormap;
344 /* printf("found existing colormap\n"); */
345 } else {
346 /* The colormap is not known to SDL so we will create it */
347 colormap = XCreateColormap(data->display,
348 RootWindow(data->display,
349 displaydata->screen),
350 visual, AllocAll);
351 /* printf("colormap = %x\n", colormap); */
352
353 /* If we can't create a colormap, then we must die */
354 if (!colormap) {
355 SDL_SetError
356 ("Couldn't create window: Could not create writable colormap");
333 return -1; 357 return -1;
334 } 358 }
335 359
336 /* OK, we got a colormap, now fill it in as best as we can */ 360 /* OK, we got a colormap, now fill it in as best as we can */
337 361
391 colorcells[i].green = green; 415 colorcells[i].green = green;
392 colorcells[i].blue = blue; 416 colorcells[i].blue = blue;
393 417
394 colorcells[i].flags = DoRed | DoGreen | DoBlue; 418 colorcells[i].flags = DoRed | DoGreen | DoBlue;
395 /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */ 419 /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
396
397 } 420 }
398 421
399 status = 422 status =
400 XStoreColors(data->display, colormap, colorcells, ncolors); 423 XStoreColors(data->display, colormap, colorcells, ncolors);
401 424