Mercurial > sdl-ios-xcode
changeset 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 | 23a2cb765052 |
files | src/video/x11/SDL_x11gamma.c src/video/x11/SDL_x11gamma.h src/video/x11/SDL_x11window.c |
diffstat | 3 files changed, 237 insertions(+), 44 deletions(-) [+] |
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; }
--- a/src/video/x11/SDL_x11gamma.h Tue Jul 24 18:46:45 2007 +0000 +++ b/src/video/x11/SDL_x11gamma.h Wed Jul 25 21:22:55 2007 +0000 @@ -24,8 +24,11 @@ #ifndef _SDL_x11gamma_h #define _SDL_x11gamma_h +extern Colormap X11_LookupColormap(Display * display, int scrNum, + VisualID vid); extern void X11_TrackColormap(Display * display, int scrNum, - XStandardColormap * cmap, Visual * visual); + Colormap colormap, XStandardColormap * cmap, + Visual * visual); extern int X11_SetDisplayGammaRamp(_THIS, Uint16 * ramp); extern int X11_GetDisplayGammaRamp(_THIS, Uint16 * ramp);
--- a/src/video/x11/SDL_x11window.c Tue Jul 24 18:46:45 2007 +0000 +++ b/src/video/x11/SDL_x11window.c Wed Jul 25 21:22:55 2007 +0000 @@ -181,46 +181,92 @@ } xattr.background_pixel = 0; xattr.border_pixel = 0; + if (visual->class == DirectColor || visual->class == PseudoColor) { int nmaps; + XStandardColormap cmap; XStandardColormap *stdmaps; + XColor *colorcells; + Colormap colormap; Bool found = False; + int i; + int ncolors; + int rmax, gmax, bmax; + int rmul, gmul, bmul; - /* 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)) { - int i; - for (i = 0; i < nmaps; i++) { - if (stdmaps[i].visualid == visual->visualid) { - xattr.colormap = stdmaps[i].colormap; - X11_TrackColormap(data->display, displaydata->screen, - &stdmaps[i], visual); - found = True; - break; + if (colormap = + X11_LookupColormap(data->display, displaydata->screen, + visual->visualid)) { + xattr.colormap = colormap; + } 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); } - XFree(stdmaps); - } - /* it doesn't exist, so create it */ - if (!found) { - int max = visual->map_entries - 1; - XStandardColormap *cmap = - XmuStandardColormap(data->display, displaydata->screen, - visual->visualid, depth, - XA_RGB_BEST_MAP, None, - max, max, max); - if (NULL != cmap && cmap->visualid == visual->visualid) { - xattr.colormap = cmap->colormap; - X11_TrackColormap(data->display, displaydata->screen, cmap, - visual); - } else { - SDL_SetError - ("Couldn't create window:XA_RGB_BEST_MAP not found"); + /* 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)); + } + + /* OK, we have the best color map, now copy it for use by the + program */ + + 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; + + rmul = cmap.red_mult; + gmul = cmap.blue_mult; + bmul = 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(data->display, cmap.colormap, colorcells, ncolors); + colormap = XCreateColormap(data->display, + RootWindow(data->display, + displaydata->screen), + visual, AllocAll); + XStoreColors(data->display, colormap, colorcells, ncolors); + SDL_free(colorcells); + + xattr.colormap = colormap; + X11_TrackColormap(data->display, displaydata->screen, colormap, + &cmap, visual); } } else { xattr.colormap =