Changes to hopefully handle the creation of a colormap for 8 bit PseudoColor visuals in X11
authorBob Pendleton <bob@pendleton.com>
Thu, 15 Jan 2009 21:35:42 +0000
changeset 3044b36579172f27
parent 3043 9a20287aaed1
child 3045 9acb9f0f7f0d
Changes to hopefully handle the creation of a colormap for 8 bit PseudoColor visuals in X11
src/video/x11/SDL_x11gamma.c
src/video/x11/SDL_x11render.c
src/video/x11/SDL_x11window.c
     1.1 --- a/src/video/x11/SDL_x11gamma.c	Wed Jan 14 15:03:44 2009 +0000
     1.2 +++ b/src/video/x11/SDL_x11gamma.c	Thu Jan 15 21:35:42 2009 +0000
     1.3 @@ -23,6 +23,9 @@
     1.4  #include "../SDL_sysvideo.h"
     1.5  #include "SDL_x11video.h"
     1.6  
     1.7 +    /* The size of *all* SDL gamma ramps */
     1.8 +#define SDL_GammaRampSize (3 * 256 * sizeof(Uint16))
     1.9 +
    1.10  static int numCmaps = 0;
    1.11  
    1.12  typedef struct
    1.13 @@ -93,20 +96,22 @@
    1.14      SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
    1.15      cmapTable[numCmaps].ramp = NULL;
    1.16  
    1.17 -    newramp = SDL_malloc(3 * 256 * sizeof(Uint16));     /* The size of *all* SDL gamma ramps */
    1.18 -    if (NULL == newramp) {
    1.19 +    if (ramp != NULL) {
    1.20 +      newramp = SDL_malloc(SDL_GammaRampSize);
    1.21 +      if (NULL == newramp) {
    1.22          SDL_SetError("Out of memory in X11_TrackColormap()");
    1.23          return;
    1.24 -    }
    1.25 -    SDL_memset(newramp, 0, sizeof(*newramp));
    1.26 -    cmapTable[numCmaps].ramp = newramp;
    1.27 +      }
    1.28 +      SDL_memset(newramp, 0, SDL_GammaRampSize);
    1.29 +      cmapTable[numCmaps].ramp = newramp;
    1.30  
    1.31 -    ncolors = cmapTable[numCmaps].visual.map_entries;
    1.32 +      ncolors = cmapTable[numCmaps].visual.map_entries;
    1.33  
    1.34 -    for (i = 0; i < ncolors; i++) {
    1.35 +      for (i = 0; i < ncolors; i++) {
    1.36          newramp[(0 * 256) + i] = ramp[i].red;
    1.37          newramp[(1 * 256) + i] = ramp[i].green;
    1.38          newramp[(2 * 256) + i] = ramp[i].blue;
    1.39 +      }
    1.40      }
    1.41  
    1.42      numCmaps++;
    1.43 @@ -144,7 +149,15 @@
    1.44                  return -1;
    1.45              }
    1.46              /* remember the new ramp */
    1.47 -            SDL_memcpy(cmapTable[j].ramp, ramp, sizeof(*cmapTable[j].ramp));
    1.48 +	    if (cmapTable[j].ramp == NULL) {
    1.49 +	      Uint16 * newramp = SDL_malloc(SDL_GammaRampSize);
    1.50 +	      if (NULL == newramp) {
    1.51 +		SDL_SetError("Out of memory in X11_TrackColormap()");
    1.52 +		return -1;
    1.53 +	      }
    1.54 +	      cmapTable[j].ramp = newramp;
    1.55 +	    }
    1.56 +            SDL_memcpy(cmapTable[j].ramp, ramp, SDL_GammaRampSize);
    1.57  
    1.58              rshift = 0;
    1.59              rmask = visual->red_mask;
    1.60 @@ -210,7 +223,7 @@
    1.61  
    1.62      for (i = 0; i < numCmaps; i++) {
    1.63          if (cmapTable[i].visual.class == DirectColor) {
    1.64 -            SDL_memcpy(ramp, cmapTable[i].ramp, sizeof(*cmapTable[i].ramp));
    1.65 +            SDL_memcpy(ramp, cmapTable[i].ramp, SDL_GammaRampSize);
    1.66              return 0;
    1.67          }
    1.68      }
     2.1 --- a/src/video/x11/SDL_x11render.c	Wed Jan 14 15:03:44 2009 +0000
     2.2 +++ b/src/video/x11/SDL_x11render.c	Thu Jan 15 21:35:42 2009 +0000
     2.3 @@ -413,7 +413,7 @@
     2.4                            texture->h, renderdata->depth);
     2.5          if (data->pixmap == None) {
     2.6              X11_DestroyTexture(renderer, texture);
     2.7 -            SDL_SetError("XCteatePixmap() failed");
     2.8 +            SDL_SetError("XCreatePixmap() failed");
     2.9              return -1;
    2.10          }
    2.11  
     3.1 --- a/src/video/x11/SDL_x11window.c	Wed Jan 14 15:03:44 2009 +0000
     3.2 +++ b/src/video/x11/SDL_x11window.c	Thu Jan 15 21:35:42 2009 +0000
     3.3 @@ -214,91 +214,115 @@
     3.4      xattr.border_pixel = 0;
     3.5  
     3.6      if (visual->class == PseudoColor) {
     3.7 -/*         printf("asking for PseudoColor\n"); */
     3.8 -        int nmaps;
     3.9 +        printf("asking for PseudoColor\n");
    3.10 +
    3.11 +        Status status;
    3.12          XStandardColormap cmap;
    3.13 -        XStandardColormap *stdmaps;
    3.14          XColor *colorcells;
    3.15          Colormap colormap;
    3.16 -        Bool found = False;
    3.17 -        int i;
    3.18 -        int ncolors;
    3.19 -        int rmax, gmax, bmax;
    3.20 -        int rmul, gmul, bmul;
    3.21 +	Sint32 pix;
    3.22 +        Sint32 ncolors;
    3.23 +        Sint32 nbits;
    3.24 +        Sint32 rmax, gmax, bmax;
    3.25 +	Sint32 rwidth, gwidth, bwidth;
    3.26 +        Sint32 rmask, gmask, bmask;
    3.27 +        Sint32 rshift, gshift, bshift;
    3.28 +	Sint32 r, g, b;
    3.29  
    3.30 +        /* Is the colormap we need already registered in SDL? */
    3.31          if (colormap =
    3.32 -            X11_LookupColormap(data->display, displaydata->screen,
    3.33 -                               visual->visualid)) {
    3.34 +            X11_LookupColormap(data->display,
    3.35 +                               displaydata->screen, visual->visualid)) {
    3.36              xattr.colormap = colormap;
    3.37 +/*             printf("found existing colormap\n"); */
    3.38          } else {
    3.39 -            /* check to see if the colormap we need already exists */
    3.40 -            if (0 != XGetRGBColormaps(data->display,
    3.41 -                                      RootWindow(data->display,
    3.42 -                                                 displaydata->screen),
    3.43 -                                      &stdmaps, &nmaps, XA_RGB_BEST_MAP)) {
    3.44 -                for (i = 0; i < nmaps; i++) {
    3.45 -                    if (stdmaps[i].visualid == visual->visualid) {
    3.46 -                        SDL_memcpy(&cmap, &stdmaps[i],
    3.47 -                                   sizeof(XStandardColormap));
    3.48 -                        found = True;
    3.49 -                        break;
    3.50 -                    }
    3.51 -                }
    3.52 -                XFree(stdmaps);
    3.53 +            /* The colormap is not known to SDL so we will create it */
    3.54 +            colormap = XCreateColormap(data->display,
    3.55 +                                       RootWindow(data->display,
    3.56 +                                                  displaydata->screen),
    3.57 +                                       visual, AllocAll);
    3.58 +/*             printf("colormap = %x\n", colormap); */
    3.59 +
    3.60 +            /* If we can't create a colormap, then we must die */
    3.61 +            if (!colormap) {
    3.62 +                SDL_SetError
    3.63 +                    ("Couldn't create window: Could not create writable colormap");
    3.64 +                return -1;
    3.65              }
    3.66  
    3.67 -            /* it doesn't exist, so create it */
    3.68 -            if (!found) {
    3.69 -                int max = visual->map_entries - 1;
    3.70 -                stdmaps =
    3.71 -                    XmuStandardColormap(data->display, displaydata->screen,
    3.72 -                                        visual->visualid, depth,
    3.73 -                                        XA_RGB_BEST_MAP, None, max, max, max);
    3.74 -                if (NULL == stdmaps || stdmaps->visualid != visual->visualid) {
    3.75 -                    SDL_SetError
    3.76 -                        ("Couldn't create window:XA_RGB_BEST_MAP not found and could not be created");
    3.77 -                    return -1;
    3.78 -                }
    3.79 -                SDL_memcpy(&cmap, stdmaps, sizeof(XStandardColormap));
    3.80 -                XFree(stdmaps);
    3.81 -            }
    3.82 -
    3.83 -            /* OK, we have the best color map, now copy it for use by the
    3.84 -               program */
    3.85 +            /* OK, we got a colormap, now fill it in as best as we can */
    3.86  
    3.87              colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
    3.88              if (NULL == colorcells) {
    3.89                  SDL_SetError("out of memory in X11_CreateWindow");
    3.90                  return -1;
    3.91              }
    3.92 +
    3.93              ncolors = visual->map_entries;
    3.94 -            rmax = cmap.red_max + 1;
    3.95 -            gmax = cmap.blue_max + 1;
    3.96 -            bmax = cmap.green_max + 1;
    3.97 +	    nbits = visual->bits_per_rgb;
    3.98 +
    3.99 +/* 	    printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
   3.100 +
   3.101 +	    /* what if ncolors != (1 << nbits)? That can happen on a
   3.102 +	       true PseudoColor display.  I'm assuming that we will
   3.103 +	       always have ncolors == (1 << nbits)*/
   3.104 +
   3.105 +	    /* I'm making a lot of assumptions here. */
   3.106 +	    
   3.107 +	    /* Compute the width of each field. If there is one extra
   3.108 +	       bit, give it to green. If there are two extra bits give
   3.109 +	       them to red and greed.  We can get extra bits when the
   3.110 +	       number of bits per pixel is not a multiple of 3. For
   3.111 +	       example when we have 16 bits per pixel and need a 5/6/5
   3.112 +	       layout for the RGB fields */
   3.113  
   3.114 -            rmul = cmap.red_mult;
   3.115 -            gmul = cmap.blue_mult;
   3.116 -            bmul = cmap.green_mult;
   3.117 +	    rwidth = (nbits / 3) + (((nbits % 3) == 2) ? 1 : 0);
   3.118 +	    gwidth = (nbits / 3) + (((nbits % 3) >= 1) ? 1 : 0);
   3.119 +	    bwidth = (nbits / 3);
   3.120 +
   3.121 +            rshift = gwidth + bwidth;
   3.122 +            gshift = bwidth;
   3.123 +            bshift = 0;
   3.124 +
   3.125 +            rmax = 1 << rwidth;
   3.126 +            gmax = 1 << gwidth;
   3.127 +            bmax = 1 << bwidth;
   3.128 +
   3.129 +            rmask = rmax - 1;
   3.130 +            gmask = gmax - 1;
   3.131 +            bmask = bmax - 1;
   3.132 +
   3.133 +/*             printf("red   mask = %4x shift = %4d width = %d\n", rmask, rshift, rwidth); */
   3.134 +/*             printf("green mask = %4x shift = %4d width = %d\n", gmask, gshift, gwidth); */
   3.135 +/*             printf("blue  mask = %4x shift = %4d width = %d\n", bmask, bshift, bwidth); */
   3.136  
   3.137              /* build the color table pixel values */
   3.138 -            for (i = 0; i < ncolors; i++) {
   3.139 -                Uint32 red = (rmax * i) / ncolors;
   3.140 -                Uint32 green = (gmax * i) / ncolors;
   3.141 -                Uint32 blue = (bmax * i) / ncolors;
   3.142 +	    pix = 0;
   3.143 +	    for (r = 0; r < rmax; r++) {
   3.144 +	      for (g = 0; g < gmax; g++) {
   3.145 +		for (b = 0; b < bmax; b++) {
   3.146 +		  colorcells[pix].pixel = (r << rshift) | (g << gshift) | (b << bshift);
   3.147 +		  colorcells[pix].red   = (0xffff * r) / rmask;
   3.148 +		  colorcells[pix].green = (0xffff * g) / gmask;
   3.149 +		  colorcells[pix].blue  = (0xffff * b) / bmask;
   3.150 +/* 		  printf("%4x:%4x [%4x %4x %4x]\n",  */
   3.151 +/* 			 pix,  */
   3.152 +/* 			 colorcells[pix].pixel, */
   3.153 +/* 			 colorcells[pix].red, */
   3.154 +/* 			 colorcells[pix].green, */
   3.155 +/* 			 colorcells[pix].blue); */
   3.156 +		  pix++;
   3.157 +		}
   3.158 +	      }
   3.159 +	    }
   3.160  
   3.161 -                colorcells[i].pixel =
   3.162 -                    (red * rmul) | (green * gmul) | (blue * bmul);
   3.163 -            }
   3.164 -            XQueryColors(data->display, cmap.colormap, colorcells, ncolors);
   3.165 -            colormap = XCreateColormap(data->display,
   3.166 -                                       RootWindow(data->display,
   3.167 -                                                  displaydata->screen),
   3.168 -                                       visual, AllocAll);
   3.169 -            XStoreColors(data->display, colormap, colorcells, ncolors);
   3.170 +/*             status = */
   3.171 +/*                 XStoreColors(data->display, colormap, colorcells, ncolors); */
   3.172  
   3.173              xattr.colormap = colormap;
   3.174 -            X11_TrackColormap(data->display, displaydata->screen, colormap,
   3.175 -                              visual, colorcells);
   3.176 +            X11_TrackColormap(data->display, displaydata->screen,
   3.177 +                              colormap, visual, NULL);
   3.178 +
   3.179              SDL_free(colorcells);
   3.180          }
   3.181      } else if (visual->class == DirectColor) {
   3.182 @@ -329,7 +353,7 @@
   3.183              /* If we can't create a colormap, then we must die */
   3.184              if (!colormap) {
   3.185                  SDL_SetError
   3.186 -                    ("Couldn't create window: Could not create wriatable colormap");
   3.187 +                    ("Couldn't create window: Could not create writable colormap");
   3.188                  return -1;
   3.189              }
   3.190  
   3.191 @@ -393,7 +417,6 @@
   3.192  
   3.193                  colorcells[i].flags = DoRed | DoGreen | DoBlue;
   3.194  /* 		printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
   3.195 -
   3.196              }
   3.197  
   3.198              status =