Mercurial > sdl-ios-xcode
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 |