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