void mate_rr_crtc_set_gamma (MateRRCrtc *crtc, int size, unsigned short *red, unsigned short *green, unsigned short *blue) { #ifdef HAVE_RANDR int copy_size; XRRCrtcGamma *gamma; g_return_if_fail (crtc != NULL); g_return_if_fail (red != NULL); g_return_if_fail (green != NULL); g_return_if_fail (blue != NULL); if (size != crtc->gamma_size) return; gamma = XRRAllocGamma (crtc->gamma_size); copy_size = crtc->gamma_size * sizeof (unsigned short); memcpy (gamma->red, red, copy_size); memcpy (gamma->green, green, copy_size); memcpy (gamma->blue, blue, copy_size); XRRSetCrtcGamma (DISPLAY (crtc), crtc->id, gamma); XRRFreeGamma (gamma); #endif /* HAVE_RANDR */ }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); XRRFreeGamma(gamma); } #if defined(_GLFW_HAS_XF86VM) else if (_glfw.x11.vidmode.available) { XF86VidModeSetGammaRamp(_glfw.x11.display, _glfw.x11.screen, ramp->size, (unsigned short*) ramp->red, (unsigned short*) ramp->green, (unsigned short*) ramp->blue); } #endif /*_GLFW_HAS_XF86VM*/ }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Gamma ramp size must match current ramp size"); return; } XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); XRRFreeGamma(gamma); } else if (_glfw.x11.vidmode.available) { XF86VidModeSetGammaRamp(_glfw.x11.display, _glfw.x11.screen, ramp->size, (unsigned short*) ramp->red, (unsigned short*) ramp->green, (unsigned short*) ramp->blue); } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Gamma ramp access not supported by server"); } }
void UpdateHardwareGamma(void) { float gamma = (vid_gamma->value); int i; Display* dpy = NULL; SDL_SysWMinfo info; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_VERSION(&info.version); if(!SDL_GetWindowWMInfo(window, &info)) #else if(SDL_GetWMInfo(&info) != 1) #endif { VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n"); return; } dpy = info.info.x11.display; XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window); if(res == NULL) { VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n"); return; } for(i=0; i < res->ncrtc; ++i) { int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]); size_t rampSize = len*sizeof(Uint16); Uint16* ramp = malloc(rampSize); // TODO: check for NULL if(ramp == NULL) { VID_Printf(PRINT_ALL, "Couldn't allocate &zd byte of memory for gamma ramp - OOM?!\n", rampSize); return; } CalculateGammaRamp(gamma, ramp, len); XRRCrtcGamma* gamma = XRRAllocGamma(len); memcpy(gamma->red, ramp, rampSize); memcpy(gamma->green, ramp, rampSize); memcpy(gamma->blue, ramp, rampSize); free(ramp); XRRSetCrtcGamma(dpy, res->crtcs[i], gamma); XRRFreeGamma(gamma); } XRRFreeScreenResources(res); }
int main(int argc, char **argv) { Display *dpy = XOpenDisplay(NULL); int screen = DefaultScreen(dpy); Window root = RootWindow(dpy, screen); XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); int temp = 6500; if (argc > 1) temp = atoi(argv[1]); if (temp < 1000 || temp > 10000) temp = 6500; temp -= 1000; double ratio = temp % 500 / 500.0; #define AVG(c) whitepoints[temp / 500].c * (1 - ratio) + whitepoints[temp / 500 + 1].c * ratio double gammar = AVG(r); double gammag = AVG(g); double gammab = AVG(b); int num_crtcs = res->ncrtc; for (int c = 0; c < res->ncrtc; c++) { int crtcxid = res->crtcs[c]; XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(dpy, res, crtcxid); int size = XRRGetCrtcGammaSize(dpy, crtcxid); XRRCrtcGamma *crtc_gamma = XRRAllocGamma(size); for (int i = 0; i < size; i++) { double g = 65535.0 * i / size; crtc_gamma->red[i] = g * gammar; crtc_gamma->green[i] = g * gammag; crtc_gamma->blue[i] = g * gammab; } XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma); XFree(crtc_gamma); } }
static void InitGamma() { #ifdef X11GAMMA int i=0; SDL_SysWMinfo info; Display* dpy = NULL; if(gammaRamps != NULL) // already saved gamma return; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_VERSION(&info.version); if(!SDL_GetWindowWMInfo(window, &info)) #else if(SDL_GetWMInfo(&info) != 1) #endif { VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n"); return; } dpy = info.info.x11.display; XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window); if(res == NULL) { VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n"); return; } noGammaRamps = res->ncrtc; gammaRamps = calloc(noGammaRamps, sizeof(XRRCrtcGamma*)); if(gammaRamps == NULL) { VID_Printf(PRINT_ALL, "Couldn't allocate memory for %d gamma ramps - OOM?!\n", noGammaRamps); return; } for(i=0; i < noGammaRamps; ++i) { int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]); size_t rampSize = len*sizeof(Uint16); XRRCrtcGamma* origGamma = XRRGetCrtcGamma(dpy, res->crtcs[i]); XRRCrtcGamma* gammaCopy = XRRAllocGamma(len); memcpy(gammaCopy->red, origGamma->red, rampSize); memcpy(gammaCopy->green, origGamma->green, rampSize); memcpy(gammaCopy->blue, origGamma->blue, rampSize); gammaRamps[i] = gammaCopy; } XRRFreeScreenResources(res); VID_Printf(PRINT_ALL, "Using hardware gamma via X11/xRandR.\n"); #else VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n"); #endif gl_state.hwgamma = true; vid_gamma->modified = true; }
int main (int argc, char *argv[]) { char in_name[256] = { '\000' }; char tag_name[40] = { '\000' }; int found; u_int16_t *r_ramp = NULL, *g_ramp = NULL, *b_ramp = NULL; int i; int clear = 0; int alter = 0; int donothing = 0; int printramps = 0; int calcloss = 0; int invert = 0; int correction = 0; u_int16_t tmpRampVal = 0; unsigned int r_res, g_res, b_res; int screen = -1; #ifdef FGLRX unsigned #endif int ramp_size = 256; #ifndef _WIN32 /* X11 */ XF86VidModeGamma gamma; Display *dpy = NULL; char *displayname = NULL; #ifdef FGLRX int controller = -1; FGLRX_X11Gamma_C16native fglrx_gammaramps; #endif #else char win_default_profile[MAX_PATH+1]; DWORD win_profile_len; typedef struct _GAMMARAMP { WORD Red[256]; WORD Green[256]; WORD Blue[256]; } GAMMARAMP; GAMMARAMP winGammaRamp; HDC hDc = NULL; #endif xcalib_state.verbose = 0; /* begin program part */ #ifdef _WIN32 for(i=0; i< ramp_size; i++) { winGammaRamp.Red[i] = i << 8; winGammaRamp.Blue[i] = i << 8; winGammaRamp.Green[i] = i << 8; } #endif /* command line parsing */ #ifndef _WIN32 if (argc < 2) usage (); #endif for (i = 1; i < argc; ++i) { /* help */ if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "-help")) { usage (); exit (0); } /* verbose mode */ if (!strcmp (argv[i], "-v") || !strcmp (argv[i], "-verbose")) { xcalib_state.verbose = 1; continue; } /* version */ if (!strcmp (argv[i], "-version")) { fprintf(stdout, "xcalib " XCALIB_VERSION "\n"); exit (0); } #ifndef _WIN32 /* X11 display */ if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display")) { if (++i >= argc) usage (); displayname = argv[i]; continue; } #endif /* X11 screen / Win32 monitor index */ if (!strcmp (argv[i], "-s") || !strcmp (argv[i], "-screen")) { if (++i >= argc) usage (); screen = atoi (argv[i]); continue; } #ifdef FGLRX /* ATI controller index (for FGLRX only) */ if (!strcmp (argv[i], "-x") || !strcmp (argv[i], "-controller")) { if (++i >= argc) usage (); controller = atoi (argv[i]); continue; } #endif /* print ramps to stdout */ if (!strcmp (argv[i], "-p") || !strcmp (argv[i], "-printramps")) { printramps = 1; continue; } /* print error introduced by applying ramps to stdout */ if (!strcmp (argv[i], "-l") || !strcmp (argv[i], "-loss")) { calcloss = 1; continue; } /* invert the LUT */ if (!strcmp (argv[i], "-i") || !strcmp (argv[i], "-invert")) { invert = 1; continue; } /* clear gamma lut */ if (!strcmp (argv[i], "-c") || !strcmp (argv[i], "-clear")) { clear = 1; continue; } #ifndef FGLRX /* alter existing lut */ if (!strcmp (argv[i], "-a") || !strcmp (argv[i], "-alter")) { alter = 1; continue; } #endif /* do not alter video-LUTs : work's best in conjunction with -v! */ if (!strcmp (argv[i], "-n") || !strcmp (argv[i], "-noaction")) { donothing = 1; if (++i >= argc) usage(); ramp_size = atoi(argv[i]); continue; } /* global gamma correction value (use 2.2 for WinXP Color Control-like behaviour) */ if (!strcmp (argv[i], "-gc") || !strcmp (argv[i], "-gammacor")) { if (++i >= argc) usage(); xcalib_state.gamma_cor = atof (argv[i]); correction = 1; continue; } /* take additional brightness into account */ if (!strcmp (argv[i], "-b") || !strcmp (argv[i], "-brightness")) { double brightness = 0.0; if (++i >= argc) usage(); brightness = atof(argv[i]); if(brightness < 0.0 || brightness > 99.0) { warning("brightness is out of range 0.0-99.0"); continue; } xcalib_state.redMin = xcalib_state.greenMin = xcalib_state.blueMin = brightness / 100.0; xcalib_state.redMax = xcalib_state.greenMax = xcalib_state.blueMax = (1.0 - xcalib_state.blueMin) * xcalib_state.blueMax + xcalib_state.blueMin; correction = 1; continue; } /* take additional contrast into account */ if (!strcmp (argv[i], "-co") || !strcmp (argv[i], "-contrast")) { double contrast = 100.0; if (++i >= argc) usage(); contrast = atof(argv[i]); if(contrast < 1.0 || contrast > 100.0) { warning("contrast is out of range 1.0-100.0"); continue; } xcalib_state.redMax = xcalib_state.greenMax = xcalib_state.blueMax = contrast / 100.0; xcalib_state.redMax = xcalib_state.greenMax = xcalib_state.blueMax = (1.0 - xcalib_state.blueMin) * xcalib_state.blueMax + xcalib_state.blueMin; correction = 1; continue; } /* additional red calibration */ if (!strcmp (argv[i], "-red")) { double gamma = 1.0, brightness = 0.0, contrast = 100.0; if (++i >= argc) usage(); gamma = atof(argv[i]); if(gamma < 0.1 || gamma > 5.0) { warning("gamma is out of range 0.1-5.0"); continue; } if (++i >= argc) usage(); brightness = atof(argv[i]); if(brightness < 0.0 || brightness > 99.0) { warning("brightness is out of range 0.0-99.0"); continue; } if (++i >= argc) usage(); contrast = atof(argv[i]); if(contrast < 1.0 || contrast > 100.0) { warning("contrast is out of range 1.0-100.0"); continue; } xcalib_state.redMin = brightness / 100.0; xcalib_state.redMax = (1.0 - xcalib_state.redMin) * (contrast / 100.0) + xcalib_state.redMin; xcalib_state.redGamma = gamma; correction = 1; continue; } /* additional green calibration */ if (!strcmp (argv[i], "-green")) { double gamma = 1.0, brightness = 0.0, contrast = 100.0; if (++i >= argc) usage(); gamma = atof(argv[i]); if(gamma < 0.1 || gamma > 5.0) { warning("gamma is out of range 0.1-5.0"); continue; } if (++i >= argc) usage(); brightness = atof(argv[i]); if(brightness < 0.0 || brightness > 99.0) { warning("brightness is out of range 0.0-99.0"); continue; } if (++i >= argc) usage(); contrast = atof(argv[i]); if(contrast < 1.0 || contrast > 100.0) { warning("contrast is out of range 1.0-100.0"); continue; } xcalib_state.greenMin = brightness / 100.0; xcalib_state.greenMax = (1.0 - xcalib_state.greenMin) * (contrast / 100.0) + xcalib_state.greenMin; xcalib_state.greenGamma = gamma; correction = 1; continue; } /* additional blue calibration */ if (!strcmp (argv[i], "-blue")) { double gamma = 1.0, brightness = 0.0, contrast = 100.0; if (++i >= argc) usage(); gamma = atof(argv[i]); if(gamma < 0.1 || gamma > 5.0) { warning("gamma is out of range 0.1-5.0"); continue; } if (++i >= argc) usage(); brightness = atof(argv[i]); if(brightness < 0.0 || brightness > 99.0) { warning("brightness is out of range 0.0-99.0"); continue; } if (++i >= argc) usage(); contrast = atof(argv[i]); if(contrast < 1.0 || contrast > 100.0) { warning("contrast is out of range 1.0-100.0"); continue; } xcalib_state.blueMin = brightness / 100.0; xcalib_state.blueMax = (1.0 - xcalib_state.blueMin) * (contrast / 100.0) + xcalib_state.blueMin; xcalib_state.blueGamma = gamma; correction = 1; continue; } if (i != argc - 1 && !clear && i) { usage (); } if(!clear || !alter) { if(strlen(argv[i]) < 255) strcpy (in_name, argv[i]); else usage (); } } #ifdef _WIN32 if ((!clear || !alter) && (in_name[0] == '\0')) { hDc = FindMonitor(screen); win_profile_len = MAX_PATH; win_default_profile[0] = '\0'; SetICMMode(hDc, ICM_ON); if(GetICMProfileA(hDc, (LPDWORD) &win_profile_len, (LPSTR)win_default_profile)) { if(strlen(win_default_profile) < 255) strcpy (in_name, win_default_profile); else usage(); } else usage(); } #endif #ifndef _WIN32 /* X11 initializing */ if ((dpy = XOpenDisplay (displayname)) == NULL) { if(!donothing) error ("Can't open display %s", XDisplayName (displayname)); else warning("Can't open display %s", XDisplayName (displayname)); } else if (screen == -1) screen = DefaultScreen (dpy); int xrr_version = -1; int crtc = 0; int major_versionp = 0; int minor_versionp = 0; int n = 0; Window root = RootWindow(dpy, DefaultScreen( dpy )); XRRQueryVersion( dpy, &major_versionp, &minor_versionp ); xrr_version = major_versionp*100 + minor_versionp; if(xrr_version >= 102) { XRRScreenResources * res = XRRGetScreenResources( dpy, root ); int ncrtc = 0; n = res->noutput; for( i = 0; i < n; ++i ) { RROutput output = res->outputs[i]; XRROutputInfo * output_info = XRRGetOutputInfo( dpy, res, output); if(output_info->crtc) if(ncrtc++ == screen) { crtc = output_info->crtc; ramp_size = XRRGetCrtcGammaSize( dpy, crtc ); message ("XRandR output: \t%s\n", output_info->name); } XRRFreeOutputInfo( output_info ); output_info = 0; } //XRRFreeScreenResources(res); res = 0; } /* clean gamma table if option set */ gamma.red = 1.0; gamma.green = 1.0; gamma.blue = 1.0; if (clear) { #ifndef FGLRX if(xrr_version >= 102) { XRRCrtcGamma * gamma = XRRAllocGamma (ramp_size); if(!gamma) warning ("Unable to clear screen gamma"); else { for(i=0; i < ramp_size; ++i) gamma->red[i] = gamma->green[i] = gamma->blue[i] = i * 65535 / ramp_size; XRRSetCrtcGamma (dpy, crtc, gamma); XRRFreeGamma (gamma); } } else if (!XF86VidModeSetGamma (dpy, screen, &gamma)) { #else for(i = 0; i < 256; i++) { fglrx_gammaramps.RGamma[i] = i << 2; fglrx_gammaramps.GGamma[i] = i << 2; fglrx_gammaramps.BGamma[i] = i << 2; } if (!FGLRX_X11SetGammaRamp_C16native_1024(dpy, screen, controller, 256, &fglrx_gammaramps)) { #endif XCloseDisplay (dpy); error ("Unable to reset display gamma"); } goto cleanupX; } /* get number of entries for gamma ramps */ if(!donothing) { #ifndef FGLRX if (xrr_version < 102 && !XF86VidModeGetGammaRampSize (dpy, screen, &ramp_size)) { #else if (!FGLRX_X11GetGammaRampSize(dpy, screen, &ramp_size)) { #endif XCloseDisplay (dpy); if(!donothing) error ("Unable to query gamma ramp size"); else { warning ("Unable to query gamma ramp size - assuming 256"); ramp_size = 256; } } } #else /* _WIN32 */ if(!donothing) { if(!hDc) hDc = FindMonitor(screen); if (clear) { if (!SetDeviceGammaRamp(hDc, &winGammaRamp)) error ("Unable to reset display gamma"); goto cleanupX; } } #endif /* check for ramp size being a power of 2 and inside the supported range */ switch(ramp_size) { case 16: case 32: case 64: case 128: case 256: case 512: case 1024: case 2048: case 4096: case 8192: case 16384: case 32768: case 65536: break; default: error("unsupported ramp size %u", ramp_size); } r_ramp = (unsigned short *) malloc (ramp_size * sizeof (unsigned short)); g_ramp = (unsigned short *) malloc (ramp_size * sizeof (unsigned short)); b_ramp = (unsigned short *) malloc (ramp_size * sizeof (unsigned short)); if(!alter) { if( (i = read_vcgt_internal(in_name, r_ramp, g_ramp, b_ramp, ramp_size)) <= 0) { if(i<0) warning ("Unable to read file '%s'", in_name); if(i == 0) warning ("No calibration data in ICC profile '%s' found", in_name); free(r_ramp); free(g_ramp); free(b_ramp); exit(0); } } else { #ifndef _WIN32 if (xrr_version >= 102) { XRRCrtcGamma * gamma = 0; if((gamma = XRRGetCrtcGamma(dpy, crtc)) != 0 ) warning ("Unable to get display calibration"); for (i = 0; i < ramp_size; i++) { r_ramp[i] = gamma->red[i]; g_ramp[i] = gamma->green[i]; b_ramp[i] = gamma->blue[i]; } } else if (!XF86VidModeGetGammaRamp (dpy, screen, ramp_size, r_ramp, g_ramp, b_ramp)) warning ("Unable to get display calibration"); #else if (!GetDeviceGammaRamp(hDc, &winGammaRamp)) warning ("Unable to get display calibration"); for (i = 0; i < ramp_size; i++) { r_ramp[i] = winGammaRamp.Red[i]; g_ramp[i] = winGammaRamp.Green[i]; b_ramp[i] = winGammaRamp.Blue[i]; } #endif } { float redBrightness = 0.0; float redContrast = 100.0; float redMin = 0.0; float redMax = 1.0; redMin = (double)r_ramp[0] / 65535.0; redMax = (double)r_ramp[ramp_size - 1] / 65535.0; redBrightness = redMin * 100.0; redContrast = (redMax - redMin) / (1.0 - redMin) * 100.0; message("Red Brightness: %f Contrast: %f Max: %f Min: %f\n", redBrightness, redContrast, redMax, redMin); } { float greenBrightness = 0.0; float greenContrast = 100.0; float greenMin = 0.0; float greenMax = 1.0; greenMin = (double)g_ramp[0] / 65535.0; greenMax = (double)g_ramp[ramp_size - 1] / 65535.0; greenBrightness = greenMin * 100.0; greenContrast = (greenMax - greenMin) / (1.0 - greenMin) * 100.0; message("Green Brightness: %f Contrast: %f Max: %f Min: %f\n", greenBrightness, greenContrast, greenMax, greenMin); } { float blueBrightness = 0.0; float blueContrast = 100.0; float blueMin = 0.0; float blueMax = 1.0; blueMin = (double)b_ramp[0] / 65535.0; blueMax = (double)b_ramp[ramp_size - 1] / 65535.0; blueBrightness = blueMin * 100.0; blueContrast = (blueMax - blueMin) / (1.0 - blueMin) * 100.0; message("Blue Brightness: %f Contrast: %f Max: %f Min: %f\n", blueBrightness, blueContrast, blueMax, blueMin); } if(correction != 0) { for(i=0; i<ramp_size; i++) { r_ramp[i] = 65536.0 * (((double) pow (((double) r_ramp[i]/65536.0), xcalib_state.redGamma * (double) xcalib_state.gamma_cor ) * (xcalib_state.redMax - xcalib_state.redMin)) + xcalib_state.redMin); g_ramp[i] = 65536.0 * (((double) pow (((double) g_ramp[i]/65536.0), xcalib_state.greenGamma * (double) xcalib_state.gamma_cor ) * (xcalib_state.greenMax - xcalib_state.greenMin)) + xcalib_state.greenMin); b_ramp[i] = 65536.0 * (((double) pow (((double) b_ramp[i]/65536.0), xcalib_state.blueGamma * (double) xcalib_state.gamma_cor ) * (xcalib_state.blueMax - xcalib_state.blueMin)) + xcalib_state.blueMin); } message("Altering Red LUTs with Gamma %f Min %f Max %f\n", xcalib_state.redGamma, xcalib_state.redMin, xcalib_state.redMax); message("Altering Green LUTs with Gamma %f Min %f Max %f\n", xcalib_state.greenGamma, xcalib_state.greenMin, xcalib_state.greenMax); message("Altering Blue LUTs with Gamma %f Min %f Max %f\n", xcalib_state.blueGamma, xcalib_state.blueMin, xcalib_state.blueMax); } if(!invert) { /* ramps should be monotonic - otherwise content is nonsense! */ for (i = 0; i < ramp_size - 1; i++) { if (r_ramp[i + 1] < r_ramp[i]) warning ("red gamma table not monotonic"); if (g_ramp[i + 1] < g_ramp[i]) warning ("green gamma table not monotonic"); if (b_ramp[i + 1] < b_ramp[i]) warning ("blue gamma table not monotonic"); } } else { for (i = 0; i < ramp_size; i++) { if(i >= ramp_size / 2) break; tmpRampVal = r_ramp[i]; r_ramp[i] = r_ramp[ramp_size - i - 1]; r_ramp[ramp_size - i - 1] = tmpRampVal; tmpRampVal = g_ramp[i]; g_ramp[i] = g_ramp[ramp_size - i - 1]; g_ramp[ramp_size - i - 1] = tmpRampVal; tmpRampVal = b_ramp[i]; b_ramp[i] = b_ramp[ramp_size - i - 1]; b_ramp[ramp_size - i - 1] = tmpRampVal; } } if(calcloss) { fprintf(stdout, "Resolution loss for %d entries:\n", ramp_size); r_res = 0; g_res = 0; b_res = 0; tmpRampVal = 0xffff; for(i = 0; i < ramp_size; i++) { if ((r_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { r_res++; } tmpRampVal = r_ramp[i]; } tmpRampVal = 0xffff; for(i = 0; i < ramp_size; i++) { if ((g_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { g_res++; } tmpRampVal = g_ramp[i]; } tmpRampVal = 0xffff; for(i = 0; i < ramp_size; i++) { if ((b_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { b_res++; } tmpRampVal = b_ramp[i]; } fprintf(stdout, "R: %d\tG: %d\t B: %d\t colors lost\n", ramp_size - r_res, ramp_size - g_res, ramp_size - b_res ); } #ifdef _WIN32 for (i = 0; i < ramp_size; i++) { winGammaRamp.Red[i] = r_ramp[i]; winGammaRamp.Green[i] = g_ramp[i]; winGammaRamp.Blue[i] = b_ramp[i]; } #endif if(printramps) for(i=0; i<ramp_size; i++) fprintf(stdout,"%d %d %d\n", r_ramp[i], g_ramp[i], b_ramp[i]); if(!donothing) { /* write gamma ramp to X-server */ #ifndef _WIN32 # ifdef FGLRX for(i = 0; i < ramp_size; i++) { fglrx_gammaramps.RGamma[i] = r_ramp[i] >> 6; fglrx_gammaramps.GGamma[i] = g_ramp[i] >> 6; fglrx_gammaramps.BGamma[i] = b_ramp[i] >> 6; } if (!FGLRX_X11SetGammaRamp_C16native_1024(dpy, screen, controller, ramp_size, &fglrx_gammaramps)) # else if(xrr_version >= 102) { XRRCrtcGamma * gamma = XRRAllocGamma (ramp_size); if(!gamma) warning ("Unable to calibrate display"); else { for(i=0; i < ramp_size; ++i) { gamma->red[i] = r_ramp[i]; gamma->green[i] = g_ramp[i]; gamma->blue[i] = b_ramp[i]; } XRRSetCrtcGamma (dpy, crtc, gamma); XRRFreeGamma (gamma); } } else if (!XF86VidModeSetGammaRamp (dpy, screen, ramp_size, r_ramp, g_ramp, b_ramp)) # endif #else if (!SetDeviceGammaRamp(hDc, &winGammaRamp)) #endif warning ("Unable to calibrate display"); } message ("X-LUT size: \t%d\n", ramp_size); free(r_ramp); free(g_ramp); free(b_ramp); cleanupX: #ifndef _WIN32 if(dpy) if(!donothing) XCloseDisplay (dpy); #endif return 0; } /* Basic printf type error() and warning() routines */ /* errors are printed to stderr */ void error (char *fmt, ...) { va_list args; fprintf (stderr, "Error - "); va_start (args, fmt); vfprintf (stderr, fmt, args); va_end (args); fprintf (stderr, "\n"); exit (-1); } /* warnings are printed to stdout */ void warning (char *fmt, ...) { va_list args; fprintf (stdout, "Warning - "); va_start (args, fmt); vfprintf (stdout, fmt, args); va_end (args); fprintf (stdout, "\n"); }