pax_global_header00006660000000000000000000000064127377776170014542gustar00rootroot0000000000000052 comment=8fe031473830f6b91e3009a46446ed3ceb64affa setcolortemperature-1.3/000077500000000000000000000000001273777761700155155ustar00rootroot00000000000000setcolortemperature-1.3/.gitignore000066400000000000000000000000041273777761700174770ustar00rootroot00000000000000sct setcolortemperature-1.3/LICENSE000066400000000000000000000007721273777761700165300ustar00rootroot00000000000000This project is public domain, do as you wish The whitepoints data within sct.c has been released into the public domain by Ingo Thies: "I have calculated the table by following mathematical rules of color integration and conversion from the CIE 1931 color space to sRGB. I doubt that a numerically computed color table is copyrightable at all (in contrast to the actual software implementation). However, if it is indeed copyrightable, I have no problem with releasing it into the public domain." setcolortemperature-1.3/Makefile000066400000000000000000000005071273777761700171570ustar00rootroot00000000000000BIN = $(DESTDIR)/usr/bin MAN = $(DESTDIR)/usr/share/man/man1 sct: sct.c $(CC) sct.c $(CFLAGS) $(CPPFLAGS) -Wall -lX11 -lXrandr $(LDFLAGS) -o sct install: sct mkdir -p $(BIN) cp sct $(BIN)/sct install.man: sct.1 mkdir -p $(MAN) cp sct.1 $(MAN)/sct.1 uninstall: rm -f $(BIN)/sct rm -f $(MAN)/sct.1 clean: rm -f sct setcolortemperature-1.3/README.md000066400000000000000000000043441273777761700170010ustar00rootroot00000000000000# sct - Set Color Temperature Based on the simple sct utility written by Ted Unangst http://www.tedunangst.com/flak/post/sct-set-color-temperature ## How Does it Work? From the original blog post (http://www.tedunangst.com/flak/post/sct-set-color-temperature ): The mechanism redshift uses to change the color temperature is XRandR, the X Resize and Rotate protocol. There’s even an official xrandr configuration utility. It has a gamma option! But it’s almost wholly unsuitable for this purpose. Specifying an RGB gamma of 1.0:0.9:0.4 doesn’t make the screen “warm”. It turns gray into an ugly puke color, but leaves white just as bright and cold as before. I don’t just want to bend the gamma curve, I want to compress/truncate it such that there aren’t any blue=255 pixels. The function which xrandr uses for this purpose is XRRSetCrtcGamma which has no documentation because why would it. The protocol documents that the request exists, but not much about its operation and the Xlib style C function takes different arguments. So here’s how that works. You start by getting information for each Canadian Radio-television and Telecommunications Commission (CRTC) with the XRRGetCrtcInfo function. Then you need the size of the gamma, (XRRGetCrtcGammaSize), and memory (XRRAllocGamma). This gives you a structure with three arrays in it, suitably named red, green, and blue. The index for each array is the “input” color value. The value at each index is the “output” color value, always scaled between 0 and 65535. A common configuration would have a gamma size of 256 (8 bits), and a flat gamma ramp would then be index times 256 for each value. If we wanted to really tone down the blues, we might do index times 128 for that channel, which results in a white (255,255,255) pixel looking like a (255,255,128) pixel on an uncorrected screen. Setting the color temp of the screen really only requires about 40 lines of C (80 or so all inclusive). sct is a crude utility which does roughly that. I’d say exactly that, but some of the calculations aren’t actually exact. In any case, it looks much, much, better than anything xrandr is capable of delivering. It takes temperature values in the range 1000 to 10000. setcolortemperature-1.3/changelog000066400000000000000000000006101273777761700173640ustar00rootroot00000000000000v1.3: * Add -h option to print usage information * Prevent failing silently when temperature are out of range * Fix order of flags and add CPPFLAGS in Makefile * Add license documentation v1.2: * Add changelog * Fix compiler warnings * Sign releases v1.1: * Add support for using flags from the enviornment in the Makefile v1: * Initial setup * Add Makefile * Add manual page * Add README setcolortemperature-1.3/sct.1000066400000000000000000000012451273777761700163720ustar00rootroot00000000000000.\" Released into the public domain like sct itself .TH sct 1 "June 2016" .SH NAME sct \- set screen color temperature .SH SYNOPSIS .B sct [temperature] or .B sct [-h] .SH DESCRIPTION .B sct sets the screen's color temperature in a range from 1000 to 10000 .SH OPTIONS .IP temperature If passed a value in the correct range (see above) .B sct will set the current screen temperature to this value .IP -h If -h is passed sct will display usage information .IP none If no options are passed sct sets the color temperature to the default of 6500 .SH AUTHOR sct was written by Ted Unangst This manual page was written by Jacob Adams setcolortemperature-1.3/sct.c000066400000000000000000000050741273777761700164600ustar00rootroot00000000000000/* public domain, do as you wish * http://www.tedunangst.com/flak/post/sct-set-color-temperature */ #include #include #include #include #include #include #include #include /* cribbed from redshift, but truncated with 500K steps */ static const struct { float r; float g; float b; } whitepoints[] = { { 1.00000000, 0.18172716, 0.00000000, }, /* 1000K */ { 1.00000000, 0.42322816, 0.00000000, }, { 1.00000000, 0.54360078, 0.08679949, }, { 1.00000000, 0.64373109, 0.28819679, }, { 1.00000000, 0.71976951, 0.42860152, }, { 1.00000000, 0.77987699, 0.54642268, }, { 1.00000000, 0.82854786, 0.64816570, }, { 1.00000000, 0.86860704, 0.73688797, }, { 1.00000000, 0.90198230, 0.81465502, }, { 1.00000000, 0.93853986, 0.88130458, }, { 1.00000000, 0.97107439, 0.94305985, }, { 1.00000000, 1.00000000, 1.00000000, }, /* 6500K */ { 0.95160805, 0.96983355, 1.00000000, }, { 0.91194747, 0.94470005, 1.00000000, }, { 0.87906581, 0.92357340, 1.00000000, }, { 0.85139976, 0.90559011, 1.00000000, }, { 0.82782969, 0.89011714, 1.00000000, }, { 0.80753191, 0.87667891, 1.00000000, }, { 0.78988728, 0.86491137, 1.00000000, }, /* 10000K */ { 0.77442176, 0.85453121, 1.00000000, }, }; void usage() { printf("Usage: sct [temperature]\n" "Temperatures must be in a range from 1000-10000\n" "If no arguments are passed sct resets the display to the default temperature (6500K)\n" "If -h is passed sct will display this usage information\n"); exit(0); } 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) { if (!strcmp(argv[1],"-h")) usage(); temp = atoi(argv[1]); if (temp < 1000 || temp > 10000) usage(); } 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); for (int c = 0; c < res->ncrtc; c++) { int crtcxid = res->crtcs[c]; 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); } }