Commit ffe056ff authored by Bob Pendleton's avatar Bob Pendleton

Changes to hopefully handle the creation of a colormap for 8 bit PseudoColor visuals in X11

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403506
parent 19e137cf
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include "SDL_x11video.h" #include "SDL_x11video.h"
/* The size of *all* SDL gamma ramps */
#define SDL_GammaRampSize (3 * 256 * sizeof(Uint16))
static int numCmaps = 0; static int numCmaps = 0;
typedef struct typedef struct
...@@ -93,20 +96,22 @@ X11_TrackColormap(Display * display, int scrNum, Colormap colormap, ...@@ -93,20 +96,22 @@ X11_TrackColormap(Display * display, int scrNum, Colormap colormap,
SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual)); SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
cmapTable[numCmaps].ramp = NULL; cmapTable[numCmaps].ramp = NULL;
newramp = SDL_malloc(3 * 256 * sizeof(Uint16)); /* The size of *all* SDL gamma ramps */ if (ramp != NULL) {
if (NULL == newramp) { newramp = SDL_malloc(SDL_GammaRampSize);
if (NULL == newramp) {
SDL_SetError("Out of memory in X11_TrackColormap()"); SDL_SetError("Out of memory in X11_TrackColormap()");
return; return;
} }
SDL_memset(newramp, 0, sizeof(*newramp)); SDL_memset(newramp, 0, SDL_GammaRampSize);
cmapTable[numCmaps].ramp = newramp; cmapTable[numCmaps].ramp = newramp;
ncolors = cmapTable[numCmaps].visual.map_entries; ncolors = cmapTable[numCmaps].visual.map_entries;
for (i = 0; i < ncolors; i++) { for (i = 0; i < ncolors; i++) {
newramp[(0 * 256) + i] = ramp[i].red; newramp[(0 * 256) + i] = ramp[i].red;
newramp[(1 * 256) + i] = ramp[i].green; newramp[(1 * 256) + i] = ramp[i].green;
newramp[(2 * 256) + i] = ramp[i].blue; newramp[(2 * 256) + i] = ramp[i].blue;
}
} }
numCmaps++; numCmaps++;
...@@ -144,7 +149,15 @@ X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp) ...@@ -144,7 +149,15 @@ X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
return -1; return -1;
} }
/* remember the new ramp */ /* remember the new ramp */
SDL_memcpy(cmapTable[j].ramp, ramp, sizeof(*cmapTable[j].ramp)); if (cmapTable[j].ramp == NULL) {
Uint16 * newramp = SDL_malloc(SDL_GammaRampSize);
if (NULL == newramp) {
SDL_SetError("Out of memory in X11_TrackColormap()");
return -1;
}
cmapTable[j].ramp = newramp;
}
SDL_memcpy(cmapTable[j].ramp, ramp, SDL_GammaRampSize);
rshift = 0; rshift = 0;
rmask = visual->red_mask; rmask = visual->red_mask;
...@@ -210,7 +223,7 @@ X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp) ...@@ -210,7 +223,7 @@ X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
for (i = 0; i < numCmaps; i++) { for (i = 0; i < numCmaps; i++) {
if (cmapTable[i].visual.class == DirectColor) { if (cmapTable[i].visual.class == DirectColor) {
SDL_memcpy(ramp, cmapTable[i].ramp, sizeof(*cmapTable[i].ramp)); SDL_memcpy(ramp, cmapTable[i].ramp, SDL_GammaRampSize);
return 0; return 0;
} }
} }
......
...@@ -413,7 +413,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -413,7 +413,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
texture->h, renderdata->depth); texture->h, renderdata->depth);
if (data->pixmap == None) { if (data->pixmap == None) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_SetError("XCteatePixmap() failed"); SDL_SetError("XCreatePixmap() failed");
return -1; return -1;
} }
......
...@@ -214,91 +214,115 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -214,91 +214,115 @@ X11_CreateWindow(_THIS, SDL_Window * window)
xattr.border_pixel = 0; xattr.border_pixel = 0;
if (visual->class == PseudoColor) { if (visual->class == PseudoColor) {
/* printf("asking for PseudoColor\n"); */ printf("asking for PseudoColor\n");
int nmaps;
Status status;
XStandardColormap cmap; XStandardColormap cmap;
XStandardColormap *stdmaps;
XColor *colorcells; XColor *colorcells;
Colormap colormap; Colormap colormap;
Bool found = False; Sint32 pix;
int i; Sint32 ncolors;
int ncolors; Sint32 nbits;
int rmax, gmax, bmax; Sint32 rmax, gmax, bmax;
int rmul, gmul, bmul; Sint32 rwidth, gwidth, bwidth;
Sint32 rmask, gmask, bmask;
Sint32 rshift, gshift, bshift;
Sint32 r, g, b;
/* Is the colormap we need already registered in SDL? */
if (colormap = if (colormap =
X11_LookupColormap(data->display, displaydata->screen, X11_LookupColormap(data->display,
visual->visualid)) { displaydata->screen, visual->visualid)) {
xattr.colormap = colormap; xattr.colormap = colormap;
/* printf("found existing colormap\n"); */
} else { } else {
/* check to see if the colormap we need already exists */ /* The colormap is not known to SDL so we will create it */
if (0 != XGetRGBColormaps(data->display, colormap = XCreateColormap(data->display,
RootWindow(data->display, RootWindow(data->display,
displaydata->screen), displaydata->screen),
&stdmaps, &nmaps, XA_RGB_BEST_MAP)) { visual, AllocAll);
for (i = 0; i < nmaps; i++) { /* printf("colormap = %x\n", colormap); */
if (stdmaps[i].visualid == visual->visualid) {
SDL_memcpy(&cmap, &stdmaps[i],
sizeof(XStandardColormap));
found = True;
break;
}
}
XFree(stdmaps);
}
/* it doesn't exist, so create it */ /* If we can't create a colormap, then we must die */
if (!found) { if (!colormap) {
int max = visual->map_entries - 1; SDL_SetError
stdmaps = ("Couldn't create window: Could not create writable colormap");
XmuStandardColormap(data->display, displaydata->screen, return -1;
visual->visualid, depth,
XA_RGB_BEST_MAP, None, max, max, max);
if (NULL == stdmaps || stdmaps->visualid != visual->visualid) {
SDL_SetError
("Couldn't create window:XA_RGB_BEST_MAP not found and could not be created");
return -1;
}
SDL_memcpy(&cmap, stdmaps, sizeof(XStandardColormap));
XFree(stdmaps);
} }
/* OK, we have the best color map, now copy it for use by the /* OK, we got a colormap, now fill it in as best as we can */
program */
colorcells = SDL_malloc(visual->map_entries * sizeof(XColor)); colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
if (NULL == colorcells) { if (NULL == colorcells) {
SDL_SetError("out of memory in X11_CreateWindow"); SDL_SetError("out of memory in X11_CreateWindow");
return -1; return -1;
} }
ncolors = visual->map_entries; ncolors = visual->map_entries;
rmax = cmap.red_max + 1; nbits = visual->bits_per_rgb;
gmax = cmap.blue_max + 1;
bmax = cmap.green_max + 1;
rmul = cmap.red_mult; /* printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
gmul = cmap.blue_mult;
bmul = cmap.green_mult;
/* build the color table pixel values */ /* what if ncolors != (1 << nbits)? That can happen on a
for (i = 0; i < ncolors; i++) { true PseudoColor display. I'm assuming that we will
Uint32 red = (rmax * i) / ncolors; always have ncolors == (1 << nbits)*/
Uint32 green = (gmax * i) / ncolors;
Uint32 blue = (bmax * i) / ncolors;
colorcells[i].pixel = /* I'm making a lot of assumptions here. */
(red * rmul) | (green * gmul) | (blue * bmul);
} /* Compute the width of each field. If there is one extra
XQueryColors(data->display, cmap.colormap, colorcells, ncolors); bit, give it to green. If there are two extra bits give
colormap = XCreateColormap(data->display, them to red and greed. We can get extra bits when the
RootWindow(data->display, number of bits per pixel is not a multiple of 3. For
displaydata->screen), example when we have 16 bits per pixel and need a 5/6/5
visual, AllocAll); layout for the RGB fields */
XStoreColors(data->display, colormap, colorcells, ncolors);
rwidth = (nbits / 3) + (((nbits % 3) == 2) ? 1 : 0);
gwidth = (nbits / 3) + (((nbits % 3) >= 1) ? 1 : 0);
bwidth = (nbits / 3);
rshift = gwidth + bwidth;
gshift = bwidth;
bshift = 0;
rmax = 1 << rwidth;
gmax = 1 << gwidth;
bmax = 1 << bwidth;
rmask = rmax - 1;
gmask = gmax - 1;
bmask = bmax - 1;
/* printf("red mask = %4x shift = %4d width = %d\n", rmask, rshift, rwidth); */
/* printf("green mask = %4x shift = %4d width = %d\n", gmask, gshift, gwidth); */
/* printf("blue mask = %4x shift = %4d width = %d\n", bmask, bshift, bwidth); */
/* build the color table pixel values */
pix = 0;
for (r = 0; r < rmax; r++) {
for (g = 0; g < gmax; g++) {
for (b = 0; b < bmax; b++) {
colorcells[pix].pixel = (r << rshift) | (g << gshift) | (b << bshift);
colorcells[pix].red = (0xffff * r) / rmask;
colorcells[pix].green = (0xffff * g) / gmask;
colorcells[pix].blue = (0xffff * b) / bmask;
/* printf("%4x:%4x [%4x %4x %4x]\n", */
/* pix, */
/* colorcells[pix].pixel, */
/* colorcells[pix].red, */
/* colorcells[pix].green, */
/* colorcells[pix].blue); */
pix++;
}
}
}
/* status = */
/* XStoreColors(data->display, colormap, colorcells, ncolors); */
xattr.colormap = colormap; xattr.colormap = colormap;
X11_TrackColormap(data->display, displaydata->screen, colormap, X11_TrackColormap(data->display, displaydata->screen,
visual, colorcells); colormap, visual, NULL);
SDL_free(colorcells); SDL_free(colorcells);
} }
} else if (visual->class == DirectColor) { } else if (visual->class == DirectColor) {
...@@ -329,7 +353,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -329,7 +353,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
/* If we can't create a colormap, then we must die */ /* If we can't create a colormap, then we must die */
if (!colormap) { if (!colormap) {
SDL_SetError SDL_SetError
("Couldn't create window: Could not create wriatable colormap"); ("Couldn't create window: Could not create writable colormap");
return -1; return -1;
} }
...@@ -393,7 +417,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -393,7 +417,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
colorcells[i].flags = DoRed | DoGreen | DoBlue; colorcells[i].flags = DoRed | DoGreen | DoBlue;
/* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */ /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
} }
status = status =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment