Mercurial > sdl-ios-xcode
diff src/video/x11/SDL_x11gamma.c @ 2214:e7164a4dac62
Added gamma table support to X11. Also now supports DirectColor visuals.
author | Bob Pendleton <bob@pendleton.com> |
---|---|
date | Wed, 25 Jul 2007 21:22:55 +0000 |
parents | 59a667370c57 |
children | 82a133b784c9 |
line wrap: on
line diff
--- a/src/video/x11/SDL_x11gamma.c Tue Jul 24 18:46:45 2007 +0000 +++ b/src/video/x11/SDL_x11gamma.c Wed Jul 25 21:22:55 2007 +0000 @@ -29,32 +29,50 @@ { Display *display; int scrNum; + Colormap colormap; XStandardColormap cmap; Visual visual; } cmapTableEntry; cmapTableEntry *cmapTable = NULL; +/* To reduce the overhead as much as possible lets do as little as + possible. When we do have to create a colormap keep track of it and + reuse it. We're going to do this for both DirectColor and + PseudoColor colormaps. */ + +Colormap +X11_LookupColormap(Display * display, int scrNum, VisualID vid) +{ + int i; + + for (i = 0; i < numCmaps; i++) { + if (cmapTable[i].display == display && + cmapTable[i].scrNum == scrNum && + cmapTable[i].cmap.visualid == vid) { + return cmapTable[i].cmap.colormap; + } + } + + return 0; +} + + void -X11_TrackColormap(Display * display, int scrNum, +X11_TrackColormap(Display * display, int scrNum, Colormap colormap, XStandardColormap * cmap, Visual * visual) { int i; cmapTableEntry *newTable = NULL; - /* only tracking DirectColor colormaps because they're the only ones - with gamma ramps */ - if (DirectColor != visual->class) { - return; - } - - /* search the table to find out if we already have this one. We only - want one entry for each display, screen number, visualid - combination */ + /* search the table to find out if we already have this one. We + only want one entry for each display, screen number, visualid, + and colormap combination */ for (i = 0; i < numCmaps; i++) { if (cmapTable[i].display == display && cmapTable[i].scrNum == scrNum && - cmapTable[i].cmap.visualid == cmap->visualid) { + cmapTable[i].cmap.visualid == cmap->visualid && + cmapTable[i].cmap.colormap == colormap) { return; } } @@ -75,20 +93,146 @@ cmapTable[numCmaps].display = display; cmapTable[numCmaps].scrNum = scrNum; + cmapTable[numCmaps].colormap = colormap; SDL_memcpy(&cmapTable[numCmaps].cmap, cmap, sizeof(XStandardColormap)); SDL_memcpy(&cmapTable[numCmaps].visual, visual, sizeof(Visual)); numCmaps++; } +/* The problem is that you have to have at least one DirectColor + colormap before you can set the gamma ramps or read the gamma + ramps. If the application has created a DirectColor window then the + cmapTable will have at least one colormap in it and everything is + cool. If not, then we just fail */ + int X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp) { - return -1; + Display *display; + Colormap colormap; + XColor *colorcells; + int ncolors; + int i; + int j; + + int rmax, gmax, bmax; + int rmul, gmul, bmul; + + for (j = 0; j < numCmaps; j++) { + if (cmapTable[j].visual.class == DirectColor) { + display = cmapTable[j].display; + colormap = cmapTable[j].colormap; + ncolors = cmapTable[j].visual.map_entries; + + colorcells = SDL_malloc(ncolors * sizeof(XColor)); + if (NULL == colorcells) { + SDL_SetError("out of memory in X11_SetDisplayGammaRamp"); + return -1; + } + + rmax = cmapTable[j].cmap.red_max + 1; + gmax = cmapTable[j].cmap.blue_max + 1; + bmax = cmapTable[j].cmap.green_max + 1; + + rmul = cmapTable[j].cmap.red_mult; + gmul = cmapTable[j].cmap.blue_mult; + bmul = cmapTable[j].cmap.green_mult; + + /* 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; + + colorcells[i].pixel = + (red * rmul) | (green * gmul) | (blue * bmul); + colorcells[i].flags = DoRed | DoGreen | DoBlue; + + colorcells[i].red = ramp[(0 * 256) + i]; + colorcells[i].green = ramp[(1 * 256) + i]; + colorcells[i].blue = ramp[(2 * 256) + i]; + } + + XStoreColors(display, colormap, colorcells, ncolors); + XFlush(display); + SDL_free(colorcells); + } + } + + return 0; } int X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp) { - return -1; + Display *display; + Colormap colormap; + XColor *colorcells; + int ncolors; + int dc; + int i; + + int rmax, gmax, bmax; + int rmul, gmul, bmul; + + /* find the first DirectColor colormap and use it to get the gamma + ramp */ + + dc = -1; + for (i = 0; i < numCmaps; i++) { + if (cmapTable[i].visual.class == DirectColor) { + dc = i; + break; + } + } + + if (dc < 0) { + return -1; + } + + /* there is at least one DirectColor colormap in the cmapTable, + let's just get the entries from that colormap */ + + display = cmapTable[dc].display; + colormap = cmapTable[dc].colormap; + ncolors = cmapTable[dc].visual.map_entries; + colorcells = SDL_malloc(ncolors * sizeof(XColor)); + if (NULL == colorcells) { + SDL_SetError("out of memory in X11_GetDisplayGammaRamp"); + return -1; + } + + rmax = cmapTable[dc].cmap.red_max + 1; + gmax = cmapTable[dc].cmap.blue_max + 1; + bmax = cmapTable[dc].cmap.green_max + 1; + + rmul = cmapTable[dc].cmap.red_mult; + gmul = cmapTable[dc].cmap.blue_mult; + bmul = cmapTable[dc].cmap.green_mult; + + /* 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; + + colorcells[i].pixel = (red * rmul) | (green * gmul) | (blue * bmul); + } + + XQueryColors(display, colormap, colorcells, ncolors); + + /* prepare the values to be returned. Note that SDL assumes that + gamma ramps are always 3 * 256 entries long with the red entries + in the first 256 elements, the green in the second 256 elements + and the blue in the last 256 elements */ + + for (i = 0; i < ncolors; i++) { + ramp[(0 * 256) + i] = colorcells[i].red; + ramp[(1 * 256) + i] = colorcells[i].green; + ramp[(2 * 256) + i] = colorcells[i].blue; + } + + SDL_free(colorcells); + return 0; }