Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Changes to hopefully handle the creation of a colormap for 8 bit Pseu…

…doColor visuals in X11
  • Loading branch information
pendletonrc committed Jan 15, 2009
1 parent dba2579 commit 8d65a9ca37a46d44aad69f6be3be9cce3a1168cf
Showing with 111 additions and 75 deletions.
  1. +22 −9 src/video/x11/SDL_x11gamma.c
  2. +1 −1 src/video/x11/SDL_x11render.c
  3. +88 −65 src/video/x11/SDL_x11window.c
@@ -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); */

/* 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) {
@@ -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 =

0 comments on commit 8d65a9c

Please sign in to comment.