Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Changes to hopefully handle the creation of a colormap for 8 bit Pseu…
Browse files Browse the repository at this point in the history
…doColor visuals in X11
  • Loading branch information
pendletonrc committed Jan 15, 2009
1 parent dba2579 commit 8d65a9c
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 75 deletions.
31 changes: 22 additions & 9 deletions src/video/x11/SDL_x11gamma.c
Expand Up @@ -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
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/video/x11/SDL_x11render.c
Expand Up @@ -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;
}

Expand Down
153 changes: 88 additions & 65 deletions src/video/x11/SDL_x11window.c
Expand Up @@ -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); */

/* 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);
/* 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;
}

/* 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)*/

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);
/* 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 */
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;
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) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 =
Expand Down

0 comments on commit 8d65a9c

Please sign in to comment.