mirror of
https://github.com/yawut/SDL.git
synced 2026-08-19 23:34:04 -05:00
Changes to hopefully handle the creation of a colormap for 8 bit PseudoColor visuals in X11
This commit is contained in:
@@ -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,20 +96,22 @@ 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 (NULL == newramp) {
|
||||
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));
|
||||
cmapTable[numCmaps].ramp = newramp;
|
||||
}
|
||||
SDL_memset(newramp, 0, SDL_GammaRampSize);
|
||||
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[(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,
|
||||
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);
|
||||
/* The colormap is not known to SDL so we will create it */
|
||||
colormap = XCreateColormap(data->display,
|
||||
RootWindow(data->display,
|
||||
displaydata->screen),
|
||||
visual, AllocAll);
|
||||
/* printf("colormap = %x\n", colormap); */
|
||||
|
||||
/* If we can't create a colormap, then we must die */
|
||||
if (!colormap) {
|
||||
SDL_SetError
|
||||
("Couldn't create window: Could not create writable colormap");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
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
|
||||
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;
|
||||
|
||||
rmul = cmap.red_mult;
|
||||
gmul = cmap.blue_mult;
|
||||
bmul = cmap.green_mult;
|
||||
ncolors = visual->map_entries;
|
||||
nbits = visual->bits_per_rgb;
|
||||
|
||||
/* printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* 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 */
|
||||
for (i = 0; i < ncolors; i++) {
|
||||
Uint32 red = (rmax * i) / ncolors;
|
||||
Uint32 green = (gmax * i) / ncolors;
|
||||
Uint32 blue = (bmax * i) / ncolors;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colorcells[i].pixel =
|
||||
(red * rmul) | (green * gmul) | (blue * bmul);
|
||||
}
|
||||
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 =
|
||||
|
||||
Reference in New Issue
Block a user