src/video/x11/SDL_x11gamma.c
changeset 2214 e7164a4dac62
parent 2213 59a667370c57
child 2216 82a133b784c9
     1.1 --- a/src/video/x11/SDL_x11gamma.c	Tue Jul 24 18:46:45 2007 +0000
     1.2 +++ b/src/video/x11/SDL_x11gamma.c	Wed Jul 25 21:22:55 2007 +0000
     1.3 @@ -29,32 +29,50 @@
     1.4  {
     1.5      Display *display;
     1.6      int scrNum;
     1.7 +    Colormap colormap;
     1.8      XStandardColormap cmap;
     1.9      Visual visual;
    1.10  } cmapTableEntry;
    1.11  
    1.12  cmapTableEntry *cmapTable = NULL;
    1.13  
    1.14 +/* To reduce the overhead as much as possible lets do as little as
    1.15 +   possible. When we do have to create a colormap keep track of it and
    1.16 +   reuse it. We're going to do this for both DirectColor and
    1.17 +   PseudoColor colormaps. */
    1.18 +
    1.19 +Colormap
    1.20 +X11_LookupColormap(Display * display, int scrNum, VisualID vid)
    1.21 +{
    1.22 +    int i;
    1.23 +
    1.24 +    for (i = 0; i < numCmaps; i++) {
    1.25 +        if (cmapTable[i].display == display &&
    1.26 +            cmapTable[i].scrNum == scrNum &&
    1.27 +            cmapTable[i].cmap.visualid == vid) {
    1.28 +            return cmapTable[i].cmap.colormap;
    1.29 +        }
    1.30 +    }
    1.31 +
    1.32 +    return 0;
    1.33 +}
    1.34 +
    1.35 +
    1.36  void
    1.37 -X11_TrackColormap(Display * display, int scrNum,
    1.38 +X11_TrackColormap(Display * display, int scrNum, Colormap colormap,
    1.39                    XStandardColormap * cmap, Visual * visual)
    1.40  {
    1.41      int i;
    1.42      cmapTableEntry *newTable = NULL;
    1.43  
    1.44 -    /* only tracking DirectColor colormaps because they're the only ones
    1.45 -       with gamma ramps */
    1.46 -    if (DirectColor != visual->class) {
    1.47 -        return;
    1.48 -    }
    1.49 -
    1.50 -    /* search the table to find out if we already have this one. We only
    1.51 -       want one entry for each display, screen number, visualid
    1.52 -       combination */
    1.53 +    /* search the table to find out if we already have this one. We
    1.54 +       only want one entry for each display, screen number, visualid,
    1.55 +       and colormap combination */
    1.56      for (i = 0; i < numCmaps; i++) {
    1.57          if (cmapTable[i].display == display &&
    1.58              cmapTable[i].scrNum == scrNum &&
    1.59 -            cmapTable[i].cmap.visualid == cmap->visualid) {
    1.60 +            cmapTable[i].cmap.visualid == cmap->visualid &&
    1.61 +            cmapTable[i].cmap.colormap == colormap) {
    1.62              return;
    1.63          }
    1.64      }
    1.65 @@ -75,20 +93,146 @@
    1.66  
    1.67      cmapTable[numCmaps].display = display;
    1.68      cmapTable[numCmaps].scrNum = scrNum;
    1.69 +    cmapTable[numCmaps].colormap = colormap;
    1.70      SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap));
    1.71      SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
    1.72  
    1.73      numCmaps++;
    1.74  }
    1.75  
    1.76 +/* The problem is that you have to have at least one DirectColor
    1.77 +   colormap before you can set the gamma ramps or read the gamma
    1.78 +   ramps. If the application has created a DirectColor window then the
    1.79 +   cmapTable will have at least one colormap in it and everything is
    1.80 +   cool. If not, then we just fail  */
    1.81 +
    1.82  int
    1.83  X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
    1.84  {
    1.85 -    return -1;
    1.86 +    Display *display;
    1.87 +    Colormap colormap;
    1.88 +    XColor *colorcells;
    1.89 +    int ncolors;
    1.90 +    int i;
    1.91 +    int j;
    1.92 +
    1.93 +    int rmax, gmax, bmax;
    1.94 +    int rmul, gmul, bmul;
    1.95 +
    1.96 +    for (j = 0; j < numCmaps; j++) {
    1.97 +        if (cmapTable[j].visual.class == DirectColor) {
    1.98 +            display = cmapTable[j].display;
    1.99 +            colormap = cmapTable[j].colormap;
   1.100 +            ncolors = cmapTable[j].visual.map_entries;
   1.101 +
   1.102 +            colorcells = SDL_malloc(ncolors * sizeof(XColor));
   1.103 +            if (NULL == colorcells) {
   1.104 +                SDL_SetError("out of memory in X11_SetDisplayGammaRamp");
   1.105 +                return -1;
   1.106 +            }
   1.107 +
   1.108 +            rmax = cmapTable[j].cmap.red_max + 1;
   1.109 +            gmax = cmapTable[j].cmap.blue_max + 1;
   1.110 +            bmax = cmapTable[j].cmap.green_max + 1;
   1.111 +
   1.112 +            rmul = cmapTable[j].cmap.red_mult;
   1.113 +            gmul = cmapTable[j].cmap.blue_mult;
   1.114 +            bmul = cmapTable[j].cmap.green_mult;
   1.115 +
   1.116 +            /* build the color table pixel values */
   1.117 +            for (i = 0; i < ncolors; i++) {
   1.118 +                Uint32 red = (rmax * i) / ncolors;
   1.119 +                Uint32 green = (gmax * i) / ncolors;
   1.120 +                Uint32 blue = (bmax * i) / ncolors;
   1.121 +
   1.122 +                colorcells[i].pixel =
   1.123 +                    (red * rmul) | (green * gmul) | (blue * bmul);
   1.124 +                colorcells[i].flags = DoRed | DoGreen | DoBlue;
   1.125 +
   1.126 +                colorcells[i].red = ramp[(0 * 256) + i];
   1.127 +                colorcells[i].green = ramp[(1 * 256) + i];
   1.128 +                colorcells[i].blue = ramp[(2 * 256) + i];
   1.129 +            }
   1.130 +
   1.131 +            XStoreColors(display, colormap, colorcells, ncolors);
   1.132 +            XFlush(display);
   1.133 +            SDL_free(colorcells);
   1.134 +        }
   1.135 +    }
   1.136 +
   1.137 +    return 0;
   1.138  }
   1.139  
   1.140  int
   1.141  X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
   1.142  {
   1.143 -    return -1;
   1.144 +    Display *display;
   1.145 +    Colormap colormap;
   1.146 +    XColor *colorcells;
   1.147 +    int ncolors;
   1.148 +    int dc;
   1.149 +    int i;
   1.150 +
   1.151 +    int rmax, gmax, bmax;
   1.152 +    int rmul, gmul, bmul;
   1.153 +
   1.154 +    /* find the first DirectColor colormap and use it to get the gamma
   1.155 +       ramp */
   1.156 +
   1.157 +    dc = -1;
   1.158 +    for (i = 0; i < numCmaps; i++) {
   1.159 +        if (cmapTable[i].visual.class == DirectColor) {
   1.160 +            dc = i;
   1.161 +            break;
   1.162 +        }
   1.163 +    }
   1.164 +
   1.165 +    if (dc < 0) {
   1.166 +        return -1;
   1.167 +    }
   1.168 +
   1.169 +    /* there is at least one DirectColor colormap in the cmapTable,
   1.170 +       let's just get the entries from that colormap */
   1.171 +
   1.172 +    display = cmapTable[dc].display;
   1.173 +    colormap = cmapTable[dc].colormap;
   1.174 +    ncolors = cmapTable[dc].visual.map_entries;
   1.175 +    colorcells = SDL_malloc(ncolors * sizeof(XColor));
   1.176 +    if (NULL == colorcells) {
   1.177 +        SDL_SetError("out of memory in X11_GetDisplayGammaRamp");
   1.178 +        return -1;
   1.179 +    }
   1.180 +
   1.181 +    rmax = cmapTable[dc].cmap.red_max + 1;
   1.182 +    gmax = cmapTable[dc].cmap.blue_max + 1;
   1.183 +    bmax = cmapTable[dc].cmap.green_max + 1;
   1.184 +
   1.185 +    rmul = cmapTable[dc].cmap.red_mult;
   1.186 +    gmul = cmapTable[dc].cmap.blue_mult;
   1.187 +    bmul = cmapTable[dc].cmap.green_mult;
   1.188 +
   1.189 +    /* build the color table pixel values */
   1.190 +    for (i = 0; i < ncolors; i++) {
   1.191 +        Uint32 red = (rmax * i) / ncolors;
   1.192 +        Uint32 green = (gmax * i) / ncolors;
   1.193 +        Uint32 blue = (bmax * i) / ncolors;
   1.194 +
   1.195 +        colorcells[i].pixel = (red * rmul) | (green * gmul) | (blue * bmul);
   1.196 +    }
   1.197 +
   1.198 +    XQueryColors(display, colormap, colorcells, ncolors);
   1.199 +
   1.200 +    /* prepare the values to be returned. Note that SDL assumes that
   1.201 +       gamma ramps are always 3 * 256 entries long with the red entries
   1.202 +       in the first 256 elements, the green in the second 256 elements
   1.203 +       and the blue in the last 256 elements */
   1.204 +
   1.205 +    for (i = 0; i < ncolors; i++) {
   1.206 +        ramp[(0 * 256) + i] = colorcells[i].red;
   1.207 +        ramp[(1 * 256) + i] = colorcells[i].green;
   1.208 +        ramp[(2 * 256) + i] = colorcells[i].blue;
   1.209 +    }
   1.210 +
   1.211 +    SDL_free(colorcells);
   1.212 +    return 0;
   1.213  }