src/video/x11/SDL_x11gamma.c
changeset 2214 e7164a4dac62
parent 2213 59a667370c57
child 2216 82a133b784c9
equal deleted inserted replaced
2213:59a667370c57 2214:e7164a4dac62
    27 
    27 
    28 typedef struct
    28 typedef struct
    29 {
    29 {
    30     Display *display;
    30     Display *display;
    31     int scrNum;
    31     int scrNum;
       
    32     Colormap colormap;
    32     XStandardColormap cmap;
    33     XStandardColormap cmap;
    33     Visual visual;
    34     Visual visual;
    34 } cmapTableEntry;
    35 } cmapTableEntry;
    35 
    36 
    36 cmapTableEntry *cmapTable = NULL;
    37 cmapTableEntry *cmapTable = NULL;
    37 
    38 
    38 void
    39 /* To reduce the overhead as much as possible lets do as little as
    39 X11_TrackColormap(Display * display, int scrNum,
    40    possible. When we do have to create a colormap keep track of it and
    40                   XStandardColormap * cmap, Visual * visual)
    41    reuse it. We're going to do this for both DirectColor and
    41 {
    42    PseudoColor colormaps. */
    42     int i;
    43 
    43     cmapTableEntry *newTable = NULL;
    44 Colormap
    44 
    45 X11_LookupColormap(Display * display, int scrNum, VisualID vid)
    45     /* only tracking DirectColor colormaps because they're the only ones
    46 {
    46        with gamma ramps */
    47     int i;
    47     if (DirectColor != visual->class) {
    48 
    48         return;
       
    49     }
       
    50 
       
    51     /* search the table to find out if we already have this one. We only
       
    52        want one entry for each display, screen number, visualid
       
    53        combination */
       
    54     for (i = 0; i < numCmaps; i++) {
    49     for (i = 0; i < numCmaps; i++) {
    55         if (cmapTable[i].display == display &&
    50         if (cmapTable[i].display == display &&
    56             cmapTable[i].scrNum == scrNum &&
    51             cmapTable[i].scrNum == scrNum &&
    57             cmapTable[i].cmap.visualid == cmap->visualid) {
    52             cmapTable[i].cmap.visualid == vid) {
       
    53             return cmapTable[i].cmap.colormap;
       
    54         }
       
    55     }
       
    56 
       
    57     return 0;
       
    58 }
       
    59 
       
    60 
       
    61 void
       
    62 X11_TrackColormap(Display * display, int scrNum, Colormap colormap,
       
    63                   XStandardColormap * cmap, Visual * visual)
       
    64 {
       
    65     int i;
       
    66     cmapTableEntry *newTable = NULL;
       
    67 
       
    68     /* search the table to find out if we already have this one. We
       
    69        only want one entry for each display, screen number, visualid,
       
    70        and colormap combination */
       
    71     for (i = 0; i < numCmaps; i++) {
       
    72         if (cmapTable[i].display == display &&
       
    73             cmapTable[i].scrNum == scrNum &&
       
    74             cmapTable[i].cmap.visualid == cmap->visualid &&
       
    75             cmapTable[i].cmap.colormap == colormap) {
    58             return;
    76             return;
    59         }
    77         }
    60     }
    78     }
    61 
    79 
    62     /* increase the table by one entry. If the table is NULL create the
    80     /* increase the table by one entry. If the table is NULL create the
    73     }
    91     }
    74     cmapTable = newTable;
    92     cmapTable = newTable;
    75 
    93 
    76     cmapTable[numCmaps].display = display;
    94     cmapTable[numCmaps].display = display;
    77     cmapTable[numCmaps].scrNum = scrNum;
    95     cmapTable[numCmaps].scrNum = scrNum;
       
    96     cmapTable[numCmaps].colormap = colormap;
    78     SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap));
    97     SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap));
    79     SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
    98     SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual));
    80 
    99 
    81     numCmaps++;
   100     numCmaps++;
    82 }
   101 }
    83 
   102 
       
   103 /* The problem is that you have to have at least one DirectColor
       
   104    colormap before you can set the gamma ramps or read the gamma
       
   105    ramps. If the application has created a DirectColor window then the
       
   106    cmapTable will have at least one colormap in it and everything is
       
   107    cool. If not, then we just fail  */
       
   108 
    84 int
   109 int
    85 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
   110 X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
    86 {
   111 {
    87     return -1;
   112     Display *display;
       
   113     Colormap colormap;
       
   114     XColor *colorcells;
       
   115     int ncolors;
       
   116     int i;
       
   117     int j;
       
   118 
       
   119     int rmax, gmax, bmax;
       
   120     int rmul, gmul, bmul;
       
   121 
       
   122     for (j = 0; j < numCmaps; j++) {
       
   123         if (cmapTable[j].visual.class == DirectColor) {
       
   124             display = cmapTable[j].display;
       
   125             colormap = cmapTable[j].colormap;
       
   126             ncolors = cmapTable[j].visual.map_entries;
       
   127 
       
   128             colorcells = SDL_malloc(ncolors * sizeof(XColor));
       
   129             if (NULL == colorcells) {
       
   130                 SDL_SetError("out of memory in X11_SetDisplayGammaRamp");
       
   131                 return -1;
       
   132             }
       
   133 
       
   134             rmax = cmapTable[j].cmap.red_max + 1;
       
   135             gmax = cmapTable[j].cmap.blue_max + 1;
       
   136             bmax = cmapTable[j].cmap.green_max + 1;
       
   137 
       
   138             rmul = cmapTable[j].cmap.red_mult;
       
   139             gmul = cmapTable[j].cmap.blue_mult;
       
   140             bmul = cmapTable[j].cmap.green_mult;
       
   141 
       
   142             /* build the color table pixel values */
       
   143             for (i = 0; i < ncolors; i++) {
       
   144                 Uint32 red = (rmax * i) / ncolors;
       
   145                 Uint32 green = (gmax * i) / ncolors;
       
   146                 Uint32 blue = (bmax * i) / ncolors;
       
   147 
       
   148                 colorcells[i].pixel =
       
   149                     (red * rmul) | (green * gmul) | (blue * bmul);
       
   150                 colorcells[i].flags = DoRed | DoGreen | DoBlue;
       
   151 
       
   152                 colorcells[i].red = ramp[(0 * 256) + i];
       
   153                 colorcells[i].green = ramp[(1 * 256) + i];
       
   154                 colorcells[i].blue = ramp[(2 * 256) + i];
       
   155             }
       
   156 
       
   157             XStoreColors(display, colormap, colorcells, ncolors);
       
   158             XFlush(display);
       
   159             SDL_free(colorcells);
       
   160         }
       
   161     }
       
   162 
       
   163     return 0;
    88 }
   164 }
    89 
   165 
    90 int
   166 int
    91 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
   167 X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
    92 {
   168 {
    93     return -1;
   169     Display *display;
    94 }
   170     Colormap colormap;
       
   171     XColor *colorcells;
       
   172     int ncolors;
       
   173     int dc;
       
   174     int i;
       
   175 
       
   176     int rmax, gmax, bmax;
       
   177     int rmul, gmul, bmul;
       
   178 
       
   179     /* find the first DirectColor colormap and use it to get the gamma
       
   180        ramp */
       
   181 
       
   182     dc = -1;
       
   183     for (i = 0; i < numCmaps; i++) {
       
   184         if (cmapTable[i].visual.class == DirectColor) {
       
   185             dc = i;
       
   186             break;
       
   187         }
       
   188     }
       
   189 
       
   190     if (dc < 0) {
       
   191         return -1;
       
   192     }
       
   193 
       
   194     /* there is at least one DirectColor colormap in the cmapTable,
       
   195        let's just get the entries from that colormap */
       
   196 
       
   197     display = cmapTable[dc].display;
       
   198     colormap = cmapTable[dc].colormap;
       
   199     ncolors = cmapTable[dc].visual.map_entries;
       
   200     colorcells = SDL_malloc(ncolors * sizeof(XColor));
       
   201     if (NULL == colorcells) {
       
   202         SDL_SetError("out of memory in X11_GetDisplayGammaRamp");
       
   203         return -1;
       
   204     }
       
   205 
       
   206     rmax = cmapTable[dc].cmap.red_max + 1;
       
   207     gmax = cmapTable[dc].cmap.blue_max + 1;
       
   208     bmax = cmapTable[dc].cmap.green_max + 1;
       
   209 
       
   210     rmul = cmapTable[dc].cmap.red_mult;
       
   211     gmul = cmapTable[dc].cmap.blue_mult;
       
   212     bmul = cmapTable[dc].cmap.green_mult;
       
   213 
       
   214     /* build the color table pixel values */
       
   215     for (i = 0; i < ncolors; i++) {
       
   216         Uint32 red = (rmax * i) / ncolors;
       
   217         Uint32 green = (gmax * i) / ncolors;
       
   218         Uint32 blue = (bmax * i) / ncolors;
       
   219 
       
   220         colorcells[i].pixel = (red * rmul) | (green * gmul) | (blue * bmul);
       
   221     }
       
   222 
       
   223     XQueryColors(display, colormap, colorcells, ncolors);
       
   224 
       
   225     /* prepare the values to be returned. Note that SDL assumes that
       
   226        gamma ramps are always 3 * 256 entries long with the red entries
       
   227        in the first 256 elements, the green in the second 256 elements
       
   228        and the blue in the last 256 elements */
       
   229 
       
   230     for (i = 0; i < ncolors; i++) {
       
   231         ramp[(0 * 256) + i] = colorcells[i].red;
       
   232         ramp[(1 * 256) + i] = colorcells[i].green;
       
   233         ramp[(2 * 256) + i] = colorcells[i].blue;
       
   234     }
       
   235 
       
   236     SDL_free(colorcells);
       
   237     return 0;
       
   238 }