/* ================= GLimp_SetGamma gamma ramp is generated by the renderer from r_gamma and r_brightness for 256 elements the size of the gamma ramp can not be changed on X (I need to confirm this) ================= */ void GLimp_SetGamma(unsigned short red[256], unsigned short green[256], unsigned short blue[256]) { if ( dpy ) { int size; GLimp_SaveGamma(); XF86VidModeGetGammaRampSize( dpy, scrnum, &size); common->DPrintf("XF86VidModeGetGammaRampSize: %d\n", size); if ( size > 256 ) { // silly generic resample int i; unsigned short *l_red, *l_green, *l_blue; l_red = (unsigned short *)malloc(size*sizeof(unsigned short)); l_green = (unsigned short *)malloc(size*sizeof(unsigned short)); l_blue = (unsigned short *)malloc(size*sizeof(unsigned short)); //int r_size = 256; int r_i; float r_f; for(i=0; i<size-1; i++) { r_f = (float)i*255.0f/(float)(size-1); r_i = (int)floor(r_f); r_f -= (float)r_i; l_red[i] = (int)round((1.0f-r_f)*(float)red[r_i]+r_f*(float)red[r_i+1]); l_green[i] = (int)round((1.0f-r_f)*(float)green[r_i]+r_f*(float)green[r_i+1]); l_blue[i] = (int)round((1.0f-r_f)*(float)blue[r_i]+r_f*(float)blue[r_i+1]); } l_red[size-1] = red[255]; l_green[size-1] = green[255]; l_blue[size-1] = blue[255]; XF86VidModeSetGammaRamp( dpy, scrnum, size, l_red, l_green, l_blue ); free(l_red); free(l_green); free(l_blue); } else { XF86VidModeSetGammaRamp( dpy, scrnum, size, red, green, blue ); } } }
BOOL X11DRV_XF86VM_SetGammaRamp(LPDDGAMMARAMP ramp) { #ifdef X_XF86VidModeSetGamma XF86VidModeGamma gamma; if (xf86vm_major < 2) return FALSE; /* no gamma control */ #ifdef X_XF86VidModeSetGammaRamp else if (xf86vm_use_gammaramp) { Bool ret; wine_tsx11_lock(); ret = XF86VidModeSetGammaRamp(gdi_display, DefaultScreen(gdi_display), 256, ramp->red, ramp->green, ramp->blue); wine_tsx11_unlock(); return ret; } #endif else { if (ComputeGammaFromRamp(ramp->red, &gamma.red) && ComputeGammaFromRamp(ramp->green, &gamma.green) && ComputeGammaFromRamp(ramp->blue, &gamma.blue)) { Bool ret; wine_tsx11_lock(); ret = XF86VidModeSetGamma(gdi_display, DefaultScreen(gdi_display), &gamma); wine_tsx11_unlock(); return ret; } } #endif /* X_XF86VidModeSetGamma */ return FALSE; }
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*/ }
int vidmode_set_temperature(vidmode_state_t *state, int temp, float brightness, float gamma[3]) { int r; /* Create new gamma ramps */ uint16_t *gamma_ramps = malloc(3*state->ramp_size*sizeof(uint16_t)); if (gamma_ramps == NULL) { perror("malloc"); return -1; } uint16_t *gamma_r = &gamma_ramps[0*state->ramp_size]; uint16_t *gamma_g = &gamma_ramps[1*state->ramp_size]; uint16_t *gamma_b = &gamma_ramps[2*state->ramp_size]; colorramp_fill(gamma_r, gamma_g, gamma_b, state->ramp_size, temp, brightness, gamma); /* Set new gamma ramps */ r = XF86VidModeSetGammaRamp(state->display, state->screen_num, state->ramp_size, gamma_r, gamma_g, gamma_b); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeSetGammaRamp"); free(gamma_ramps); return -1; } free(gamma_ramps); return 0; }
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"); } }
/* ================= GLimp_RestoreGamma save and restore the original gamma of the system ================= */ void GLimp_RestoreGamma() { if (!save_rampsize) return; XF86VidModeSetGammaRamp( dpy, scrnum, save_rampsize, save_red, save_green, save_blue); free(save_red); free(save_green); free(save_blue); save_rampsize = 0; }
void RestoreHWGamma (void) { #ifdef USE_VMODE if (vid_gammaworks && customgamma) { customgamma = false; XF86VidModeSetGammaRamp(x_disp, scrnum, 256, systemgammaramp[0], systemgammaramp[1], systemgammaramp[2]); } #endif }
int GNULUTLoader::setGammaRamp(const int screenIndex, const LUT2DCorrection * const lut) const throw (CannotSetLutException) { // Bool XF86VidModeGetGammaRamp( // Display* /* dpy */, // int /* screen */, // int /* size */, // unsigned short* /* red array */, // unsigned short* /* green array */, // unsigned short* /* blue array */ // ); Display* dpy = XOpenDisplay(NULL);//prend la valeur par defaut int *cardRampSize = new int; bool res2; try { res2 = XF86VidModeGetGammaRampSize(dpy, screenIndex, cardRampSize); } catch(...) { res2 =false; } if (res2 == false) { throw CannotGetLutException("XF86VidModeGetGammaRampSize returned false."); } int rampSize = lut->getRampSize(); //printf("card size : %d, lut size : %d \n", *cardRampSize, rampSize); unsigned short * ramp = lut->get16BitsLUT(*cardRampSize); unsigned short gammaArray[3][*cardRampSize]; for (int i = 0; i < *cardRampSize; i++) { gammaArray[0][i] = ramp[i*3]; gammaArray[1][i] = ramp[i*3+1]; gammaArray[2][i] = ramp[i*3+2]; } bool res = false; try { res = XF86VidModeSetGammaRamp(dpy, screenIndex, *cardRampSize, gammaArray[0], gammaArray[1], gammaArray[2]); } catch(...) { res =false; } // XCloseDisplay(dpy); delete ramp; if (res == false) { throw CannotSetLutException("XF86VidModeSetGammaRamp returned false."); } XCloseDisplay(dpy) ; return 0; }
/* ====================== VID_SetDeviceGammaRamp Note: ramps must point to a static array ====================== */ void VID_SetDeviceGammaRamp (unsigned short *ramps) { #ifdef USE_VMODE if (vid_gammaworks) { currentgammaramp = ramps; if (vid_hwgamma_enabled) { XF86VidModeSetGammaRamp(x_disp, scrnum, 256, ramps, ramps + 256, ramps + 512); customgamma = true; } } #endif }
int vidmode_set_temperature(vidmode_state_t *state, const color_setting_t *setting) { int r; /* Create new gamma ramps */ uint16_t *gamma_ramps = malloc(3*state->ramp_size*sizeof(uint16_t)); if (gamma_ramps == NULL) { perror("malloc"); return -1; } uint16_t *gamma_r = &gamma_ramps[0*state->ramp_size]; uint16_t *gamma_g = &gamma_ramps[1*state->ramp_size]; uint16_t *gamma_b = &gamma_ramps[2*state->ramp_size]; if (state->preserve) { /* Initialize gamma ramps from saved state */ memcpy(gamma_ramps, state->saved_ramps, 3*state->ramp_size*sizeof(uint16_t)); } else { /* Initialize gamma ramps to pure state */ for (int i = 0; i < state->ramp_size; i++) { uint16_t value = (double)i/state->ramp_size * (UINT16_MAX+1); gamma_r[i] = value; gamma_g[i] = value; gamma_b[i] = value; } } colorramp_fill(gamma_r, gamma_g, gamma_b, state->ramp_size, setting); /* Set new gamma ramps */ r = XF86VidModeSetGammaRamp(state->display, state->screen_num, state->ramp_size, gamma_r, gamma_g, gamma_b); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeSetGammaRamp"); free(gamma_ramps); return -1; } free(gamma_ramps); return 0; }
void vidmode_restore(vidmode_state_t *state) { uint16_t *gamma_r = &state->saved_ramps[0*state->ramp_size]; uint16_t *gamma_g = &state->saved_ramps[1*state->ramp_size]; uint16_t *gamma_b = &state->saved_ramps[2*state->ramp_size]; /* Restore gamma ramps */ int r = XF86VidModeSetGammaRamp(state->display, state->screen_num, state->ramp_size, gamma_r, gamma_g, gamma_b); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeSetGammaRamp"); } }
int main(int argc, char **argv) { Display *dpy; int screen, len, i; float mult = -1; unsigned short rgb[256]; assert(argc == 2); mult = atof(argv[1]); assert(mult > 0.1 && mult <= 1); dpy = XOpenDisplay(NULL); assert(dpy); screen = DefaultScreen(dpy); XF86VidModeGetGammaRampSize(dpy, screen, &len); assert(len <= (ssize_t) (sizeof(rgb) / sizeof(rgb[0]))); for (i = 0; i < len; i++) rgb[i] = mult * i * 65535 / (len-1); XF86VidModeSetGammaRamp(dpy, screen, len, rgb, rgb, rgb); XCloseDisplay(dpy); return 0; }
int main(int argc, char *argv[]) { Display *dpy = XOpenDisplay(NULL); int sz, i; short *red, *green, *blue; XF86VidModeGetGammaRampSize(dpy, 0, &sz); red = malloc(sz * sizeof(short)); green = malloc(sz * sizeof(short)); blue = malloc(sz * sizeof(short)); XF86VidModeGetGammaRamp(dpy, 0, sz, red, green, blue); for (i = 0; i < sz / 2; i++) { short j = sz - i - 1, tmp; tmp = red[i]; red[i] = red[j]; red[j] = tmp; tmp = green[i]; green[i] = green[j]; green[j] = tmp; tmp = blue[i]; blue[i] = blue[j]; blue[j] = tmp; } XF86VidModeSetGammaRamp(dpy, 0, sz, red, green, blue); if ( red[0] == 0 ) printf("RESET\n"); return 0; }
void PsychLoadNormalizedGammaTable(int screenNumber, int numEntries, float *redTable, float *greenTable, float *blueTable) { CGDirectDisplayID cgDisplayID; int i; psych_uint16 RTable[256]; psych_uint16 GTable[256]; psych_uint16 BTable[256]; // Table must have 256 slots! if (numEntries!=256) PsychErrorExitMsg(PsychError_user, "Loadable hardware gamma tables must have 256 slots!"); // The X-Windows hardware LUT has 3 tables for R,G,B, 256 slots each. // Each entry is a 16-bit word with the n most significant bits used for an n-bit DAC. // Convert input table to X11 specific gammaTable: for (i=0; i<256; i++) RTable[i] = (int)(redTable[i] * 65535.0f + 0.5f); for (i=0; i<256; i++) GTable[i] = (int)(greenTable[i] * 65535.0f + 0.5f); for (i=0; i<256; i++) BTable[i] = (int)(blueTable[i] * 65535.0f + 0.5f); // Set new gammaTable: PsychGetCGDisplayIDFromScreenNumber(&cgDisplayID, screenNumber); XF86VidModeSetGammaRamp(cgDisplayID, PsychGetXScreenIdForScreen(screenNumber), 256, (unsigned short*) RTable, (unsigned short*) GTable, (unsigned short*) BTable); return; }
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"); }